parameters: - name: Location type: string default: '' - name: ServiceDirectory type: string default: not-specified - name: CtestRegex type: string default: .* - name: Coverage type: string default: 'enabled' - name: CoverageReportPath type: string default: sdk/*/*/*cov_xml.xml - name: TimeoutInMinutes type: number default: 120 - name: DependsOn type: string default: '' # Matrix generation: # https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/scripts/job-matrix/README.md - name: Matrix type: string - name: MaxParallel type: number default: 0 - name: CloudConfig type: object default: {} - name: UsePlatformContainer type: boolean default: false - name: PreTestSteps type: stepList default: [] - name: PostTestSteps type: stepList default: [] - name: OSName type: string default: '' - name: EnvVars type: object default: {} - name: UseFederatedAuth type: boolean default: true jobs: - job: displayName: ValidateLive dependsOn: ${{ parameters.DependsOn }} condition: and(ne(variables['Skip.LiveTest'], 'true'), ne(${{ parameters.Matrix }}, '{}')) timeoutInMinutes: ${{ parameters.TimeoutInMinutes }} pool: name: $(Pool) # 1es pipeline templates converts `image` to demands: ImageOverride under the hood # which is incompatible with image selection in the default non-1es hosted pools ${{ if eq(parameters.OSName, 'macOS') }}: vmImage: $(OSVmImage) ${{ else }}: image: $(OSVmImage) os: ${{ parameters.OSName }} ${{ if eq(parameters.UsePlatformContainer, 'true') }}: # Add a default so the job doesn't fail when the matrix is empty container: $[ variables['Container'] ] strategy: maxParallel: ${{ parameters.MaxParallel }} matrix: $[ ${{ parameters.Matrix }} ] variables: - template: /eng/pipelines/templates/variables/globals.yml@self - template: /eng/pipelines/templates/variables/image.yml@self - name: CMOCKA_XML_FILE value: "%g-test-results.xml" - name: CMOCKA_MESSAGE_OUTPUT value: "xml" - name: BuildArgs value: "" - name: VcpkgArgs value: "" - name: WindowsCtestConfig value: "" - name: CmakeEnvArg value: "" - name: CmakeArgs value: "" - name: AZURE_TEST_MODE value: "LIVE" - name: AZURE_LOG_LEVEL value: "verbose" # Surface the ServiceDirectory parameter as an environment variable so tests can take advantage of it. - name: AZURE_SERVICE_DIRECTORY value: ${{ parameters.ServiceDirectory }} steps: - checkout: self submodules: recursive - template: /eng/common/pipelines/templates/steps/verify-agent-os.yml parameters: AgentImage: $(OSVmImage) - template: /eng/pipelines/templates/steps/fix-1es-image-apt-azure-sources.yml # Add g++5 repo to ubuntu - bash: sudo sh -c "echo 'deb http://ftp.debian.org/debian/ stretch main' >> /etc/apt/sources.list" displayName: Add g++ 5 condition: >- and( succeeded(), contains(variables['OSVmImage'], 'Ubuntu'), contains(variables['CmakeEnvArg'], 'CC=/usr/bin/gcc-5 CXX=/usr/bin/g++-5 cmake') ) # Install g++5 - bash: sudo apt-get update & sudo apt-get install g++-5 displayName: Install g++ 5 condition: >- and( succeeded(), contains(variables['OSVmImage'], 'Ubuntu'), contains(variables['CmakeEnvArg'], 'CC=/usr/bin/gcc-5 CXX=/usr/bin/g++-5 cmake') ) # Install apt dependencies (if appropriate) - bash: sudo apt install -y $(AptDependencies) retryCountOnTaskFailure: 10 condition: and(succeededOrFailed(), ne(variables['AptDependencies'], '')) displayName: Install dependencies from apt - template: /eng/pipelines/templates/steps/vcpkg.yml - script: | dotnet tool install -g dotnet-reportgenerator-globaltool dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools displayName: Install coverage tools # CODE_COVERAGE variable is '' (do-not-generate) in all matrix but linux-gcc # It is 'enabled' by default on linux-gcc but it can be opt-out by each pipeline (disabled) condition: and(succeededOrFailed(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) - template: /eng/pipelines/templates/steps/cmake-build.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} GenerateArgs: $(CmakeArgs) VcpkgArgs: "$(VcpkgArgs)" BuildArgs: "$(BuildArgs)" Env: "$(CmakeEnvArg)" - template: /eng/pipelines/templates/steps/show-failure-logs.yml - template: /eng/common/TestResources/build-test-resource-config.yml parameters: SubscriptionConfiguration: ${{ parameters.CloudConfig.SubscriptionConfiguration }} SubscriptionConfigurations: ${{ parameters.CloudConfig.SubscriptionConfigurations }} EnvVars: Pool: $(Pool) ${{ insert }}: ${{ parameters.EnvVars }} ${{ if parameters.UseFederatedAuth }}: SubscriptionConfigurationFilePaths: ${{ parameters.CloudConfig.SubscriptionConfigurationFilePaths }} - template: /eng/common/TestResources/deploy-test-resources.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} Location: ${{ coalesce(parameters.Location, parameters.CloudConfig.Location) }} SubscriptionConfiguration: $(SubscriptionConfiguration) EnvVars: Pool: $(Pool) ${{ insert }}: ${{ parameters.EnvVars }} UseFederatedAuth: ${{ parameters.UseFederatedAuth }} ServiceConnection: ${{ parameters.CloudConfig.ServiceConnection }} - template: /eng/common/testproxy/test-proxy-tool.yml parameters: runProxy: false - ${{ parameters.PreTestSteps }} - ${{ if parameters.UseFederatedAuth }}: - task: AzurePowerShell@5 displayName: ctest condition: and(succeeded(), ne(variables['RunSamples'], '1')) inputs: azureSubscription: ${{ parameters.CloudConfig.ServiceConnection }} azurePowerShellVersion: LatestVersion ScriptType: InlineScript Inline: | $account = (Get-AzContext).Account $env:AZURESUBSCRIPTION_CLIENT_ID = $account.Id $env:AZURESUBSCRIPTION_TENANT_ID = $account.Tenants ctest $(WindowsCtestConfig) -V --tests-regex "${{ parameters.CtestRegex }}" --no-compress-output -T Test exit $LASTEXITCODE workingDirectory: build env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) ${{ insert }}: ${{ parameters.EnvVars }} - ${{ else }}: # For non multi-config generator use the same build configuration to run tests # We don't need to set it to invoke ctest # Visual Studio generator used in CI is a multi-config generator. # As such, it requires the configuration argument for building and invoking ctest - bash: | export AZURE_CLIENT_ID=$(${{parameters.ServiceDirectory}}_CLIENT_ID) export AZURE_TENANT_ID=$(${{parameters.ServiceDirectory}}_TENANT_ID) export AZURE_CLIENT_SECRET=$(${{parameters.ServiceDirectory}}_CLIENT_SECRET) ctest $(WindowsCtestConfig) -V --tests-regex "${{ parameters.CtestRegex }}" --no-compress-output -T Test workingDirectory: build displayName: ctest # Runs only if test-resources are happily deployed. # unit-tests runs for those configs where samples are not ran. # This enables to run tests and samples at the same time as different matrix configuration. # Then unit-tests runs, samples should not run. condition: and(succeeded(), ne(variables['RunSamples'], '1')) env: ${{ insert }}: ${{ parameters.EnvVars }} - ${{ parameters.PostTestSteps }} - task: PublishTestResults@2 inputs: testResultsFormat: cTest testResultsFiles: Testing/*/Test.xml testRunTitle: $(Agent.JobName) searchFolder: build mergeTestResults: true publishRunAttachments: true displayName: Publish test results # this step only makes sense when ctest has run condition: and(succeededOrFailed(), ne(variables['RunSamples'], '1')) - ${{ if parameters.UseFederatedAuth }}: # Running Samples step. # Will run samples described on a file name [service]-samples.txt within the build directory. # For example keyvault-samples.txt. # The file is written by CMake during configuration when building samples. - task: AzureCLI@2 displayName: "Run Samples for : ${{ parameters.ServiceDirectory }}" condition: and(succeeded(), eq(variables['RunSamples'], '1')) inputs: azureSubscription: ${{ parameters.CloudConfig.ServiceConnection }} scriptType: 'pscore' scriptLocation: 'inlineScript' inlineScript: | if (Test-Path -Path "${{ parameters.ServiceDirectory }}-samples.txt") { $samples = Get-Content "${{ parameters.ServiceDirectory }}-samples.txt" foreach ($sample in $samples) { Write-Host "**********Running sample: $sample" & "$sample" if ($LASTEXITCODE) { Write-Host "Sample failed with exit code $LASTEXITCODE" exit 1 } Write-Host "**********Sample completed" } } workingDirectory: build useGlobalConfig: true env: ${{ insert }}: ${{ parameters.EnvVars }} # Set fake authority host to ensure Managed Identity fail for Default Azure Credential # so "execute samples" step correctly picks up Azure CLI credential. AZURE_POD_IDENTITY_AUTHORITY_HOST: 'FakeAuthorityHost' AZURE_SDK_IDENTITY_SAMPLE_SERVICE_GETTOKEN: 'disable' - ${{ else }}: - bash: | IFS=$'\n' if [[ -f "./${{ parameters.ServiceDirectory }}-samples.txt" ]]; then for sample in `cat ./${{ parameters.ServiceDirectory }}-samples.txt` do export AZURE_CLIENT_ID=$(${{parameters.ServiceDirectory}}_CLIENT_ID) export AZURE_TENANT_ID=$(${{parameters.ServiceDirectory}}_TENANT_ID) export AZURE_CLIENT_SECRET=$(${{parameters.ServiceDirectory}}_CLIENT_SECRET) echo "**********Running sample: ${sample}" bash -c "$sample" status=$? if [[ $status -eq 0 ]]; then echo "*********Sample completed*********" else echo "*Sample returned a failed code: $status" exit 1 fi done fi workingDirectory: build displayName: "Run Samples for : ${{ parameters.ServiceDirectory }}" condition: and(succeeded(), eq(variables['RunSamples'], '1')) env: ${{ insert }}: ${{ parameters.EnvVars }} # Set fake authority host to ensure Managed Identity fail for Default Azure Credential # so "execute samples" step correctly picks up Azure CLI credential. AZURE_POD_IDENTITY_AUTHORITY_HOST: 'FakeAuthorityHost' AZURE_SDK_IDENTITY_SAMPLE_SERVICE_GETTOKEN: 'disable' # Make coverage targets (specified in coverage_targets.txt) and assemble # coverage report - bash: | make `cat ${{ parameters.ServiceDirectory }}-targets-coverage.txt` ../tools/reportgenerator "-reports:${{ parameters.CoverageReportPath }}" "-targetdir:." "-reporttypes:Cobertura" workingDirectory: build displayName: Generate Code Coverage Data condition: and(succeeded(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: Cobertura summaryFileLocation: '$(Build.SourcesDirectory)/**/Cobertura.xml' displayName: Publish Code Coverage to DevOps condition: and(succeededOrFailed(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) - template: /eng/common/TestResources/remove-test-resources.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} SubscriptionConfiguration: $(SubscriptionConfiguration) UseFederatedAuth: ${{ parameters.UseFederatedAuth }} EnvVars: ${{ parameters.EnvVars }} ServiceConnection: ${{ parameters.CloudConfig.ServiceConnection }}