CloudMigrations: fix flaky test on snapshot status (#96827)

* cloudmigration: uncomment flaky test

* cloudmigration: refactor test snapshot status
This commit is contained in:
Matheus Macabu
2024-11-25 09:28:00 +01:00
committed by GitHub
parent 97fc5abb85
commit 1bf35c97e5

View File

@ -81,68 +81,56 @@ func Test_CreateGetAndDeleteToken(t *testing.T) {
} }
func Test_GetSnapshotStatusFromGMS(t *testing.T) { func Test_GetSnapshotStatusFromGMS(t *testing.T) {
s := setUpServiceTest(t, false).(*Service) setupTest := func(ctx context.Context) (service *Service, snapshotUID string, sessionUID string) {
s := setUpServiceTest(t, false).(*Service)
gmsClientFake := &gmsClientMock{} gmsClientFake := &gmsClientMock{}
s.gmsClient = gmsClientFake
// Insert a session and snapshot into the database before we start
createTokenResp, err := s.CreateToken(context.Background())
assert.NoError(t, err)
assert.NotEmpty(t, createTokenResp.Token)
sess, err := s.store.CreateMigrationSession(context.Background(), cloudmigration.CloudMigrationSession{
AuthToken: createTokenResp.Token,
})
require.NoError(t, err)
uid, err := s.store.CreateSnapshot(context.Background(), cloudmigration.CloudMigrationSnapshot{
UID: "test uid",
SessionUID: sess.UID,
Status: cloudmigration.SnapshotStatusCreating,
GMSSnapshotUID: "gms uid",
})
require.NoError(t, err)
assert.Equal(t, "test uid", uid)
// Make sure status is coming from the db only
snapshot, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
assert.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
assert.Never(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() > 0 }, time.Second, 10*time.Millisecond)
// Make the status pending processing and ensure GMS gets called
err = s.store.UpdateSnapshot(context.Background(), cloudmigration.UpdateSnapshotCmd{
UID: uid,
SessionID: sess.UID,
Status: cloudmigration.SnapshotStatusPendingProcessing,
})
assert.NoError(t, err)
cleanupFunc := func() {
if s.cancelFunc != nil {
s.cancelFunc()
}
gmsClientFake = &gmsClientMock{}
s.gmsClient = gmsClientFake s.gmsClient = gmsClientFake
err = s.store.UpdateSnapshot(context.Background(), cloudmigration.UpdateSnapshotCmd{ // Insert a session and snapshot into the database before we start
createTokenResp, err := s.CreateToken(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, createTokenResp.Token)
sess, err := s.store.CreateMigrationSession(ctx, cloudmigration.CloudMigrationSession{
AuthToken: createTokenResp.Token,
})
require.NoError(t, err)
uid, err := s.store.CreateSnapshot(ctx, cloudmigration.CloudMigrationSnapshot{
UID: "test uid",
SessionUID: sess.UID,
Status: cloudmigration.SnapshotStatusCreating,
GMSSnapshotUID: "gms uid",
})
require.NoError(t, err)
assert.Equal(t, "test uid", uid)
// Make sure status is coming from the db only
snapshot, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
assert.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
assert.Never(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() > 0 }, time.Second, 10*time.Millisecond)
// Make the status pending processing and ensure GMS gets called
err = s.store.UpdateSnapshot(ctx, cloudmigration.UpdateSnapshotCmd{
UID: uid, UID: uid,
SessionID: sess.UID, SessionID: sess.UID,
Status: cloudmigration.SnapshotStatusPendingProcessing, Status: cloudmigration.SnapshotStatusPendingProcessing,
}) })
assert.NoError(t, err) assert.NoError(t, err)
return s, uid, sess.UID
} }
checkStatusSync := func(status cloudmigration.SnapshotStatus) func() bool { checkStatusSync := func(ctx context.Context, s *Service, snapshotUID, sessionUID string, status cloudmigration.SnapshotStatus) func() bool {
return func() bool { return func() bool {
snapshot, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ snapshot, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid, SnapshotUID: snapshotUID,
SessionUID: sess.UID, SessionUID: sessionUID,
}) })
if err != nil { if err != nil {
return false return false
@ -153,135 +141,187 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) {
} }
t.Run("test case: gms snapshot initialized", func(t *testing.T) { t.Run("test case: gms snapshot initialized", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateInitialized, t.Cleanup(cancel)
s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateInitialized,
},
} }
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ s.gmsClient = gmsClientFake
SnapshotUID: uid,
SessionUID: sess.UID, _, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
}) })
assert.NoError(t, err) require.NoError(t, err)
require.Eventually(t, checkStatusSync(cloudmigration.SnapshotStatusPendingProcessing), time.Second, 10*time.Millisecond) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusPendingProcessing), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
t.Cleanup(cleanupFunc)
}) })
t.Run("test case: gms snapshot processing", func(t *testing.T) { t.Run("test case: gms snapshot processing", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateProcessing, t.Cleanup(cancel)
s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateProcessing,
},
} }
_, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ s.gmsClient = gmsClientFake
SnapshotUID: uid,
SessionUID: sess.UID, _, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
}) })
assert.NoError(t, err) require.NoError(t, err)
require.Eventually(t, checkStatusSync(cloudmigration.SnapshotStatusProcessing), time.Second, 10*time.Millisecond) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusProcessing), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
t.Cleanup(cleanupFunc)
}) })
t.Run("test case: gms snapshot finished", func(t *testing.T) { t.Run("test case: gms snapshot finished", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateFinished, t.Cleanup(cancel)
}
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
require.Eventually(t, checkStatusSync(cloudmigration.SnapshotStatusFinished), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
t.Cleanup(cleanupFunc) s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateFinished,
},
}
s.gmsClient = gmsClientFake
_, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
})
require.NoError(t, err)
require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusFinished), time.Second, 10*time.Millisecond)
require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
}) })
t.Run("test case: gms snapshot canceled", func(t *testing.T) { t.Run("test case: gms snapshot canceled", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateCanceled, t.Cleanup(cancel)
}
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
require.Eventually(t, checkStatusSync(cloudmigration.SnapshotStatusCanceled), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
t.Cleanup(cleanupFunc) s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateCanceled,
},
}
s.gmsClient = gmsClientFake
_, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
})
require.NoError(t, err)
require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusCanceled), time.Second, 10*time.Millisecond)
require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
}) })
t.Run("test case: gms snapshot error", func(t *testing.T) { t.Run("test case: gms snapshot error", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateError, t.Cleanup(cancel)
}
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
require.Eventually(t, checkStatusSync(cloudmigration.SnapshotStatusError), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
t.Cleanup(cleanupFunc) s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateError,
},
}
s.gmsClient = gmsClientFake
_, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
})
require.NoError(t, err)
require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusError), time.Second, 10*time.Millisecond)
assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount())
}) })
t.Run("test case: gms snapshot unknown", func(t *testing.T) { t.Run("test case: gms snapshot unknown", func(t *testing.T) {
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ ctx, cancel := context.WithCancel(context.Background())
State: cloudmigration.SnapshotStateUnknown, t.Cleanup(cancel)
s, snapshotUID, sessionUID := setupTest(ctx)
gmsClientFake := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateUnknown,
},
} }
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ s.gmsClient = gmsClientFake
SnapshotUID: uid,
SessionUID: sess.UID, snapshot, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
}) })
assert.NoError(t, err) require.NoError(t, err)
require.NotNil(t, snapshot)
// snapshot status should remain unchanged // snapshot status should remain unchanged
require.Eventually(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() == 1 }, time.Second, 10*time.Millisecond) require.Eventually(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() == 1 }, time.Second, 10*time.Millisecond)
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid,
SessionUID: sess.UID,
})
assert.NoError(t, err)
assert.Equal(t, cloudmigration.SnapshotStatusPendingProcessing, snapshot.Status)
t.Cleanup(cleanupFunc) snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUID,
SessionUID: sessionUID,
})
require.NoError(t, err)
require.NotNil(t, snapshot)
require.Equal(t, cloudmigration.SnapshotStatusPendingProcessing, snapshot.Status)
}) })
t.Run("GMS results applied to local snapshot", func(t *testing.T) { t.Run("GMS results applied to local snapshot", func(t *testing.T) {
t.Skip("This test is flaky and needs to be fixed") ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
gmsClientFake.getSnapshotResponse = &cloudmigration.GetSnapshotStatusResponse{ s, snapshotUID, sessionUID := setupTest(ctx)
State: cloudmigration.SnapshotStateFinished,
Results: []cloudmigration.CloudMigrationResource{ gmsClientFake := &gmsClientMock{
{ getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
Name: "A name", State: cloudmigration.SnapshotStateFinished,
Type: cloudmigration.DatasourceDataType, Results: []cloudmigration.CloudMigrationResource{
RefID: "A", {
Status: cloudmigration.ItemStatusError, Name: "A name",
Error: "fake", Type: cloudmigration.DatasourceDataType,
RefID: "A",
Status: cloudmigration.ItemStatusError,
Error: "fake",
},
}, },
}, },
} }
s.gmsClient = gmsClientFake
// ensure it is persisted // ensure it is persisted
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ snapshot, err := s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid, SnapshotUID: snapshotUID,
SessionUID: sess.UID, SessionUID: sessionUID,
}) })
assert.NoError(t, err) require.NoError(t, err)
require.NotNil(t, snapshot)
require.Eventually(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() == 1 }, time.Second, 10*time.Millisecond) require.Eventually(t, func() bool { return gmsClientFake.GetSnapshotStatusCallCount() == 1 }, time.Second, 10*time.Millisecond)
snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{ snapshot, err = s.GetSnapshot(context.Background(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: uid, SnapshotUID: snapshotUID,
SessionUID: sess.UID, SessionUID: sessionUID,
}) })
assert.NoError(t, err) require.NoError(t, err)
require.NotNil(t, snapshot)
assert.Len(t, snapshot.Resources, 1) require.Len(t, snapshot.Resources, 1)
assert.Equal(t, "A", snapshot.Resources[0].RefID) require.Equal(t, "A", snapshot.Resources[0].RefID)
assert.Equal(t, "fake", snapshot.Resources[0].Error) require.Equal(t, "fake", snapshot.Resources[0].Error)
t.Cleanup(cleanupFunc)
}) })
} }