Skip to content

Comments

fix: include package name for duplicate bench names [#264]#330

Merged
ktrz merged 10 commits intomasterfrom
ktrz/264/golang-package-name-in-bench-name
Feb 5, 2026
Merged

fix: include package name for duplicate bench names [#264]#330
ktrz merged 10 commits intomasterfrom
ktrz/264/golang-package-name-in-bench-name

Conversation

@ktrz
Copy link
Member

@ktrz ktrz commented Jan 8, 2026

Problem Solved

When running Go benchmarks across multiple packages that have benchmarks with the same name (e.g., BenchmarkAppendMsgitem in both middleware/cache and middleware/csrf), the results would collide since they shared identical names. This made it impossible to track them separately over time.

Solution

Benchmark names are now disambiguated by appending the package name in parentheses when multiple packages are detected in the output:

  • BenchmarkFooBenchmarkFoo (github.com/example/package1)
  • BenchmarkFooBenchmarkFoo (github.com/example/package2)

Backward compatible: When only a single package exists (or no pkg: lines), names remain unchanged.

Code Changes

src/extract.ts (+33/-28 lines)

  • Refactored extractGoResult() to detect multiple packages by parsing pkg: lines
  • Split output into sections by package context
  • Added chunkPairs() helper function for cleaner [value, unit] pair extraction
  • Changed from imperative loops to a functional, chained flatMap approach
  • Exported extractGoResult for direct unit testing

New Test Coverage

test/extractGoResult.spec.ts (254 lines)

Comprehensive unit tests covering:

  • Basic benchmark extraction (with/without processor count)
  • Multiple metrics per benchmark
  • Single package backward compatibility
  • Multiple package disambiguation (the main fix)
  • Edge cases (orphan benchmarks, empty input, Windows line endings)

Test fixtures added

  • go_fiber_duplicate_names_output.txt - Real-world example with duplicate names across cache and csrf packages
  • go_single_package_output.txt - Single package output for backward compatibility testing

Summary by CodeRabbit

  • New Features

    • Enhanced Go benchmark extraction to support multiple packages with contextual naming.
  • Tests

    • Added comprehensive test coverage for Go benchmark parsing across single and multi-package scenarios.
  • Chores

    • Added new test script for silent test execution.
    • Added code review configuration settings.

@ktrz ktrz self-assigned this Jan 8, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

Enhanced Go benchmark result extraction to handle multiple packages. The extractGoResult function now parses benchmark output by sections marked with "pkg:" identifiers, conditionally appending package suffixes to benchmark names when multiple packages are detected. Extensive test coverage validates single-package backward compatibility and multi-package disambiguation scenarios.

Changes

Cohort / File(s) Summary
Core Parsing Logic
src/extract.ts
Refactored extractGoResult from single-pass to section-based parsing, preserving package context. Adds chunkPairs helper for value/unit pairing and conditional package suffix logic for benchmark names when multiple packages exist.
Test Coverage
test/extractGoResult.spec.ts
Comprehensive new test suite (290 lines) validating benchmark extraction across single/multiple packages, edge cases (orphan benchmarks, Windows line endings), and correct package-suffix behavior.
Test Data
test/data/extract/go_fiber_duplicate_names_output.txt, test/data/extract/go_single_package_output.txt
New test fixtures demonstrating multi-package and single-package Go benchmark output formats.
Test References
test/extract.spec.ts
Added two normalCases entries referencing new Go test data files.
Configuration
package.json, .coderabbit.yaml
Added test-s script for silent Jest runs; disabled docstring pre-merge checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hop through packages with glee!
Sections parse and context flows free,
Suffixes dance when multiples meet,
Benchmarks bundled, parsing complete!

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: include package name for duplicate bench names [#264]' directly and clearly summarizes the main change: adding package names to disambiguate duplicate Go benchmark names across multiple packages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ktrz/264/golang-package-name-in-bench-name

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.13%. Comparing base (45cba09) to head (c68fc65).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #330      +/-   ##
==========================================
- Coverage   89.14%   89.13%   -0.02%     
==========================================
  Files          16       16              
  Lines         949      948       -1     
  Branches      200      201       +1     
==========================================
- Hits          846      845       -1     
+ Misses        103       99       -4     
- Partials        0        4       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ktrz ktrz marked this pull request as ready for review January 30, 2026 21:28
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/extract.ts`:
- Around line 399-400: The chunkPairs function currently drops the last token
when given an odd-length arr; add a validation at the top of chunkPairs to check
arr.length % 2 === 0 and throw a descriptive error (including arr length or the
offending token) when odd so malformed Go output surfaces immediately; keep the
rest of the logic intact (Array.from(...)) and ensure callers can catch this
exception if necessary.
🧹 Nitpick comments (1)
src/extract.ts (1)

346-388: Normalize and dedupe package names before deciding to suffix.

hasMultiplePackages currently counts sections rather than unique package names, and pkg isn’t trimmed. If output concatenates multiple runs of the same package (or includes trailing whitespace), names will be suffixed even though there’s only one unique package, changing the backward‑compat behavior.

🛠️ Suggested tweak (trim + unique package counting)
-    const sections = output.split(/^pkg:\s+/m).map((section, index) => {
+    const sections = output.split(/^pkg:\s+/m).map((section, index) => {
         if (index === 0) return { pkg: '', lines: section.split(/\r?\n/g) };
         const [pkg, ...rest] = section.split(/\r?\n/g);
-        return { pkg, lines: rest };
+        return { pkg: pkg.trim(), lines: rest };
     });
 
-    const hasMultiplePackages = sections.filter((s) => s.pkg).length > 1;
+    const packageNames = new Set(sections.map((s) => s.pkg).filter(Boolean));
+    const hasMultiplePackages = packageNames.size > 1;

Comment on lines +399 to +400
function chunkPairs(arr: string[]): Array<[string, string]> {
return Array.from({ length: Math.floor(arr.length / 2) }, (_, i) => [arr[i * 2], arr[i * 2 + 1]]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard against odd-length value/unit sequences.

chunkPairs silently drops the last token when arr.length is odd, which can yield partial or misleading metrics on malformed input. Consider throwing to surface invalid Go output early.

🛡️ Suggested validation
 function chunkPairs(arr: string[]): Array<[string, string]> {
+    if (arr.length % 2 !== 0) {
+        throw new Error(
+            `Malformed Go benchmark metrics (expected value/unit pairs, got ${arr.length} fields): ${arr.join(' ')}`
+        );
+    }
     return Array.from({ length: Math.floor(arr.length / 2) }, (_, i) => [arr[i * 2], arr[i * 2 + 1]]);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function chunkPairs(arr: string[]): Array<[string, string]> {
return Array.from({ length: Math.floor(arr.length / 2) }, (_, i) => [arr[i * 2], arr[i * 2 + 1]]);
function chunkPairs(arr: string[]): Array<[string, string]> {
if (arr.length % 2 !== 0) {
throw new Error(
`Malformed Go benchmark metrics (expected value/unit pairs, got ${arr.length} fields): ${arr.join(' ')}`
);
}
return Array.from({ length: Math.floor(arr.length / 2) }, (_, i) => [arr[i * 2], arr[i * 2 + 1]]);
}
🤖 Prompt for AI Agents
In `@src/extract.ts` around lines 399 - 400, The chunkPairs function currently
drops the last token when given an odd-length arr; add a validation at the top
of chunkPairs to check arr.length % 2 === 0 and throw a descriptive error
(including arr length or the offending token) when odd so malformed Go output
surfaces immediately; keep the rest of the logic intact (Array.from(...)) and
ensure callers can catch this exception if necessary.

NachoVazquez
NachoVazquez previously approved these changes Feb 2, 2026
Copy link

@NachoVazquez NachoVazquez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just have a question, but it looks good otherwise!

ktrz added 10 commits February 5, 2026 13:28
* add test file with a snapshot

* add test output
* add test for backwards compatibility

* add test output
* initial implementation

* add test output
Replace index arithmetic (i * 2, i * 2 + 1) with explicit chunking using
a purpose-built chunkPairs function. This makes the [value, unit] pair
structure obvious through destructuring and isolates the index math.
@ktrz ktrz force-pushed the ktrz/264/golang-package-name-in-bench-name branch from 3d0659f to c68fc65 Compare February 5, 2026 12:41
Copy link

@NachoVazquez NachoVazquez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great 🚀

@ktrz ktrz merged commit 7e8372b into master Feb 5, 2026
29 checks passed
@ktrz ktrz deleted the ktrz/264/golang-package-name-in-bench-name branch February 5, 2026 12:48
ktrz added a commit that referenced this pull request Feb 24, 2026
Users who worked around #264 by including package name in benchmark
names would get duplicate suffixes after #330. This detects when a
benchmark name already contains a reference to the package path
(full path, normalized with underscores, or ≥2 trailing segments)
and skips adding the suffix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants