Skip to content

Commit 77a0a34

Browse files
authored
Add benchmark result comparison support (#10753)
* Tag a build as baseline. Download a baseline and do a comparison if one is present. * fix whitespace * Change branch to release/4.x * Optimizations based on PR feedback.
1 parent a3d1338 commit 77a0a34

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

eng/ci/host.benchmarks.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ resources:
2222
type: git
2323
name: engineering
2424
ref: refs/tags/release
25+
pipelines:
26+
- pipeline: BaselineResult
27+
source: host.benchmarks
28+
tags:
29+
- AzFunc.Perf.Baseline
2530

2631
variables:
2732
- template: /eng/ci/templates/variables/benchmarks.yml@self

eng/ci/templates/official/jobs/run-benchmarks.yml

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,29 @@ jobs:
1616
variables:
1717
runDescription: ${{ parameters.description }}
1818
functionApp: ${{ parameters.functionAppName }}
19+
benchmarkArtifactName: benchmark_results_$(functionApp)
1920
functionAppOutputPath: $(Build.ArtifactStagingDirectory)/FunctionApps/$(functionApp)
20-
benchmarkResultsJsonPath: "$(Build.ArtifactStagingDirectory)/BenchmarkResults/$(buildNumber)_$(functionApp).json"
21+
benchmarkResultsJsonPath: $(Build.ArtifactStagingDirectory)/BenchmarkResults/$(Build.BuildNumber)_$(functionApp).json
2122
functionsWorkerRuntime: 'dotnet-isolated'
22-
crankAgentUrl: "http://localhost:5010" # Default crank agent URL.
23+
crankAgentUrl: "http://localhost:5010" # Default crank agent URL.
2324
configFilePath: "./eng/perf/http.benchmarks.yml"
2425
hostLocation: "./../../"
26+
baselineBenchmarkResultFilePath: ''
27+
baselineBenchmarkResultsDownloadDir: $(Pipeline.Workspace)/BenchmarkBaselineResult
2528

2629
templateContext:
30+
inputs:
31+
- input: pipelineArtifact
32+
artifactName: $(benchmarkArtifactName)
33+
pipeline: BaselineResult
34+
targetPath: $(baselineBenchmarkResultsDownloadDir)
35+
2736
outputParentDirectory: $(Build.ArtifactStagingDirectory)
2837
outputs:
2938
- output: pipelineArtifact
3039
displayName: Publish benchmark results
3140
path: $(benchmarkResultsJsonPath)
32-
artifact: 'BenchmarkResults_$(functionApp)'
41+
artifact: $(benchmarkArtifactName)
3342

3443
steps:
3544

@@ -46,12 +55,8 @@ jobs:
4655
- script: dotnet tool install -g Microsoft.Crank.Agent --version "0.2.0-*"
4756
displayName: Install Microsoft.Crank.Agent tool
4857

49-
- task: PowerShell@2
50-
displayName: Start crank-agent
51-
inputs:
52-
targetType: 'inline'
53-
script: |
54-
Start-Process powershell -ArgumentList '-NoExit', '-Command', 'crank-agent'
58+
- pwsh: Start-Process powershell -ArgumentList '-NoExit', '-Command', 'crank-agent'
59+
displayName: 'Start crank-agent'
5560

5661
- task: CopyFiles@2
5762
displayName: Copy benchmark apps to temp location
@@ -75,12 +80,8 @@ jobs:
7580
- script: dotnet tool install -g Microsoft.Crank.Controller --version "0.2.0-*"
7681
displayName: Install Microsoft.Crank.Controller
7782

78-
- task: PowerShell@2
79-
displayName: Run crank-controller
80-
inputs:
81-
targetType: 'inline'
82-
script: |
83-
$crankArgs = "--config $(configFilePath) --scenario hellohttp --profile win2022 --load.options.reuseBuild true --description `"$(runDescription)`" --command-line-property --no-metadata --no-measurements --json $(benchmarkResultsJsonPath) --property sourceVersion=$(sourceVersion) --property buildNumber=$(buildNumber) --property buildId=$(buildId) --variable FunctionsWorkerRuntime=$(functionsWorkerRuntime) --variable HostLocation=$(hostLocation) --variable FunctionAppPath=$(functionAppOutputPath)"
83+
- pwsh: |
84+
$crankArgs = "--config $(configFilePath) --scenario hellohttp --profile win2022 --load.options.reuseBuild true --description `"$(runDescription)`" --command-line-property --no-measurements --json $(benchmarkResultsJsonPath) --property sourceVersion=$(Build.SourceVersion) --property buildNumber=$(Build.BuildNumber) --property buildId=$(Build.BuildId) --property sourceBranch=$(Build.SourceBranch) --variable FunctionsWorkerRuntime=$(functionsWorkerRuntime) --variable HostLocation=$(hostLocation) --variable FunctionAppPath=$(functionAppOutputPath)"
8485
$crankArgs += " ${{ parameters.additionalCrankArgs }}"
8586
$command = "crank $crankArgs"
8687
@@ -90,13 +91,40 @@ jobs:
9091
9192
Write-Host "Running command: $command"
9293
Invoke-Expression $command
94+
displayName: 'Run Benchmark'
9395
94-
- task: PowerShell@2
95-
displayName: Functions host logs
96-
inputs:
97-
targetType: 'inline'
98-
script: |
99-
$url = "$(crankAgentUrl)/jobs/1/output"
100-
Write-Host "Making GET request to: $url to get logs"
101-
$response = Invoke-WebRequest -Uri $url -Method GET -UseBasicParsing
102-
Write-Host $response.Content
96+
# Retrieve function host logs
97+
- pwsh: |
98+
$url = "$(crankAgentUrl)/jobs/1/output"
99+
Write-Host "Fetching logs from: $url"
100+
$response = Invoke-WebRequest -Uri $url -Method GET -UseBasicParsing
101+
Write-Host $response.Content
102+
displayName: 'Fetch Function Host Logs'
103+
104+
# Tag the build as a baseline if it originates from the specified branch.
105+
# Baseline builds serve as reference points for performance comparisons in future builds.
106+
# The tag added here will help identify these builds in the pipeline.
107+
- pwsh: |
108+
Write-Host "##vso[build.addbuildtag]$(benchmarkBaselineTagName)"
109+
condition: and(succeeded(), eq(variables['Build.SourceBranch'], variables['benchmarkBaselineBranch']))
110+
displayName: 'Tag Build as Baseline'
111+
112+
# Locate baseline benchmark result file from the downloaded baseline artifact.
113+
- pwsh: |
114+
$baselineDir = "$(baselineBenchmarkResultsDownloadDir)"
115+
$fileNamePattern = "*_$(functionApp).json"
116+
$baselineFile = Get-ChildItem -Path $baselineDir -Filter $fileNamePattern | Select-Object -First 1
117+
118+
if ($baselineFile) {
119+
Write-Host "Found baseline benchmark result file: $($baselineFile.FullName)"
120+
Write-Host "##vso[task.setvariable variable=baselineBenchmarkResultFilePath]$($baselineFile.FullName)"
121+
} else {
122+
Write-Host "No baseline benchmark result file found."
123+
}
124+
displayName: 'Set Baseline Benchmark Result File Path'
125+
126+
# Compare results with baseline
127+
- pwsh: |
128+
crank compare "$(baselineBenchmarkResultFilePath)" "$(benchmarkResultsJsonPath)"
129+
condition: and(succeeded(), ne(variables['baselineBenchmarkResultFilePath'], ''))
130+
displayName: 'Compare Results with Baseline'
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
variables:
2-
- name: buildId
3-
value: $(Build.BuildId)
4-
- name: buildNumber
5-
value: $(Build.BuildNumber)
6-
- name: sourceVersion
7-
value: $(Build.SourceVersion)
82
- name: storeBenchmarkResultsInDatabase
9-
value: ${{ eq(variables['Build.Reason'], 'Schedule') }}
3+
value: ${{ eq(variables['Build.Reason'], 'Schedule') }}
4+
- name: benchmarkBaselineBranch
5+
value: refs/heads/release/4.x
6+
- name: benchmarkBaselineTagName
7+
value: AzFunc.Perf.Baseline

0 commit comments

Comments
 (0)