diff --git a/.github/actions/start-promtail/action.yml b/.github/actions/start-promtail/action.yml new file mode 100644 index 000000000..b2256f86c --- /dev/null +++ b/.github/actions/start-promtail/action.yml @@ -0,0 +1,30 @@ +name: Start Promtail +description: Start promtail in a docker container to ship test results to Grafana Loki, then stop the container +inputs: + loki_url: + description: URL endpoint of the Grafana Loki instance + required: true +runs: + using: 'composite' + steps: + - name: Start promtail container + shell: bash + run: | + docker run -d \ + --name=promtail \ + -v ${{ github.workspace }}/test/dashboard/promtail/promtail-config.yaml:/etc/promtail/promtail-config.yaml \ + -v ${{ github.workspace }}/test/dashboard/logs/:/var/log \ + -e TEST_OUTDIR=test/dashboard/logs \ + -e LOKI_URL=${{ inputs.loki_url }} \ + -e GITHUB_RUN_ID="${{ github.run_id }}" \ + -e GITHUB_WORKFLOW="${{ github.workflow }}" \ + -e GITHUB_EVENT_NAME="${{ github.event_name }}" \ + -e GITHUB_REPOSITORY="${{ github.repository }}" \ + -e GITHUB_SERVER_URL="${{ github.server_url }}" \ + -e GITHUB_JOB="${{ github.job }}" \ + -e GITHUB_HEAD_REF="${{ github.head_ref }}" \ + -e GITHUB_SHA="${{ github.sha }}" \ + -e GITHUB_ACTOR="${{ github.actor }}" \ + grafana/promtail:3.4.4 \ + -config.file=/etc/promtail/promtail-config.yaml \ + -config.expand-env=true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5beedc9d..5cf81715c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,11 +136,25 @@ jobs: with: name: nginx-agent-unsigned-snapshots path: build + + - name: Create Results 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_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: Format Results + if: always() + run: bash ./scripts/dashboard/format_results.sh ${{job.status}} ${{github.job}}/${{matrix.container.image}}-${{matrix.container.version}} ${{github.workspace}} official-oss-image-integration-tests: name: Integration Tests - Official OSS Images @@ -173,13 +187,27 @@ jobs: with: name: nginx-agent-unsigned-snapshots path: build + + - name: Create Results 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_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="docker-registry.nginx.com" \ TAG="${{ matrix.container.version }}-${{ matrix.container.image }}" \ OS_RELEASE="${{ matrix.container.release }}" OS_VERSION="${{ matrix.container.version }}" \ - 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: Format Results + if: always() + run: bash ./scripts/dashboard/format_results.sh ${{job.status}} ${{github.job}}/${{matrix.container.image}}-${{matrix.container.version}} ${{github.workspace}} official-plus-image-integration-tests: name: Integration Tests - Official Plus Images @@ -226,13 +254,27 @@ jobs: registry: ${{ secrets.REGISTRY_URL }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Create Results 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_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 }}" OS_VERSION="${{ matrix.container.version }}" 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: Format Results + if: always() + run: bash ./scripts/dashboard/format_results.sh ${{job.status}} ${{github.job}}/${{matrix.container.image}}-${{matrix.container.version}} ${{github.workspace}} performance-tests: name: Performance Tests diff --git a/Makefile.tools b/Makefile.tools index e850a1d02..6f745952f 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -8,6 +8,7 @@ NFPM = github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.36.1 GOTESTCOVERAGE = github.com/vladopajic/go-test-coverage/v2@v2.10.1 BENCHSTAT = golang.org/x/perf/cmd/benchstat@v0.0.0-20240404204407-f3e401e020e4 BUF = github.com/bufbuild/buf/cmd/buf@v1.30.1 +PROMTAIL = github.com/prometheus/promtail/cmd/promtail@v2.10.0 install-tools: ## Install tool dependencies @echo "Installing Tools" @@ -22,4 +23,5 @@ install-tools: ## Install tool dependencies @$(GOINST) $(GOTESTCOVERAGE) @$(GOINST) $(BENCHSTAT) @$(GOINST) $(BUF) + @$(GOINST) $(PROMTAIL) @$(GORUN) $(LEFTHOOK) install diff --git a/scripts/dashboard/format_results.sh b/scripts/dashboard/format_results.sh new file mode 100755 index 000000000..4536a256f --- /dev/null +++ b/scripts/dashboard/format_results.sh @@ -0,0 +1,224 @@ +#!/bin/bash +# Script to process test logs and generate formatted result files +# Usage: ./format_results.sh + +set -euo pipefail + +# Check if required arguments are provided +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Parameters +RESULT="$1" +TEST_TYPE="$2" +WORKSPACE="$3" + +# File paths +INPUT_FILE="$WORKSPACE/test/dashboard/logs/$TEST_TYPE/raw_logs.log" +OUTPUT_DIR="$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 + +format_log() { + 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" +} + +write_result() { + start_at="$1" + end_at="$2" + result="$3" + msg="$4" + output_dir="$5" + duration_seconds=0 + + if [[ $end_at == "end_at" ]]; then + end_at=$(date +"%Y/%m/%d %H:%M:%S") + fi + + # Format timestamps + if [[ "$start_at" =~ ^[0-9]{4}/[0-9]{2}/[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}$ && \ + "$end_at" =~ ^[0-9]{4}/[0-9]{2}/[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}$ ]]; then + duration_seconds=$(( $(date -d "$end_at" +%s) - $(date -d "$start_at" +%s) )) + start_iso="" + end_iso="" + start_iso=$(date -d "$start_at" +"%Y-%m-%dT%H:%M:%S.%NZ") + end_iso=$(date -d "$end_at" +"%Y-%m-%dT%H:%M:%S.%NZ") + else + duration_seconds=0 + fi + + if [[ ${msg} == "msg" ]]; then + msg="" + fi + + mkdir -p "$output_dir" + result_file="$output_dir/result.json" + + echo "{\"start_at\":\"$start_iso\", \"end_at\":\"$end_iso\", \"duration_seconds\":$duration_seconds, \"result\":\"$result\", \"msg\":\"$msg\"}" > "$result_file" +} + +format_results() { + test_group=("name" "start_at" "end_at" "result" "msg") + current_test=("name" "start_at" "end_at" "result" "msg") + test_queue=() + is_running=false + has_failed=false + error_trace="" + + while IFS= read -r line; do + # Detect if the line is a test start + if [[ "$line" =~ ^===\ RUN[[:space:]]+(.+) ]]; then + test_name="${BASH_REMATCH[1]}" + has_failed=false + + if [[ "${test_group[0]}" == "name" && "$is_running" == false ]]; then + is_running=true + test_group[0]="$test_name" + elif [[ "${test_group[0]}" != "name" && "$is_running" == true ]]; then + is_running=true + if [[ "${current_test[0]}" != "${test_group[0]}" ]]; then + test_queue+=("${current_test[@]}") + fi + fi + + current_test=("$test_name" "start_at" "end_at" "result" "msg") + continue + fi + + # Get start time + if [[ "$line" =~ ^([0-9]{4}/[0-9]{2}/[0-9]{2}[[:space:]][0-9]{2}:[0-9]{2}:[0-9]{2}).*INFO[[:space:]]+starting.*test* ]]; then + test_start="${BASH_REMATCH[1]}" + current_test[1]="$test_start" + if [[ "${current_test[0]}" == "${test_group[0]}" ]]; then + test_group[1]="$test_start" + fi + continue + fi + + # Get end time + if [[ "$line" =~ ^([0-9]{4}/[0-9]{2}/[0-9]{2}[[:space:]][0-9]{2}:[0-9]{2}:[0-9]{2}).*INFO[[:space:]]+finished.*test* ]]; then + test_end="${BASH_REMATCH[1]}" + if [[ "${current_test[2]}" == "end_at" ]]; then + current_test[2]="$test_end" + if [[ "${current_test[0]}" == "${test_group[0]}" ]]; then + test_group[2]="$test_end" + fi + elif [[ "${current_test[2]}" != "end_at" ]]; then + test_group[2]="$test_end" + fi + continue + fi + + # Capture error messages + if [[ "$line" == *"Error Trace"* || "$line" == *"runtime error"* ]]; then + has_failed=true + error_trace+="${line}"$'\n' + continue + fi + + # Detect result + if [[ "$line" == *"--- PASS"* || "$line" == *"--- FAIL"* ]]; then + [[ "$line" == *"--- PASS"* ]] && result_val="pass" + [[ "$line" == *"--- FAIL"* ]] && result_val="fail" + + has_failed=false + + # Clear current_test field + if [[ "${current_test[0]}" != "name" ]]; then + if [[ "${current_test[0]}" == "${test_group[0]}" ]]; then + current_test=("name" "start_at" "end_at" "result" "msg") + else + test_queue+=("${current_test[@]}") + current_test=("name" "start_at" "end_at" "result" "msg") + fi + fi + + # Write results for the test group + if [[ "${test_group[0]}" != "name" && "${#test_queue[@]}" -eq 0 ]] || + [[ "${test_group[0]}" != "name" && "${#test_queue[@]}" -gt 0 ]]; then + if [[ "$line" != *"${test_group[0]}"* ]]; then + echo "Error: Test name did not match. Expected '${test_group[0]}', in line: '$line'." + exit 1 + fi + test_group[3]="$result_val" + if [[ "$result_val" == "fail" ]]; then + if [[ ${test_group[4]} == "msg" ]]; then + test_group[4]="" + fi + test_group[4]+="$error_trace" + fi + write_result "${test_group[1]}" "${test_group[2]}" "${test_group[3]}" "${test_group[4]}" "$OUTPUT_DIR/${test_group[0]}" + test_group=("name" "start_at" "end_at" "result" "msg") + is_running=false + continue + fi + + # Write results for individual tests in the queue + if [[ "${test_group[0]}" == "name" && "${#test_queue[@]}" -gt 0 ]]; then + test_match=("${test_queue[0]}" "${test_queue[1]}" "${test_queue[2]}" "${test_queue[3]}" "${test_queue[4]}") + test_match[3]="$result_val" + if [[ "$result_val" == "fail" ]]; then + if [[ ${test_match[4]} == "msg" ]]; then + test_match[4]="" + fi + test_match[4]+="$error_trace" + fi + write_result "${test_match[1]}" "${test_match[2]}" "${test_match[3]}" "${test_match[4]}" "$OUTPUT_DIR/${test_match[0]}" + + for i in {0..4}; do + unset 'test_queue[$i]' + done + test_queue=("${test_queue[@]:5}") + fi + + # No tests to analyze + if [[ "${test_group[0]}" == "name" && "${#test_queue[@]}" -eq 0 ]]; then + error_trace="" + continue + fi + fi + + # Capture error messages + if [[ $has_failed == true ]]; then + error_trace+="${line}"$'\n' + fi + + # Capture logs + if [[ "$line" =~ time=([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z)[[:space:]]+level= ]]; then + LOG_LINE=$(format_log "$line") + LOG_FILE_OUT_DIR="$OUTPUT_DIR/${test_group[0]}" + LOG_FILE=${LOG_FILE_OUT_DIR}/test.log + if [[ ! -d "$LOG_FILE_OUT_DIR" ]]; then + mkdir -p "$LOG_FILE_OUT_DIR" + fi + echo "$LOG_LINE" >> "$LOG_FILE" + continue + fi + done < "$INPUT_FILE" +} + +{ + format_results +} diff --git a/test/dashboard/promtail/promtail-config.yaml b/test/dashboard/promtail/promtail-config.yaml new file mode 100644 index 000000000..af830942c --- /dev/null +++ b/test/dashboard/promtail/promtail-config.yaml @@ -0,0 +1,135 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 + log_level: info + +positions: + filename: /tmp/positions.yaml + sync_period: "10s" + +clients: + - url: "${LOKI_URL}" + external_labels: + systest_project: agent_v3 + systest_type: "${GITHUB_JOB}" + timeout: 30s + backoff_config: + min_period: 500ms + max_period: 5s + max_retries: 5 + +scrape_configs: + - 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 + + - job_name: test-results + static_configs: + - targets: + - localhost + labels: + systest_job: test-results + __path__: /var/log/**/result.json + pipeline_stages: + - json: + expressions: + start_at: + - 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/integration/auxiliarycommandserver/connection_test.go b/test/integration/auxiliarycommandserver/connection_test.go index 4b2204daa..772c355f2 100644 --- a/test/integration/auxiliarycommandserver/connection_test.go +++ b/test/integration/auxiliarycommandserver/connection_test.go @@ -8,6 +8,7 @@ package auxiliarycommandserver import ( "context" "fmt" + "log/slog" "net" "net/http" "os" @@ -32,19 +33,22 @@ func (s *AuxiliaryTestSuite) SetupSuite() { t := s.T() // Expect errors in logs should be false for recconnection tests // For now for these test we will skip checking the logs for errors + slog.Info("starting auxiliary command server tests") s.teardownTest = utils.SetupConnectionTest(t, false, false, true, "../../config/agent/nginx-agent-with-auxiliary-command.conf") } func (s *AuxiliaryTestSuite) TearDownSuite() { + slog.Info("finished auxiliary command server tests") s.teardownTest(s.T()) } -func TestSuite(t *testing.T) { +func TestAuxiliaryTestSuite(t *testing.T) { suite.Run(t, new(AuxiliaryTestSuite)) } func (s *AuxiliaryTestSuite) TestAuxiliary_Test1_Connection() { + slog.Info("starting auxiliary command server connection test") s.instanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) s.False(s.T().Failed()) utils.VerifyUpdateDataPlaneHealth(s.T(), utils.MockManagementPlaneAPIAddress) @@ -56,9 +60,11 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test1_Connection() { commandResponses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress) s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, commandResponses[0].GetCommandResponse().GetStatus()) s.Equal("Successfully updated all files", commandResponses[0].GetCommandResponse().GetMessage()) + slog.Info("finished auxiliary command server connection test") } func (s *AuxiliaryTestSuite) TestAuxiliary_Test2_Reconnection() { + slog.Info("starting auxiliary command server reconnection test") ctx := context.Background() timeout := 15 * time.Second @@ -81,9 +87,11 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test2_Reconnection() { currentID := utils.VerifyConnection(s.T(), 2, utils.AuxiliaryMockManagementPlaneAPIAddress) s.Equal(originalID, currentID) + slog.Info("finished auxiliary command server reconnection test") } func (s *AuxiliaryTestSuite) TestAuxiliary_Test3_DataplaneHealthRequest() { + slog.Info("starting auxiliary command server data plane health request test") utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress) utils.ClearManagementPlaneResponses(s.T(), utils.AuxiliaryMockManagementPlaneAPIAddress) @@ -115,9 +123,11 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test3_DataplaneHealthRequest() { // Check auxiliary server still only has 1 ManagementPlaneResponses as it didn't send the request utils.ManagementPlaneResponses(s.T(), 0, utils.AuxiliaryMockManagementPlaneAPIAddress) s.False(s.T().Failed()) + slog.Info("finished auxiliary command server data plane health request test") } func (s *AuxiliaryTestSuite) TestAuxiliary_Test4_FileWatcher() { + slog.Info("starting auxiliary command server file watcher test") // Clear any previous responses from previous tests utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress) utils.ClearManagementPlaneResponses(s.T(), utils.AuxiliaryMockManagementPlaneAPIAddress) @@ -140,9 +150,11 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test4_FileWatcher() { auxResponses := utils.ManagementPlaneResponses(s.T(), 1, utils.AuxiliaryMockManagementPlaneAPIAddress) s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, auxResponses[0].GetCommandResponse().GetStatus()) s.Equal("Successfully updated all files", auxResponses[0].GetCommandResponse().GetMessage()) + slog.Info("finished auxiliary command server file watcher test") } func (s *AuxiliaryTestSuite) TestAuxiliary_Test5_ConfigApply() { + slog.Info("starting auxiliary command server config apply test") utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress) utils.ClearManagementPlaneResponses(s.T(), utils.AuxiliaryMockManagementPlaneAPIAddress) @@ -185,9 +197,11 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test5_ConfigApply() { commandOverview := utils.CurrentFileOverview(s.T(), s.instanceID, utils.MockManagementPlaneAPIAddress) auxOverview := utils.CurrentFileOverview(s.T(), s.instanceID, utils.AuxiliaryMockManagementPlaneAPIAddress) s.Equal(commandOverview.GetConfigVersion(), auxOverview.GetConfigVersion()) + slog.Info("finished auxiliary command server config apply test") } func (s *AuxiliaryTestSuite) TestAuxiliary_Test6_ConfigApplyInvalid() { + slog.Info("starting auxiliary command server invalid config apply test") utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress) utils.ClearManagementPlaneResponses(s.T(), utils.AuxiliaryMockManagementPlaneAPIAddress) @@ -200,4 +214,5 @@ func (s *AuxiliaryTestSuite) TestAuxiliary_Test6_ConfigApplyInvalid() { s.Equal("Config apply failed", commandResponses[0].GetCommandResponse().GetMessage()) s.Equal("Unable to process request. Management plane is configured as read only.", commandResponses[0].GetCommandResponse().GetError()) + slog.Info("finished auxiliary command server invalid config apply test") } diff --git a/test/integration/installuninstall/install_uninstall_test.go b/test/integration/installuninstall/install_uninstall_test.go index 14b60a0f1..a6d207491 100644 --- a/test/integration/installuninstall/install_uninstall_test.go +++ b/test/integration/installuninstall/install_uninstall_test.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "io" + "log/slog" "os" "path" "path/filepath" @@ -51,6 +52,8 @@ func installUninstallSetup(tb testing.TB, expectNoErrorsInLogs bool) (testcontai LogMessage: "nginx_pid", } + slog.Info("starting install uninstall tests") + // start container without agent installed testContainer := helpers.StartAgentlessContainer( ctx, @@ -68,6 +71,7 @@ func installUninstallSetup(tb testing.TB, expectNoErrorsInLogs bool) (testcontai expectNoErrorsInLogs, nil, ) + slog.Info("finished install uninstall tests") } } diff --git a/test/integration/managementplane/config_apply_test.go b/test/integration/managementplane/config_apply_test.go index 39297e716..01a9405eb 100644 --- a/test/integration/managementplane/config_apply_test.go +++ b/test/integration/managementplane/config_apply_test.go @@ -8,6 +8,7 @@ package managementplane import ( "context" "fmt" + "log/slog" "os" "sort" "testing" @@ -38,6 +39,7 @@ type ConfigApplyChunkingTestSuite struct { } func (s *ConfigApplyTestSuite) SetupSuite() { + slog.Info("starting config apply tests") s.ctx = context.Background() s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, "../../config/agent/nginx-config-with-grpc-client.conf") @@ -48,6 +50,7 @@ func (s *ConfigApplyTestSuite) SetupSuite() { } func (s *ConfigApplyTestSuite) TearDownSuite() { + slog.Info("finished config apply tests") s.teardownTest(s.T()) } @@ -56,6 +59,7 @@ func (s *ConfigApplyTestSuite) TearDownTest() { } func (s *ConfigApplyTestSuite) TestConfigApply_Test1_TestNoConfigChanges() { + slog.Info("starting config apply no config changes test") utils.PerformConfigApply(s.T(), s.nginxInstanceID, utils.MockManagementPlaneAPIAddress) responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress) s.T().Logf("Config apply responses: %v", responses) @@ -64,9 +68,11 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test1_TestNoConfigChanges() { s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus()) s.Equal("Config apply successful, no files to change", responses[1].GetCommandResponse().GetMessage()) + slog.Info("finished config apply no config changes test") } func (s *ConfigApplyTestSuite) TestConfigApply_Test2_TestValidConfig() { + slog.Info("starting config apply valid config test") newConfigFile := "../../config/nginx/nginx-with-test-location.conf" if os.Getenv("IMAGE_PATH") == "/nginx-plus/agent" { @@ -92,9 +98,11 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test2_TestValidConfig() { s.Equal("Config apply successful", responses[0].GetCommandResponse().GetMessage()) s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus()) s.Equal("Successfully updated all files", responses[1].GetCommandResponse().GetMessage()) + slog.Info("finished config apply valid config test") } func (s *ConfigApplyTestSuite) TestConfigApply_Test3_TestInvalidConfig() { + slog.Info("starting config apply invalid config test") err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer( s.ctx, "../../config/nginx/invalid-nginx.conf", @@ -114,9 +122,11 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test3_TestInvalidConfig() { s.Equal(mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[1].GetCommandResponse().GetStatus()) s.Equal("Config apply failed, rollback successful", responses[1].GetCommandResponse().GetMessage()) s.Equal(configApplyErrorMessage, responses[1].GetCommandResponse().GetError()) + slog.Info("finished config apply invalid config test") } func (s *ConfigApplyTestSuite) TestConfigApply_Test4_TestFileNotInAllowedDirectory() { + slog.Info("starting config apply file not in allowed directory test") utils.PerformInvalidConfigApply(s.T(), s.nginxInstanceID) responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress) @@ -128,9 +138,11 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test4_TestFileNotInAllowedDirecto "file not in allowed directories /unknown/nginx.conf", responses[0].GetCommandResponse().GetError(), ) + slog.Info("finished config apply file not in allowed directory test") } func (s *ConfigApplyChunkingTestSuite) SetupSuite() { + slog.Info("starting config apply chunking tests") s.ctx = context.Background() s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, "../../config/agent/nginx-config-with-max-file-size.conf") @@ -141,6 +153,7 @@ func (s *ConfigApplyChunkingTestSuite) SetupSuite() { } func (s *ConfigApplyChunkingTestSuite) TearDownSuite() { + slog.Info("finished config apply chunking tests") s.teardownTest(s.T()) } diff --git a/test/integration/managementplane/config_upload_test.go b/test/integration/managementplane/config_upload_test.go index 0f888d3c4..92e9bf1ae 100644 --- a/test/integration/managementplane/config_upload_test.go +++ b/test/integration/managementplane/config_upload_test.go @@ -8,6 +8,7 @@ package managementplane import ( "context" "fmt" + "log/slog" "net/http" "testing" @@ -26,6 +27,7 @@ type MPITestSuite struct { } func (s *MPITestSuite) TearDownSuite() { + slog.Info("finished MPI tests") s.teardownTest(s.T()) } @@ -34,6 +36,7 @@ func (s *MPITestSuite) TearDownTest() { } func (s *MPITestSuite) SetupSuite() { + slog.Info("starting MPI tests") s.ctx = context.Background() s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, "../../config/agent/nginx-config-with-grpc-client.conf") @@ -46,6 +49,7 @@ func (s *MPITestSuite) SetupSuite() { } func (s *MPITestSuite) TestConfigUpload() { + slog.Info("starting MPI config upload test") request := fmt.Sprintf(`{ "message_meta": { "message_id": "5d0fa83e-351c-4009-90cd-1f2acce2d184", @@ -79,6 +83,7 @@ func (s *MPITestSuite) TestConfigUpload() { s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus()) s.Equal("Successfully updated all files", responses[1].GetCommandResponse().GetMessage()) + slog.Info("finished MPI config upload test") } func TestMPITestSuite(t *testing.T) { diff --git a/test/integration/managementplane/file_watcher_test.go b/test/integration/managementplane/file_watcher_test.go index 3e6824233..a7d8b3f17 100644 --- a/test/integration/managementplane/file_watcher_test.go +++ b/test/integration/managementplane/file_watcher_test.go @@ -6,12 +6,15 @@ package managementplane import ( + "log/slog" + "github.com/nginx/agent/v3/test/integration/utils" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" ) func (s *MPITestSuite) TestFileWatcher_Test1_TestUpdateNGINXConfig() { + slog.Info("starting MPI update NGINX config test") err := utils.Container.CopyFileToContainer( s.ctx, "../../config/nginx/nginx-with-server-block-access-log.conf", @@ -26,9 +29,11 @@ func (s *MPITestSuite) TestFileWatcher_Test1_TestUpdateNGINXConfig() { s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) utils.VerifyUpdateDataPlaneStatus(s.T(), utils.MockManagementPlaneAPIAddress) + slog.Info("finished MPI update NGINX config test") } func (s *MPITestSuite) TestFileWatcher_Test2_TestCreateNGINXConfig() { + slog.Info("starting MPI create NGINX config test") err := utils.Container.CopyFileToContainer( s.ctx, "../../config/nginx/empty-nginx.conf", @@ -42,9 +47,11 @@ func (s *MPITestSuite) TestFileWatcher_Test2_TestCreateNGINXConfig() { s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) utils.VerifyUpdateDataPlaneStatus(s.T(), utils.MockManagementPlaneAPIAddress) + slog.Info("finished MPI create NGINX config test") } func (s *MPITestSuite) TestFileWatcher_Test3_TestDeleteNGINXConfig() { + slog.Info("starting MPI delete NGINX config test") _, _, err := utils.Container.Exec( s.ctx, []string{"rm", "-rf", "/etc/nginx/test"}, @@ -56,4 +63,5 @@ func (s *MPITestSuite) TestFileWatcher_Test3_TestDeleteNGINXConfig() { s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) utils.VerifyUpdateDataPlaneStatus(s.T(), utils.MockManagementPlaneAPIAddress) + slog.Info("finished MPI delete NGINX config test") } diff --git a/test/integration/managementplane/grpc_management_plane_api_test.go b/test/integration/managementplane/grpc_management_plane_api_test.go index 7cfe9050d..1d77485bc 100644 --- a/test/integration/managementplane/grpc_management_plane_api_test.go +++ b/test/integration/managementplane/grpc_management_plane_api_test.go @@ -7,6 +7,7 @@ package managementplane import ( "fmt" + "log/slog" "net" "net/http" "time" @@ -18,6 +19,7 @@ import ( ) func (s *ConfigApplyTestSuite) TestGrpc_Test1_Reconnection() { + slog.Info("starting grpc reconnection test") timeout := 15 * time.Second stopErr := utils.MockManagementPlaneGrpcContainer.Stop(s.ctx, &timeout) @@ -35,14 +37,18 @@ func (s *ConfigApplyTestSuite) TestGrpc_Test1_Reconnection() { currentID := utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) s.Equal(s.nginxInstanceID, currentID) + slog.Info("finished grpc reconnection test") } // Verify that the agent sends a connection request and an update data plane status request func (s *MPITestSuite) TestGrpc_Test2_StartUp() { + slog.Info("starting grpc startup test") utils.VerifyUpdateDataPlaneHealth(s.T(), utils.MockManagementPlaneAPIAddress) + slog.Info("finished grpc startup test") } func (s *MPITestSuite) TestGrpc_Test3_DataplaneHealthRequest() { + slog.Info("starting grpc dataplane health request test") request := `{ "message_meta": { "message_id": "5d0fa83e-351c-4009-90cd-1f2acce2d184", @@ -66,4 +72,5 @@ func (s *MPITestSuite) TestGrpc_Test3_DataplaneHealthRequest() { s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus()) s.Equal("Successfully sent health status update", responses[0].GetCommandResponse().GetMessage()) + slog.Info("finished grpc dataplane health request test") } diff --git a/test/integration/nginxless/nginx_less_mpi_connection_test.go b/test/integration/nginxless/nginx_less_mpi_connection_test.go index c979fadca..c5f58a50f 100644 --- a/test/integration/nginxless/nginx_less_mpi_connection_test.go +++ b/test/integration/nginxless/nginx_less_mpi_connection_test.go @@ -6,6 +6,7 @@ package nginxless import ( + "log/slog" "testing" "github.com/nginx/agent/v3/test/integration/utils" @@ -15,10 +16,13 @@ import ( // Verify that the agent sends a connection request to Management Plane even when Nginx is not present func TestNginxLessGrpc_Connection(t *testing.T) { + slog.Info("starting nginxless connection test") teardownTest := utils.SetupConnectionTest(t, true, true, false, "../../config/agent/nginx-config-with-grpc-client.conf") defer teardownTest(t) utils.VerifyConnection(t, 1, utils.MockManagementPlaneAPIAddress) assert.False(t, t.Failed()) + + slog.Info("Finished nginxless connection test") }