# Copyright (c) Microsoft Corporation # SPDX-License-Identifier: MIT # This workflow executes a single test, optionally gathering code coverage and logs. parameters: - name: name type: string # Job dependency - name: dependency type: string # The test command to invoke. - name: test_command type: string # The name of the build artifact to download. - name: build_artifact type: string # The environment to run this test on. - name: environment type: string # Set to true to gather code coverage when this test runs. - name: code_coverage type: boolean default: false # Set to true to gather and upload memory dumps if a test process crashes. - name: gather_dumps type: boolean default: false - name: pre_test type: string default: '' - name: post_test type: string default: '' - name: capture_etw type: boolean default: false # Set to true to use Visual Studio Developer command shell. - name: vs_dev type: boolean default: false - name: fault_injection type: boolean default: false - name: leak_detection type: boolean default: false - name: configurations type: object default: ["Debug", "Release"] jobs: - job: ${{parameters.name}} dependsOn: ${{parameters.dependency}} timeoutInMinutes: 90 strategy: matrix: ${{ each configuration in parameters.configurations }}: ${{ configuration }}: buildConfiguration: ${{ configuration }} pool: vmImage: ${{parameters.environment}} type: windows variables: # Configuration type to build. PROJECT_NAME: ebpf-for-windows NAME: ${{parameters.name}} BUILD_CONFIGURATION: $(buildConfiguration) BUILD_PLATFORM: x64 TEST_COMMAND: ${{parameters.test_command}} PRE_COMMAND: ${{parameters.pre_test}} POST_COMMAND: ${{parameters.post_test}} USERSIM_MEMORY_LEAK_DETECTION: ${{parameters.leak_detection}} # Skip Codesign Validation task, as ths is a test job. runCodesignValidationInjection: false DUMP_PATH: c:\dumps\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION) TEST_TIMEOUT: 3600 # 1 hour timeout for tests. steps: # Checking out the branch is needed to gather correct code coverage data. - checkout: self submodules: 'recursive' fetchDepth: 0 # Only check out source code if code coverage is being gathered. condition: eq('${{parameters.code_coverage}}', 'true') displayName: 'Checkout Repo' # Perform shallow checkout for self-hosted runner. - checkout: self fetchDepth: 0 condition: eq('${{parameters.environment}}', 'ebpf_cicd_tests') displayName: 'Shallow Checkout Repo' - powershell: | $value = "true" Write-Host "##vso[task.setvariable variable=ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE;]$value" $value = "allocator_may_return_null=1" Write-Host "##vso[task.setvariable variable=ASAN_OPTIONS;]$value" workingDirectory: $(Build.SourcesDirectory) displayName: 'Set ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE' - bash: | choco install -y procdump where procdump.exe condition: eq('${{parameters.gather_dumps}}', 'true') name: install_procdump displayName: 'Install ProcDump' - bash: | choco install -y --requirechecksum=true --checksum=2295A733DA39412C61E4F478677519DD0BB1893D88313CE56B468C9E50517888 --checksum-type=sha256 OpenCppCoverage echo '##vso[task.prependpath]C:\Program Files\OpenCppCoverage' condition: and(eq('${{parameters.code_coverage}}', 'true'), ne('${{parameters.environment}}', 'ebpf_cicd_tests')) name: set_up_opencppcoverage displayName: 'Set up OpenCppCoverage and add to PATH' - bash: | echo "*** All environment variables ***" env | sort workingDirectory: $(Build.SourcesDirectory) displayName: 'Dump Environment variables' - powershell: | mkdir $(DUMP_PATH) New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -ErrorAction SilentlyContinue New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpType" -Value 2 -PropertyType DWord -ErrorAction SilentlyContinue $dump_path = "$(DUMP_PATH)".Replace("/", "\") New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpFolder" -Value "$dump_path" -PropertyType ExpandString -ErrorAction SilentlyContinue condition: eq('${{parameters.gather_dumps}}', 'true') name: configure_windows_error_reporting displayName: 'Configure Windows Error Reporting to make a local copy of any crashes that occur' - powershell: | Remove-Item -Path $(Build.SourcesDirectory)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION) -Recurse -Force -ErrorAction SilentlyContinue condition: eq('${{parameters.environment}}', 'ebpf_cicd_tests') displayName: Remove existing artifacts - download: current artifact: "${{parameters.build_artifact}} $(buildConfiguration)" condition: succeeded() name: download_artifact displayName: "Download build artifact" - powershell: | mkdir $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\ cd $(Build.ArtifactStagingDirectory) cd .. $source = ".\${{parameters.build_artifact}} $(buildConfiguration)" $destination = "$(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)" Get-ChildItem $source | Copy-Item -Destination $destination -Recurse -filter *.* displayName: Copy build artifacts to correct path - script: | mkdir "$(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\Artifacts" displayName: Create generated artifact folder - script: | mkdir $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\TestLogs wpr.exe -start $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\ebpfforwindows.wprp -filemode condition: eq('${{parameters.capture_etw}}', 'true') name: start_etw_tracing displayName: Start ETW tracing - script: | .\export_program_info.exe --clear .\export_program_info.exe workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) name: configure_ebpf_store displayName: Configure eBPF store - script: | .\export_program_info_sample.exe --clear .\export_program_info_sample.exe workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) condition: ne(variables.buildConfiguration, 'FuzzerDebug') name: configure_ebpf_store_sample displayName: Configure eBPF store (undocked) - script: | $(PRE_COMMAND) workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) name: run_pre_test_command displayName: Run pre test command - script: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" set EBPF_ENABLE_WER_REPORT=yes OpenCppCoverage.exe -q --cover_children --sources $(Build.SourcesDirectory)\$(PROJECT_NAME) --excluded_sources $(Build.SourcesDirectory)\$(PROJECT_NAME)\external\Catch2 --export_type cobertura:ebpf_for_windows.xml --working_dir $(BUILD_PLATFORM)\$(BUILD_CONFIGURATION) -- $(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\$(TEST_COMMAND) workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME) condition: and(eq('${{parameters.code_coverage}}', 'true'), eq('${{parameters.vs_dev}}', 'true')) name: run_test_with_code_coverage_in_vs_dev displayName: Run test with Code Coverage in VS Dev environment - script: | OpenCppCoverage.exe -q --cover_children --sources $(Build.SourcesDirectory)\$(PROJECT_NAME) --excluded_sources $(Build.SourcesDirectory)\$(PROJECT_NAME)\external\Catch2 --export_type cobertura:ebpf_for_windows.xml --working_dir $(BUILD_PLATFORM)\$(BUILD_CONFIGURATION) -- powershell.exe .\Test-FaultInjection.ps1 $(DUMP_PATH) $(TEST_TIMEOUT) $(TEST_COMMAND) 4 workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME) condition: and(eq('${{parameters.code_coverage}}', 'true'), eq('${{parameters.fault_injection}}', 'true')) name: run_test_with_code_coverage_with_fault_injection displayName: Run test with Code Coverage and low resource simulation - script: | powershell.exe .\Test-FaultInjection.ps1 $(DUMP_PATH) $(TEST_TIMEOUT) $(TEST_COMMAND) 16 workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) condition: and(ne('${{parameters.code_coverage}}', 'true'), eq('${{parameters.fault_injection}}', 'true')) name: run_test_with_fault_injection displayName: Run test with low resource simulation - script: | set EBPF_ENABLE_WER_REPORT=yes OpenCppCoverage.exe -q --sources $(Build.SourcesDirectory)\$(PROJECT_NAME) --excluded_sources $(Build.SourcesDirectory)\$(PROJECT_NAME)\external\Catch2 --export_type cobertura:ebpf_for_windows.xml --working_dir $(BUILD_PLATFORM)\$(BUILD_CONFIGURATION) -- powershell .\Run-Test.ps1 $(DUMP_PATH) $(TEST_TIMEOUT) $(TEST_COMMAND) workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME) condition: and(eq('${{parameters.code_coverage}}', 'true'), ne('${{parameters.vs_dev}}', 'true'), ne('${{parameters.fault_injection}}', 'true')) name: run_test_with_code_coverage displayName: Run test with Code Coverage - script: | $(TEST_COMMAND) workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) condition: eq('${{parameters.code_coverage}}', 'false') name: run_test_without_code_coverage displayName: Run test without Code Coverage - script: | $(POST_COMMAND) condition: succeededOrFailed() workingDirectory: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION) name: run_post_test_command displayName: Run post test command - powershell: | $fileExists = Test-Path -Path "$(Build.SourcesDirectory)\$(PROJECT_NAME)\ebpf_for_windows.xml" Write-Output "##vso[task.setvariable variable=FileExists;isOutput=true]$fileExists" name: check_coverage displayName: Check for CodeCoverage - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: 'Cobertura' summaryFileLocation: $(Build.SourcesDirectory)/$(PROJECT_NAME)/ebpf_for_windows.xml pathToSources: $(Build.SourcesDirectory)/$(PROJECT_NAME) condition: eq(variables['check_coverage.FileExists'], 'True') displayName: Upload Code Coverage Report - script: | wpr.exe -stop $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\TestLogs\ebpfforwindows.etl condition: eq('${{parameters.capture_etw}}', 'true') displayName: Stop ETW tracing - script: | copy $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\*.log $(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\TestLogs condition: and(eq('${{parameters.name}}', 'bpf2c'), eq('${{parameters.capture_etw}}', 'true')) displayName: Copy any bpf2c test logs to TestLogs - powershell: | $fileExists = Test-Path -Path "$(DUMP_PATH)\*.dmp" Write-Output "##vso[task.setvariable variable=FileExists;isOutput=true]$fileExists" condition: succeededOrFailed() name: check_dumps displayName: Check for crash dumps - publish: '$(DUMP_PATH)' artifact: 'Crash-Dumps-$(NAME)-$(BUILD_PLATFORM)-$(BUILD_CONFIGURATION)' condition: and(succeededOrFailed(), eq('${{parameters.gather_dumps}}', 'true'), eq(variables['check_dumps.FileExists'], 'True')) displayName: "Upload any crash dumps" - powershell: | $fileExists = Test-Path -Path "$(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\TestLogs\*" Write-Output "##vso[task.setvariable variable=FileExists;isOutput=true]$fileExists" condition: and(succeededOrFailed(), eq('${{parameters.capture_etw}}', 'true')) name: check_logs displayName: Check for TestLogs - publish: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(buildConfiguration)/TestLogs artifact: 'Test-Logs-$(NAME)-$(BUILD_PLATFORM)-$(BUILD_CONFIGURATION)' condition: and(succeededOrFailed(), eq(variables['check_logs.FileExists'], 'True')) displayName: "Upload log files" - powershell: | $fileExists = Test-Path -Path "$(Build.SourcesDirectory)\$(PROJECT_NAME)\$(BUILD_PLATFORM)\$(BUILD_CONFIGURATION)\Artifacts\*" Write-Output "##vso[task.setvariable variable=FileExists;isOutput=true]$fileExists" condition: succeededOrFailed() name: check_artifacts displayName: Check for generated artifacts - publish: $(Build.SourcesDirectory)/$(PROJECT_NAME)/$(BUILD_PLATFORM)/$(BUILD_CONFIGURATION)/Artifacts artifact: 'Artifacts-$(NAME)-$(BUILD_PLATFORM)-$(BUILD_CONFIGURATION)' condition: and(succeededOrFailed(), eq(variables['check_artifacts.FileExists'], 'True')) displayName: "Upload log files" - script: | exit 1 condition: eq(variables['check_dumps.FileExists'], 'True') displayName: Mark run as failed if crash dumps are found