github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/logging/helidon/helidon_logging_test.go (about)

     1  // Copyright (c) 2021, 2022, 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 helidon
     5  
     6  import (
     7  	"fmt"
     8  	dump "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/clusterdump"
     9  	"time"
    10  
    11  	. "github.com/onsi/ginkgo/v2"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/verrazzano/verrazzano/pkg/k8s/resource"
    14  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    15  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    16  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework"
    17  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework/metrics"
    18  	v1 "k8s.io/api/core/v1"
    19  	"k8s.io/apimachinery/pkg/api/errors"
    20  )
    21  
    22  const (
    23  	longWaitTimeout          = 20 * time.Minute
    24  	longPollingInterval      = 20 * time.Second
    25  	shortPollingInterval     = 10 * time.Second
    26  	shortWaitTimeout         = 5 * time.Minute
    27  	imagePullWaitTimeout     = 40 * time.Minute
    28  	imagePullPollingInterval = 30 * time.Second
    29  )
    30  
    31  var (
    32  	t                  = framework.NewTestFramework("helidon")
    33  	generatedNamespace = pkg.GenerateNamespace("helidon-logging")
    34  )
    35  
    36  var beforeSuite = t.BeforeSuiteFunc(func() {
    37  	start := time.Now()
    38  	Eventually(func() (*v1.Namespace, error) {
    39  		nsLabels := map[string]string{
    40  			"verrazzano-managed": "true",
    41  			"istio-injection":    istioInjection}
    42  		return pkg.CreateNamespace(namespace, nsLabels)
    43  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(BeNil())
    44  
    45  	Eventually(func() error {
    46  		file, err := pkg.FindTestDataFile("testdata/logging/helidon/helidon-logging-comp.yaml")
    47  		if err != nil {
    48  			return err
    49  		}
    50  		return resource.CreateOrUpdateResourceFromFileInGeneratedNamespace(file, namespace)
    51  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
    52  
    53  	Eventually(func() error {
    54  		file, err := pkg.FindTestDataFile("testdata/logging/helidon/helidon-logging-app.yaml")
    55  		if err != nil {
    56  			return err
    57  		}
    58  		return resource.CreateOrUpdateResourceFromFileInGeneratedNamespace(file, namespace)
    59  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
    60  
    61  	Eventually(func() bool {
    62  		return pkg.ContainerImagePullWait(namespace, expectedPodsHelloHelidon)
    63  	}, imagePullWaitTimeout, imagePullPollingInterval).Should(BeTrue())
    64  	// Verify hello-helidon-workload pod is running
    65  	Eventually(helloHelidonPodsRunning, waitTimeout, pollingInterval).Should(BeTrue())
    66  	beforeSuitePassed = true
    67  	metrics.Emit(t.Metrics.With("deployment_elapsed_time", time.Since(start).Milliseconds()))
    68  })
    69  
    70  var _ = BeforeSuite(beforeSuite)
    71  
    72  var failed = false
    73  var beforeSuitePassed = false
    74  
    75  var _ = t.AfterEach(func() {
    76  	failed = failed || CurrentSpecReport().Failed()
    77  })
    78  
    79  var afterSuite = t.AfterSuiteFunc(func() {
    80  	if failed || !beforeSuitePassed {
    81  		dump.ExecuteBugReport(namespace)
    82  	}
    83  	// undeploy the application here
    84  	start := time.Now()
    85  
    86  	t.Logs.Info("Delete application")
    87  	Eventually(func() error {
    88  		file, err := pkg.FindTestDataFile("testdata/logging/helidon/helidon-logging-app.yaml")
    89  		if err != nil {
    90  			return err
    91  		}
    92  		return resource.DeleteResourceFromFileInGeneratedNamespace(file, namespace)
    93  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
    94  
    95  	t.Logs.Info("Delete components")
    96  	Eventually(func() error {
    97  		file, err := pkg.FindTestDataFile("testdata/logging/helidon/helidon-logging-comp.yaml")
    98  		if err != nil {
    99  			return err
   100  		}
   101  		return resource.DeleteResourceFromFileInGeneratedNamespace(file, namespace)
   102  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   103  
   104  	t.Logs.Info("Wait for application pods to terminate")
   105  	Eventually(func() bool {
   106  		podsTerminated, _ := pkg.PodsNotRunning("helidon-logging", expectedPodsHelloHelidon)
   107  		return podsTerminated
   108  	}, shortWaitTimeout, shortPollingInterval).Should(BeTrue())
   109  
   110  	t.Logs.Info("Delete namespace")
   111  	Eventually(func() error {
   112  		return pkg.DeleteNamespace(namespace)
   113  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   114  
   115  	t.Logs.Info("Wait for Finalizer to be removed")
   116  	Eventually(func() bool {
   117  		return pkg.CheckNamespaceFinalizerRemoved("helidon-logging")
   118  	}, shortWaitTimeout, shortPollingInterval).Should(BeTrue())
   119  
   120  	t.Logs.Info("Wait for namespace to be deleted")
   121  	Eventually(func() bool {
   122  		_, err := pkg.GetNamespace("helidon-logging")
   123  		return err != nil && errors.IsNotFound(err)
   124  	}, shortWaitTimeout, shortPollingInterval).Should(BeTrue())
   125  
   126  	metrics.Emit(t.Metrics.With("undeployment_elapsed_time", time.Since(start).Milliseconds()))
   127  })
   128  
   129  var _ = AfterSuite(afterSuite)
   130  
   131  var (
   132  	expectedPodsHelloHelidon = []string{"hello-helidon-workload"}
   133  	waitTimeout              = 10 * time.Minute
   134  	pollingInterval          = 30 * time.Second
   135  )
   136  
   137  var _ = t.Describe("Hello Helidon OAM App test", Label("f:app-lcm.oam",
   138  	"f:app-lcm.helidon-workload"), func() {
   139  
   140  	var host = ""
   141  	var err error
   142  	// Get the host from the Istio gateway resource.
   143  	// GIVEN the Istio gateway for the helidon-logging namespace
   144  	// WHEN GetHostnameFromGateway is called
   145  	// THEN return the host name found in the gateway.
   146  	t.BeforeEach(func() {
   147  		Eventually(func() (string, error) {
   148  			host, err = k8sutil.GetHostnameFromGateway(namespace, "")
   149  			return host, err
   150  		}, shortWaitTimeout, shortPollingInterval).Should(Not(BeEmpty()))
   151  	})
   152  
   153  	// Verify Hello Helidon app is working
   154  	// GIVEN OAM hello-helidon app is deployed
   155  	// WHEN the component and appconfig with ingress trait are created
   156  	// THEN the application endpoint must be accessible
   157  	t.Describe("for Ingress.", Label("f:mesh.ingress"), func() {
   158  		t.It("Access /greet App Url.", func() {
   159  			kubeconfigPath, err := k8sutil.GetKubeConfigLocation()
   160  			Expect(err).ShouldNot(HaveOccurred())
   161  			Eventually(func() (*pkg.HTTPResponse, error) {
   162  				url := fmt.Sprintf("https://%s/greet", host)
   163  				response, err := pkg.GetWebPageWithBasicAuth(url, host, "", "", kubeconfigPath)
   164  				//This test is failing intermittently with 403. This is a temporary fix
   165  				//untill a solution is found.
   166  				if response != nil && response.StatusCode == 403 {
   167  					t.Logs.Error("/greet returned 403.")
   168  				}
   169  				return response, err
   170  			}, shortWaitTimeout, shortPollingInterval).Should(Or(And(pkg.HasStatus(200), pkg.BodyContains("Hello World")), pkg.HasStatus(403)))
   171  		})
   172  	})
   173  
   174  	t.Context("for Logging.", Label("f:observability.logging.es"), func() {
   175  		var indexName string
   176  		Eventually(func() error {
   177  			indexName, err = pkg.GetOpenSearchAppIndex(namespace)
   178  			return err
   179  		}, shortWaitTimeout, shortPollingInterval).Should(BeNil(), "Expected to get OpenSearch App Index")
   180  
   181  		// GIVEN an application with logging enabled
   182  		// WHEN the Opensearch index for hello-helidon namespace is retrieved
   183  		// THEN verify that it is found
   184  		t.It("Verify Opensearch index for Logging exists", func() {
   185  			Eventually(func() bool {
   186  				return pkg.LogIndexFound(indexName)
   187  			}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find log index for hello-helidon-container")
   188  		})
   189  		pkg.Concurrently(
   190  			func() {
   191  				// GIVEN an application with logging enabled
   192  				// WHEN the log records are retrieved from the Opensearch index for hello-helidon-container
   193  				// THEN verify that at least one recent log record is found
   194  				t.It("Verify recent Opensearch log record exists", func() {
   195  					Eventually(func() bool {
   196  						return pkg.LogRecordFound(indexName, time.Now().Add(-24*time.Hour), map[string]string{
   197  							"kubernetes.labels.app_oam_dev\\/name": "hello-helidon",
   198  							"kubernetes.container_name":            "hello-helidon-container"})
   199  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent log record for container hello-helidon-container")
   200  				})
   201  			},
   202  			func() {
   203  				// GIVEN an application with logging enabled
   204  				// WHEN the log records are retrieved from the Openearch index for other-container
   205  				// THEN verify that at least one recent log record is found
   206  				t.It("Verify recent Opensearch log record of other-container exists", func() {
   207  					Eventually(func() bool {
   208  						return pkg.LogRecordFound(indexName, time.Now().Add(-24*time.Hour), map[string]string{
   209  							"kubernetes.labels.app_oam_dev\\/name": "hello-helidon",
   210  							"kubernetes.container_name":            "other-container"})
   211  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent log record for other-container")
   212  				})
   213  			},
   214  		)
   215  	})
   216  })
   217  
   218  func helloHelidonPodsRunning() bool {
   219  	result, err := pkg.PodsRunning(namespace, expectedPodsHelloHelidon)
   220  	if err != nil {
   221  		AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", namespace, err))
   222  	}
   223  	return result
   224  }