This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 69d8d7302e976e7ebe96b58d42d2506e1ec8338f Author: Gaelle Fournier <[email protected]> AuthorDate: Wed Jan 11 18:06:23 2023 +0100 feat(e2e): Add Telemetry e2e test * Add specific github action * Add opentelemetry basic config collector in telemetry e2e env --- .github/actions/e2e-telemetry/action.yml | 137 ++++++++++++++++++++ .github/actions/e2e-telemetry/exec-tests.sh | 141 +++++++++++++++++++++ .github/actions/kamel-cleanup/action.yaml | 7 + .../kamel-cleanup/clean-telemetry-resources.sh | 26 ++++ .../kamel-install-otlp-collector/action.yml | 117 +++++++++++++++++ .github/workflows/telemetry.yml | 94 ++++++++++++++ e2e/global/telemetry/files/rest-consumer.yaml | 29 +++++ e2e/global/telemetry/files/rest-producer.yaml | 24 ++++ e2e/global/telemetry/telemetry_test.go | 73 +++++++++++ e2e/support/test_support.go | 34 +++++ script/Makefile | 4 + 11 files changed, 686 insertions(+) diff --git a/.github/actions/e2e-telemetry/action.yml b/.github/actions/e2e-telemetry/action.yml new file mode 100644 index 000000000..000ddde2d --- /dev/null +++ b/.github/actions/e2e-telemetry/action.yml @@ -0,0 +1,137 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +name: e2e-telemetry +description: 'End-to-End tests for telemetry use-cases' + +inputs: + cluster-config-data: + description: 'The configuration of the underlying cluster (if cluster-type is custom)' + required: false + cluster-kube-config-data: + description: 'Base16 encoded kube config - required for custom cluster type only' + required: false + +runs: + using: "composite" + + steps: + - id: prepare-env + name: Prepare Test Environment + uses: ./.github/actions/kamel-prepare-env + + - id: config-cluster + name: Configure Platform + uses: ./.github/actions/kamel-config-cluster + with: + cluster-config-data: ${{ inputs.cluster-config-data }} + cluster-kube-config-data: ${{ inputs.cluster-kube-config-data }} + # + # Try and ensure the cluster is in a vanilla state before + # starting in on an installation + # + - id: pre-clean-cluster + name: Pre Clean Cluster + uses: ./.github/actions/kamel-cleanup + if: ${{ always() }} + with: + catalog-source-name: ${{ steps.config-cluster.outputs.cluster-catalog-source-name }} + catalog-source-namespace: ${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }} + image-namespace: ${{ steps.config-cluster.outputs.cluster-image-namespace }} + global-operator-namespace: ${{ steps.config-cluster.outputs.cluster-global-operator-namespace }} + + - id: build-kamel + name: Build Kamel + uses: ./.github/actions/kamel-build + with: + image-registry-push-host: ${{ steps.config-cluster.outputs.cluster-image-registry-push-host }} + image-registry-pull-host: ${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }} + image-namespace: ${{ steps.config-cluster.outputs.cluster-image-namespace }} + # Builds the bundle if an OLM is available - depends on cluster being tested + build-bundle: ${{ steps.config-cluster.outputs.cluster-has-olm }} + # Both can be empty and so catalog source will not be created + catalog-source-name: ${{ steps.config-cluster.outputs.cluster-catalog-source-name }} + catalog-source-namespace: ${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }} + + - id: install-kamel-cluster-setup + name: Install Kamel Cluster Setup + uses: ./.github/actions/kamel-install-cluster-setup + with: + kube-admin-user-ctx: ${{ steps.config-cluster.outputs.cluster-kube-admin-user-ctx }} + + - id: preflight-test + name: Preflight Check Test + uses: ./.github/actions/kamel-preflight-test + with: + catalog-source-name: ${{ steps.config-cluster.outputs.cluster-catalog-source-name }} + catalog-source-namespace: ${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }} + image-namespace: ${{ steps.config-cluster.outputs.cluster-image-namespace }} + image-registry-host: ${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }} + image-name: ${{ steps.build-kamel.outputs.build-binary-local-image-name }} + image-registry-insecure: ${{steps.config-cluster.outputs.cluster-image-registry-insecure }} + image-version: ${{ steps.build-kamel.outputs.build-binary-local-image-version }} + + - id: install-global-operator + name: "Install Global Operator" + if: ${{ steps.config-cluster.outputs.cluster-global-operator-namespace }} + uses: ./.github/actions/kamel-install-global-operator + with: + global-operator-namespace: ${{ steps.config-cluster.outputs.cluster-global-operator-namespace }} + catalog-source-name: ${{ steps.config-cluster.outputs.cluster-catalog-source-name }} + catalog-source-namespace: ${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }} + image-namespace: ${{ steps.config-cluster.outputs.cluster-image-namespace }} + image-registry-host: ${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }} + image-name: ${{ steps.build-kamel.outputs.build-binary-local-image-name }} + image-registry-insecure: ${{steps.config-cluster.outputs.cluster-image-registry-insecure }} + image-version: ${{ steps.build-kamel.outputs.build-binary-local-image-version }} + + - name: Install OTLP Collector + uses: ./.github/actions/kamel-install-otlp-collector + with: + otlp-collector-image-name: otel/opentelemetry-collector + otlp-collector-image-version: 0.68.0 + + - id: report-problematic + name: List Tests Marked As Problematic + uses: ./.github/actions/kamel-report-problematic + with: + test-suite: global/common + + - id: run-it + name: Run IT + shell: bash + run: | + ./.github/actions/e2e-telemetry/exec-tests.sh \ + -b "${{ steps.config-cluster.outputs.cluster-catalog-source-name }}" \ + -c "${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }}" \ + -g "${{ steps.config-cluster.outputs.cluster-global-operator-namespace }}" \ + -i "${{ steps.config-cluster.outputs.cluster-image-namespace }}" \ + -l "${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }}" \ + -n "${{ steps.build-kamel.outputs.build-binary-local-image-name }}" \ + -q "${{ env.CAMEL_K_LOG_LEVEL }}" \ + -s "${{steps.config-cluster.outputs.cluster-image-registry-insecure }}" \ + -v "${{ steps.build-kamel.outputs.build-binary-local-image-version }}" \ + -x "${{ env.CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE }}" + + - name: Cleanup + uses: ./.github/actions/kamel-cleanup + if: ${{ always() }} + with: + catalog-source-name: ${{ steps.config-cluster.outputs.cluster-catalog-source-name }} + catalog-source-namespace: ${{ steps.config-cluster.outputs.cluster-catalog-source-namespace }} + image-namespace: ${{ steps.config-cluster.outputs.cluster-image-namespace }} + global-operator-namespace: ${{ steps.config-cluster.outputs.cluster-global-operator-namespace }} diff --git a/.github/actions/e2e-telemetry/exec-tests.sh b/.github/actions/e2e-telemetry/exec-tests.sh new file mode 100755 index 000000000..92ba0a7c4 --- /dev/null +++ b/.github/actions/e2e-telemetry/exec-tests.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +#### +# +# Execute the telemetry tests +# +#### + +set -e + +while getopts ":b:c:g:i:l:n:q:s:v:x:" opt; do + case "${opt}" in + b) + BUILD_CATALOG_SOURCE_NAME=${OPTARG} + ;; + c) + BUILD_CATALOG_SOURCE_NAMESPACE=${OPTARG} + ;; + g) + GLOBAL_OPERATOR_NAMESPACE=${OPTARG} + ;; + i) + IMAGE_NAMESPACE=${OPTARG} + ;; + l) + REGISTRY_PULL_HOST=${OPTARG} + ;; + n) + IMAGE_NAME=${OPTARG} + ;; + q) + LOG_LEVEL=${OPTARG} + ;; + s) + REGISTRY_INSECURE=${OPTARG} + ;; + v) + IMAGE_VERSION=${OPTARG} + ;; + x) + SAVE_FAILED_TEST_NS=${OPTARG} + ;; + :) + echo "ERROR: Option -$OPTARG requires an argument" + exit 1 + ;; + \?) + echo "ERROR: Invalid option -$OPTARG" + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +if [ -z "${IMAGE_NAME}" ]; then + echo "Error: local-image-name not defined" + exit 1 +fi + +if [ -z "${IMAGE_VERSION}" ]; then + echo "Error: local-image-version not defined" + exit 1 +fi + +if [ -z "${IMAGE_NAMESPACE}" ]; then + echo "Error: image-namespace not defined" + exit 1 +fi + +if [ -z "${REGISTRY_PULL_HOST}" ]; then + echo "Error: image-registry-pull-host not defined" + exit 1 +fi + +if [ -z "${REGISTRY_INSECURE}" ]; then + echo "Error: image-registry-insecure not defined" + exit 1 +fi + +# Cluster environment +export CUSTOM_IMAGE=${IMAGE_NAME} +export CUSTOM_VERSION=${IMAGE_VERSION} + +# +# If bundle has been built and installed then use it +# +if [ -n "${BUILD_CATALOG_SOURCE_NAMESPACE}" ]; then + export KAMEL_INSTALL_OLM_SOURCE=${BUILD_CATALOG_SOURCE_NAME} + export KAMEL_INSTALL_OLM_SOURCE_NAMESPACE=${BUILD_CATALOG_SOURCE_NAMESPACE} + export KAMEL_INSTALL_OLM_CHANNEL="${NEW_XY_CHANNEL}" +fi + +export KAMEL_INSTALL_MAVEN_REPOSITORIES=$(make get-staging-repo) +export KAMEL_INSTALL_REGISTRY=${REGISTRY_PULL_HOST} +export KAMEL_INSTALL_REGISTRY_INSECURE=${REGISTRY_INSECURE} +export KAMEL_INSTALL_OPERATOR_IMAGE=${CUSTOM_IMAGE}:${CUSTOM_VERSION} + +# Will only have an effect if olm=false +# since, for OLM, the csv determines the policy +# (see kamel-build-bundle/build-bundle-image.sh) +export KAMEL_INSTALL_OPERATOR_IMAGE_PULL_POLICY="Always" + +export CAMEL_K_TEST_LOG_LEVEL="${LOG_LEVEL}" +if [ "${LOG_LEVEL}" == "debug" ]; then + export CAMEL_K_TEST_MAVEN_CLI_OPTIONS="-X ${CAMEL_K_TEST_MAVEN_CLI_OPTIONS}" +fi +export CAMEL_K_TEST_IMAGE_NAME=${CUSTOM_IMAGE} +export CAMEL_K_TEST_IMAGE_VERSION=${CUSTOM_VERSION} +export CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE=${SAVE_FAILED_TEST_NS} + +if [ -n "${GLOBAL_OPERATOR_NAMESPACE}" ]; then + echo "Info: Tests being run using global operator" + export CAMEL_K_FORCE_GLOBAL_TEST=true + export CAMEL_K_GLOBAL_OPERATOR_NS="${GLOBAL_OPERATOR_NAMESPACE}" +fi + +# Then run all integration telemetry test rather than ending on first failure +set -e +exit_code=0 +DO_TEST_PREBUILD=false make test-telemetry || exit_code=1 +set +e + +echo "Tests completed with exit code: ${exit_code}" +exit ${exit_code} diff --git a/.github/actions/kamel-cleanup/action.yaml b/.github/actions/kamel-cleanup/action.yaml index f54c4407e..3a937787f 100644 --- a/.github/actions/kamel-cleanup/action.yaml +++ b/.github/actions/kamel-cleanup/action.yaml @@ -57,6 +57,13 @@ runs: run: | ./.github/actions/kamel-cleanup/clean-operator-groups.sh + - id: remove-telemetry-resources + name: Remove Installed Telemetry Resources + shell: bash + if: ${{ always() }} + run: | + ./.github/actions/kamel-cleanup/clean-telemetry-resources.sh + - id: remove-installed-kamel name: Remove Installed Kamel shell: bash diff --git a/.github/actions/kamel-cleanup/clean-telemetry-resources.sh b/.github/actions/kamel-cleanup/clean-telemetry-resources.sh new file mode 100755 index 000000000..619dbe528 --- /dev/null +++ b/.github/actions/kamel-cleanup/clean-telemetry-resources.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# +# Remove any telemetry groups resources that might have been deployed for tests. +# All the telemetry resources are deployed in otlp namespace. +# + +set +e + +# +# Find if the namespace containing telemetry resources exists +# +namespace_otlp=$(kubectl --ignore-not-found=true get namespaces otlp) +if [ -z "${namespace_otlp}" ]; then + echo "No telemetry resource installed" + exit 0 +fi + +echo "Telemetry namespace exists: ${namespace_otlp}" + +# +# Delete telemetry resources namespace +# +kubectl delete --now --timeout=600s namespace ${namespace_otlp} 1> /dev/null + +echo "Telemetry resources deleted" \ No newline at end of file diff --git a/.github/actions/kamel-install-otlp-collector/action.yml b/.github/actions/kamel-install-otlp-collector/action.yml new file mode 100644 index 000000000..b16310457 --- /dev/null +++ b/.github/actions/kamel-install-otlp-collector/action.yml @@ -0,0 +1,117 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +name: kamel-install-otlp-collector +description: 'Install opentelemetry OTLP collector' + + +inputs: + otlp-collector-image-name: + description: "The OTLP collector image name" + required: true + otlp-collector-image-version: + description: "The OTLP collector image version" + required: true +runs: + using: "composite" + steps: + - id: install-otlp-collector + name: Install opentelemetry OTLP Collector + shell: bash + run: | + # Create namespace otlp + cat <<EOF | kubectl apply -f - + apiVersion: v1 + kind: Namespace + metadata: + name: otlp + EOF + + # Add collector configuration : basic otlp grpc reciever to logging + cat <<EOF | kubectl apply -n otlp -f - + kind: ConfigMap + apiVersion: v1 + metadata: + name: collector-config + data: + collector.yaml: | + receivers: + otlp: + protocols: + grpc: + processors: + batch: + exporters: + logging: + verbosity: detailed + service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [logging] + EOF + + # Deployment for opentelemetry collector + cat <<EOF | kubectl apply -n otlp -f - + kind: Deployment + apiVersion: apps/v1 + metadata: + name: opentelemetrycollector + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: opentelemetrycollector + template: + metadata: + labels: + app.kubernetes.io/name: opentelemetrycollector + spec: + containers: + - name: otelcol + args: + - --config=/conf/collector.yaml + image: ${{ inputs.otlp-collector-image-name }}:${{ inputs.otlp-collector-image-version }} + volumeMounts: + - mountPath: /conf + name: collector-config + volumes: + - configMap: + items: + - key: collector.yaml + path: collector.yaml + name: collector-config + name: collector-config + EOF + + # Add service with grpc access for opentelemetry collector + cat <<EOF | kubectl apply -n otlp -f - + kind: Service + apiVersion: v1 + metadata: + name: opentelemetrycollector + spec: + ports: + - name: grpc-otlp + port: 4317 + protocol: TCP + targetPort: 4317 + selector: + app.kubernetes.io/name: opentelemetrycollector + type: ClusterIP + EOF diff --git a/.github/workflows/telemetry.yml b/.github/workflows/telemetry.yml new file mode 100644 index 000000000..d227faba3 --- /dev/null +++ b/.github/workflows/telemetry.yml @@ -0,0 +1,94 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +name: telemetry + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +on: + pull_request: + branches: + - main + - "release-*" + paths-ignore: + - 'docs/**' + - 'proposals/**' + - '**.adoc' + - '**.md' + - 'KEYS' + - 'LICENSE' + - 'NOTICE' + push: + branches: + - main + - "release-*" + paths-ignore: + - 'docs/**' + - 'proposals/**' + - '**.adoc' + - '**.md' + - 'KEYS' + - 'LICENSE' + - 'NOTICE' + workflow_dispatch: + inputs: + log-level: + description: 'Set the operator log level (info or debug)' + required: false + pre-built-kamel-image: + description: 'Kamel image url for skipping building of kamel stages. Used for debugging' + required: false + skip-problematic: + description: 'Whether tests marked as problematic should be skipped - false by default (sets CAMEL_K_TEST_SKIP_PROBLEMATIC)' + required: false + default: false + test-filters: + description: | + Filter the tests in this test suite by assigning the test pattern to TEST_TELEMETRY_RUN, + eg. TEST_TELEMETRY_RUN=TestBasic will only run tests prefixed with 'TestBasic' + required: false + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +jobs: + telemetry-it: + + runs-on: ubuntu-20.04 + + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + persist-credentials: false + submodules: recursive + - name: Convert input parameters to env vars + shell: bash + run: | + ./.github/workflows/manual-exec-process-inputs.sh \ + -i "${{ github.event.inputs.pre-built-kamel-image }}" \ + -p "${{ github.event.inputs.skip-problematic }}" \ + -q "${{ github.event.inputs.log-level }}" \ + -t "${{ github.event.inputs.test-filters }}" + + - name: Execute Tests + uses: ./.github/actions/e2e-telemetry + with: + cluster-config-data: ${{ secrets.E2E_CLUSTER_CONFIG }} + cluster-kube-config-data: ${{ secrets.E2E_KUBE_CONFIG }} diff --git a/e2e/global/telemetry/files/rest-consumer.yaml b/e2e/global/telemetry/files/rest-consumer.yaml new file mode 100644 index 000000000..b7b8e26bb --- /dev/null +++ b/e2e/global/telemetry/files/rest-consumer.yaml @@ -0,0 +1,29 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +- rest: + get: + - to: "direct:start" + path: "/customers/{name}" + +- from: + uri: "direct:start" + steps: + - log: + message: "get ${header.name}" + - set-body: + simple: "${header.name} Doe" diff --git a/e2e/global/telemetry/files/rest-producer.yaml b/e2e/global/telemetry/files/rest-producer.yaml new file mode 100644 index 000000000..1693bee72 --- /dev/null +++ b/e2e/global/telemetry/files/rest-producer.yaml @@ -0,0 +1,24 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# --------------------------------------------------------------------------- + +- from: + uri: "timer:tick" + steps: + - to: + uri: "http:{{serviceName}}/customers/{{name}}" + - log: + message: "${body}" diff --git a/e2e/global/telemetry/telemetry_test.go b/e2e/global/telemetry/telemetry_test.go new file mode 100644 index 000000000..50623f72e --- /dev/null +++ b/e2e/global/telemetry/telemetry_test.go @@ -0,0 +1,73 @@ +//go:build integration +// +build integration + +// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" + +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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 telemetry + +import ( + "fmt" + "testing" + + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + + . "github.com/apache/camel-k/e2e/support" +) + +func TestTelemetryTrait(t *testing.T) { + WithNewTestNamespace(t, func(ns string) { + operatorID := "camel-k-trait-telemetry" + Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + + // Check service is available + Eventually(ServicesByType("otlp", corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) + + // Create integration and activate traces by telemetry trait + + Expect(KamelRunWithID(operatorID, ns, "files/rest-consumer.yaml", + "--name", "rest-consumer", + "-t", "telemetry.enabled=true", + "-t", "telemetry.endpoint=http://opentelemetrycollector.otlp.svc.cluster.local:4317").Execute()).To(Succeed()) + Eventually(IntegrationPodPhase(ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + name := "Bob" + Expect(KamelRunWithID(operatorID, ns, "files/rest-producer.yaml", + "-p", "serviceName=rest-consumer", + "-p", "name="+name, + "--name", "rest-producer").Execute()).To(Succeed()) + Eventually(IntegrationPodPhase(ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name))) + Eventually(IntegrationLogs(ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name))) + + // Find opentelemetrycollector pod : the exporter is configured to log traces with detailed verborsity. + pod, err := Pod("otlp", "opentelemetrycollector")() + Expect(err).To(BeNil()) + Expect(pod).NotTo(BeNil()) + + // Ensured logs in opentelemetrycollector pod are present + Eventually(TailedLogs(pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.target: Str(/customers/%s)", name))) + Eventually(TailedLogs(pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.url: Str(http://rest-consumer/customers/%s)", name))) + + // Clean up + Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) +} diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go index 21c565c04..e4bee4913 100644 --- a/e2e/support/test_support.go +++ b/e2e/support/test_support.go @@ -445,6 +445,17 @@ func IntegrationLogs(ns, name string) func() string { } } +// Retrieve the Logs from the Pod defined by its name in the given namespace ns. The number of lines numLines from the end of the logs to show. +func TailedLogs(ns, name string, numLines int64) func() string { + return func() string { + options := corev1.PodLogOptions{ + TailLines: pointer.Int64(numLines), + } + + return Logs(ns, name, options)() + } +} + func Logs(ns, podName string, options corev1.PodLogOptions) func() string { return func() string { byteReader, err := TestClient().CoreV1().Pods(ns).GetLogs(podName, &options).Stream(TestContext) @@ -1679,6 +1690,29 @@ func OperatorPod(ns string) func() *corev1.Pod { } } +// Find one Pod filtered by namespace ns and label app.kubernetes.io/name value appName. +func Pod(ns string, appName string) func() (*corev1.Pod, error) { + return func() (*corev1.Pod, error) { + lst := corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + APIVersion: v1.SchemeGroupVersion.String(), + }, + } + if err := TestClient().List(TestContext, &lst, + ctrl.InNamespace(ns), + ctrl.MatchingLabels{ + "app.kubernetes.io/name": appName, + }); err != nil { + return nil, err + } + if len(lst.Items) == 0 { + return nil, nil + } + return &lst.Items[0], nil + } +} + func OperatorTryPodForceKill(ns string, timeSeconds int) { pod := OperatorPod(ns)() if pod != nil { diff --git a/script/Makefile b/script/Makefile index 7aa12f790..6ee04db5a 100644 --- a/script/Makefile +++ b/script/Makefile @@ -289,6 +289,10 @@ test-service-binding: do-build STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ go test -timeout 90m -v ./e2e/global/service-binding -tags=integration $(TEST_SERVICE_RUN) -json 2>&1 | gotestfmt +test-telemetry: do-build + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 90m -v ./e2e/global/telemetry -tags=integration $(TEST_TELEMETRY_RUN) -json 2>&1 | gotestfmt + test-local: do-build STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ RUNTIME_VERSION="$(RUNTIME_VERSION)" \
