github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/logging/weblogic/weblogic_logging_test.go (about)

     1  // Copyright (c) 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 weblogic
     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/tests/e2e/pkg"
    15  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework"
    16  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework/metrics"
    17  	pkgweblogic "github.com/verrazzano/verrazzano/tests/e2e/pkg/weblogic"
    18  	v1 "k8s.io/api/core/v1"
    19  	"k8s.io/apimachinery/pkg/api/errors"
    20  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    21  )
    22  
    23  const (
    24  	longWaitTimeout          = 20 * time.Minute
    25  	longPollingInterval      = 20 * time.Second
    26  	shortWaitTimeout         = 5 * time.Minute
    27  	shortPollingInterval     = 10 * time.Second
    28  	imagePullWaitTimeout     = 30 * time.Minute
    29  	imagePullPollingInterval = 30 * time.Second
    30  )
    31  
    32  var (
    33  	t                  = framework.NewTestFramework("weblogic-logging")
    34  	generatedNamespace = pkg.GenerateNamespace("weblogic-logging")
    35  
    36  	failed            = false
    37  	beforeSuitePassed = false
    38  
    39  	expectedPods = []string{"weblogicloggingdomain-adminserver"}
    40  )
    41  
    42  var _ = t.AfterEach(func() {
    43  	failed = failed || CurrentSpecReport().Failed()
    44  })
    45  
    46  // Create all of the resources to deploy the application and wait for the pods to run
    47  var beforeSuite = t.BeforeSuiteFunc(func() {
    48  	start := time.Now()
    49  
    50  	t.Logs.Info("Deploy WebLogic logging application")
    51  	wlsUser := "weblogic"
    52  	wlsPass := pkg.GetRequiredEnvVarOrFail("WEBLOGIC_PSW")
    53  	regServ := pkg.GetRequiredEnvVarOrFail("OCR_REPO")
    54  	regUser := pkg.GetRequiredEnvVarOrFail("OCR_CREDS_USR")
    55  	regPass := pkg.GetRequiredEnvVarOrFail("OCR_CREDS_PSW")
    56  
    57  	t.Logs.Info("Create namespace")
    58  	Eventually(func() (*v1.Namespace, error) {
    59  		nsLabels := map[string]string{
    60  			"verrazzano-managed": "true",
    61  			"istio-injection":    istioInjection}
    62  		return pkg.CreateNamespace(namespace, nsLabels)
    63  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(BeNil())
    64  
    65  	t.Logs.Info("Create repository secret")
    66  	Eventually(func() (*v1.Secret, error) {
    67  		return pkg.CreateDockerSecret(namespace, "weblogicloggingdomain-repo-credentials", regServ, regUser, regPass)
    68  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(BeNil())
    69  
    70  	t.Logs.Info("Create WebLogic credentials secret")
    71  	Eventually(func() (*v1.Secret, error) {
    72  		return pkg.CreateCredentialsSecret(namespace, "weblogicloggingdomain-weblogic-credentials", wlsUser, wlsPass, nil)
    73  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(BeNil())
    74  
    75  	t.Logs.Info("Create persistent volume claim")
    76  	Eventually(func() error {
    77  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/pvc.yaml")
    78  		if err != nil {
    79  			return err
    80  		}
    81  		return resource.CreateOrUpdateResourceFromFileInGeneratedNamespace(file, namespace)
    82  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
    83  
    84  	t.Logs.Info("Create component resources")
    85  	Eventually(func() error {
    86  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/weblogic-logging-comp.yaml")
    87  		if err != nil {
    88  			return err
    89  		}
    90  		return resource.CreateOrUpdateResourceFromFileInGeneratedNamespace(file, namespace)
    91  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
    92  
    93  	t.Logs.Info("Create application resources")
    94  	Eventually(func() error {
    95  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/weblogic-logging-app.yaml")
    96  		if err != nil {
    97  			return err
    98  		}
    99  		return resource.CreateOrUpdateResourceFromFileInGeneratedNamespace(file, namespace)
   100  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   101  
   102  	t.Logs.Info("Wait for image pulls")
   103  	Eventually(func() bool {
   104  		return pkg.ContainerImagePullWait(namespace, expectedPods)
   105  	}, imagePullWaitTimeout, imagePullPollingInterval).Should(BeTrue())
   106  
   107  	t.Logs.Info("Wait for running pods")
   108  	Eventually(func() bool {
   109  		result, err := pkg.PodsRunning(namespace, expectedPods)
   110  		if err != nil {
   111  			AbortSuite(fmt.Sprintf("One or more pods are not running in namespace: %v, error: %v", namespace, err))
   112  		}
   113  		return result
   114  	}, longWaitTimeout, longPollingInterval).Should(BeTrue())
   115  
   116  	beforeSuitePassed = true
   117  	metrics.Emit(t.Metrics.With("deployment_elapsed_time", time.Since(start).Milliseconds()))
   118  })
   119  
   120  var _ = BeforeSuite(beforeSuite)
   121  
   122  // Delete all of the resources to undeploy the application
   123  var afterSuite = t.AfterSuiteFunc(func() {
   124  	if failed || !beforeSuitePassed {
   125  		dump.ExecuteBugReport(namespace)
   126  	}
   127  	start := time.Now()
   128  
   129  	t.Logs.Info("Delete component resources")
   130  	Eventually(func() error {
   131  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/weblogic-logging-app.yaml")
   132  		if err != nil {
   133  			return err
   134  		}
   135  		return resource.DeleteResourceFromFileInGeneratedNamespace(file, namespace)
   136  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   137  
   138  	t.Logs.Info("Delete application resources")
   139  	Eventually(func() error {
   140  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/weblogic-logging-comp.yaml")
   141  		if err != nil {
   142  			return err
   143  		}
   144  		return resource.DeleteResourceFromFileInGeneratedNamespace(file, namespace)
   145  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   146  
   147  	t.Logs.Info("Wait for application pods to terminate")
   148  	Eventually(func() bool {
   149  		podsTerminated, _ := pkg.PodsNotRunning(namespace, expectedPods)
   150  		return podsTerminated
   151  	}, shortWaitTimeout, shortPollingInterval).Should(BeTrue())
   152  
   153  	t.Logs.Info("Delete persistent volume claim")
   154  	Eventually(func() error {
   155  		file, err := pkg.FindTestDataFile("testdata/logging/weblogic/pvc.yaml")
   156  		if err != nil {
   157  			return err
   158  		}
   159  		return resource.DeleteResourceFromFileInGeneratedNamespace(file, namespace)
   160  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   161  
   162  	t.Logs.Info("Delete namespace")
   163  	Eventually(func() error {
   164  		return pkg.DeleteNamespace(namespace)
   165  	}, shortWaitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   166  
   167  	t.Logs.Info("Wait for namespace to be deleted")
   168  	Eventually(func() bool {
   169  		_, err := pkg.GetNamespace(namespace)
   170  		return err != nil && errors.IsNotFound(err)
   171  	}, shortWaitTimeout, shortPollingInterval).Should(BeTrue())
   172  
   173  	metrics.Emit(t.Metrics.With("undeployment_elapsed_time", time.Since(start).Milliseconds()))
   174  })
   175  
   176  var _ = AfterSuite(afterSuite)
   177  
   178  var _ = t.Describe("WebLogic logging test", Label("f:app-lcm.oam", "f:app-lcm.weblogic-workload"), func() {
   179  
   180  	t.Context("WebLogic domain is configured properly.", func() {
   181  		// GIVEN the WebLogic domain resource has been created by the Verrazzano Application Operator
   182  		// WHEN we fetch the domain
   183  		// THEN the logHome in the spec has not been overwritten with a /scratch directory
   184  		t.It("logHome has not been overwritten", func() {
   185  			domain, err := pkgweblogic.GetDomain(namespace, "weblogic-logging-domain")
   186  			Expect(domain, err).ShouldNot(BeNil())
   187  
   188  			logHome, _, err := unstructured.NestedString(domain.Object, "spec", "logHome")
   189  			Expect(logHome, err).To(Equal("/mnt/shared/logs"))
   190  		})
   191  	})
   192  
   193  	t.Context("Logging.", Label("f:observability.logging.es"), func() {
   194  		var indexName string
   195  		var err error
   196  		Eventually(func() error {
   197  			indexName, err = pkg.GetOpenSearchAppIndex(namespace)
   198  			return err
   199  		}, shortWaitTimeout, shortPollingInterval).Should(BeNil(), "Expected to get OpenSearch App Index")
   200  
   201  		// GIVEN a WebLogic application with logging enabled
   202  		// WHEN the Opensearch index is retrieved
   203  		// THEN verify that it is found
   204  		t.It("Verify Opensearch index exists", func() {
   205  			Eventually(func() bool {
   206  				return pkg.LogIndexFound(indexName)
   207  			}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find log index")
   208  		})
   209  
   210  		// GIVEN a WebLogic application with logging enabled
   211  		// WHEN the log records are retrieved from the Opensearch index
   212  		// THEN verify that at least one recent log record is found
   213  		const k8sContainerNameKeyword = "kubernetes.container_name.keyword"
   214  		const fluentdStdoutSidecarName = "fluentd-stdout-sidecar"
   215  
   216  		pkg.Concurrently(
   217  			func() {
   218  				t.It("Verify recent adminserver log record exists", func() {
   219  					Eventually(func() bool {
   220  						return pkg.LogRecordFound(indexName, time.Now().Add(-24*time.Hour), map[string]string{
   221  							"kubernetes.labels.weblogic_domainUID":  "weblogicloggingdomain",
   222  							"kubernetes.labels.app_oam_dev\\/name":  "weblogicloggingdomain-appconf",
   223  							"kubernetes.labels.weblogic_serverName": "AdminServer",
   224  							"kubernetes.container_name":             "weblogic-server",
   225  						})
   226  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent adminserver log record")
   227  				})
   228  			},
   229  			func() {
   230  				t.It("Verify recent pattern-matched AdminServer log record exists", func() {
   231  					Eventually(func() bool {
   232  						return pkg.FindLog(indexName,
   233  							[]pkg.Match{
   234  								{Key: k8sContainerNameKeyword, Value: fluentdStdoutSidecarName},
   235  								{Key: "messageID", Value: "BEA-"},
   236  								{Key: "serverName", Value: "weblogicloggingdomain-adminserver"},
   237  								{Key: "serverName2", Value: "AdminServer"}},
   238  							[]pkg.Match{})
   239  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent pattern-matched adminserver log record")
   240  				})
   241  			},
   242  			func() {
   243  				t.It("Verify recent pattern-matched WebLogic Server log record exists", func() {
   244  					Eventually(func() bool {
   245  						return pkg.FindLog(indexName,
   246  							[]pkg.Match{
   247  								{Key: k8sContainerNameKeyword, Value: fluentdStdoutSidecarName},
   248  								{Key: "messageID", Value: "BEA-"},
   249  								{Key: "message", Value: "WebLogic Server"},
   250  								{Key: "subSystem", Value: "WebLogicServer"}},
   251  							[]pkg.Match{})
   252  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent pattern-matched WebLogic Server log record")
   253  				})
   254  			},
   255  			func() {
   256  				t.It("Verify recent fluentd-stdout-sidecar server log record exists", func() {
   257  					Eventually(func() bool {
   258  						return pkg.FindLog(indexName,
   259  							[]pkg.Match{
   260  								{Key: k8sContainerNameKeyword, Value: fluentdStdoutSidecarName},
   261  								{Key: "wls_log_stream", Value: "server_log"},
   262  								{Key: "stream", Value: "stdout"}},
   263  							[]pkg.Match{})
   264  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent fluentd-stdout-sidecar server log record")
   265  				})
   266  			},
   267  			func() {
   268  				t.It("Verify recent fluentd-stdout-sidecar domain log record exists", func() {
   269  					Eventually(func() bool {
   270  						return pkg.FindLog(indexName,
   271  							[]pkg.Match{
   272  								{Key: k8sContainerNameKeyword, Value: fluentdStdoutSidecarName},
   273  								{Key: "wls_log_stream", Value: "domain_log"},
   274  								{Key: "stream", Value: "stdout"}},
   275  							[]pkg.Match{})
   276  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent fluentd-stdout-sidecar domain log record")
   277  				})
   278  			},
   279  			func() {
   280  				t.It("Verify recent fluentd-stdout-sidecar nodemanager log record exists", func() {
   281  					Eventually(func() bool {
   282  						return pkg.FindLog(indexName,
   283  							[]pkg.Match{
   284  								{Key: "kubernetes.container_name.keyword", Value: fluentdStdoutSidecarName},
   285  								{Key: "wls_log_stream", Value: "server_nodemanager_log"},
   286  								{Key: "stream", Value: "stdout"}},
   287  							[]pkg.Match{})
   288  					}, longWaitTimeout, longPollingInterval).Should(BeTrue(), "Expected to find a recent server fluentd-stdout-sidecar nodemanager log record")
   289  				})
   290  			},
   291  		)
   292  	})
   293  })