diff --git a/.github/actions/start-promtail/action.yml b/.github/actions/start-promtail/action.yml new file mode 100644 index 000000000..c9c38227c --- /dev/null +++ b/.github/actions/start-promtail/action.yml @@ -0,0 +1,30 @@ +name: Start Promtail +description: Start promtail in a Docker container to send test results to loki +inputs: + loki-dashboard-url: + description: "URL of the Loki dashboard to send the logs" + required: true +runs: + using: "composite" + steps: + - name: Start Promtail container + shell: bash + run: | + docker run -d \ + --name=promtail \ + -v "${{ github.workspace }}/test/dashboard/prep/promtail.yaml:/etc/promtail/config.yaml" \ + -v "${{ github.workspace }}/test/dashboard/logs:/var/log" \ + -e TEST_OUTDIR=test/dashboard/logs \ + -e GITHUB_RUN_ID=${{ github.run_id }} \ + -e GITHUB_JOB=${{ github.job }} \ + -e GITHUB_WORKFLOW=${{ github.workflow }} \ + -e GITHUB_EVENT_NAME=${{ github.event_name }} \ + -e GITHUB_SERVER_URL=${{ github.server_url }} \ + -e GITHUB_REPOSITORY=${{ github.repository }} \ + -e GITHUB_HEAD_REF=${{ github.head_ref }} \ + -e GITHUB_SHA=${{ github.sha }} \ + -e GITHUB_ACTOR=${{ github.actor }} \ + -e LOKI_DASHBOARD_URL=${{ inputs.loki-dashboard-url }} \ + grafana/promtail:3.4.4 \ + -config.file=/etc/promtail/config.yaml \ + -config.expand-env=true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd2a18403..0712fccda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,8 +57,19 @@ jobs: - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version-file: 'go.mod' + - name: Set Start Time + run: echo "START_TIME=$(date +"%Y-%m-%dT%H:%M:%S.%NZ")" >> ${GITHUB_ENV} + - name: Create Directory + run: mkdir -p ${{github.workspace}}/test/dashboard/logs/${{github.job}}/ + - name: Start Promtail + uses: ./.github/actions/start-promtail + with: + loki-dashboard-url: ${{ secrets.LOKI_DASHBOARD_URL }} - name: Run Unit Tests - run: make unit-test + run: make unit-test | tee ${{github.workspace}}/test/dashboard/logs/${{github.job}}/raw_logs.log && exit "${PIPESTATUS[0]}" + - name: Generate Test Results + if: always() + run: bash ./scripts/workflow/generate_results.sh ${{job.status}} ${{env.START_TIME}} ${{github.job}} ${{github.workspace}} - name: Upload Test Coverage uses: codecov/codecov-action@84508663e988701840491b86de86b666e8a86bed # v4.3.0 with: @@ -161,18 +172,29 @@ jobs: with: name: nginx-agent-unsigned-snapshots path: build + - name: Set Start Time + run: echo "START_TIME=$(date +"%Y-%m-%dT%H:%M:%S.%NZ")" >> ${GITHUB_ENV} + - name: Create Directory + run: mkdir -p ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/ + - name: Start Promtail + uses: ./.github/actions/start-promtail + with: + loki-dashboard-url: ${{ secrets.LOKI_DASHBOARD_URL }} - name: Run Integration Tests run: | go install github.com/goreleaser/nfpm/v2/cmd/nfpm@${{ env.NFPM_VERSION }} OS_RELEASE="${{ matrix.container.image }}" OS_VERSION="${{ matrix.container.version }}" \ - make integration-test + make integration-test | tee ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/raw_logs.log && exit "${PIPESTATUS[0]}" + - name: Generate Test Results + if: always() + run: bash ./scripts/workflow/generate_results.sh ${{job.status}} ${{env.START_TIME}} ${{github.job}}/${{matrix.container.image}}${{matrix.container.version}} ${{github.workspace}} - name: Container Output Logs if: failure() run: | docker ps -a dockerid=$(docker ps -a --format "{{.ID}}") docker logs "$dockerid" - + - name: Archive integration test logs if: success() || failure() uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 @@ -214,11 +236,22 @@ jobs: with: name: nginx-agent-unsigned-snapshots path: build + - name: Set Start Time + run: echo "START_TIME=$(date +"%Y-%m-%dT%H:%M:%S.%NZ")" >> ${GITHUB_ENV} + - name: Create Directory + run: mkdir -p ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/ + - name: Start Promtail + uses: ./.github/actions/start-promtail + with: + loki-dashboard-url: ${{ secrets.LOKI_DASHBOARD_URL }} - name: Run Integration Tests run: | go install github.com/goreleaser/nfpm/v2/cmd/nfpm@${{ env.NFPM_VERSION }} CONTAINER_NGINX_IMAGE_REGISTRY="${{ env.NGINX_OSS_REGISTRY }}" TAG="${{ matrix.container.version }}-${{ matrix.container.image }}" OS_RELEASE="${{ matrix.container.release }}"\ - make official-image-integration-test + make official-image-integration-test | tee ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/raw_logs.log && exit "${PIPESTATUS[0]}" + - name: Generate Test Results + if: always() + run: bash ./scripts/workflow/generate_results.sh ${{job.status}} ${{env.START_TIME}} ${{github.job}}/${{matrix.container.image}}${{matrix.container.version}} ${{github.workspace}} - name: Container Output Logs if: failure() run: | @@ -281,12 +314,23 @@ jobs: registry: ${{ secrets.REGISTRY_URL }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Set Start Time + run: echo "START_TIME=$(date +"%Y-%m-%dT%H:%M:%S.%NZ")" >> ${GITHUB_ENV} + - name: Create Directory + run: mkdir -p ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/ + - name: Start Promtail + uses: ./.github/actions/start-promtail + with: + loki-dashboard-url: ${{ secrets.LOKI_DASHBOARD_URL }} - name: Run Integration Tests run: | go install github.com/goreleaser/nfpm/v2/cmd/nfpm@${{ env.NFPM_VERSION }} CONTAINER_NGINX_IMAGE_REGISTRY="${{ secrets.REGISTRY_URL }}" TAG="${{ matrix.container.plus }}-${{ matrix.container.image }}-${{ matrix.container.version }}" \ OS_RELEASE="${{ matrix.container.release }}" IMAGE_PATH="${{ matrix.container.path }}" \ - make official-image-integration-test + make official-image-integration-test | tee ${{github.workspace}}/test/dashboard/logs/${{github.job}}/${{matrix.container.image}}${{matrix.container.version}}/raw_logs.log && exit "${PIPESTATUS[0]}" + - name: Generate Test Results + if: always() + run: bash ./scripts/workflow/generate_results.sh ${{job.status}} ${{env.START_TIME}} ${{github.job}}/${{matrix.container.image}}${{matrix.container.version}} ${{github.workspace}} - name: Container Output Logs if: failure() run: | diff --git a/Makefile b/Makefile index 9a468cd2d..9069b7d76 100644 --- a/Makefile +++ b/Makefile @@ -193,16 +193,16 @@ unit-test: $(TEST_BUILD_DIR) test-core test-plugins test-sdk test-extensions ## @printf "\nTotal code coverage: " && $(GOTOOL) cover -func=$(TEST_BUILD_DIR)/coverage.out | grep 'total:' | awk '{print $$3}' test-core: $(TEST_BUILD_DIR) ## Run core unit tests - GOWORK=off CGO_ENABLED=0 go test -count=1 -coverprofile=$(TEST_BUILD_DIR)/core_coverage.out -covermode count ./src/core/... + GOWORK=off CGO_ENABLED=0 go test -v -count=1 -coverprofile=$(TEST_BUILD_DIR)/core_coverage.out -covermode count ./src/core/... test-plugins: $(TEST_BUILD_DIR) ## Run plugins unit tests - GOWORK=off CGO_ENABLED=0 go test -count=1 -coverprofile=$(TEST_BUILD_DIR)/plugins_coverage.out -covermode count ./src/plugins/... + GOWORK=off CGO_ENABLED=0 go test -v -count=1 -coverprofile=$(TEST_BUILD_DIR)/plugins_coverage.out -covermode count ./src/plugins/... test-extensions: $(TEST_BUILD_DIR) ## Run extensions unit tests - GOWORK=off CGO_ENABLED=0 go test -count=1 -coverprofile=$(TEST_BUILD_DIR)/extensions_coverage.out -covermode count ./src/extensions/... + GOWORK=off CGO_ENABLED=0 go test -v -count=1 -coverprofile=$(TEST_BUILD_DIR)/extensions_coverage.out -covermode count ./src/extensions/... test-sdk: $(TEST_BUILD_DIR) ## Run sdk unit tests from root directory - cd sdk && GOWORK=off CGO_ENABLED=0 go test -count=1 -coverprofile=../$(TEST_BUILD_DIR)/sdk_coverage.out -covermode count ./... + cd sdk && GOWORK=off CGO_ENABLED=0 go test -v -count=1 -coverprofile=../$(TEST_BUILD_DIR)/sdk_coverage.out -covermode count ./... # Component tests component-test: test-component-build test-component-run ## Run component tests diff --git a/docs/proto/proto.md b/docs/proto/proto.md index d1d040047..4f40b2f2c 100644 --- a/docs/proto/proto.md +++ b/docs/proto/proto.md @@ -18,9 +18,6 @@ - [AgentConnectStatus.StatusCode](#f5-nginx-agent-sdk-AgentConnectStatus-StatusCode) - [AgentLogging.Level](#f5-nginx-agent-sdk-AgentLogging-Level) -- [command_svc.proto](#command_svc-proto) - - [Commander](#f5-nginx-agent-sdk-Commander) - - [command.proto](#command-proto) - [AgentActivityStatus](#f5-nginx-agent-sdk-AgentActivityStatus) - [ChunkedResourceChunk](#f5-nginx-agent-sdk-ChunkedResourceChunk) @@ -42,6 +39,9 @@ - [NginxConfigStatus.Status](#f5-nginx-agent-sdk-NginxConfigStatus-Status) - [UploadStatus.TransferStatus](#f5-nginx-agent-sdk-UploadStatus-TransferStatus) +- [command_svc.proto](#command_svc-proto) + - [Commander](#f5-nginx-agent-sdk-Commander) + - [common.proto](#common-proto) - [CertificateDates](#f5-nginx-agent-sdk-CertificateDates) - [CertificateName](#f5-nginx-agent-sdk-CertificateName) @@ -341,34 +341,6 @@ Log level enum - -

Top

- -## command_svc.proto - - - - - - - - - - - -### Commander -Represents a service used to sent command messages between the management server and the agent. - -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| CommandChannel | [Command](#f5-nginx-agent-sdk-Command) stream | [Command](#f5-nginx-agent-sdk-Command) stream | A Bidirectional streaming RPC established by the agent and is kept open | -| Download | [DownloadRequest](#f5-nginx-agent-sdk-DownloadRequest) | [DataChunk](#f5-nginx-agent-sdk-DataChunk) stream | A streaming RPC established by the agent and is used to download resources associated with commands The download stream will be kept open for the duration of the data transfer and will be closed when its done. The transfer is a stream of chunks as follows: header -> data chunk 1 -> data chunk N. Each data chunk is of a size smaller than the maximum gRPC payload | -| Upload | [DataChunk](#f5-nginx-agent-sdk-DataChunk) stream | [UploadStatus](#f5-nginx-agent-sdk-UploadStatus) | A streaming RPC established by the agent and is used to upload resources associated with commands | - - - - -

Top

@@ -680,6 +652,34 @@ Transfer status enum + +

Top

+ +## command_svc.proto + + + + + + + + + + + +### Commander +Represents a service used to sent command messages between the management server and the agent. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| CommandChannel | [Command](#f5-nginx-agent-sdk-Command) stream | [Command](#f5-nginx-agent-sdk-Command) stream | A Bidirectional streaming RPC established by the agent and is kept open | +| Download | [DownloadRequest](#f5-nginx-agent-sdk-DownloadRequest) | [DataChunk](#f5-nginx-agent-sdk-DataChunk) stream | A streaming RPC established by the agent and is used to download resources associated with commands The download stream will be kept open for the duration of the data transfer and will be closed when its done. The transfer is a stream of chunks as follows: header -> data chunk 1 -> data chunk N. Each data chunk is of a size smaller than the maximum gRPC payload | +| Upload | [DataChunk](#f5-nginx-agent-sdk-DataChunk) stream | [UploadStatus](#f5-nginx-agent-sdk-UploadStatus) | A streaming RPC established by the agent and is used to upload resources associated with commands | + + + + +

Top

diff --git a/scripts/workflow/generate_results.sh b/scripts/workflow/generate_results.sh new file mode 100644 index 000000000..cd5dd9682 --- /dev/null +++ b/scripts/workflow/generate_results.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +# Script to process test logs and generate formatted JSON result files +# Usage: ./generate_results.sh + +set -euo pipefail + +# Check if the correct number of arguments are provided +if [ "$#" -ne 4 ]; then + echo "Usage: $0 " + exit 1 +fi + +JOB_RESULT="$1" +START_TIME="$2" +TEST_TYPE="$3" +WORKSPACE="$4" + +INPUT_FILE="$WORKSPACE/test/dashboard/logs/$TEST_TYPE/raw_logs.log" +OUTPUT_PATH="$WORKSPACE/test/dashboard/logs/$TEST_TYPE" + +# Validate input file exists +if [ ! -f "$INPUT_FILE" ]; then + echo "Error: Input file not found: $INPUT_FILE" + exit 1 +fi + +END_TIME="`date "+%Y-%m-%dT%H:%M:%S.%NZ"`" +START_SECONDS=$(date -d "$START_TIME" +%s.%N) +END_SECONDS=$(date -d "$END_TIME" +%s.%N) +DURATION=$(echo "$END_SECONDS - $START_SECONDS" | bc) + +MSG="" # individual test msg +FAIL_MSG="" # msg for entire job run +RESULT="" +HAS_FAILED=false +IS_RUNNING=false + +load_job_status(){ + if [ "$JOB_RESULT" == "success" ]; then + RESULT="pass" + elif [ "$JOB_RESULT" == "failure" ]; then + RESULT="fail" + else + RESULT="skip" + fi +} + +format_logs_to_json(){ + line="$1" + json="{" + + while [[ "$line" =~ ([a-zA-Z0-9_]+)=((\"([^\"\\]|\\.)*\")|[^[:space:]]+) ]]; do + key="${BASH_REMATCH[1]}" + value="${BASH_REMATCH[2]}" + line="${line#*"${key}=${value}"}" + + if [[ "$value" == \"*\" ]]; then + value="${value:1:${#value}-2}" + value="${value//\"/\\\"}" + fi + json+="\"$key\":\"$value\"," + done + + json="${json%,}}" + echo "$json" +} + +format_results(){ + while IFS= read -r line; do + + if [[ "$line" =~ ^===\ RUN[[:space:]]+(.+) ]]; then + TEST_NAME="${BASH_REMATCH[1]}" + IS_RUNNING=true + MSG="" + TEST_START="" + TEST_END="" + mkdir -p "$OUTPUT_PATH/$TEST_NAME/" + RESULT_FILE="$OUTPUT_PATH/$TEST_NAME/result.json" + LOG_FILE="$OUTPUT_PATH/$TEST_NAME/test.log" + elif [[ "$line" =~ ([0-9T:\.\-Z]+)[[:space:]]+testing ]]; then + TEST_START="${BASH_REMATCH[1]}" + elif [[ "$line" =~ ([0-9T:\.\-Z]+)[[:space:]]+finished[[:space:]]testing ]]; then + TEST_END="${BASH_REMATCH[1]}" + elif [[ "$line" == "FAIL" ]]; then + HAS_FAILED=false + MSG="$MSG_STR" + FAIL_MSG+="$MSG" + HAS_FAILED=false + echo "{\"start_at\": \"$START_TIME\", \"end_at\": \"$END_TIME\", \"duration_seconds\": \"$DURATION\", \"result\": \"$TEST_RES\", \"msg\": \"$MSG\"}" > $RESULT_FILE + elif [[ "$line" == "--- PASS"* ]]; then + TEST_RES="pass" + IS_RUNNING=false + echo "{\"start_at\": \"$START_TIME\", \"end_at\": \"$END_TIME\", \"duration_seconds\": \"$DURATION\", \"result\": \"$TEST_RES\", \"msg\": \"$MSG\"}" > $RESULT_FILE + elif [[ "$line" == "--- FAIL"* ]]; then + TEST_RES="fail" + HAS_FAILED=true + IS_RUNNING=false + elif [[ "$line" == time=* && "$line" == *level=* ]]; then + LOG_LINE=$(format_logs_to_json "$line") + echo "$LOG_LINE" >> "$LOG_FILE" + fi + + if [ $HAS_FAILED == true ]; then + MSG_STR+="$line" + fi + + done < "$INPUT_FILE" +} + +# Main body of the script +{ + load_job_status + format_results +} diff --git a/test/dashboard/prep/promtail.yaml b/test/dashboard/prep/promtail.yaml new file mode 100644 index 000000000..c327d47b5 --- /dev/null +++ b/test/dashboard/prep/promtail.yaml @@ -0,0 +1,134 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 + log_level: info + +positions: + filename: /tmp/positions.yaml + sync_period: "10s" + +clients: + - url: "${LOKI_DASHBOARD_URL}" + external_labels: + systest_project: agent_v2 + systest_type: "${GITHUB_JOB}" + timeout: 30s + backoff_config: + min_period: 500ms + max_period: 5s + max_retries: 5 + +scrape_configs: + - job_name: test-results + static_configs: + - targets: + - localhost + labels: + systest_job: test-results + __path__: /var/log/**/result.json + pipeline_stages: + - json: + expressions: + time: + - timestamp: + source: time + format: RFC3339Nano + - template: + source: ci_pipeline_id + template: "${GITHUB_RUN_ID}" + - template: + source: ci_pipeline_url + template: "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + - template: + source: ci_pipeline_name + template: "${WORKFLOW}" + - template: + source: ci_pipeline_source + template: "${GITHUB_EVENT_NAME}" + - template: + source: ci_job_name + template: "${GITHUB_JOB}" + - template: + source: ci_commit_ref + template: "${GITHUB_HEAD_REF}" + - template: + source: ci_commit_sha + template: "${GITHUB_SHA}" + - template: + source: ci_commit_author + template: "${GITHUB_ACTOR}" + - template: + source: systest_path + template: '{{ trimPrefix "${TEST_OUTDIR}/" .filename | dir | replace "." "/" }}' + + - structured_metadata: + ci_pipeline_id: + ci_pipeline_url: + ci_pipeline_name: + ci_pipeline_source: + ci_job_name: + ci_commit_ref: + ci_commit_sha: + ci_commit_author: + filename: + systest_path: + + - labeldrop: + - filename + + - job_name: test-logs + static_configs: + - targets: + - localhost + labels: + systest_job: test-logs + __path__: /var/log/**/test.log + pipeline_stages: + - json: + expressions: + time: + - timestamp: + source: time + format: RFC3339Nano + - template: + source: ci_pipeline_id + template: "${GITHUB_RUN_ID}" + - template: + source: ci_pipeline_url + template: "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + - template: + source: ci_pipeline_name + template: "${WORKFLOW}" + - template: + source: ci_pipeline_source + template: "${GITHUB_EVENT_NAME}" + - template: + source: ci_job_name + template: "${GITHUB_JOB}" + - template: + source: ci_commit_ref + template: "${GITHUB_HEAD_REF}" + - template: + source: ci_commit_sha + template: "${GITHUB_SHA}" + - template: + source: ci_commit_author + template: "${GITHUB_ACTOR}" + - template: + source: systest_path + template: '{{ trimPrefix "${TEST_OUTDIR}/" .filename | dir | replace "." "/" }}' + + - structured_metadata: + ci_pipeline_id: + ci_pipeline_url: + ci_pipeline_name: + ci_pipeline_source: + ci_job_name: + ci_commit_ref: + ci_commit_sha: + ci_commit_author: + filename: + systest_path: + + - labeldrop: + - filename diff --git a/test/docker/nginx-official-image/apk/Dockerfile b/test/docker/nginx-official-image/apk/Dockerfile index dbca0f18c..34d3c1008 100644 --- a/test/docker/nginx-official-image/apk/Dockerfile +++ b/test/docker/nginx-official-image/apk/Dockerfile @@ -11,7 +11,6 @@ ARG CONTAINER_OS_TYPE WORKDIR /agent COPY ./build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} /agent/build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} -COPY ./ /agent RUN apk add --allow-untrusted /agent/build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} diff --git a/test/docker/nginx-official-image/deb/Dockerfile b/test/docker/nginx-official-image/deb/Dockerfile index 960e9cceb..f8a9c9bb5 100644 --- a/test/docker/nginx-official-image/deb/Dockerfile +++ b/test/docker/nginx-official-image/deb/Dockerfile @@ -12,7 +12,6 @@ ARG CONTAINER_OS_TYPE WORKDIR /agent COPY ./build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} /agent/build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} -COPY ./ /agent RUN apt-get update \ && apt install --no-install-recommends --no-install-suggests --allow-downgrades -y /agent/build/${PACKAGE_NAME}.${CONTAINER_OS_TYPE} \ @@ -20,4 +19,3 @@ RUN apt-get update \ RUN unlink /var/log/nginx/access.log RUN unlink /var/log/nginx/error.log - diff --git a/test/docker/nginx-oss/rpm/Dockerfile b/test/docker/nginx-oss/rpm/Dockerfile index d14dff242..fa4ec6b9b 100644 --- a/test/docker/nginx-oss/rpm/Dockerfile +++ b/test/docker/nginx-oss/rpm/Dockerfile @@ -8,7 +8,7 @@ ARG OS_VERSION ARG OS_RELEASE WORKDIR /agent -COPY ./ /agent +COPY ./build /agent/build COPY $ENTRY_POINT /agent/entrypoint.sh RUN if [ "$OS_VERSION" = "7" ] && [ "$OS_RELEASE" = "oraclelinux" ]; \ diff --git a/test/docker/performance/Dockerfile b/test/docker/performance/Dockerfile index 19a815f63..cc3ec42c1 100644 --- a/test/docker/performance/Dockerfile +++ b/test/docker/performance/Dockerfile @@ -25,23 +25,11 @@ RUN --mount=type=secret,id=nginx-crt,dst=nginx-repo.crt \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ ca-certificates \ - gnupg1 \ + gpg \ lsb-release \ git \ wget \ make \ - && \ - NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ - found=''; \ - for server in \ - hkp://keyserver.ubuntu.com:80 \ - pgp.mit.edu \ - ; do \ - echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ - apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ - done; \ - test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ - apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \ # Install the latest release of NGINX Plus and/or NGINX Plus modules # Uncomment individual modules if necessary # Use versioned packages over defaults to specify a release @@ -63,7 +51,8 @@ RUN --mount=type=secret,id=nginx-crt,dst=nginx-repo.crt \ && echo "Acquire::https::pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ && echo "Acquire::https::pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ && echo "Acquire::https::pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ - && printf "deb https://pkgs.nginx.com/plus/R32/ubuntu `lsb_release -cs` nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/R32/ubuntu/ `lsb_release -cs` nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \ && mkdir -p /etc/ssl/nginx \ && cat nginx-repo.crt > /etc/ssl/nginx/nginx-repo.crt \ && cat nginx-repo.key > /etc/ssl/nginx/nginx-repo.key \ @@ -72,6 +61,7 @@ RUN --mount=type=secret,id=nginx-crt,dst=nginx-repo.crt \ $nginxPackages \ curl \ gettext-base \ + gnupg2 \ && apt-get remove --purge -y lsb-release \ && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list \ && rm -rf /etc/apt/apt.conf.d/90nginx /etc/ssl/nginx diff --git a/test/integration/api/api_test.go b/test/integration/api/api_test.go index 0f336b5b7..1ecd67171 100644 --- a/test/integration/api/api_test.go +++ b/test/integration/api/api_test.go @@ -12,6 +12,8 @@ import ( "testing" "time" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" "github.com/nginx/agent/sdk/v2/proto" @@ -25,6 +27,7 @@ import ( var delay = time.Duration(5 * time.Second) func TestAPI_Nginx(t *testing.T) { + log.Info("testing nginx api") ctx := context.Background() containerNetwork := utils.CreateContainerNetwork(ctx, t) @@ -80,9 +83,11 @@ func TestAPI_Nginx(t *testing.T) { assert.Equal(t, "/etc/nginx/nginx.conf", nginxDetailsResponse[0].ConfPath) utils.TestAgentHasNoErrorLogs(t, testContainer) + log.Info("finished testing nginx api") } func TestAPI_Metrics(t *testing.T) { + log.Info("testing metrics api") ctx := context.Background() containerNetwork := utils.CreateContainerNetwork(ctx, t) @@ -157,4 +162,5 @@ func TestAPI_Metrics(t *testing.T) { } utils.TestAgentHasNoErrorLogs(t, testContainer) + log.Info("finished testing metrics api") } diff --git a/test/integration/features/features_test.go b/test/integration/features/features_test.go index c5c6e5aa1..0f83a8b2f 100644 --- a/test/integration/features/features_test.go +++ b/test/integration/features/features_test.go @@ -6,11 +6,14 @@ import ( "os" "testing" + log "github.com/sirupsen/logrus" + "github.com/nginx/agent/test/integration/utils" "github.com/stretchr/testify/assert" ) func TestFeatures_NginxCountingEnabled(t *testing.T) { + log.Info("testing nginx counting enabled") enabledFeatureLogs := []string{ "level=info msg=\"NGINX Counter initializing", "level=info msg=\"MetricsThrottle initializing\"", "level=info msg=\"DataPlaneStatus initializing\"", "level=info msg=\"OneTimeRegistration initializing\"", "level=info msg=\"Metrics initializing\"", @@ -56,9 +59,11 @@ func TestFeatures_NginxCountingEnabled(t *testing.T) { for _, logLine := range disabledFeatureLogs { assert.NotContains(t, string(agentLogContent), logLine, "agent log file contains disabled feature log") } + log.Info("finished testing nginx counting enabled") } func TestFeatures_MetricsEnabled(t *testing.T) { + log.Info("testing metrics enabled") enabledFeatureLogs := []string{"level=info msg=\"Metrics initializing\"", "level=info msg=\"MetricsThrottle initializing\"", "level=info msg=\"DataPlaneStatus initializing\""} disabledFeatureLogs := []string{"level=info msg=\"OneTimeRegistration initializing\"", "level=info msg=\"Events initializing\"", "level=info msg=\"Agent API initializing\""} @@ -101,9 +106,11 @@ func TestFeatures_MetricsEnabled(t *testing.T) { for _, logLine := range disabledFeatureLogs { assert.NotContains(t, string(agentLogContent), logLine, "agent log file contains disabled feature log") } + log.Info("finished testing metrics enabled") } func TestFeatures_ConfigEnabled(t *testing.T) { + log.Info("testing config enabled") enabledFeatureLogs := []string{"level=info msg=\"DataPlaneStatus initializing\""} disabledFeatureLogs := []string{"level=info msg=\"Events initializing\"", "level=info msg=\"Agent API initializing\"", "level=info msg=\"Metrics initializing\"", "level=info msg=\"MetricsThrottle initializing\""} @@ -146,4 +153,5 @@ func TestFeatures_ConfigEnabled(t *testing.T) { for _, logLine := range disabledFeatureLogs { assert.NotContains(t, string(agentLogContent), logLine, "agent log file contains disabled feature log") } + log.Info("finished testing config enabled") } diff --git a/test/integration/grpc/grpc_config_apply_test.go b/test/integration/grpc/grpc_config_apply_test.go index 25001d122..98b9ab858 100644 --- a/test/integration/grpc/grpc_config_apply_test.go +++ b/test/integration/grpc/grpc_config_apply_test.go @@ -67,6 +67,7 @@ config_dirs: "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms: ) func TestRegistrationAndConfigApply(t *testing.T) { + log.Info("testing registration and config apply") ctx := context.Background() grpcListener, grpcClose := createListener() defer grpcClose() @@ -210,6 +211,7 @@ messageLoop: } }) } + log.Info("finished testing registration and config apply") } func createListener() (listener net.Listener, close func() error) { diff --git a/test/integration/install/install_uninstall_test.go b/test/integration/install/install_uninstall_test.go index ee2ae7e9f..e838491f3 100644 --- a/test/integration/install/install_uninstall_test.go +++ b/test/integration/install/install_uninstall_test.go @@ -11,6 +11,8 @@ import ( "testing" "time" + log "github.com/sirupsen/logrus" + "github.com/nginx/agent/test/integration/utils" "github.com/stretchr/testify/assert" @@ -64,6 +66,7 @@ func installUninstallSetup(tb testing.TB, expectNoErrorsInLogs bool) (testcontai // Verifies that agent installs with correct output and files. // Verifies that agent uninstalls and removes all the files. func TestAgentManualInstallUninstall(t *testing.T) { + log.Info("testing agent install uninstall") expectedInstallLogMsgs := map[string]string{ "InstallFoundNginxAgent": "Found nginx-agent /usr/bin/nginx-agent", "InstallAgentSuccess": "NGINX Agent package has been successfully installed.", @@ -148,6 +151,7 @@ func TestAgentManualInstallUninstall(t *testing.T) { _, err = testContainer.CopyFileFromContainer(ctx, agentPath) assert.Error(t, err) } + log.Info("finished testing agent install uninstall") } // installAgent installs the agent returning total install time and install output