From 783dfcb7c365ccdbbd1d4a666d960cbff545dfea Mon Sep 17 00:00:00 2001 From: Jack Shirazi Date: Wed, 2 Oct 2024 11:49:10 +0100 Subject: [PATCH] Integration test for EDOT agents with operator, plus skeleton for collector --- .github/workflows/operator-regression.yml | 68 +++++++++++++++++++++++ test/operator/dotnet/Dockerfile | 17 ++++++ test/operator/dotnet/Program.cs | 7 +++ test/operator/dotnet/dotnetapp.csproj | 9 +++ test/operator/dotnet/test-app.yaml | 21 +++++++ test/operator/elastic-instrumentation.yml | 25 +++++++++ test/operator/go/Dockerfile | 3 + test/operator/go/test-app.yaml | 25 +++++++++ test/operator/java/Dockerfile | 3 + test/operator/java/Hello.java | 12 ++++ test/operator/java/test-app.yaml | 19 +++++++ test/operator/kind-with-registry.sh | 42 ++++++++++++++ test/operator/nodejs/Dockerfile | 5 ++ test/operator/nodejs/app.js | 8 +++ test/operator/nodejs/test-app.yaml | 19 +++++++ test/operator/python/Dockerfile | 9 +++ test/operator/python/app.py | 8 +++ test/operator/python/requirements.txt | 7 +++ test/operator/python/test-app.yaml | 19 +++++++ test/operator/wait_for_agent_start.sh | 28 ++++++++++ test/operator/wait_for_pod_start.sh | 28 ++++++++++ 21 files changed, 382 insertions(+) create mode 100644 .github/workflows/operator-regression.yml create mode 100644 test/operator/dotnet/Dockerfile create mode 100644 test/operator/dotnet/Program.cs create mode 100644 test/operator/dotnet/dotnetapp.csproj create mode 100644 test/operator/dotnet/test-app.yaml create mode 100644 test/operator/elastic-instrumentation.yml create mode 100644 test/operator/go/Dockerfile create mode 100644 test/operator/go/test-app.yaml create mode 100644 test/operator/java/Dockerfile create mode 100644 test/operator/java/Hello.java create mode 100644 test/operator/java/test-app.yaml create mode 100644 test/operator/kind-with-registry.sh create mode 100644 test/operator/nodejs/Dockerfile create mode 100644 test/operator/nodejs/app.js create mode 100644 test/operator/nodejs/test-app.yaml create mode 100644 test/operator/python/Dockerfile create mode 100644 test/operator/python/app.py create mode 100644 test/operator/python/requirements.txt create mode 100644 test/operator/python/test-app.yaml create mode 100644 test/operator/wait_for_agent_start.sh create mode 100644 test/operator/wait_for_pod_start.sh diff --git a/.github/workflows/operator-regression.yml b/.github/workflows/operator-regression.yml new file mode 100644 index 0000000..68a8d74 --- /dev/null +++ b/.github/workflows/operator-regression.yml @@ -0,0 +1,68 @@ +name: Regression Testing Operator Integration + +on: + workflow_dispatch: + +env: + AGENT_TESTS: python nodejs java + #go dotnet --- both pending + +jobs: + integration-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create Kind cluster and local Docker registry + run: + bash test/operator/kind-with-registry.sh + + - name: Create Test Images + run: | + for t in ${AGENT_TESTS[@]} + do + echo "Creating image for $t" + docker build -t $t-test-app test/operator/$t + docker tag $t-test-app localhost:5001/registry/$t-test-app + docker push localhost:5001/registry/$t-test-app + done + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.11.2 + + - name: Install Operator Skeleton + run: | + kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml + bash test/operator/wait_for_pod_start.sh cert-manager cert-manager- 1/1 3 + helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts + helm repo update + helm install opentelemetry-operator --namespace opentelemetry-operator-system open-telemetry/opentelemetry-operator --create-namespace --set manager.collectorImage.repository="docker.elastic.co/beats/elastic-agent:8.15.0-SNAPSHOT",manager.extraArgs={"--enable-go-instrumentation=true"} + bash test/operator/wait_for_pod_start.sh opentelemetry-operator-system opentelemetry-operator 2/2 1 + kubectl get pods -A + + - name: Add Namespaces And Instrumentation Skeleton + run: | + kubectl create namespace banana + kubectl create -f test/operator/elastic-instrumentation.yml + + - name: Start And Test Collector Skeleton + run: | + echo "Nothing here yet" + + - name: Start Test Images + run: | + for t in ${AGENT_TESTS[@]} + do + if [ "x$t" = "xgo" ]; then CONTAINER_READY="2/2"; else CONTAINER_READY="1/1"; fi + AGENT_START_GREP=`grep -A1 AGENT_HAS_STARTED_IF_YOU_SEE test/operator/$t/test-app.yaml | perl -ne '/value:\s*"(.*)"/ && print "$1\n"'` + echo "Starting pod for $t" + kubectl create -f test/operator/$t/test-app.yaml + bash test/operator/wait_for_pod_start.sh banana $t-test-app $CONTAINER_READY 1 + bash test/operator/wait_for_agent_start.sh banana $t-test-app "$AGENT_START_GREP" + kubectl delete -f test/operator/$t/test-app.yaml + done diff --git a/test/operator/dotnet/Dockerfile b/test/operator/dotnet/Dockerfile new file mode 100644 index 0000000..12062ee --- /dev/null +++ b/test/operator/dotnet/Dockerfile @@ -0,0 +1,17 @@ +# https://hub.docker.com/_/microsoft-dotnet +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /source + +# copy csproj and restore as distinct layers +COPY *.csproj . +RUN dotnet restore + +# copy everything else and build app +COPY . . +RUN dotnet publish -c release -o /app --no-restore + +# final stage/image +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +WORKDIR /app +COPY --from=build /app ./ +ENTRYPOINT ["dotnet", "dotnetapp.dll"] \ No newline at end of file diff --git a/test/operator/dotnet/Program.cs b/test/operator/dotnet/Program.cs new file mode 100644 index 0000000..0fa2ed0 --- /dev/null +++ b/test/operator/dotnet/Program.cs @@ -0,0 +1,7 @@ +var builder = WebApplication.CreateBuilder(args); +_ = builder.Logging.SetMinimumLevel(LogLevel.Trace); +var app = builder.Build(); + +app.MapGet("/", () => "Hello World!"); + +app.Run(); diff --git a/test/operator/dotnet/dotnetapp.csproj b/test/operator/dotnet/dotnetapp.csproj new file mode 100644 index 0000000..1b28a01 --- /dev/null +++ b/test/operator/dotnet/dotnetapp.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/test/operator/dotnet/test-app.yaml b/test/operator/dotnet/test-app.yaml new file mode 100644 index 0000000..0a4c0ac --- /dev/null +++ b/test/operator/dotnet/test-app.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dotnet-test-app + namespace: banana + annotations: + instrumentation.opentelemetry.io/inject-dotnet: "opentelemetry-operator-system/elastic-instrumentation" + labels: + app: dotnet-test-app +spec: + containers: + - image: localhost:5001/registry/dotnet-test-app + imagePullPolicy: Always + name: dotnet-test-app + env: + - name: OTEL_LOG_LEVEL + value: "debug" + - name: ELASTIC_OTEL_LOG_TARGETS + value: "stdout" + - name: AGENT_HAS_STARTED_IF_YOU_SEE + value: "Elastic Distribution of OpenTelemetry .NET" diff --git a/test/operator/elastic-instrumentation.yml b/test/operator/elastic-instrumentation.yml new file mode 100644 index 0000000..d3f3f95 --- /dev/null +++ b/test/operator/elastic-instrumentation.yml @@ -0,0 +1,25 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: elastic-instrumentation + namespace: opentelemetry-operator-system +spec: + exporter: + endpoint: http://opentelemetry-kube-stack-daemon-collector:4318 + propagators: + - tracecontext + - baggage + - b3 + sampler: + type: parentbased_traceidratio + argument: "1.0" + java: + image: docker.elastic.co/observability/elastic-otel-javaagent:1.0.0 + nodejs: + image: docker.elastic.co/observability/elastic-otel-node:edge + dotnet: + image: docker.elastic.co/observability/elastic-otel-dotnet:edge + python: + image: docker.elastic.co/observability/elastic-otel-python:edge + go: + image: ghcr.io/open-telemetry/opentelemetry-go-instrumentation/autoinstrumentation-go:v0.14.0-alpha diff --git a/test/operator/go/Dockerfile b/test/operator/go/Dockerfile new file mode 100644 index 0000000..4bcbcbb --- /dev/null +++ b/test/operator/go/Dockerfile @@ -0,0 +1,3 @@ +#dummy implementation for now +FROM busybox +CMD ["bash", "-c", "sleep", "6000"] diff --git a/test/operator/go/test-app.yaml b/test/operator/go/test-app.yaml new file mode 100644 index 0000000..743f4df --- /dev/null +++ b/test/operator/go/test-app.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Pod +metadata: + name: go-test-app + namespace: banana + annotations: + instrumentation.opentelemetry.io/inject-go: "opentelemetry-operator-system/elastic-instrumentation" + instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/usr/src/app/productcatalogservice" + sidecar.opentelemetry.io/inject: "true" + labels: + app: go-test-app +spec: + shareProcessNamespace: true + containers: + - image: ghcr.io/open-telemetry/opentelemetry-operator/e2e-test-app-golang:main + imagePullPolicy: Always + name: go-test-app + env: + - name: OTEL_LOG_LEVEL + value: "debug" + - name: AGENT_HAS_STARTED_IF_YOU_SEE + value: "no idea" + securityContext: + runAsUser: 0 + privileged: true diff --git a/test/operator/java/Dockerfile b/test/operator/java/Dockerfile new file mode 100644 index 0000000..453d031 --- /dev/null +++ b/test/operator/java/Dockerfile @@ -0,0 +1,3 @@ +FROM eclipse-temurin:17 +COPY Hello.java /usr/src/Hello.java +CMD ["java", "/usr/src/Hello.java"] diff --git a/test/operator/java/Hello.java b/test/operator/java/Hello.java new file mode 100644 index 0000000..c385fe5 --- /dev/null +++ b/test/operator/java/Hello.java @@ -0,0 +1,12 @@ +public class Hello{ + public static void main(String[] args) throws Exception { + System.out.println("This is java app in a container"); + for(;;) { + Thread.sleep(2000L); + test(); + } + } + public static void test() { + System.out.println("Executing test()"); + } +} diff --git a/test/operator/java/test-app.yaml b/test/operator/java/test-app.yaml new file mode 100644 index 0000000..4a6af09 --- /dev/null +++ b/test/operator/java/test-app.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: java-test-app + namespace: banana + annotations: + instrumentation.opentelemetry.io/inject-java: "opentelemetry-operator-system/elastic-instrumentation" + labels: + app: java-test-app +spec: + containers: + - image: localhost:5001/registry/java-test-app + imagePullPolicy: Always + name: java-test-app + env: + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: AGENT_HAS_STARTED_IF_YOU_SEE + value: "javaagent.tooling.VersionLogger - opentelemetry-javaagent" diff --git a/test/operator/kind-with-registry.sh b/test/operator/kind-with-registry.sh new file mode 100644 index 0000000..2a83bc7 --- /dev/null +++ b/test/operator/kind-with-registry.sh @@ -0,0 +1,42 @@ +#!/bin/sh +set -o errexit +#https://kind.sigs.k8s.io/docs/user/local-registry/ + +# create registry container unless it already exists +reg_name='kind-registry' +reg_port='5001' +if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + registry:2 +fi + +# create a cluster with the local registry enabled in containerd +cat <