github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/multicluster/examples/sock-shop/sock_shop_example_test.go (about) 1 // Copyright (c) 2021, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package sock_shop 5 6 import ( 7 "fmt" 8 dump "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/clusterdump" 9 "os" 10 "strconv" 11 "time" 12 13 "github.com/verrazzano/verrazzano/pkg/k8s/resource" 14 "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework" 15 "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework/metrics" 16 17 . "github.com/onsi/ginkgo/v2" 18 . "github.com/onsi/gomega" 19 "github.com/verrazzano/verrazzano/tests/e2e/pkg" 20 ) 21 22 const ( 23 longPollingInterval = 20 * time.Second 24 longWaitTimeout = 10 * time.Minute 25 pollingInterval = 5 * time.Second 26 waitTimeout = 5 * time.Minute 27 consistentlyDuration = 1 * time.Minute 28 sourceDir = "sock-shop" 29 testNamespace = "mc-sockshop" 30 testProjectName = "sockshop" 31 testCluster = "SockShop" 32 testApp = "carts-coh" 33 ) 34 35 var clusterName = os.Getenv("MANAGED_CLUSTER_NAME") 36 var adminKubeconfig = os.Getenv("ADMIN_KUBECONFIG") 37 var managedKubeconfig = os.Getenv("MANAGED_KUBECONFIG") 38 var metricsTest pkg.MetricsTest 39 40 // failed indicates whether any of the tests has failed 41 var failed = false 42 var beforeSuitePassed = false 43 44 var t = framework.NewTestFramework("sock_shop") 45 46 var _ = t.AfterEach(func() { 47 // set failed to true if any of the tests has failed 48 failed = failed || CurrentSpecReport().Failed() 49 }) 50 51 // set the kubeconfig to use the admin cluster kubeconfig and deploy the example resources 52 var beforeSuite = t.BeforeSuiteFunc(func() { 53 // deploy the VerrazzanoProject 54 start := time.Now() 55 Eventually(func() error { 56 return DeploySockShopProject(adminKubeconfig, sourceDir) 57 }, waitTimeout, pollingInterval).ShouldNot(HaveOccurred()) 58 59 // wait for the namespace to be created on the cluster before deploying app 60 Eventually(func() bool { 61 return SockShopNamespaceExists(adminKubeconfig, testNamespace) 62 }, waitTimeout, pollingInterval).Should(BeTrue()) 63 64 Eventually(func() error { 65 return DeploySockShopApp(adminKubeconfig, sourceDir) 66 }, waitTimeout, pollingInterval).ShouldNot(HaveOccurred()) 67 68 var err error 69 metricsTest, err = pkg.NewMetricsTest(adminKubeconfig, map[string]string{}, managedKubeconfig) 70 if err != nil { 71 AbortSuite(fmt.Sprintf("Failed to create the Metrics test object: %v", err)) 72 } 73 74 beforeSuitePassed = true 75 metrics.Emit(t.Metrics.With("deployment_elapsed_time", time.Since(start).Milliseconds())) 76 }) 77 78 var _ = BeforeSuite(beforeSuite) 79 80 var _ = t.Describe("In Multi-cluster, verify sock-shop", Label("f:multicluster.mc-app-lcm"), func() { 81 t.Context("Admin Cluster", func() { 82 // GIVEN an admin cluster and at least one managed cluster 83 // WHEN the example application has been deployed to the admin cluster 84 // THEN expect that the multi-cluster resources have been created on the admin cluster 85 t.It("Has multi cluster resources", func() { 86 Eventually(func() bool { 87 return VerifyMCResources(adminKubeconfig, true, false, testNamespace) 88 }, waitTimeout, pollingInterval).Should(BeTrue()) 89 }) 90 // GIVEN an admin cluster 91 // WHEN the multi-cluster example application has been created on admin cluster but not placed there 92 // THEN expect that the app is not deployed to the admin cluster consistently for some length of time 93 t.It("Does not have application placed", func() { 94 Consistently(func() bool { 95 result, err := VerifySockShopInCluster(adminKubeconfig, true, false, testProjectName, testNamespace) 96 if err != nil { 97 AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", testNamespace, err)) 98 } 99 return result 100 }, consistentlyDuration, pollingInterval).Should(BeTrue()) 101 }) 102 }) 103 104 t.Context("Managed Cluster", func() { 105 // GIVEN an admin cluster and at least one managed cluster 106 // WHEN the example application has been deployed to the admin cluster 107 // THEN expect that the multi-cluster resources have been created on the managed cluster 108 t.It("Has multi cluster resources", func() { 109 Eventually(func() bool { 110 return VerifyMCResources(managedKubeconfig, false, true, testNamespace) 111 }, waitTimeout, pollingInterval).Should(BeTrue()) 112 }) 113 // GIVEN an admin cluster and at least one managed cluster 114 // WHEN the multi-cluster example application has been created on admin cluster and placed in managed cluster 115 // THEN expect that the app is deployed to the managed cluster 116 t.It("Has application placed", func() { 117 Eventually(func() bool { 118 result, err := VerifySockShopInCluster(managedKubeconfig, false, true, testProjectName, testNamespace) 119 if err != nil { 120 AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", testNamespace, err)) 121 } 122 return result 123 }, waitTimeout, pollingInterval).Should(BeTrue()) 124 }) 125 }) 126 127 t.Context("Remaining Managed Clusters", func() { 128 clusterCountStr := os.Getenv("CLUSTER_COUNT") 129 if clusterCountStr == "" { 130 // skip tests 131 return 132 } 133 clusterCount, err := strconv.Atoi(clusterCountStr) 134 if err != nil { 135 // skip tests 136 return 137 } 138 139 kubeconfigDir := os.Getenv("KUBECONFIG_DIR") 140 for i := 3; i <= clusterCount; i++ { 141 kubeconfig := kubeconfigDir + "/" + fmt.Sprintf("%d", i) + "/kube_config" 142 t.It("Does not have multi cluster resources", func() { 143 Eventually(func() bool { 144 return VerifyMCResources(kubeconfig, false, false, testNamespace) 145 }, waitTimeout, pollingInterval).Should(BeTrue()) 146 }) 147 t.It("Does not have application placed", func() { 148 Eventually(func() bool { 149 result, err := VerifySockShopInCluster(kubeconfig, false, false, testProjectName, testNamespace) 150 if err != nil { 151 AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", testNamespace, err)) 152 } 153 return result 154 }, waitTimeout, pollingInterval).Should(BeTrue()) 155 }) 156 } 157 }) 158 159 t.Context("for Logging", Label("f:observability.logging.es"), func() { 160 indexName, err := pkg.GetOpenSearchAppIndexWithKC(testNamespace, adminKubeconfig) 161 Expect(err).To(BeNil()) 162 // GIVEN an admin cluster and at least one managed cluster 163 // WHEN the example application has been deployed to the admin cluster 164 // THEN expect the Opensearch index for the app exists on the admin cluster Opensearch 165 t.It("Verify Opensearch index exists on admin cluster", func() { 166 Eventually(func() bool { 167 return pkg.LogIndexFoundInCluster(indexName, adminKubeconfig) 168 }, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find log index for sock-shop") 169 }) 170 }) 171 172 // GIVEN an admin cluster and at least one managed cluster 173 // WHEN the example application has been deployed to the admin cluster 174 // THEN expect Prometheus metrics for the app to exist in Prometheus on the admin cluster 175 t.Context("for Prometheus Metrics", Label("f:observability.monitoring.prom"), func() { 176 177 // Coherence metric fix available only from 1.3.0 178 if ok, _ := pkg.IsVerrazzanoMinVersion("1.3.0", adminKubeconfig); ok { 179 t.It("Verify base_jvm_uptime_seconds metrics exist for managed cluster", func() { 180 clusterNameMetricsLabel, _ := pkg.GetClusterNameMetricLabel(adminKubeconfig) 181 Eventually(func() bool { 182 m := make(map[string]string) 183 m["app"] = testApp 184 m[clusterNameMetricsLabel] = clusterName 185 return metricsTest.MetricsExist("base_jvm_uptime_seconds", m) 186 }, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find base_jvm_uptime_seconds metric") 187 }) 188 189 t.It("Verify DNE base_jvm_uptime_seconds metrics does not exist for managed cluster", func() { 190 clusterNameMetricsLabel, _ := pkg.GetClusterNameMetricLabel(adminKubeconfig) 191 Eventually(func() bool { 192 m := make(map[string]string) 193 m["app"] = testApp 194 m[clusterNameMetricsLabel] = "DNE" 195 return metricsTest.MetricsExist("base_jvm_uptime_seconds", m) 196 }, longWaitTimeout, longPollingInterval).Should(BeFalse(), "Not expected to find base_jvm_uptime_seconds metric") 197 }) 198 199 t.It("Verify vendor_requests_count_total metrics exist for managed cluster", func() { 200 clusterNameMetricsLabel, _ := pkg.GetClusterNameMetricLabel(adminKubeconfig) 201 Eventually(func() bool { 202 m := make(map[string]string) 203 m["app"] = testApp 204 m[clusterNameMetricsLabel] = clusterName 205 return metricsTest.MetricsExist("vendor_requests_count_total", m) 206 }, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find vendor_requests_count_total metric") 207 }) 208 209 t.It("Verify container_cpu_cfs_periods_total metrics exist for managed cluster", func() { 210 clusterNameMetricsLabel, _ := pkg.GetClusterNameMetricLabel(adminKubeconfig) 211 Eventually(func() bool { 212 m := make(map[string]string) 213 m["namespace"] = testNamespace 214 m[clusterNameMetricsLabel] = clusterName 215 return metricsTest.MetricsExist("container_cpu_cfs_periods_total", m) 216 }, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find container_cpu_cfs_periods_total metric") 217 }) 218 219 t.It("Verify coherence metrics exist for managed cluster", func() { 220 clusterNameMetricsLabel, _ := pkg.GetClusterNameMetricLabel(adminKubeconfig) 221 Eventually(func() bool { 222 m := make(map[string]string) 223 m["cluster"] = testCluster 224 m[clusterNameMetricsLabel] = clusterName 225 return metricsTest.MetricsExist("vendor:coherence_service_messages_local", m) 226 }, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find coherence metric") 227 }) 228 } 229 }) 230 231 t.Context("Delete resources", func() { 232 t.It("on admin cluster", func() { 233 Eventually(func() error { 234 return cleanUp(adminKubeconfig) 235 }, waitTimeout, pollingInterval).ShouldNot(HaveOccurred()) 236 }) 237 238 t.It("Verify deletion on admin cluster", func() { 239 Eventually(func() bool { 240 return VerifySockShopDeleteOnAdminCluster(adminKubeconfig, false, testNamespace, testProjectName) 241 }, waitTimeout, pollingInterval).Should(BeTrue()) 242 }) 243 244 t.It("Verify automatic deletion on managed cluster", func() { 245 Eventually(func() bool { 246 return VerifySockShopDeleteOnManagedCluster(managedKubeconfig, testNamespace, testProjectName) 247 }, waitTimeout, pollingInterval).Should(BeTrue()) 248 }) 249 250 t.It("Delete test namespace on managed cluster", func() { 251 Eventually(func() error { 252 return pkg.DeleteNamespaceInCluster(testNamespace, managedKubeconfig) 253 }, waitTimeout, pollingInterval).ShouldNot(HaveOccurred()) 254 }) 255 256 t.It("Delete test namespace on admin cluster", func() { 257 Eventually(func() error { 258 return pkg.DeleteNamespaceInCluster(testNamespace, adminKubeconfig) 259 }, waitTimeout, pollingInterval).ShouldNot(HaveOccurred()) 260 }) 261 }) 262 }) 263 264 var afterSuite = t.AfterSuiteFunc(func() { 265 if failed || !beforeSuitePassed { 266 err := dump.ExecuteBugReport(testNamespace) 267 if err != nil { 268 return 269 } 270 } 271 }) 272 273 var _ = AfterSuite(afterSuite) 274 275 func cleanUp(kubeconfigPath string) error { 276 start := time.Now() 277 file, err := pkg.FindTestDataFile(fmt.Sprintf("examples/multicluster/%s/sock-shop-app.yaml", sourceDir)) 278 if err != nil { 279 return err 280 } 281 if err := resource.DeleteResourceFromFileInCluster(file, kubeconfigPath); err != nil { 282 return fmt.Errorf("failed to delete multi-cluster sock-shop application resource: %v", err) 283 } 284 285 file, err = pkg.FindTestDataFile(fmt.Sprintf("examples/multicluster/%s/sock-shop-comp.yaml", sourceDir)) 286 if err != nil { 287 return err 288 } 289 if err := resource.DeleteResourceFromFileInCluster(file, kubeconfigPath); err != nil { 290 return fmt.Errorf("failed to delete multi-cluster sock-shop component resources: %v", err) 291 } 292 293 file, err = pkg.FindTestDataFile(fmt.Sprintf("examples/multicluster/%s/verrazzano-project.yaml", sourceDir)) 294 if err != nil { 295 return err 296 } 297 if err := resource.DeleteResourceFromFileInCluster(file, kubeconfigPath); err != nil { 298 return fmt.Errorf("failed to delete sock-shop project resource: %v", err) 299 } 300 metrics.Emit(t.Metrics.With("undeployment_elapsed_time", time.Since(start).Milliseconds())) 301 return nil 302 }