/* * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package integration import ( "context" "encoding/json" "fmt" "io" "net/http" "reflect" "testing" "time" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/common/consts" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/common/env" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/database" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/models" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/runtime" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/schemas" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/schemasv2" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/api/services" "github.com/dynemo-ai/dynemo/deploy/compoundai/api-server/tests/integration/fixtures" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) const ( port = 9999 expectedStatusOkMsg = "Expected status code 200" ) var apiServerUrl = fmt.Sprintf("http://localhost:%d", port) var client = CompoundAIClient{ Url: apiServerUrl, Headers: http.Header{}, } type ApiServerSuite struct { suite.Suite } func TestApiServerSuite(t *testing.T) { suite.Run(t, new(ApiServerSuite)) } // run once, before test suite methods func (s *ApiServerSuite) SetupSuite() { log.Info().Msgf("Starting suite...") _, err := testContainers.CreatePostgresContainer() if err != nil { s.T().FailNow() } log.Info().Msgf("Created Postgres Container") // Setup server go func() { // Mute all logs for this goroutine gin.DefaultWriter = io.Discard runtime.Runtime.StartServer(port) }() s.waitUntilReady() log.Info().Msgf("API Server Ready") services.K8sService = &fixtures.MockedK8sService{} log.Info().Msgf("Mocked K8s Service") } func (s *ApiServerSuite) waitUntilReady() { url := fmt.Sprintf("%s/healthz", apiServerUrl) for { resp, err := http.Get(url) if err == nil && resp.StatusCode == http.StatusOK { log.Info().Msg("CompoundAI API server is running") return // Server is ready } log.Info().Msgf("Waiting 500ms before checking /healthz again") time.Sleep(500 * time.Millisecond) // Wait before retrying } } // run once, after test suite methods func (s *ApiServerSuite) TearDownSuite() { testContainers.TearDownPostgresContainer() } // run before every test func (s *ApiServerSuite) SetupTest() { client.Headers.Set(consts.NgcOrganizationHeaderName, "test-org-nvidia") client.Headers.Set(consts.NgcUserHeaderName, "test-user-nvidia") env.ApplicationScope = env.UserScope } // run after each test func (s *ApiServerSuite) TearDownTest() { ctx := context.Background() db := database.DatabaseUtil.GetDBSession(ctx) if err := db.Unscoped().Where("true").Delete(&models.Deployment{}).Error; err != nil { s.T().Fatalf("Failed to delete records from deployment table: %v", err) } if err := db.Unscoped().Where("true").Delete(&models.Cluster{}).Error; err != nil { s.T().Fatalf("Failed to delete records from cluster table: %v", err) } } func (s *ApiServerSuite) TestCreateCluster() { cluster := fixtures.DefaultCreateClusterSchema() resp, clusterFullSchema := client.CreateCluster(s.T(), cluster) // Verify the response status code assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Additional checks on response content (optional) assert.Equal(s.T(), clusterFullSchema.Description, cluster.Description) assert.Equal(s.T(), *(clusterFullSchema.KubeConfig), cluster.KubeConfig) assert.Equal(s.T(), clusterFullSchema.Name, cluster.Name) } func (s *ApiServerSuite) TestGetCluster() { cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Get Cluster resp, clusterFullSchema := client.GetCluster(s.T(), cluster.Name) // Verify the response status code assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Additional checks on response content assert.Equal(s.T(), clusterFullSchema.Description, cluster.Description) assert.Equal(s.T(), *(clusterFullSchema.KubeConfig), cluster.KubeConfig) assert.Equal(s.T(), clusterFullSchema.Name, cluster.Name) } func (s *ApiServerSuite) TestGetUnknownClusterFails() { resp, _ := client.GetCluster(s.T(), "unknown") assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") } func (s *ApiServerSuite) TestGetMultipleClusters() { cluster1 := fixtures.DefaultCreateClusterSchema() cluster1.Name = "c1" resp, _ := client.CreateCluster(s.T(), cluster1) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) cluster2 := fixtures.DefaultCreateClusterSchema() cluster2.Name = "c2" resp, _ = client.CreateCluster(s.T(), cluster2) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) req := fixtures.DefaultListQuerySchema() resp, clusterListSchema := client.GetClusterList(s.T(), req) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) for _, item := range clusterListSchema.Items { assert.Contains(s.T(), []string{"c1", "c2"}, item.Name, expectedStatusOkMsg) } } func (s *ApiServerSuite) TestUpdateCluster() { cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) req := fixtures.DefaultUpdateClusterSchema() d := "Nemo" kc := "KcNemo" req.Description = &d req.KubeConfig = &kc resp, clusterFullSchema := client.UpdateCluster(s.T(), cluster.Name, req) // Verify the response status code assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Additional checks on response content (optional) assert.Equal(s.T(), clusterFullSchema.Description, *(req.Description)) assert.Equal(s.T(), *(clusterFullSchema.KubeConfig), *(req.KubeConfig)) assert.Equal(s.T(), clusterFullSchema.Name, cluster.Name) } func (s *ApiServerSuite) TestCreateDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, deploymentSchema := client.GetDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) assert.Equalf(s.T(), int(1), len(deploymentSchema.LatestRevision.Targets), "expected 1 target") assert.Equal(s.T(), deployment.Targets[0].Version, deploymentSchema.LatestRevision.Targets[0].CompoundNimVersion.Version) } func (s *ApiServerSuite) TestCreateDeploymentWithNDSErrorDoesNotChangeDB() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() d1, r1, t1, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } nds.Throws(true) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode) d2, r2, t2, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.True(s.T(), compareDeployments(d1, d2)) assert.True(s.T(), compareDeploymentRevisions(r1, r2)) assert.True(s.T(), compareDeploymentTargets(t1, t2)) } func (s *ApiServerSuite) TestCreateDeploymentUnknownClusterFails() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ := client.CreateDeployment(s.T(), "unknown", deployment) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 400") } func (s *ApiServerSuite) TestUpdateDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() // Create cluster cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Create deployment deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Update deployment updateTarget := fixtures.DefaultCreateDeploymentTargetSchema() updateTarget.Version = "2025" updateTarget.CompoundNim = "compoundai" updateDeployment := fixtures.DefaultUpdateDeploymentSchema() updatedDescription := "new description" updateDeployment.Description = &updatedDescription updateDeployment.Targets = []*schemas.CreateDeploymentTargetSchema{ updateTarget, } resp, deploymentSchema := client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Validate fields assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) // Todo: once Deployment Schema is available make this test more rigorous ctx := context.Background() _, r1, _, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.Equal(s.T(), 2, len(r1)) status_ := schemas.DeploymentRevisionStatusActive activeRevisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{ Status: &status_, }) if err != nil { s.T().Fatalf("Could not fetch revisions: %s", err.Error()) } assert.Equal(s.T(), 1, len(activeRevisions)) assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) assert.Equalf(s.T(), int(1), len(deploymentSchema.LatestRevision.Targets), "expected 1 target") assert.Equal(s.T(), updateDeployment.Targets[0].Version, deploymentSchema.LatestRevision.Targets[0].CompoundNimVersion.Version) } func (s *ApiServerSuite) TestUpdateDeploymentWithNDSErrorDoesNotChangeDB() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() d1, r1, t1, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } nds.Throws(true) updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusInternalServerError, resp.StatusCode) d2, r2, t2, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.True(s.T(), compareDeployments(d1, d2)) assert.True(s.T(), compareDeploymentRevisions(r1, r2)) assert.True(s.T(), compareDeploymentTargets(t1, t2)) } func (s *ApiServerSuite) TestUpdateDeploymentWithoutDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() // Create cluster cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Create deployment deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Update deployment updateTarget := fixtures.DefaultCreateDeploymentTargetSchema() updateTarget.Config.KubeResourceUid = "abc123" updateTarget.Config.KubeResourceVersion = "alphav1" updateDeployment := fixtures.DefaultUpdateDeploymentSchema() updateDeployment.Targets = []*schemas.CreateDeploymentTargetSchema{ updateTarget, } updateDeployment.DoNotDeploy = true ctx := context.Background() _, r1, _, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } resp, deploymentSchema := client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Validate fields assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) assert.Equalf(s.T(), 1, len(deploymentSchema.LatestRevision.Targets), "More deployment targets than expected") assert.Equal(s.T(), updateTarget.Config.KubeResourceUid, deploymentSchema.LatestRevision.Targets[0].Config.KubeResourceUid) assert.Equal(s.T(), updateTarget.Config.KubeResourceVersion, deploymentSchema.LatestRevision.Targets[0].Config.KubeResourceVersion) // Updating without deployment does not deactivate any deployment revision or create a new one _, r2, _, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.True(s.T(), compareDeploymentRevisions(r1, r2)) } func (s *ApiServerSuite) TestUpdateDeploymentUnknownClusterFails() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ := client.UpdateDeployment(s.T(), "unknown", "default", "unknown", updateDeployment) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") } func (s *ApiServerSuite) TestUpdateDeploymentUnknownDeploymentFails() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() // Create cluster cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, "default", "unknown", updateDeployment) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") } func (s *ApiServerSuite) TestTerminateDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() status_ := schemas.DeploymentRevisionStatusActive activeRevisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{ Status: &status_, }) if err != nil { s.T().Fatalf("Could not fetch revisions: %s", err.Error()) } assert.Equal(s.T(), 1, len(activeRevisions)) // Terminate deployment resp, deploymentSchema := client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) status_ = schemas.DeploymentRevisionStatusInactive inactiveRevisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{ Status: &status_, }) if err != nil { s.T().Fatalf("Could not fetch revisions: %s", err.Error()) } assert.Equal(s.T(), 1, len(inactiveRevisions)) var expectedRevision *schemas.DeploymentRevisionSchema = nil assert.Equal(s.T(), expectedRevision, deploymentSchema.LatestRevision) } func (s *ApiServerSuite) TestTerminateNonExistingDeployment() { resp, _ := client.TerminateDeployment(s.T(), "nonexistent-cluster", "nonexistent-namespace", "nonexistent-deployment") assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") } func (s *ApiServerSuite) TestTerminateNonIncorrectDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, _ = client.TerminateDeployment(s.T(), "nonexistent-cluster", deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") resp, _ = client.TerminateDeployment(s.T(), cluster.Name, "nonexistent-namespace", deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, "nonexistent-deployment") assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, "Expected status code 404") } func (s *ApiServerSuite) TestDeleteDeactivatedDeployment() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Terminate the deployment resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Delete the deactivated deployment resp, _ = client.DeleteDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Check that there are no remaining deployment entities ctx := context.Background() d, r, t, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.Equal(s.T(), 0, len(d)) assert.Equal(s.T(), 0, len(r)) assert.Equal(s.T(), 0, len(t)) } func (s *ApiServerSuite) TestDeleteActiveDeploymentFails() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Attempt to delete the active deployment resp, _ = client.DeleteDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusInternalServerError, resp.StatusCode) } func (s *ApiServerSuite) TestUpdateDeploymentWithDMSErrorDoesNotChangeDB() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() d1, r1, t1, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Failed to get snapshot %s", err.Error()) } dms.Throws(true) // Attempt to update the deployment updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusInternalServerError, resp.StatusCode) d2, r2, t2, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Failed to get snapshot %s", err.Error()) } assert.True(s.T(), compareDeployments(d1, d2)) assert.True(s.T(), compareDeploymentRevisions(r1, r2)) assert.True(s.T(), compareDeploymentTargets(t1, t2)) } func (s *ApiServerSuite) TestTerminateDeploymentWithDMSErrorDoesNotChangeDB() { dms := fixtures.CreateMockDMSServer(s.T()) // Does not throw error initially defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() d1, r1, t1, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Failed to get snapshot %s", err.Error()) } dms.Throws(true) // Attempt to terminate the deployment resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusInternalServerError, resp.StatusCode) // Verify DB state remains unchanged d2, r2, t2, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Failed to get snapshot %s", err.Error()) } assert.True(s.T(), compareDeployments(d1, d2)) assert.True(s.T(), compareDeploymentRevisions(r1, r2)) assert.True(s.T(), compareDeploymentTargets(t1, t2)) } func (s *ApiServerSuite) TestGetDeploymentRevisions() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, deploymentSchema := client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, deploymentRevisionSchema := client.GetDeploymentRevision(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, deploymentSchema.LatestRevision.Uid) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), deploymentSchema.LatestRevision.Uid, deploymentRevisionSchema.Uid) lr, err := json.Marshal(deploymentSchema.LatestRevision) if err != nil { s.T().Fatalf("%s", err.Error()) } ar, err := json.Marshal(deploymentSchema.LatestRevision) if err != nil { s.T().Fatalf("%s", err.Error()) } assert.Equal(s.T(), lr, ar) } func (s *ApiServerSuite) TestGetDeploymentRevisionsDifferentDeployments() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) d1 := fixtures.DefaultCreateDeploymentSchema() d1.Name = "dep1" resp, ds1 := client.CreateDeployment(s.T(), cluster.Name, d1) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) d2 := fixtures.DefaultCreateDeploymentSchema() d2.Name = "dep2" resp, ds2 := client.CreateDeployment(s.T(), cluster.Name, d2) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, drs1 := client.GetDeploymentRevision(s.T(), cluster.Name, d1.KubeNamespace, d1.Name, ds1.LatestRevision.Uid) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, drs2 := client.GetDeploymentRevision(s.T(), cluster.Name, d1.KubeNamespace, d1.Name, ds2.LatestRevision.Uid) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.NotEqual(s.T(), drs2.Uid, drs1.Uid) } func (s *ApiServerSuite) TestGetDeploymentRevisionsList() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) query := schemas.ListQuerySchema{ Count: 10, } resp, deploymentRevisionsListSchema := client.GetDeploymentRevisionList(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, query) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 2, len(deploymentRevisionsListSchema.Items)) } func (s *ApiServerSuite) TestOrganizationLevelScopeForClusterWhenCreatingDeployment() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") deployment2 := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment2) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode) } func (s *ApiServerSuite) TestOrganizationLevelScopeForClusterWhenUpdatingDeployment() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode) } func (s *ApiServerSuite) TestOrganizationLevelScopeForClusterWhenTerminatingDeployment() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Terminate deployment client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestOrganizationLevelScopeForClusterWhenDeletingDeployment() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Terminate the deployment resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Delete the deactivated deployment client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") resp, _ = client.DeleteDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestOrganizationLevelScopeForClusterWhenListingDeploymentRevisions() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") query := schemas.ListQuerySchema{} resp, _ = client.GetDeploymentRevisionList(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, query) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestOrganizationLevelScopeForGetClusterDeployments() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() client.Headers.Set(consts.NgcOrganizationHeaderName, "org-1") cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "org-2") cluster = fixtures.DefaultCreateClusterSchema() resp, _ = client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment = fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "org-1") resp, deploymentSchemas := client.GetClusterDeploymentList(s.T(), cluster.Name, schemas.ListQuerySchema{Count: 10}) assert.Equalf(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(deploymentSchemas.Items)) } func (s *ApiServerSuite) TestOrganizationLevelScopeForGetDeployments() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() client.Headers.Set(consts.NgcOrganizationHeaderName, "org-1") cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "org-2") cluster = fixtures.DefaultCreateClusterSchema() resp, _ = client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment = fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "org-1") resp, deploymentSchemas := client.GetDeploymentList(s.T(), schemas.ListQuerySchema{Count: 10}) assert.Equalf(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(deploymentSchemas.Items)) } func (s *ApiServerSuite) TestUserLevelScopeForClusterWhenCreatingDeployment() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() deployment.Name = "dep1" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "some-other-user") deployment2 := fixtures.DefaultCreateDeploymentSchema() deployment2.Name = "dep2" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment2) assert.Equal(s.T(), http.StatusOK, resp.StatusCode) resp, deploymentSchemas := client.GetClusterDeploymentList(s.T(), cluster.Name, schemas.ListQuerySchema{Count: 10}) assert.Equalf(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(deploymentSchemas.Items)) } func (s *ApiServerSuite) TestUserLevelScopeForClusterWhenUpdatingDeployment() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "some-other-user") updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode) } func (s *ApiServerSuite) TestUserLevelScopeForClusterWhenTerminatingDeployment() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "some-other-user") resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestUserLevelScopeForClusterWhenDeletingDeployment() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, _ = client.TerminateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "some-other-user") resp, _ = client.DeleteDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestUserLevelScopeForClusterWhenListingDeploymentRevisions() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) updateDeployment := fixtures.DefaultUpdateDeploymentSchema() resp, _ = client.UpdateDeployment(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "some-other-user") query := schemas.ListQuerySchema{} resp, _ = client.GetDeploymentRevisionList(s.T(), cluster.Name, deployment.KubeNamespace, deployment.Name, query) assert.Equal(s.T(), http.StatusNotFound, resp.StatusCode, expectedStatusOkMsg) } func (s *ApiServerSuite) TestUserLevelScopeForGetClusterDeployments() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() client.Headers.Set(consts.NgcUserHeaderName, "user-1") cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() deployment.Name = "dep1" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "user-2") deployment = fixtures.DefaultCreateDeploymentSchema() deployment.Name = "dep2" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "user-1") resp, deploymentSchemas := client.GetClusterDeploymentList(s.T(), cluster.Name, schemas.ListQuerySchema{Count: 10}) assert.Equalf(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(deploymentSchemas.Items)) } func (s *ApiServerSuite) TestUserLevelScopeForGetDeployments() { env.ApplicationScope = env.UserScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() client.Headers.Set(consts.NgcUserHeaderName, "user-1") cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchema() deployment.Name = "dep1" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "user-2") deployment = fixtures.DefaultCreateDeploymentSchema() deployment.Name = "dep2" resp, _ = client.CreateDeployment(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcUserHeaderName, "user-1") resp, deploymentSchemas := client.GetDeploymentList(s.T(), schemas.ListQuerySchema{Count: 10}) assert.Equalf(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(deploymentSchemas.Items)) } func (s *ApiServerSuite) TestOrganizationLevelScopeForListClusters() { env.ApplicationScope = env.OrganizationScope dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) client.Headers.Set(consts.NgcOrganizationHeaderName, "some-other-org") resp, _ = client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) req := fixtures.DefaultListQuerySchema() resp, clusterListSchema := client.GetClusterList(s.T(), req) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), 1, len(clusterListSchema.Items)) } // V2 API Tests func (s *ApiServerSuite) TestCreateDeploymentV2() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchemaV2() resp, _ = client.CreateDeploymentV2(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) resp, deploymentSchema := client.GetDeploymentV2(s.T(), cluster.Name, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) assert.Equalf(s.T(), int(1), len(deploymentSchema.LatestRevision.Targets), "expected 1 target") assert.Equal(s.T(), deployment.Services["default-service"].ConfigOverrides.Resources, *deploymentSchema.LatestRevision.Targets[0].Config.Resources) } func (s *ApiServerSuite) TestUpdateDeploymentV2() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() // Create cluster cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Create deployment deployment := fixtures.DefaultCreateDeploymentSchemaV2() resp, _ = client.CreateDeploymentV2(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Update deployment resourceItem := &schemas.ResourceItem{ CPU: "123m", GPU: "2", Memory: "5Gi", } updateService := fixtures.DefaultServiceSpec() updateService.ConfigOverrides.Resources.Limits = resourceItem updateService.ConfigOverrides.Resources.Requests = resourceItem updateDeployment := fixtures.DefaultUpdateDeploymentSchemaV2() updateDeployment.CompoundNim = "new:654321" updateDeployment.DeploymentConfigSchema.Services = map[string]schemasv2.ServiceSpec{ "new-service": updateService, } resp, deploymentSchema := client.UpdateDeploymentV2(s.T(), cluster.Name, deployment.Name, updateDeployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) assert.Equal(s.T(), deployment.Name, deploymentSchema.Name) assert.Equal(s.T(), schemas.DeploymentStatusNonDeployed, deploymentSchema.Status) assert.Equalf(s.T(), int(1), len(deploymentSchema.LatestRevision.Targets), "expected 1 target") assert.Equal(s.T(), updateDeployment.Services["new-service"].ConfigOverrides.Resources, *deploymentSchema.LatestRevision.Targets[0].Config.Resources) } func (s *ApiServerSuite) TestTerminateDeploymentV2() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchemaV2() resp, _ = client.CreateDeploymentV2(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) ctx := context.Background() status_ := schemas.DeploymentRevisionStatusActive activeRevisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{ Status: &status_, }) if err != nil { s.T().Fatalf("Could not fetch revisions: %s", err.Error()) } assert.Equal(s.T(), 1, len(activeRevisions)) // Terminate deployment resp, deploymentSchema := client.TerminateDeploymentV2(s.T(), cluster.Name, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) status_ = schemas.DeploymentRevisionStatusInactive inactiveRevisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{ Status: &status_, }) if err != nil { s.T().Fatalf("Could not fetch revisions: %s", err.Error()) } assert.Equal(s.T(), 1, len(inactiveRevisions)) var expectedRevision *schemas.DeploymentRevisionSchema = nil assert.Equal(s.T(), expectedRevision, deploymentSchema.LatestRevision) } func (s *ApiServerSuite) TestDeleteDeactivatedDeploymentV2() { dms := fixtures.CreateMockDMSServer(s.T()) defer dms.Close() nds := fixtures.CreateMockNDSServer(s.T()) defer nds.Close() cluster := fixtures.DefaultCreateClusterSchema() resp, _ := client.CreateCluster(s.T(), cluster) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) deployment := fixtures.DefaultCreateDeploymentSchemaV2() resp, _ = client.CreateDeploymentV2(s.T(), cluster.Name, deployment) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Terminate the deployment resp, _ = client.TerminateDeploymentV2(s.T(), cluster.Name, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Delete the deactivated deployment resp, _ = client.DeleteDeploymentV2(s.T(), cluster.Name, deployment.Name) assert.Equal(s.T(), http.StatusOK, resp.StatusCode, expectedStatusOkMsg) // Check that there are no remaining deployment entities ctx := context.Background() d, r, t, err := getDeploymentEntitiesSnapshot(ctx) if err != nil { s.T().Fatalf("Could not fetch deployment entities snapshot: %s", err.Error()) } assert.Equal(s.T(), 0, len(d)) assert.Equal(s.T(), 0, len(r)) assert.Equal(s.T(), 0, len(t)) } func compareDeployments(slice1, slice2 []*models.Deployment) bool { // Check if lengths are equal if len(slice1) != len(slice2) { return false } // Compare each element using reflect.DeepEqual for i := range slice1 { if !reflect.DeepEqual(slice1[i], slice2[i]) { log.Info().Msgf("Expected deployment: %+v", slice1[i]) log.Info().Msgf("Actual deployment: %+v", slice2[i]) return false } } return true } func compareDeploymentRevisions(slice1, slice2 []*models.DeploymentRevision) bool { // Check if lengths are equal if len(slice1) != len(slice2) { return false } // Compare each element using reflect.DeepEqual for i := range slice1 { if !reflect.DeepEqual(slice1[i], slice2[i]) { log.Info().Msgf("Expected revision: %+v", slice1[i]) log.Info().Msgf("Actual revision: %+v", slice2[i]) return false } } return true } func compareDeploymentTargets(slice1, slice2 []*models.DeploymentTarget) bool { // Check if lengths are equal if len(slice1) != len(slice2) { return false } // Compare each element using reflect.DeepEqual for i := range slice1 { if !reflect.DeepEqual(slice1[i], slice2[i]) { log.Info().Msgf("Expected target: %+v", slice1[i]) log.Info().Msgf("Actual target: %+v", slice2[i]) return false } } return true } func getDeploymentEntitiesSnapshot(ctx context.Context) ([]*models.Deployment, []*models.DeploymentRevision, []*models.DeploymentTarget, error) { deployments, _, err := services.DeploymentService.List(ctx, services.ListDeploymentOption{}) if err != nil { return nil, nil, nil, err } revisions, _, err := services.DeploymentRevisionService.List(ctx, services.ListDeploymentRevisionOption{}) if err != nil { return nil, nil, nil, err } targets, _, err := services.DeploymentTargetService.List(ctx, services.ListDeploymentTargetOption{}) if err != nil { return nil, nil, nil, err } return deployments, revisions, targets, nil }