diff --git a/.gitignore b/.gitignore index 2923430..19fad0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea **/*.pb.go -!**/*_aiptest.pb.go +!**/*aiptest.pb.go # files generated by go-semantic-release in release CI .semrel diff --git a/example/freight_service_test.go b/example/freight_service_test.go index 68f68ca..41d2c15 100644 --- a/example/freight_service_test.go +++ b/example/freight_service_test.go @@ -54,7 +54,7 @@ func Test_FreightService(t *testing.T) { func Test_FreightService_AlternativeSetup(t *testing.T) { // Even though no implementation exists, the tests will pass but be skipped. - examplefreightv1.TestFreightService(t, &aipTests{}) + examplefreightv1.TestServices(t, &aipTests{}) } type aipTests struct{} diff --git a/internal/plugin/generate.go b/internal/plugin/generate.go index 3225c77..caf0c9f 100644 --- a/internal/plugin/generate.go +++ b/internal/plugin/generate.go @@ -2,6 +2,7 @@ package plugin import ( "fmt" + "path/filepath" "sort" "github.com/einride/protoc-gen-go-aip-test/internal/util" @@ -17,11 +18,11 @@ const ( func Generate(plugin *protogen.Plugin) error { plugin.SupportedFeatures |= 1 // proto3 optional - files, err := collectServices(plugin) + filesPerPackage, err := collectServices(plugin) if err != nil { return err } - return generate(plugin, files) + return generate(plugin, filesPerPackage) } type File struct { @@ -32,9 +33,9 @@ type File struct { // collectServices collects valid services to generate AIP test code for. func collectServices( plugin *protogen.Plugin, -) ([]File, error) { +) (map[protoreflect.FullName][]File, error) { pkgResources := findResourcesPerPackage(plugin) - result := make([]File, 0, 10) + result := make(map[protoreflect.FullName][]File, 10) for _, file := range plugin.Files { if len(file.Services) == 0 || !file.Generate { continue @@ -75,25 +76,68 @@ func collectServices( } f.services = append(f.services, generator) } - result = append(result, f) + result[file.Desc.Package()] = append(result[file.Desc.Package()], f) } return result, nil } -func generate(plugin *protogen.Plugin, files []File) error { - for _, file := range files { - f := createServiceTestFile(plugin, file) - f.Skip() - for _, generator := range file.services { - if err := generator.Generate(f); err != nil { - return err +func generate(plugin *protogen.Plugin, filesPerPackage map[protoreflect.FullName][]File) error { + for _, files := range filesPerPackage { + generateForPackage(plugin, files) + for _, file := range files { + f := createServiceTestFile(plugin, file) + f.Skip() + for _, generator := range file.services { + if err := generator.Generate(f); err != nil { + return err + } + f.Unskip() } - f.Unskip() } } return nil } +func generateForPackage(plugin *protogen.Plugin, files []File) { + filename := filepath.Join(filepath.Dir(files[0].GeneratedFilenamePrefix), fileSuffix) + f := plugin.NewGeneratedFile(filename, files[0].GoImportPath) + writeHeader(files[0].File, f) + generateServicesConfigProvidersInterface(f, files) + generateTestAllServices(f, files) +} + +func generateServicesConfigProvidersInterface(f *protogen.GeneratedFile, files []File) { + name := servicesTestSuiteConfigProvidersName() + f.P("// ", name, " embeds providers for all services.") + f.P("type ", name, " interface {") + for _, file := range files { + for _, service := range file.services { + f.P(serviceTestConfigProviderName(service.service.Desc)) + } + } + f.P("}") + f.P() +} + +func generateTestAllServices(f *protogen.GeneratedFile, files []File) { + t := f.QualifiedGoIdent(protogen.GoIdent{ + GoName: "T", + GoImportPath: "testing", + }) + name := servicesTestSuiteConfigProvidersName() + funcName := "TestServices" + f.P("// ", funcName, " is the main entrypoint for starting the AIP tests for all services.") + f.P("func ", funcName, "(t *", t, ",s ", name, ") {") + for _, file := range files { + for _, service := range file.services { + name := "Test" + string(service.service.Desc.Name()) + f.P(name, "(t, s)") + } + } + f.P("}") + f.P() +} + func createServiceTestFile(plugin *protogen.Plugin, file File) *protogen.GeneratedFile { filename := fmt.Sprintf("%s_%s", file.GeneratedFilenamePrefix, fileSuffix) f := plugin.NewGeneratedFile(filename, file.GoImportPath) diff --git a/internal/plugin/name.go b/internal/plugin/name.go index 92bdf93..2c2d2f5 100644 --- a/internal/plugin/name.go +++ b/internal/plugin/name.go @@ -31,3 +31,7 @@ func resourceTestSuiteConfigName( func serviceTestConfigProviderName(service protoreflect.ServiceDescriptor) string { return string(service.Name()) + "TestSuiteConfigProvider" } + +func servicesTestSuiteConfigProvidersName() string { + return "ServicesTestSuiteConfigProviders" +} diff --git a/proto/gen/einride/example/freight/v1/aiptest.pb.go b/proto/gen/einride/example/freight/v1/aiptest.pb.go new file mode 100644 index 0000000..773df21 --- /dev/null +++ b/proto/gen/einride/example/freight/v1/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package examplefreightv1 + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + FreightServiceTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestFreightService(t, s) +} diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/aiptest.pb.go new file mode 100644 index 0000000..dc499cd --- /dev/null +++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/aiptest.pb.go @@ -0,0 +1,49 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package aiplatformpb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + DatasetServiceTestSuiteConfigProvider + DeploymentResourcePoolServiceTestSuiteConfigProvider + EndpointServiceTestSuiteConfigProvider + FeatureOnlineStoreAdminServiceTestSuiteConfigProvider + FeaturestoreServiceTestSuiteConfigProvider + FeatureRegistryServiceTestSuiteConfigProvider + IndexEndpointServiceTestSuiteConfigProvider + IndexServiceTestSuiteConfigProvider + JobServiceTestSuiteConfigProvider + MetadataServiceTestSuiteConfigProvider + ModelGardenServiceTestSuiteConfigProvider + ModelServiceTestSuiteConfigProvider + PipelineServiceTestSuiteConfigProvider + ScheduleServiceTestSuiteConfigProvider + SpecialistPoolServiceTestSuiteConfigProvider + TensorboardServiceTestSuiteConfigProvider + VizierServiceTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestDatasetService(t, s) + TestDeploymentResourcePoolService(t, s) + TestEndpointService(t, s) + TestFeatureOnlineStoreAdminService(t, s) + TestFeaturestoreService(t, s) + TestFeatureRegistryService(t, s) + TestIndexEndpointService(t, s) + TestIndexService(t, s) + TestJobService(t, s) + TestMetadataService(t, s) + TestModelGardenService(t, s) + TestModelService(t, s) + TestPipelineService(t, s) + TestScheduleService(t, s) + TestSpecialistPoolService(t, s) + TestTensorboardService(t, s) + TestVizierService(t, s) +} diff --git a/proto/gen/googleapis/area120/tables/apiv1alpha1/tablespb/aiptest.pb.go b/proto/gen/googleapis/area120/tables/apiv1alpha1/tablespb/aiptest.pb.go new file mode 100644 index 0000000..80b2793 --- /dev/null +++ b/proto/gen/googleapis/area120/tables/apiv1alpha1/tablespb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package tablespb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + TablesServiceTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestTablesService(t, s) +} diff --git a/proto/gen/googleapis/gsuiteaddons/apiv1/gsuiteaddonspb/aiptest.pb.go b/proto/gen/googleapis/gsuiteaddons/apiv1/gsuiteaddonspb/aiptest.pb.go new file mode 100644 index 0000000..4a0e86e --- /dev/null +++ b/proto/gen/googleapis/gsuiteaddons/apiv1/gsuiteaddonspb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package gsuiteaddonspb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + GSuiteAddOnsTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestGSuiteAddOns(t, s) +} diff --git a/proto/gen/googleapis/pubsub/apiv1/pubsubpb/aiptest.pb.go b/proto/gen/googleapis/pubsub/apiv1/pubsubpb/aiptest.pb.go new file mode 100644 index 0000000..34b9caa --- /dev/null +++ b/proto/gen/googleapis/pubsub/apiv1/pubsubpb/aiptest.pb.go @@ -0,0 +1,21 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package pubsubpb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + SchemaServiceTestSuiteConfigProvider + PublisherTestSuiteConfigProvider + SubscriberTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestSchemaService(t, s) + TestPublisher(t, s) + TestSubscriber(t, s) +} diff --git a/proto/gen/googleapis/scheduler/apiv1/schedulerpb/aiptest.pb.go b/proto/gen/googleapis/scheduler/apiv1/schedulerpb/aiptest.pb.go new file mode 100644 index 0000000..3318947 --- /dev/null +++ b/proto/gen/googleapis/scheduler/apiv1/schedulerpb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package schedulerpb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + CloudSchedulerTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestCloudScheduler(t, s) +} diff --git a/proto/gen/googleapis/spanner/admin/database/apiv1/databasepb/aiptest.pb.go b/proto/gen/googleapis/spanner/admin/database/apiv1/databasepb/aiptest.pb.go new file mode 100644 index 0000000..3278dfb --- /dev/null +++ b/proto/gen/googleapis/spanner/admin/database/apiv1/databasepb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package databasepb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + DatabaseAdminTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestDatabaseAdmin(t, s) +} diff --git a/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/aiptest.pb.go b/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/aiptest.pb.go new file mode 100644 index 0000000..755c57f --- /dev/null +++ b/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package instancepb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + InstanceAdminTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestInstanceAdmin(t, s) +} diff --git a/proto/gen/googleapis/spanner/apiv1/spannerpb/aiptest.pb.go b/proto/gen/googleapis/spanner/apiv1/spannerpb/aiptest.pb.go new file mode 100644 index 0000000..e190c3d --- /dev/null +++ b/proto/gen/googleapis/spanner/apiv1/spannerpb/aiptest.pb.go @@ -0,0 +1,17 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package spannerpb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { + SpannerTestSuiteConfigProvider +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { + TestSpanner(t, s) +} diff --git a/proto/gen/googleapis/spanner/executor/apiv1/executorpb/aiptest.pb.go b/proto/gen/googleapis/spanner/executor/apiv1/executorpb/aiptest.pb.go new file mode 100644 index 0000000..f9074e2 --- /dev/null +++ b/proto/gen/googleapis/spanner/executor/apiv1/executorpb/aiptest.pb.go @@ -0,0 +1,15 @@ +// Code generated by protoc-gen-go-aip-test. DO NOT EDIT. + +package executorpb + +import ( + testing "testing" +) + +// ServicesTestSuiteConfigProviders embeds providers for all services. +type ServicesTestSuiteConfigProviders interface { +} + +// TestServices is the main entrypoint for starting the AIP tests for all services. +func TestServices(t *testing.T, s ServicesTestSuiteConfigProviders) { +}