diff --git a/internal/testutil/fake_backup.go b/internal/testutil/fake_backup.go index c60b660..ed0fbf4 100644 --- a/internal/testutil/fake_backup.go +++ b/internal/testutil/fake_backup.go @@ -22,92 +22,115 @@ type FakeBackupService struct { CreateBackupScheduleFunc func(context.Context, *backupv1.CreateBackupScheduleRequest) (*backupv1.CreateBackupScheduleResponse, error) UpdateBackupScheduleFunc func(context.Context, *backupv1.UpdateBackupScheduleRequest) (*backupv1.UpdateBackupScheduleResponse, error) DeleteBackupScheduleFunc func(context.Context, *backupv1.DeleteBackupScheduleRequest) (*backupv1.DeleteBackupScheduleResponse, error) + + ListBackupsCalls MethodSpy[*backupv1.ListBackupsRequest, *backupv1.ListBackupsResponse] + GetBackupCalls MethodSpy[*backupv1.GetBackupRequest, *backupv1.GetBackupResponse] + CreateBackupCalls MethodSpy[*backupv1.CreateBackupRequest, *backupv1.CreateBackupResponse] + DeleteBackupCalls MethodSpy[*backupv1.DeleteBackupRequest, *backupv1.DeleteBackupResponse] + ListBackupRestoresCalls MethodSpy[*backupv1.ListBackupRestoresRequest, *backupv1.ListBackupRestoresResponse] + RestoreBackupCalls MethodSpy[*backupv1.RestoreBackupRequest, *backupv1.RestoreBackupResponse] + ListBackupSchedulesCalls MethodSpy[*backupv1.ListBackupSchedulesRequest, *backupv1.ListBackupSchedulesResponse] + GetBackupScheduleCalls MethodSpy[*backupv1.GetBackupScheduleRequest, *backupv1.GetBackupScheduleResponse] + CreateBackupScheduleCalls MethodSpy[*backupv1.CreateBackupScheduleRequest, *backupv1.CreateBackupScheduleResponse] + UpdateBackupScheduleCalls MethodSpy[*backupv1.UpdateBackupScheduleRequest, *backupv1.UpdateBackupScheduleResponse] + DeleteBackupScheduleCalls MethodSpy[*backupv1.DeleteBackupScheduleRequest, *backupv1.DeleteBackupScheduleResponse] } -// ListBackups delegates to ListBackupsFunc if set. +// ListBackups delegates to ListBackupsFunc if set, otherwise dispatches via ListBackupsCalls. func (f *FakeBackupService) ListBackups(ctx context.Context, req *backupv1.ListBackupsRequest) (*backupv1.ListBackupsResponse, error) { + f.ListBackupsCalls.record(req) if f.ListBackupsFunc != nil { return f.ListBackupsFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.ListBackups(ctx, req) + return f.ListBackupsCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.ListBackups) } -// GetBackup delegates to GetBackupFunc if set. +// GetBackup delegates to GetBackupFunc if set, otherwise dispatches via GetBackupCalls. func (f *FakeBackupService) GetBackup(ctx context.Context, req *backupv1.GetBackupRequest) (*backupv1.GetBackupResponse, error) { + f.GetBackupCalls.record(req) if f.GetBackupFunc != nil { return f.GetBackupFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.GetBackup(ctx, req) + return f.GetBackupCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.GetBackup) } -// CreateBackup delegates to CreateBackupFunc if set. +// CreateBackup delegates to CreateBackupFunc if set, otherwise dispatches via CreateBackupCalls. func (f *FakeBackupService) CreateBackup(ctx context.Context, req *backupv1.CreateBackupRequest) (*backupv1.CreateBackupResponse, error) { + f.CreateBackupCalls.record(req) if f.CreateBackupFunc != nil { return f.CreateBackupFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.CreateBackup(ctx, req) + return f.CreateBackupCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.CreateBackup) } -// DeleteBackup delegates to DeleteBackupFunc if set. +// DeleteBackup delegates to DeleteBackupFunc if set, otherwise dispatches via DeleteBackupCalls. func (f *FakeBackupService) DeleteBackup(ctx context.Context, req *backupv1.DeleteBackupRequest) (*backupv1.DeleteBackupResponse, error) { + f.DeleteBackupCalls.record(req) if f.DeleteBackupFunc != nil { return f.DeleteBackupFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.DeleteBackup(ctx, req) + return f.DeleteBackupCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.DeleteBackup) } -// ListBackupRestores delegates to ListBackupRestoresFunc if set. +// ListBackupRestores delegates to ListBackupRestoresFunc if set, otherwise dispatches via ListBackupRestoresCalls. func (f *FakeBackupService) ListBackupRestores(ctx context.Context, req *backupv1.ListBackupRestoresRequest) (*backupv1.ListBackupRestoresResponse, error) { + f.ListBackupRestoresCalls.record(req) if f.ListBackupRestoresFunc != nil { return f.ListBackupRestoresFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.ListBackupRestores(ctx, req) + return f.ListBackupRestoresCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.ListBackupRestores) } -// RestoreBackup delegates to RestoreBackupFunc if set. +// RestoreBackup delegates to RestoreBackupFunc if set, otherwise dispatches via RestoreBackupCalls. func (f *FakeBackupService) RestoreBackup(ctx context.Context, req *backupv1.RestoreBackupRequest) (*backupv1.RestoreBackupResponse, error) { + f.RestoreBackupCalls.record(req) if f.RestoreBackupFunc != nil { return f.RestoreBackupFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.RestoreBackup(ctx, req) + return f.RestoreBackupCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.RestoreBackup) } -// ListBackupSchedules delegates to ListBackupSchedulesFunc if set. +// ListBackupSchedules delegates to ListBackupSchedulesFunc if set, otherwise dispatches via ListBackupSchedulesCalls. func (f *FakeBackupService) ListBackupSchedules(ctx context.Context, req *backupv1.ListBackupSchedulesRequest) (*backupv1.ListBackupSchedulesResponse, error) { + f.ListBackupSchedulesCalls.record(req) if f.ListBackupSchedulesFunc != nil { return f.ListBackupSchedulesFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.ListBackupSchedules(ctx, req) + return f.ListBackupSchedulesCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.ListBackupSchedules) } -// GetBackupSchedule delegates to GetBackupScheduleFunc if set. +// GetBackupSchedule delegates to GetBackupScheduleFunc if set, otherwise dispatches via GetBackupScheduleCalls. func (f *FakeBackupService) GetBackupSchedule(ctx context.Context, req *backupv1.GetBackupScheduleRequest) (*backupv1.GetBackupScheduleResponse, error) { + f.GetBackupScheduleCalls.record(req) if f.GetBackupScheduleFunc != nil { return f.GetBackupScheduleFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.GetBackupSchedule(ctx, req) + return f.GetBackupScheduleCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.GetBackupSchedule) } -// CreateBackupSchedule delegates to CreateBackupScheduleFunc if set. +// CreateBackupSchedule delegates to CreateBackupScheduleFunc if set, otherwise dispatches via CreateBackupScheduleCalls. func (f *FakeBackupService) CreateBackupSchedule(ctx context.Context, req *backupv1.CreateBackupScheduleRequest) (*backupv1.CreateBackupScheduleResponse, error) { + f.CreateBackupScheduleCalls.record(req) if f.CreateBackupScheduleFunc != nil { return f.CreateBackupScheduleFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.CreateBackupSchedule(ctx, req) + return f.CreateBackupScheduleCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.CreateBackupSchedule) } -// UpdateBackupSchedule delegates to UpdateBackupScheduleFunc if set. +// UpdateBackupSchedule delegates to UpdateBackupScheduleFunc if set, otherwise dispatches via UpdateBackupScheduleCalls. func (f *FakeBackupService) UpdateBackupSchedule(ctx context.Context, req *backupv1.UpdateBackupScheduleRequest) (*backupv1.UpdateBackupScheduleResponse, error) { + f.UpdateBackupScheduleCalls.record(req) if f.UpdateBackupScheduleFunc != nil { return f.UpdateBackupScheduleFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.UpdateBackupSchedule(ctx, req) + return f.UpdateBackupScheduleCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.UpdateBackupSchedule) } -// DeleteBackupSchedule delegates to DeleteBackupScheduleFunc if set. +// DeleteBackupSchedule delegates to DeleteBackupScheduleFunc if set, otherwise dispatches via DeleteBackupScheduleCalls. func (f *FakeBackupService) DeleteBackupSchedule(ctx context.Context, req *backupv1.DeleteBackupScheduleRequest) (*backupv1.DeleteBackupScheduleResponse, error) { + f.DeleteBackupScheduleCalls.record(req) if f.DeleteBackupScheduleFunc != nil { return f.DeleteBackupScheduleFunc(ctx, req) } - return f.UnimplementedBackupServiceServer.DeleteBackupSchedule(ctx, req) + return f.DeleteBackupScheduleCalls.dispatch(ctx, req, f.UnimplementedBackupServiceServer.DeleteBackupSchedule) } diff --git a/internal/testutil/fake_booking.go b/internal/testutil/fake_booking.go index 202bf15..88402b3 100644 --- a/internal/testutil/fake_booking.go +++ b/internal/testutil/fake_booking.go @@ -12,12 +12,15 @@ type FakeBookingService struct { bookingv1.UnimplementedBookingServiceServer ListPackagesFunc func(context.Context, *bookingv1.ListPackagesRequest) (*bookingv1.ListPackagesResponse, error) + + ListPackagesCalls MethodSpy[*bookingv1.ListPackagesRequest, *bookingv1.ListPackagesResponse] } -// ListPackages delegates to ListPackagesFunc if set. +// ListPackages delegates to ListPackagesFunc if set, otherwise dispatches via ListPackagesCalls. func (f *FakeBookingService) ListPackages(ctx context.Context, req *bookingv1.ListPackagesRequest) (*bookingv1.ListPackagesResponse, error) { + f.ListPackagesCalls.record(req) if f.ListPackagesFunc != nil { return f.ListPackagesFunc(ctx, req) } - return f.UnimplementedBookingServiceServer.ListPackages(ctx, req) + return f.ListPackagesCalls.dispatch(ctx, req, f.UnimplementedBookingServiceServer.ListPackages) } diff --git a/internal/testutil/fake_cluster.go b/internal/testutil/fake_cluster.go index b2c55ac..6c5c563 100644 --- a/internal/testutil/fake_cluster.go +++ b/internal/testutil/fake_cluster.go @@ -21,84 +21,105 @@ type FakeClusterService struct { UnsuspendClusterFunc func(context.Context, *clusterv1.UnsuspendClusterRequest) (*clusterv1.UnsuspendClusterResponse, error) SuggestClusterNameFunc func(context.Context, *clusterv1.SuggestClusterNameRequest) (*clusterv1.SuggestClusterNameResponse, error) ListQdrantReleasesFunc func(context.Context, *clusterv1.ListQdrantReleasesRequest) (*clusterv1.ListQdrantReleasesResponse, error) + + ListClustersCalls MethodSpy[*clusterv1.ListClustersRequest, *clusterv1.ListClustersResponse] + GetClusterCalls MethodSpy[*clusterv1.GetClusterRequest, *clusterv1.GetClusterResponse] + CreateClusterCalls MethodSpy[*clusterv1.CreateClusterRequest, *clusterv1.CreateClusterResponse] + UpdateClusterCalls MethodSpy[*clusterv1.UpdateClusterRequest, *clusterv1.UpdateClusterResponse] + DeleteClusterCalls MethodSpy[*clusterv1.DeleteClusterRequest, *clusterv1.DeleteClusterResponse] + RestartClusterCalls MethodSpy[*clusterv1.RestartClusterRequest, *clusterv1.RestartClusterResponse] + SuspendClusterCalls MethodSpy[*clusterv1.SuspendClusterRequest, *clusterv1.SuspendClusterResponse] + UnsuspendClusterCalls MethodSpy[*clusterv1.UnsuspendClusterRequest, *clusterv1.UnsuspendClusterResponse] + SuggestClusterNameCalls MethodSpy[*clusterv1.SuggestClusterNameRequest, *clusterv1.SuggestClusterNameResponse] + ListQdrantReleasesCalls MethodSpy[*clusterv1.ListQdrantReleasesRequest, *clusterv1.ListQdrantReleasesResponse] } -// ListClusters delegates to ListClustersFunc if set. +// ListClusters delegates to ListClustersFunc if set, otherwise dispatches via ListClustersCalls. func (f *FakeClusterService) ListClusters(ctx context.Context, req *clusterv1.ListClustersRequest) (*clusterv1.ListClustersResponse, error) { + f.ListClustersCalls.record(req) if f.ListClustersFunc != nil { return f.ListClustersFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.ListClusters(ctx, req) + return f.ListClustersCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.ListClusters) } -// GetCluster delegates to GetClusterFunc if set. +// GetCluster delegates to GetClusterFunc if set, otherwise dispatches via GetClusterCalls. func (f *FakeClusterService) GetCluster(ctx context.Context, req *clusterv1.GetClusterRequest) (*clusterv1.GetClusterResponse, error) { + f.GetClusterCalls.record(req) if f.GetClusterFunc != nil { return f.GetClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.GetCluster(ctx, req) + return f.GetClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.GetCluster) } -// CreateCluster delegates to CreateClusterFunc if set. +// CreateCluster delegates to CreateClusterFunc if set, otherwise dispatches via CreateClusterCalls. func (f *FakeClusterService) CreateCluster(ctx context.Context, req *clusterv1.CreateClusterRequest) (*clusterv1.CreateClusterResponse, error) { + f.CreateClusterCalls.record(req) if f.CreateClusterFunc != nil { return f.CreateClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.CreateCluster(ctx, req) + return f.CreateClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.CreateCluster) } -// UpdateCluster delegates to UpdateClusterFunc if set. +// UpdateCluster delegates to UpdateClusterFunc if set, otherwise dispatches via UpdateClusterCalls. func (f *FakeClusterService) UpdateCluster(ctx context.Context, req *clusterv1.UpdateClusterRequest) (*clusterv1.UpdateClusterResponse, error) { + f.UpdateClusterCalls.record(req) if f.UpdateClusterFunc != nil { return f.UpdateClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.UpdateCluster(ctx, req) + return f.UpdateClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.UpdateCluster) } -// DeleteCluster delegates to DeleteClusterFunc if set. +// DeleteCluster delegates to DeleteClusterFunc if set, otherwise dispatches via DeleteClusterCalls. func (f *FakeClusterService) DeleteCluster(ctx context.Context, req *clusterv1.DeleteClusterRequest) (*clusterv1.DeleteClusterResponse, error) { + f.DeleteClusterCalls.record(req) if f.DeleteClusterFunc != nil { return f.DeleteClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.DeleteCluster(ctx, req) + return f.DeleteClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.DeleteCluster) } -// RestartCluster delegates to RestartClusterFunc if set. +// RestartCluster delegates to RestartClusterFunc if set, otherwise dispatches via RestartClusterCalls. func (f *FakeClusterService) RestartCluster(ctx context.Context, req *clusterv1.RestartClusterRequest) (*clusterv1.RestartClusterResponse, error) { + f.RestartClusterCalls.record(req) if f.RestartClusterFunc != nil { return f.RestartClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.RestartCluster(ctx, req) + return f.RestartClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.RestartCluster) } -// SuspendCluster delegates to SuspendClusterFunc if set. +// SuspendCluster delegates to SuspendClusterFunc if set, otherwise dispatches via SuspendClusterCalls. func (f *FakeClusterService) SuspendCluster(ctx context.Context, req *clusterv1.SuspendClusterRequest) (*clusterv1.SuspendClusterResponse, error) { + f.SuspendClusterCalls.record(req) if f.SuspendClusterFunc != nil { return f.SuspendClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.SuspendCluster(ctx, req) + return f.SuspendClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.SuspendCluster) } -// UnsuspendCluster delegates to UnsuspendClusterFunc if set. +// UnsuspendCluster delegates to UnsuspendClusterFunc if set, otherwise dispatches via UnsuspendClusterCalls. func (f *FakeClusterService) UnsuspendCluster(ctx context.Context, req *clusterv1.UnsuspendClusterRequest) (*clusterv1.UnsuspendClusterResponse, error) { + f.UnsuspendClusterCalls.record(req) if f.UnsuspendClusterFunc != nil { return f.UnsuspendClusterFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.UnsuspendCluster(ctx, req) + return f.UnsuspendClusterCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.UnsuspendCluster) } -// SuggestClusterName delegates to SuggestClusterNameFunc if set. +// SuggestClusterName delegates to SuggestClusterNameFunc if set, otherwise dispatches via SuggestClusterNameCalls. func (f *FakeClusterService) SuggestClusterName(ctx context.Context, req *clusterv1.SuggestClusterNameRequest) (*clusterv1.SuggestClusterNameResponse, error) { + f.SuggestClusterNameCalls.record(req) if f.SuggestClusterNameFunc != nil { return f.SuggestClusterNameFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.SuggestClusterName(ctx, req) + return f.SuggestClusterNameCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.SuggestClusterName) } -// ListQdrantReleases delegates to ListQdrantReleasesFunc if set. +// ListQdrantReleases delegates to ListQdrantReleasesFunc if set, otherwise dispatches via ListQdrantReleasesCalls. func (f *FakeClusterService) ListQdrantReleases(ctx context.Context, req *clusterv1.ListQdrantReleasesRequest) (*clusterv1.ListQdrantReleasesResponse, error) { + f.ListQdrantReleasesCalls.record(req) if f.ListQdrantReleasesFunc != nil { return f.ListQdrantReleasesFunc(ctx, req) } - return f.UnimplementedClusterServiceServer.ListQdrantReleases(ctx, req) + return f.ListQdrantReleasesCalls.dispatch(ctx, req, f.UnimplementedClusterServiceServer.ListQdrantReleases) } diff --git a/internal/testutil/fake_database_api_key.go b/internal/testutil/fake_database_api_key.go index e741f99..052cd3d 100644 --- a/internal/testutil/fake_database_api_key.go +++ b/internal/testutil/fake_database_api_key.go @@ -14,28 +14,35 @@ type FakeDatabaseApiKeyService struct { ListDatabaseApiKeysFunc func(context.Context, *clusterauthv2.ListDatabaseApiKeysRequest) (*clusterauthv2.ListDatabaseApiKeysResponse, error) CreateDatabaseApiKeyFunc func(context.Context, *clusterauthv2.CreateDatabaseApiKeyRequest) (*clusterauthv2.CreateDatabaseApiKeyResponse, error) DeleteDatabaseApiKeyFunc func(context.Context, *clusterauthv2.DeleteDatabaseApiKeyRequest) (*clusterauthv2.DeleteDatabaseApiKeyResponse, error) + + ListDatabaseApiKeysCalls MethodSpy[*clusterauthv2.ListDatabaseApiKeysRequest, *clusterauthv2.ListDatabaseApiKeysResponse] + CreateDatabaseApiKeyCalls MethodSpy[*clusterauthv2.CreateDatabaseApiKeyRequest, *clusterauthv2.CreateDatabaseApiKeyResponse] + DeleteDatabaseApiKeyCalls MethodSpy[*clusterauthv2.DeleteDatabaseApiKeyRequest, *clusterauthv2.DeleteDatabaseApiKeyResponse] } -// ListDatabaseApiKeys delegates to ListDatabaseApiKeysFunc if set. +// ListDatabaseApiKeys delegates to ListDatabaseApiKeysFunc if set, otherwise dispatches via ListDatabaseApiKeysCalls. func (f *FakeDatabaseApiKeyService) ListDatabaseApiKeys(ctx context.Context, req *clusterauthv2.ListDatabaseApiKeysRequest) (*clusterauthv2.ListDatabaseApiKeysResponse, error) { + f.ListDatabaseApiKeysCalls.record(req) if f.ListDatabaseApiKeysFunc != nil { return f.ListDatabaseApiKeysFunc(ctx, req) } - return f.UnimplementedDatabaseApiKeyServiceServer.ListDatabaseApiKeys(ctx, req) + return f.ListDatabaseApiKeysCalls.dispatch(ctx, req, f.UnimplementedDatabaseApiKeyServiceServer.ListDatabaseApiKeys) } -// CreateDatabaseApiKey delegates to CreateDatabaseApiKeyFunc if set. +// CreateDatabaseApiKey delegates to CreateDatabaseApiKeyFunc if set, otherwise dispatches via CreateDatabaseApiKeyCalls. func (f *FakeDatabaseApiKeyService) CreateDatabaseApiKey(ctx context.Context, req *clusterauthv2.CreateDatabaseApiKeyRequest) (*clusterauthv2.CreateDatabaseApiKeyResponse, error) { + f.CreateDatabaseApiKeyCalls.record(req) if f.CreateDatabaseApiKeyFunc != nil { return f.CreateDatabaseApiKeyFunc(ctx, req) } - return f.UnimplementedDatabaseApiKeyServiceServer.CreateDatabaseApiKey(ctx, req) + return f.CreateDatabaseApiKeyCalls.dispatch(ctx, req, f.UnimplementedDatabaseApiKeyServiceServer.CreateDatabaseApiKey) } -// DeleteDatabaseApiKey delegates to DeleteDatabaseApiKeyFunc if set. +// DeleteDatabaseApiKey delegates to DeleteDatabaseApiKeyFunc if set, otherwise dispatches via DeleteDatabaseApiKeyCalls. func (f *FakeDatabaseApiKeyService) DeleteDatabaseApiKey(ctx context.Context, req *clusterauthv2.DeleteDatabaseApiKeyRequest) (*clusterauthv2.DeleteDatabaseApiKeyResponse, error) { + f.DeleteDatabaseApiKeyCalls.record(req) if f.DeleteDatabaseApiKeyFunc != nil { return f.DeleteDatabaseApiKeyFunc(ctx, req) } - return f.UnimplementedDatabaseApiKeyServiceServer.DeleteDatabaseApiKey(ctx, req) + return f.DeleteDatabaseApiKeyCalls.dispatch(ctx, req, f.UnimplementedDatabaseApiKeyServiceServer.DeleteDatabaseApiKey) } diff --git a/internal/testutil/fake_platform.go b/internal/testutil/fake_platform.go index edb64b4..a89c846 100644 --- a/internal/testutil/fake_platform.go +++ b/internal/testutil/fake_platform.go @@ -13,20 +13,25 @@ type FakePlatformService struct { ListCloudProvidersFunc func(context.Context, *platformv1.ListCloudProvidersRequest) (*platformv1.ListCloudProvidersResponse, error) ListCloudProviderRegionsFunc func(context.Context, *platformv1.ListCloudProviderRegionsRequest) (*platformv1.ListCloudProviderRegionsResponse, error) + + ListCloudProvidersCalls MethodSpy[*platformv1.ListCloudProvidersRequest, *platformv1.ListCloudProvidersResponse] + ListCloudProviderRegionsCalls MethodSpy[*platformv1.ListCloudProviderRegionsRequest, *platformv1.ListCloudProviderRegionsResponse] } -// ListCloudProviders delegates to ListCloudProvidersFunc if set. +// ListCloudProviders delegates to ListCloudProvidersFunc if set, otherwise dispatches via ListCloudProvidersCalls. func (f *FakePlatformService) ListCloudProviders(ctx context.Context, req *platformv1.ListCloudProvidersRequest) (*platformv1.ListCloudProvidersResponse, error) { + f.ListCloudProvidersCalls.record(req) if f.ListCloudProvidersFunc != nil { return f.ListCloudProvidersFunc(ctx, req) } - return f.UnimplementedPlatformServiceServer.ListCloudProviders(ctx, req) + return f.ListCloudProvidersCalls.dispatch(ctx, req, f.UnimplementedPlatformServiceServer.ListCloudProviders) } -// ListCloudProviderRegions delegates to ListCloudProviderRegionsFunc if set. +// ListCloudProviderRegions delegates to ListCloudProviderRegionsFunc if set, otherwise dispatches via ListCloudProviderRegionsCalls. func (f *FakePlatformService) ListCloudProviderRegions(ctx context.Context, req *platformv1.ListCloudProviderRegionsRequest) (*platformv1.ListCloudProviderRegionsResponse, error) { + f.ListCloudProviderRegionsCalls.record(req) if f.ListCloudProviderRegionsFunc != nil { return f.ListCloudProviderRegionsFunc(ctx, req) } - return f.UnimplementedPlatformServiceServer.ListCloudProviderRegions(ctx, req) + return f.ListCloudProviderRegionsCalls.dispatch(ctx, req, f.UnimplementedPlatformServiceServer.ListCloudProviderRegions) } diff --git a/internal/testutil/method_spy.go b/internal/testutil/method_spy.go new file mode 100644 index 0000000..f3b0310 --- /dev/null +++ b/internal/testutil/method_spy.go @@ -0,0 +1,101 @@ +package testutil + +import ( + "context" + "sync" +) + +// MethodSpy records calls to a single RPC method and optionally dispatches +// to per-call or fallback handlers. Use the *Calls fields on fake services +// instead of managing call counters and captured requests manually. +// +// Priority when handling a call: *Func field > OnCall handler > Always handler > Unimplemented default. +type MethodSpy[Req, Resp any] struct { + mu sync.Mutex + requests []Req + handlers []func(context.Context, Req) (Resp, error) + fallback func(context.Context, Req) (Resp, error) +} + +// OnCall registers a handler for the i-th call (0-indexed). Chainable. +func (m *MethodSpy[Req, Resp]) OnCall(i int, fn func(context.Context, Req) (Resp, error)) *MethodSpy[Req, Resp] { + m.mu.Lock() + defer m.mu.Unlock() + for len(m.handlers) <= i { + m.handlers = append(m.handlers, nil) + } + m.handlers[i] = fn + return m +} + +// Always sets a fallback handler invoked for every call that has no matching OnCall entry. +// If neither OnCall nor Always is set the method falls back to the gRPC Unimplemented default. +func (m *MethodSpy[Req, Resp]) Always(fn func(context.Context, Req) (Resp, error)) *MethodSpy[Req, Resp] { + m.mu.Lock() + defer m.mu.Unlock() + m.fallback = fn + return m +} + +// Count returns how many times the method has been called. +func (m *MethodSpy[Req, Resp]) Count() int { + m.mu.Lock() + defer m.mu.Unlock() + return len(m.requests) +} + +// All returns a copy of all captured requests in call order. +func (m *MethodSpy[Req, Resp]) All() []Req { + m.mu.Lock() + defer m.mu.Unlock() + out := make([]Req, len(m.requests)) + copy(out, m.requests) + return out +} + +// Last returns the most recent request and true, or the zero value and false if never called. +func (m *MethodSpy[Req, Resp]) Last() (Req, bool) { + m.mu.Lock() + defer m.mu.Unlock() + if len(m.requests) == 0 { + var zero Req + return zero, false + } + return m.requests[len(m.requests)-1], true +} + +// Reset clears captured requests and all registered handlers. +func (m *MethodSpy[Req, Resp]) Reset() { + m.mu.Lock() + defer m.mu.Unlock() + m.requests = nil + m.handlers = nil + m.fallback = nil +} + +// record appends the request to the captured list. Called before dispatch. +func (m *MethodSpy[Req, Resp]) record(req Req) { + m.mu.Lock() + defer m.mu.Unlock() + m.requests = append(m.requests, req) +} + +// dispatch selects the handler for the current call index (based on len(requests) +// after recording), falls back to Always, then falls back to unimpl. +func (m *MethodSpy[Req, Resp]) dispatch(ctx context.Context, req Req, unimpl func(context.Context, Req) (Resp, error)) (Resp, error) { + m.mu.Lock() + idx := len(m.requests) - 1 + var handler func(context.Context, Req) (Resp, error) + if idx >= 0 && idx < len(m.handlers) { + handler = m.handlers[idx] + } + if handler == nil { + handler = m.fallback + } + m.mu.Unlock() + + if handler != nil { + return handler(ctx, req) + } + return unimpl(ctx, req) +} diff --git a/internal/testutil/server.go b/internal/testutil/server.go index 62caabf..d97e624 100644 --- a/internal/testutil/server.go +++ b/internal/testutil/server.go @@ -141,6 +141,15 @@ func newBaseTestEnv(t *testing.T, cfg *envConfig) *TestEnv { s := state.New(cfg.version) s.SetClient(client) + var once sync.Once + cleanup := func() { + once.Do(func() { + _ = client.Close() + srv.Stop() + }) + } + t.Cleanup(cleanup) + return &TestEnv{ State: s, Server: fake, @@ -149,10 +158,7 @@ func newBaseTestEnv(t *testing.T, cfg *envConfig) *TestEnv { DatabaseApiKeyServer: fakeDatabaseApiKey, BackupServer: fakeBackup, Capture: capture, - Cleanup: func() { - _ = client.Close() - srv.Stop() - }, + Cleanup: cleanup, } }