package integration_test import ( "github.com/udacity/graphb" "edge-infra.dev/pkg/edge/api/graph/model" "edge-infra.dev/test/framework/integration" ) const ( testBannerA = "3396a52c-6a22-4049-9593-5a63b596a101" testBannerB = "3396a52c-6a22-4049-9593-5a63b596a105" testClusterA = "3396a52c-6a22-4049-9593-5a63b596a200" testClusterB = "3396a52c-6a22-4049-9593-5a63b596a201" testRegistryA = "018ea9c2-ca5d-7a8a-830c-d533e8b52e71" testRegistryB = "018ea9c2-ca5d-7a8a-830c-d533e8b52e72" testRegistryC = "018ea9c2-ca5d-7a8a-830c-d533e8b52e73" testRegistryAURL = "a.registry.io" testRegistryBURL = "b.registry.io" testRegistryADescription = "Artifact registry A" testRegistryBDescription = "Artifact registry B" testClusterRegistryA = "019eac81-da8d-3a2d-122c-c264e7b53c91" ) var ( artifactRegistriesFields = []*graphb.Field{ {Name: "registryEdgeId"}, {Name: "bannerEdgeId"}, {Name: "description"}, {Name: "url"}, } clusterArtifactRegistriesFields = []*graphb.Field{ {Name: "clusterRegistryEdgeId"}, {Name: "clusterEdgeId"}, {Name: "registryEdgeId"}, } ) type artifactRegistryResponse struct { ArtifactRegistry *model.ArtifactRegistry ArtifactRegistries []*model.ArtifactRegistry CreateArtifactRegistry *model.ArtifactRegistry UpdateArtifactRegistry *model.ArtifactRegistry DeleteArtifactRegistry bool } type clusterArtifactRegistryResponse struct { ClusterArtifactRegistry *model.ClusterArtifactRegistry ClusterArtifactRegistries []*model.ClusterArtifactRegistry CreateClusterArtifactRegistry *model.ClusterArtifactRegistry DeleteClusterArtifactRegistry bool } func (s *Suite) TestArtifactRegistry() { integration.SkipIf(s.Framework) registryEdgeID := testRegistryA var response artifactRegistryResponse query := artifactRegistryQuery(testRegistryA) s.Require().NoError(ResolverClient.Post(query, &response)) expectedBannerEdgeID := testBannerA expectedDescription := testRegistryADescription expectedURL := testRegistryAURL s.Require().NotNil(response.ArtifactRegistry) s.Equal(registryEdgeID, response.ArtifactRegistry.RegistryEdgeID) s.Equal(expectedBannerEdgeID, response.ArtifactRegistry.BannerEdgeID) s.Require().NotNil(response.ArtifactRegistry.Description) s.Equal(expectedDescription, *response.ArtifactRegistry.Description) s.Equal(expectedURL, response.ArtifactRegistry.URL) } func artifactRegistryQuery(registryEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeQuery, Fields: []*graphb.Field{ { Name: "artifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentString("registryEdgeId", registryEdgeID), }, Fields: artifactRegistriesFields, }, }, }) } func (s *Suite) TestArtifactRegistriesForBanner() { integration.SkipIf(s.Framework) bannerEdgeID := testBannerA var response artifactRegistryResponse query := artifactRegistriesQuery(&bannerEdgeID, nil) s.Require().NoError(ResolverClient.Post(query, &response)) s.Require().NotNil(response.ArtifactRegistries) s.Require().Len(response.ArtifactRegistries, 2) for _, artifactRegistry := range response.ArtifactRegistries { s.Equal(bannerEdgeID, artifactRegistry.BannerEdgeID) s.NotEmpty(artifactRegistry.RegistryEdgeID) s.Require().NotNil(artifactRegistry.Description) s.NotEmpty(*artifactRegistry.Description) s.NotEmpty(artifactRegistry.URL) } } func (s *Suite) TestArtifactRegistriesForCluster() { integration.SkipIf(s.Framework) clusterEdgeID := testClusterA var response artifactRegistryResponse query := artifactRegistriesQuery(nil, &clusterEdgeID) s.Require().NoError(ResolverClient.Post(query, &response)) expectedBannerEdgeID := testBannerA s.Require().NotNil(response.ArtifactRegistries) s.Require().Len(response.ArtifactRegistries, 2) for _, artifactRegistry := range response.ArtifactRegistries { s.Equal(expectedBannerEdgeID, artifactRegistry.BannerEdgeID) s.NotEmpty(artifactRegistry.RegistryEdgeID) s.Require().NotNil(artifactRegistry.Description) s.NotEmpty(*artifactRegistry.Description) s.NotEmpty(artifactRegistry.URL) } } func (s *Suite) TestArtifactRegistriesFailsWithInvalidArgs() { integration.SkipIf(s.Framework) var response artifactRegistryResponse query := artifactRegistriesQuery(nil, nil) err := ResolverClient.Post(query, &response) s.ErrorContains(err, "must specify banner or cluster Edge ID") } func artifactRegistriesQuery(bannerEdgeID, clusterEdgeID *string) string { query := graphb.Query{ Type: graphb.TypeQuery, Fields: []*graphb.Field{ { Name: "artifactRegistries", Fields: artifactRegistriesFields, }, }, } args := []graphb.Argument{} if bannerEdgeID != nil { args = append(args, graphb.ArgumentString("bannerEdgeId", *bannerEdgeID)) } if clusterEdgeID != nil { args = append(args, graphb.ArgumentString("clusterEdgeId", *clusterEdgeID)) } query.Fields[0].Arguments = args return MustParse(query) } func (s *Suite) TestCreateArtifactRegistry() { integration.SkipIf(s.Framework) bannerEdgeID := testBannerB description := "Newly created registry" url := "new.registry.io" var response artifactRegistryResponse mutation := createArtifactRegistryMutation(bannerEdgeID, url, &description) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.CreateArtifactRegistry) s.NotEmpty(response.CreateArtifactRegistry.RegistryEdgeID) s.Equal(bannerEdgeID, response.CreateArtifactRegistry.BannerEdgeID) s.Require().NotNil(response.CreateArtifactRegistry.Description) s.Equal(description, *response.CreateArtifactRegistry.Description) s.Equal(url, response.CreateArtifactRegistry.URL) } func (s *Suite) TestCreateArtifactRegistryWithoutDescription() { integration.SkipIf(s.Framework) bannerEdgeID := testBannerB url := "new.withoutdescription.registry.io" var response artifactRegistryResponse mutation := createArtifactRegistryMutation(bannerEdgeID, url, nil) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.CreateArtifactRegistry) s.NotEmpty(response.CreateArtifactRegistry.RegistryEdgeID) s.Equal(bannerEdgeID, response.CreateArtifactRegistry.BannerEdgeID) s.Nil(response.CreateArtifactRegistry.Description) s.Equal(url, response.CreateArtifactRegistry.URL) } func (s *Suite) TestCreateArtifactRegistryFailsIfURLAlreadyExistsForBanner() { integration.SkipIf(s.Framework) bannerEdgeID := testBannerA description := testRegistryADescription alreadyExistsURL := testRegistryAURL var response artifactRegistryResponse mutation := createArtifactRegistryMutation(bannerEdgeID, alreadyExistsURL, &description) err := ResolverClient.Post(mutation, &response) s.Require().Error(err) s.Nil(response.CreateArtifactRegistry) } func createArtifactRegistryMutation(bannerEdgeID, url string, description *string) string { query := graphb.Query{ Type: graphb.TypeMutation, Fields: []*graphb.Field{ { Name: "createArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentCustomType( "createArtifactRegistry", graphb.ArgumentString("bannerEdgeId", bannerEdgeID), graphb.ArgumentString("url", url), ), }, Fields: artifactRegistriesFields, }, }, } if description != nil { query.Fields[0].Arguments[0] = graphb.ArgumentCustomType( "createArtifactRegistry", graphb.ArgumentString("bannerEdgeId", bannerEdgeID), graphb.ArgumentString("url", url), graphb.ArgumentString("description", *description), ) } return MustParse(query) } func (s *Suite) TestUpdateArtifactRegistry() { integration.SkipIf(s.Framework) registryEdgeID := testRegistryB updatedDescription := "Updated registry" updatedURL := "updated.registry.io" var response artifactRegistryResponse mutation := updateArtifactRegistryMutation(registryEdgeID, updatedDescription, updatedURL) s.Require().NoError(ResolverClient.Post(mutation, &response)) expectedBannerEdgeID := testBannerA s.Require().NotNil(response.UpdateArtifactRegistry) s.Equal(registryEdgeID, response.UpdateArtifactRegistry.RegistryEdgeID) s.Equal(expectedBannerEdgeID, response.UpdateArtifactRegistry.BannerEdgeID) s.Require().NotNil(response.UpdateArtifactRegistry.Description) s.Equal(updatedDescription, *response.UpdateArtifactRegistry.Description) s.Equal(updatedURL, response.UpdateArtifactRegistry.URL) // check we can update description by itself updatedDescription = "Updated description" mutation = updateArtifactRegistryMutation(registryEdgeID, updatedDescription, updatedURL) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.UpdateArtifactRegistry) s.Equal(registryEdgeID, response.UpdateArtifactRegistry.RegistryEdgeID) s.Equal(expectedBannerEdgeID, response.UpdateArtifactRegistry.BannerEdgeID) s.Require().NotNil(response.UpdateArtifactRegistry.Description) s.Equal(updatedDescription, *response.UpdateArtifactRegistry.Description) s.Equal(updatedURL, response.UpdateArtifactRegistry.URL) } func (s *Suite) TestUpdateArtifactRegistryFailsIfURLAlreadyExistsForBanner() { integration.SkipIf(s.Framework) registryEdgeID := testRegistryB updatedDescription := "Updated registry" alreadyExistsURL := testRegistryAURL var response artifactRegistryResponse mutation := updateArtifactRegistryMutation(registryEdgeID, updatedDescription, alreadyExistsURL) err := ResolverClient.Post(mutation, &response) s.Require().Error(err) s.Nil(response.CreateArtifactRegistry) } func updateArtifactRegistryMutation(registryEdgeID, description, url string) string { return MustParse(graphb.Query{ Type: graphb.TypeMutation, Fields: []*graphb.Field{ { Name: "updateArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentString("registryEdgeId", registryEdgeID), graphb.ArgumentCustomType( "updateArtifactRegistry", graphb.ArgumentString("description", description), graphb.ArgumentString("url", url), ), }, Fields: artifactRegistriesFields, }, }, }) } func (s *Suite) TestDeleteArtifactRegistry() { integration.SkipIf(s.Framework) registryEdgeID := "018ea9c2-ca5d-7a8a-830c-d533e8b52e75" var response artifactRegistryResponse // check it exists before deletion query := artifactRegistryQuery(registryEdgeID) s.Require().NoError(ResolverClient.Post(query, &response)) mutation := deleteArtifactRegistryMutation(registryEdgeID) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.DeleteArtifactRegistry) s.True(response.DeleteArtifactRegistry) // check it no longer exists s.Error(ResolverClient.Post(query, &response)) // deleting it again should do nothing s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.DeleteArtifactRegistry) s.False(response.DeleteArtifactRegistry) } func deleteArtifactRegistryMutation(registryEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeMutation, Fields: []*graphb.Field{ { Name: "deleteArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentString("registryEdgeId", registryEdgeID), }, }, }, }) } func (s *Suite) TestClusterArtifactRegistry() { integration.SkipIf(s.Framework) clusterRegistryEdgeID := testClusterRegistryA var response clusterArtifactRegistryResponse query := clusterArtifactRegistryQuery(clusterRegistryEdgeID) s.Require().NoError(ResolverClient.Post(query, &response)) expectedClusterEdgeID := testClusterA expectedRegistryEdgeID := testRegistryA s.Require().NotNil(response.ClusterArtifactRegistry) s.Equal(response.ClusterArtifactRegistry.ClusterRegistryEdgeID, clusterRegistryEdgeID) s.Equal(response.ClusterArtifactRegistry.ClusterEdgeID, expectedClusterEdgeID) s.Equal(response.ClusterArtifactRegistry.RegistryEdgeID, expectedRegistryEdgeID) } func clusterArtifactRegistryQuery(clusterRegistryEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeQuery, Fields: []*graphb.Field{ { Name: "clusterArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentString("clusterRegistryEdgeId", clusterRegistryEdgeID), }, Fields: clusterArtifactRegistriesFields, }, }, }) } func (s *Suite) TestClusterArtifactRegistries() { integration.SkipIf(s.Framework) clusterEdgeID := testClusterA var response clusterArtifactRegistryResponse query := clusterArtifactRegistriesQuery(clusterEdgeID) s.Require().NoError(ResolverClient.Post(query, &response)) s.Require().NotNil(response.ClusterArtifactRegistries) s.Require().Len(response.ClusterArtifactRegistries, 2) for _, clusterArtifactRegistry := range response.ClusterArtifactRegistries { s.Equal(clusterEdgeID, clusterArtifactRegistry.ClusterEdgeID) s.NotEmpty(clusterArtifactRegistry.ClusterRegistryEdgeID) s.NotEmpty(clusterArtifactRegistry.RegistryEdgeID) } } func clusterArtifactRegistriesQuery(clusterEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeQuery, Fields: []*graphb.Field{ { Name: "clusterArtifactRegistries", Fields: clusterArtifactRegistriesFields, Arguments: []graphb.Argument{ graphb.ArgumentString("clusterEdgeId", clusterEdgeID), }, }, }, }) } func (s *Suite) TestCreateClusterArtifactRegistry() { integration.SkipIf(s.Framework) clusterEdgeID := testClusterB registryEdgeID := testRegistryC var response clusterArtifactRegistryResponse mutation := createClusterArtifactRegistryMutation(clusterEdgeID, registryEdgeID) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.CreateClusterArtifactRegistry) s.NotEmpty(response.CreateClusterArtifactRegistry.ClusterRegistryEdgeID) s.Equal(clusterEdgeID, response.CreateClusterArtifactRegistry.ClusterEdgeID) s.Equal(registryEdgeID, response.CreateClusterArtifactRegistry.RegistryEdgeID) } func (s *Suite) TestCreateClusterArtifactRegistryFailsIfRegistryAlreadyExistsForCluster() { integration.SkipIf(s.Framework) clusterEdgeID := testClusterA alreadyExistsRegistryEdgeID := testRegistryA var response clusterArtifactRegistryResponse mutation := createClusterArtifactRegistryMutation(clusterEdgeID, alreadyExistsRegistryEdgeID) err := ResolverClient.Post(mutation, &response) s.Require().Error(err) s.Nil(response.CreateClusterArtifactRegistry) } func createClusterArtifactRegistryMutation(clusterEdgeID, registryEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeMutation, Fields: []*graphb.Field{ { Name: "createClusterArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentCustomType( "createClusterArtifactRegistry", graphb.ArgumentString("clusterEdgeId", clusterEdgeID), graphb.ArgumentString("registryEdgeId", registryEdgeID), ), }, Fields: clusterArtifactRegistriesFields, }, }, }) } func (s *Suite) TestDeleteClusterArtifactRegistry() { integration.SkipIf(s.Framework) clusterRegistryEdgeID := "019eac81-da8d-3a2d-122c-c264e7b53c94" var response clusterArtifactRegistryResponse // check it exists before deletion query := clusterArtifactRegistryQuery(clusterRegistryEdgeID) s.Require().NoError(ResolverClient.Post(query, &response)) mutation := deleteClusterArtifactRegistryMutation(clusterRegistryEdgeID) s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.DeleteClusterArtifactRegistry) s.True(response.DeleteClusterArtifactRegistry) // check it no longer exists s.Error(ResolverClient.Post(query, &response)) // deleting it again should do nothing s.Require().NoError(ResolverClient.Post(mutation, &response)) s.Require().NotNil(response.DeleteClusterArtifactRegistry) s.False(response.DeleteClusterArtifactRegistry) } func deleteClusterArtifactRegistryMutation(clusterRegistryEdgeID string) string { return MustParse(graphb.Query{ Type: graphb.TypeMutation, Fields: []*graphb.Field{ { Name: "deleteClusterArtifactRegistry", Arguments: []graphb.Argument{ graphb.ArgumentString("clusterRegistryEdgeId", clusterRegistryEdgeID), }, }, }, }) }