Skip to content

๐Ÿ› [Bug]: Test_ToUpper/non-ascii Fails in CI with -race Possibly Due to testing.AllocsPerRun Misreporting Allocationsย #141

@sixcolors

Description

@sixcolors

Bug Description

The Test_ToUpper/non-ascii test in the utils package fails in CI when run with gotestsum -f testname -- ./... -race -count=1 -shuffle=on, reporting 4 allocations instead of the expected 0 for the input "ยตรŸรครถรผ". This failure does not occur locally, with or without -race, suggesting that the CI environment and race detector are causing testing.AllocsPerRun to misreport allocations, possibly exacerbated by gotestsum's interaction with GOMAXPROCS.

Details

  • Test Case: The non-ascii test case expects ToUpper to return the input "ยตรŸรครถรผ" unchanged with zero allocations (upperNoConv: true), as non-ASCII bytes map to themselves in toUpperTable.
  • Failure: In CI, with -race -shuffle=on, testing.AllocsPerRun reports 4 allocations, failing the require.Zero assertion:
    === FAIL: . Test_ToUpper/non-ascii (0.01s)
        strings_test.go:93: 
             Error Trace: /Users/runner/work/utils/utils/strings_test.go:93
             Error: Should be zero, but was 4
             Test: Test_ToUpper/non-ascii
             Messages: ToUpper should not allocate for non-ascii
    
  • Environment: The failure is specific to CI (e.g., GitHub Actions) with -race and -shuffle=on (seed: 1752474430640501000). Locally, the test passes with or without -race.
  • Suspected Cause: The Go race detector introduces additional allocations (e.g., 8 bytes per defer and recover statement, as per Go Race Detector Documentation), which are captured by testing.AllocsPerRun. Additionally, gotestsum may interfere with testing.AllocsPerRun's setting of GOMAXPROCS to 1, potentially causing allocation misreporting in CI. This is supported by Go issues like #8734 and #5000, which discuss allocation counting inconsistencies.
  • Impact: The test failure is likely a false positive due to race detector overhead and/or gotestsum interactions, not a bug in ToUpper, as the function correctly avoids allocations for non-ASCII inputs.

Steps to Reproduce

  1. Run tests in CI with:
    gotestsum -f testname -- ./... -race -count=1 -shuffle=1752474430640501000 -v
  2. Observe the failure in Test_ToUpper/non-ascii, reporting 4 allocations instead of 0.

Expected Behavior

  • Test_ToUpper/non-ascii should pass with zero allocations, as ToUpper returns the input string unchanged for "ยตรŸรครถรผ".
  • Allocation tests should be reliable even with -race and gotestsum.

Actual Behavior

  • In CI with -race, testing.AllocsPerRun reports 4 allocations, causing the test to fail.

Proposed Debugging

Add a diagnostic test to log allocation details for debugging:

func Test_ToUpper_NonASCII_Allocations(t *testing.T) {
    t.Parallel()
    input := "ยตรŸรครถรผ"
    allocs := testing.AllocsPerRun(100, func() {
        result := ToUpper(input)
        if result != input {
            t.Errorf("ToUpper modified input: got %v, want %v", result, input)
        }
    })
    t.Logf("Bytes: %v", []byte(input))
    t.Logf("Allocations for ToUpper(ยตรŸรครถรผ): %f", allocs)
    if os.Getenv("RACE") != "1" {
        require.Zero(t, allocs, "ToUpper should not allocate for non-ascii")
    }
}

Alternatively, investigate if gotestsum affects GOMAXPROCS settings by running tests without gotestsum:

go test -race -count=1 -shuffle=1752474430640501000 -v ./...

Additional Notes

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions