github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/examples/argocd-helidon/argocd_helidon_test.go (about) 1 // Copyright (c) 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 argocd 5 6 import ( 7 "fmt" 8 "io" 9 "net/http" 10 "strings" 11 "time" 12 13 "github.com/hashicorp/go-retryablehttp" 14 "github.com/verrazzano/verrazzano/pkg/k8sutil" 15 "github.com/verrazzano/verrazzano/tests/e2e/pkg" 16 dump "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/clusterdump" 17 "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework" 18 "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework/metrics" 19 20 . "github.com/onsi/ginkgo/v2" 21 . "github.com/onsi/gomega" 22 ) 23 24 const ( 25 longWaitTimeout = 20 * time.Minute 26 longPollingInterval = 20 * time.Second 27 shortPollingInterval = 10 * time.Second 28 shortWaitTimeout = 5 * time.Minute 29 imagePullWaitTimeout = 40 * time.Minute 30 imagePullPollingInterval = 30 * time.Second 31 skipVerifications = "Skip Verifications" 32 argoCdHelidon = "argocd-helidon" 33 nodeExporterJobName = "node-exporter" 34 helloHelidonDeploymentName = "hello-helidon-deployment" 35 ) 36 37 var ( 38 t = framework.NewTestFramework("argocd") 39 // yamlApplier = k8sutil.YAMLApplier{} 40 expectedPodsHelloHelidon = []string{"hello-helidon-deployment"} 41 ) 42 43 var beforeSuite = t.BeforeSuiteFunc(func() { 44 if !skipDeploy { 45 start := time.Now() 46 pkg.CreateArgoCDGitApplication() 47 metrics.Emit(t.Metrics.With("deployment_elapsed_time", time.Since(start).Milliseconds())) 48 49 Eventually(func() bool { 50 return pkg.ContainerImagePullWait(namespace, expectedPodsHelloHelidon) 51 }, imagePullWaitTimeout, imagePullPollingInterval).Should(BeTrue()) 52 } 53 54 // Verify hello-helidon-deployment pod is running 55 // GIVEN OAM hello-helidon app is deployed 56 // WHEN the component and appconfig are created 57 // THEN the expected pod must be running in the test namespace 58 if !skipVerify { 59 Eventually(helloHelidonPodsRunning, longWaitTimeout, longPollingInterval).Should(BeTrue()) 60 } 61 beforeSuitePassed = true 62 }) 63 64 var _ = BeforeSuite(beforeSuite) 65 66 var failed = false 67 var beforeSuitePassed = false 68 69 var _ = t.AfterEach(func() { 70 failed = failed || CurrentSpecReport().Failed() 71 }) 72 73 var afterSuite = t.AfterSuiteFunc(func() { 74 if failed || !beforeSuitePassed { 75 dump.ExecuteBugReport(namespace) 76 } 77 }) 78 79 var _ = t.Describe("Argo CD Helidon Suite", Label("f:app-lcm.oam", 80 "f:app-lcm.helidon-workload"), func() { 81 var host = "" 82 var err error 83 // Get the host from the Istio gateway resource. 84 // GIVEN the Istio gateway for the hello-helidon namespace 85 // WHEN GetHostnameFromGateway is called 86 // THEN return the host name found in the gateway. 87 t.BeforeEach(func() { 88 Eventually(func() (string, error) { 89 host, err = k8sutil.GetHostnameFromGateway(namespace, "") 90 return host, err 91 }, shortWaitTimeout, shortPollingInterval).Should(Not(BeEmpty())) 92 }) 93 94 // Verify Hello Helidon app is working 95 // GIVEN OAM hello-helidon app is deployed 96 // WHEN the component and appconfig with ingress trait are created 97 // THEN the application endpoint must be accessible 98 t.Describe("for Ingress.", Label("f:mesh.ingress"), func() { 99 t.It("Access /greet App Url.", func() { 100 if skipVerify { 101 Skip(skipVerifications) 102 } 103 url := fmt.Sprintf("https://%s/greet", host) 104 Eventually(func() bool { 105 return appEndpointAccessible(url, host) 106 }, longWaitTimeout, longPollingInterval).Should(BeTrue()) 107 }) 108 }) 109 }) 110 111 func helloHelidonPodsRunning() bool { 112 result, err := pkg.PodsRunning(namespace, expectedPodsHelloHelidon) 113 if err != nil { 114 AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", namespace, err)) 115 } 116 return result 117 } 118 119 func appEndpointAccessible(url string, hostname string) bool { 120 req, err := retryablehttp.NewRequest("GET", url, nil) 121 if err != nil { 122 t.Logs.Errorf("Unexpected error while creating new request=%v", err) 123 return false 124 } 125 126 kubeconfigPath, err := k8sutil.GetKubeConfigLocation() 127 if err != nil { 128 t.Logs.Errorf("Unexpected error while getting kubeconfig location=%v", err) 129 return false 130 } 131 132 httpClient, err := pkg.GetVerrazzanoHTTPClient(kubeconfigPath) 133 if err != nil { 134 t.Logs.Errorf("Unexpected error while getting new httpClient=%v", err) 135 return false 136 } 137 req.Host = hostname 138 req.Close = true 139 resp, err := httpClient.Do(req) 140 if err != nil { 141 t.Logs.Errorf("Unexpected error while making http request=%v", err) 142 if resp != nil && resp.Body != nil { 143 bodyRaw, err := io.ReadAll(resp.Body) 144 if err != nil { 145 t.Logs.Errorf("Unexpected error while marshallling error response=%v", err) 146 return false 147 } 148 149 t.Logs.Errorf("Error Response=%v", string(bodyRaw)) 150 resp.Body.Close() 151 } 152 return false 153 } 154 155 bodyRaw, err := io.ReadAll(resp.Body) 156 resp.Body.Close() 157 if err != nil { 158 t.Logs.Errorf("Unexpected error marshallling response=%v", err) 159 return false 160 } 161 if resp.StatusCode != http.StatusOK { 162 t.Logs.Errorf("Unexpected status code=%v", resp.StatusCode) 163 return false 164 } 165 // HTTP Server headers should never be returned. 166 for headerName, headerValues := range resp.Header { 167 if strings.EqualFold(headerName, "Server") { 168 t.Logs.Errorf("Unexpected Server header=%v", headerValues) 169 return false 170 } 171 } 172 bodyStr := string(bodyRaw) 173 if !strings.Contains(bodyStr, "Hello World") { 174 t.Logs.Errorf("Unexpected response body=%v", bodyStr) 175 return false 176 } 177 return true 178 }