Skip to content

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 result parsing with improved multi-package scenario handling
  • Tests

    • Added comprehensive test suite covering various Go output formats and edge cases
  • Chores

    • Added npm test script shortcut
    • Updated configuration and ignore patterns

✏️ Tip: You can customize this high-level summary in your review settings.

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

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

Adds extractGoResult and refactors Go benchmark parsing to a section-based approach with package-aware naming; updates config and scripts, adds Go benchmark test fixtures, and introduces comprehensive tests for single/multi-package and edge cases.

Changes

Cohort / File(s) Summary
Config & Scripts
/.gitignore, package.json, /.coderabbit.yaml
Added /.ai to .gitignore, added "test-s": "jest --silent" script to package.json, and added .coderabbit.yaml (pre-merge check setting).
Parser Logic
src/extract.ts
Exports extractGoResult; refactors parsing to section-based grouping by pkg: markers, introduces chunkPairs helper, enhanced regex-driven metric extraction, and conditional package suffixing for benchmark names.
Test Data
test/data/extract/go_fiber_duplicate_names_output.txt, test/data/extract/go_single_package_output.txt
Added multi-package and single-package Go benchmark output samples used by new tests.
Tests
test/extract.spec.ts, test/extractGoResult.spec.ts
Extended extract.spec.ts with two Go cases; added extractGoResult.spec.ts containing comprehensive tests covering single/multi-package parsing, multiple metrics, edge cases, and Windows line endings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

"I hopped through lines and parsed the stream,
Benchmarks and packages, a data dream.
Names now wear their package bow,
Metrics paired, all in a row.
— 🐇"

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: exporting extractGoResult and implementing package name inclusion for duplicate benchmark names across multiple packages.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
🧪 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.12%. Comparing base (2e6f4e3) to head (3d0659f).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #330      +/-   ##
==========================================
- Coverage   89.14%   89.12%   -0.03%     
==========================================
  Files          16       16              
  Lines         949      947       -2     
  Branches      200      201       +1     
==========================================
- Hits          846      844       -2     
  Misses         99       99              
  Partials        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 added 5 commits January 30, 2026 21:18
* 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 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.

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