Skip to content

Commit cb4638b

Browse files
Fix benchmark CI workflow and format code
- Remove redundant Python transformation script (Rust already generates GitHub format) - Fix JSON parsing in benchmark summary display - Improve file copying in workflow - Run cargo fmt on all code
1 parent 8280fda commit cb4638b

2 files changed

Lines changed: 95 additions & 25 deletions

File tree

.github/workflows/benchmark.yml

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ on:
44
push:
55
branches: [ main ]
66
paths:
7-
- 'crates/rust-hsm-cli/src/pkcs11/benchmark.rs'
7+
- 'crates/rust-hsm-cli/src/**'
8+
- 'crates/rust-hsm-core/src/**'
89
- '.github/workflows/benchmark.yml'
910
schedule:
1011
# Run weekly on Sunday at 2am UTC
@@ -17,6 +18,8 @@ jobs:
1718
runs-on: ubuntu-latest
1819
steps:
1920
- uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0 # Fetch full history for gh-pages branch creation
2023

2124
- name: Set up Docker Buildx
2225
uses: docker/setup-buildx-action@v3
@@ -27,61 +30,126 @@ jobs:
2730
- name: Start container
2831
run: docker compose up -d
2932

30-
- name: Wait for container
31-
run: sleep 5
33+
- name: Wait for container to be ready
34+
run: sleep 10
3235

33-
- name: Initialize test token
36+
- name: Initialize test token using rust-hsm-cli
3437
run: |
35-
docker exec rust-hsm-app softhsm2-util --init-token \
36-
--slot 0 --label BENCH_TOKEN \
37-
--so-pin 12345678 --pin 123456
38+
docker exec rust-hsm-app rust-hsm-cli init-token \
39+
--label BENCH_TOKEN --so-pin 12345678
40+
docker exec rust-hsm-app rust-hsm-cli init-pin \
41+
--label BENCH_TOKEN --so-pin 12345678 --user-pin 123456
3842
39-
- name: Run benchmark
43+
- name: Run benchmark with rust-hsm-cli
4044
run: |
4145
docker exec rust-hsm-app rust-hsm-cli benchmark \
4246
--label BENCH_TOKEN --user-pin 123456 \
43-
--iterations 1000 --warmup 50 \
44-
--format json --output /app/benchmark-results.json
47+
--iterations 50 --warmup 5 \
48+
--format json --output /app/benchmark-results.json \
49+
--data-sizes
4550
46-
- name: Copy results
51+
- name: Copy benchmark results
4752
run: |
53+
# Copy the main results file
4854
docker cp rust-hsm-app:/app/benchmark-results.json ./benchmark-results.json
55+
56+
# Copy GitHub Actions format file (automatically generated by rust-hsm-cli)
4957
docker cp rust-hsm-app:/app/benchmark-results-gh.json ./benchmark-results-gh.json
58+
59+
# Verify files exist and show samples
60+
echo "=== Main benchmark results ==="
61+
head -20 benchmark-results.json
62+
63+
echo "=== GitHub Actions format ==="
64+
head -20 benchmark-results-gh.json
65+
66+
- name: Setup gh-pages branch if needed
67+
run: |
68+
git config --global user.name 'github-action-benchmark'
69+
git config --global user.email 'github@users.noreply.github.com'
70+
71+
# Check if gh-pages exists remotely
72+
if ! git ls-remote --exit-code --heads origin gh-pages > /dev/null 2>&1; then
73+
echo "Creating gh-pages branch..."
74+
git checkout --orphan gh-pages
75+
git rm -rf .
76+
echo "# HSM Performance Benchmarks" > README.md
77+
echo "" >> README.md
78+
echo "Automated benchmark results for rust-hsm PKCS#11 operations." >> README.md
79+
echo "" >> README.md
80+
echo "Generated by [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark)." >> README.md
81+
git add README.md
82+
git commit -m "Initialize gh-pages branch for benchmarks"
83+
git push origin gh-pages
84+
git checkout main
85+
echo "✓ Created gh-pages branch"
86+
else
87+
echo "✓ gh-pages branch already exists"
88+
fi
5089
5190
- name: Store benchmark result
5291
uses: benchmark-action/github-action-benchmark@v1
5392
with:
54-
tool: 'customBiggerIsBetter'
93+
name: 'HSM Performance Benchmarks'
94+
tool: 'customBiggerIsBetter' # ops/sec - higher is better
5595
output-file-path: benchmark-results-gh.json
5696
github-token: ${{ secrets.GITHUB_TOKEN }}
5797
auto-push: true
5898
# Show alert with commit comment on detecting possible performance regression
59-
alert-threshold: '110%'
99+
alert-threshold: '150%' # Alert if performance degrades by 50%
60100
comment-on-alert: true
61101
fail-on-alert: false
62102
alert-comment-cc-users: '@testingapisname'
63103

64-
- name: Upload benchmark results
104+
- name: Upload benchmark results as artifacts
65105
uses: actions/upload-artifact@v4
66106
with:
67107
name: benchmark-results
68-
path: benchmark-results.json
108+
path: |
109+
benchmark-results.json
110+
benchmark-results-gh.json
111+
112+
- name: Display benchmark summary
113+
run: |
114+
echo "=== Benchmark Summary ==="
115+
if [ -f benchmark-results.json ]; then
116+
jq -r '.results[]? | "\(.result.name): \(.ops_per_sec | round) ops/sec"' benchmark-results.json || echo "Could not parse results"
117+
else
118+
echo "No benchmark results file found"
119+
fi
69120
70121
- name: Comment PR with results
71122
if: github.event_name == 'pull_request'
72123
uses: actions/github-script@v7
73124
with:
74125
script: |
75126
const fs = require('fs');
127+
128+
if (!fs.existsSync('benchmark-results.json')) {
129+
console.log('No benchmark results file found');
130+
return;
131+
}
132+
76133
const results = JSON.parse(fs.readFileSync('benchmark-results.json', 'utf8'));
77134
78135
let comment = '## 📊 Benchmark Results\n\n';
79-
comment += '| Operation | Ops/sec | Avg (ms) | P95 (ms) |\n';
80-
comment += '|-----------|---------|----------|----------|\n';
136+
comment += '| Operation | Ops/sec | Avg (ms) | P95 (ms) | P99 (ms) |\n';
137+
comment += '|-----------|---------|----------|----------|----------|\n';
81138
82-
results.results.forEach(r => {
83-
comment += `| ${r.name} | ${r.ops_per_sec.toFixed(1)} | ${r.avg_latency_ms.toFixed(2)} | ${r.p95_ms.toFixed(2)} |\n`;
84-
});
139+
if (results.results) {
140+
results.results.forEach(r => {
141+
const name = r.result?.name || 'Unknown';
142+
const ops = (r.ops_per_sec || 0).toFixed(1);
143+
const avg = (r.avg_latency_ms || 0).toFixed(2);
144+
const p95 = (r.p95_ms || 0).toFixed(2);
145+
const p99 = (r.p99_ms || 0).toFixed(2);
146+
comment += `| ${name} | ${ops} | ${avg} | ${p95} | ${p99} |\n`;
147+
});
148+
} else {
149+
comment += '| No results available | - | - | - | - |\n';
150+
}
151+
152+
comment += '\n📈 [View historical results](https://testingapisname.github.io/rust-hsm/dev/bench/)\n';
85153
86154
github.rest.issues.createComment({
87155
issue_number: context.issue.number,
@@ -92,4 +160,6 @@ jobs:
92160
93161
- name: Stop container
94162
if: always()
95-
run: docker compose down
163+
run: |
164+
docker compose down
165+
docker volume prune -f

crates/rust-hsm-core/src/pkcs11/benchmark.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ fn output_json(
11461146
let mut file = File::create(path)?;
11471147
file.write_all(json.as_bytes())?;
11481148
eprintln!("✓ Benchmark results written to {}", path);
1149-
1149+
11501150
// Also generate GitHub Actions format (array of name/value/unit)
11511151
if path.ends_with(".json") {
11521152
let gh_path = path.replace(".json", "-gh.json");
@@ -1168,7 +1168,7 @@ fn output_github_format(results: &[BenchmarkResult], path: &str) -> Result<()> {
11681168
value: f64,
11691169
unit: String,
11701170
}
1171-
1171+
11721172
let gh_results: Vec<GitHubBenchmark> = results
11731173
.iter()
11741174
.map(|r| GitHubBenchmark {
@@ -1177,11 +1177,11 @@ fn output_github_format(results: &[BenchmarkResult], path: &str) -> Result<()> {
11771177
unit: "ops/sec".to_string(),
11781178
})
11791179
.collect();
1180-
1180+
11811181
let json = serde_json::to_string_pretty(&gh_results)?;
11821182
let mut file = File::create(path)?;
11831183
file.write_all(json.as_bytes())?;
1184-
1184+
11851185
Ok(())
11861186
}
11871187

0 commit comments

Comments
 (0)