From 12fc9954385b7173e9478cb7a903ee8b40ba762d Mon Sep 17 00:00:00 2001 From: Vicente Pinto Date: Thu, 10 Oct 2024 15:41:57 +0100 Subject: [PATCH 1/2] Refactor server resizeWaitHandler --- core/wait/wait.go | 11 +++-- services/iaasalpha/wait/wait.go | 46 +++++++----------- services/iaasalpha/wait/wait_test.go | 72 +--------------------------- 3 files changed, 24 insertions(+), 105 deletions(-) diff --git a/core/wait/wait.go b/core/wait/wait.go index a07901c2c..e817b1fa2 100644 --- a/core/wait/wait.go +++ b/core/wait/wait.go @@ -20,11 +20,12 @@ type AsyncActionCheck[T any] func() (waitFinished bool, response *T, err error) // AsyncActionHandler handles waiting for a specific async action to be finished. type AsyncActionHandler[T any] struct { - checkFn AsyncActionCheck[T] - sleepBeforeWait time.Duration - throttle time.Duration - timeout time.Duration - tempErrRetryLimit int + checkFn AsyncActionCheck[T] + sleepBeforeWait time.Duration + throttle time.Duration + timeout time.Duration + tempErrRetryLimit int + IntermediateStateReached bool } // New initializes an AsyncActionHandler diff --git a/services/iaasalpha/wait/wait.go b/services/iaasalpha/wait/wait.go index c7772dc1d..93c6ad855 100644 --- a/services/iaasalpha/wait/wait.go +++ b/services/iaasalpha/wait/wait.go @@ -100,47 +100,33 @@ func CreateServerWaitHandler(ctx context.Context, a APIClientInterface, projectI return handler } -// ResizingServerWaitHandler will wait for a server to be resizing -// Ii is an intermediate step inside the ResizeServerWaitHandler -func resizingServerWaitHandler(ctx context.Context, a APIClientInterface, projectId, serverId string) *wait.AsyncActionHandler[iaasalpha.Server] { +// ResizeServerWaitHandler will wait for server resize +// It checks for an intermediate resizing status and only then waits for the server to become active +func ResizeServerWaitHandler(ctx context.Context, a APIClientInterface, projectId, serverId string) (h *wait.AsyncActionHandler[iaasalpha.Server]) { handler := wait.New(func() (waitFinished bool, response *iaasalpha.Server, err error) { server, err := a.GetServerExecute(ctx, projectId, serverId) if err != nil { return false, server, err } + if server.Id == nil || server.Status == nil { return false, server, fmt.Errorf("resizing failed for server with id %s, the response is not valid: the id or the status are missing", serverId) } - if *server.Id == serverId && *server.Status == ServerResizingStatus { - return true, server, nil - } - if *server.Id == serverId && *server.Status == ErrorStatus { - if server.ErrorMessage != nil { - return true, server, fmt.Errorf("resizing failed for server with id %s: %s", serverId, *server.ErrorMessage) + + if !h.IntermediateStateReached { + if *server.Id == serverId && *server.Status == ServerResizingStatus { + h.IntermediateStateReached = true + return false, server, nil } - return true, server, fmt.Errorf("resizing failed for server with id %s", serverId) + if *server.Id == serverId && *server.Status == ErrorStatus { + if server.ErrorMessage != nil { + return true, server, fmt.Errorf("resizing failed for server with id %s: %s", serverId, *server.ErrorMessage) + } + return true, server, fmt.Errorf("resizing failed for server with id %s", serverId) + } + return false, server, nil } - return false, server, nil - }) - handler.SetTimeout(10 * time.Minute) - return handler -} -// ResizeServerWaitHandler will wait for server resize -// It checks for an intermediate resizing status and only then waits for the server to become active -func ResizeServerWaitHandler(ctx context.Context, a APIClientInterface, projectId, serverId string) *wait.AsyncActionHandler[iaasalpha.Server] { - handler := wait.New(func() (waitFinished bool, response *iaasalpha.Server, err error) { - server, err := resizingServerWaitHandler(ctx, a, projectId, serverId).WaitWithContext(ctx) - if err != nil { - return false, server, err - } - server, err = a.GetServerExecute(ctx, projectId, serverId) - if err != nil { - return false, server, err - } - if server.Id == nil || server.Status == nil { - return false, server, fmt.Errorf("resizing failed for server with id %s, the response is not valid: the id or the status are missing", serverId) - } if *server.Id == serverId && *server.Status == ServerActiveStatus { return true, server, nil } diff --git a/services/iaasalpha/wait/wait_test.go b/services/iaasalpha/wait/wait_test.go index aa0e47956..88e815d59 100644 --- a/services/iaasalpha/wait/wait_test.go +++ b/services/iaasalpha/wait/wait_test.go @@ -319,72 +319,6 @@ func TestDeleteServerWaitHandler(t *testing.T) { } } -func TestResizingServerWaitHandler(t *testing.T) { - tests := []struct { - desc string - getFails bool - resourceState string - wantErr bool - wantResp bool - }{ - { - desc: "resizing", - getFails: false, - resourceState: ServerResizingStatus, - wantErr: false, - wantResp: true, - }, - { - desc: "error_status", - getFails: false, - resourceState: ErrorStatus, - wantErr: true, - wantResp: true, - }, - { - desc: "get_fails", - getFails: true, - resourceState: "", - wantErr: true, - wantResp: false, - }, - { - desc: "timeout", - getFails: false, - resourceState: "ANOTHER Status", - wantErr: true, - wantResp: true, - }, - } - for _, tt := range tests { - t.Run(tt.desc, func(t *testing.T) { - apiClient := &apiClientMocked{ - getServerFails: tt.getFails, - resourceState: tt.resourceState, - } - - var wantRes *iaasalpha.Server - if tt.wantResp { - wantRes = &iaasalpha.Server{ - Id: utils.Ptr("sid"), - Status: &tt.resourceState, - } - } - - handler := resizingServerWaitHandler(context.Background(), apiClient, "pid", "sid") - - gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) - - if (err != nil) != tt.wantErr { - t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) - } - if !cmp.Equal(gotRes, wantRes) { - t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes) - } - }) - } -} - func TestResizeServerWaitHandler(t *testing.T) { tests := []struct { desc string @@ -449,11 +383,9 @@ func TestResizeServerWaitHandler(t *testing.T) { } } - timeoutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) - defer cancel() - handler := ResizeServerWaitHandler(timeoutCtx, apiClient, "pid", "sid") + handler := ResizeServerWaitHandler(context.Background(), apiClient, "pid", "sid") - gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(timeoutCtx) + gotRes, err := handler.SetThrottle(1 * time.Millisecond).SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) From 66ef57f49b2ceb0c6492a743191b1ed47fb9905b Mon Sep 17 00:00:00 2001 From: Vicente Pinto Date: Thu, 10 Oct 2024 15:54:58 +0100 Subject: [PATCH 2/2] Change after review --- services/iaasalpha/wait/wait.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/services/iaasalpha/wait/wait.go b/services/iaasalpha/wait/wait.go index 93c6ad855..55449990b 100644 --- a/services/iaasalpha/wait/wait.go +++ b/services/iaasalpha/wait/wait.go @@ -113,29 +113,25 @@ func ResizeServerWaitHandler(ctx context.Context, a APIClientInterface, projectI return false, server, fmt.Errorf("resizing failed for server with id %s, the response is not valid: the id or the status are missing", serverId) } + if *server.Id == serverId && *server.Status == ErrorStatus { + if server.ErrorMessage != nil { + return true, server, fmt.Errorf("resizing failed for server with id %s: %s", serverId, *server.ErrorMessage) + } + return true, server, fmt.Errorf("resizing failed for server with id %s", serverId) + } + if !h.IntermediateStateReached { if *server.Id == serverId && *server.Status == ServerResizingStatus { h.IntermediateStateReached = true return false, server, nil } - if *server.Id == serverId && *server.Status == ErrorStatus { - if server.ErrorMessage != nil { - return true, server, fmt.Errorf("resizing failed for server with id %s: %s", serverId, *server.ErrorMessage) - } - return true, server, fmt.Errorf("resizing failed for server with id %s", serverId) - } return false, server, nil } if *server.Id == serverId && *server.Status == ServerActiveStatus { return true, server, nil } - if *server.Id == serverId && *server.Status == ErrorStatus { - if server.ErrorMessage != nil { - return true, server, fmt.Errorf("resizing failed for server with id %s: %s", serverId, *server.ErrorMessage) - } - return true, server, fmt.Errorf("resizing failed for server with id %s", serverId) - } + return false, server, nil }) handler.SetTimeout(20 * time.Minute)