...

Text file src/cmd/go/testdata/script/test_cache_coverpkg_bug.txt

Documentation: cmd/go/testdata/script

     1# Test for bug where cached coverage profiles with -coverpkg can contain
     2# outdated line references when source files are modified.
     3# This reproduces the issue where coverage data from cache may reference
     4# lines that no longer exist in the updated source files.
     5
     6[short] skip
     7[GODEBUG:gocacheverify=1] skip
     8
     9# We're testing cache behavior, so start with a clean GOCACHE.
    10env GOCACHE=$WORK/cache
    11
    12# Create a project structure with multiple packages
    13# proj/
    14#   some_func.go
    15#   some_func_test.go
    16#   sub/
    17#     sub.go
    18#     sub_test.go
    19#   sum/
    20#     sum.go
    21
    22# Switch to the proj directory
    23cd proj
    24
    25# Run tests with -coverpkg to collect coverage for all packages
    26go test -coverpkg=proj/... -coverprofile=cover1.out ./...
    27stdout 'coverage:'
    28
    29# Verify the first coverage profile exists and has expected content
    30exists cover1.out
    31grep -q 'proj/sub/sub.go:' cover1.out
    32
    33# Run again to ensure caching works
    34go test -coverpkg=proj/... -coverprofile=cover1_cached.out ./...
    35stdout '\(cached\)'
    36stdout 'coverage:'
    37
    38# Note: Due to the bug, cached coverage profiles may have duplicate entries.
    39# The duplicate entries are the entries for the previous file structure and the new file structure.
    40
    41# Now modify sub.go to change line structure - this will invalidate
    42# the cache for the sub package but not for the proj package.
    43cp ../sub_modified.go sub/sub.go
    44
    45# After modifying sub.go, we should not have both old and new line references.
    46go test -coverpkg=proj/... -coverprofile=cover2.out ./...
    47stdout 'coverage:'
    48
    49# With the bug present, we would see duplicate entries for the same lines.
    50# With the bug fixed, there should be no duplicate or stale entries in the coverage profile.
    51grep 'proj/sub/sub.go:' cover2.out
    52# The fix should ensure that only the new line format exists, not the old one
    53grep 'proj/sub/sub.go:3.24,4.35' cover2.out
    54# This should fail if the stale coverage line exists (the bug is present)
    55! grep 'proj/sub/sub.go:3.24,4.22' cover2.out
    56
    57-- proj/go.mod --
    58module proj
    59
    60go 1.21
    61
    62-- proj/some_func.go --
    63package proj
    64
    65import "proj/sum"
    66
    67func SomeFunc(a, b int) int {
    68	if a == 0 && b == 0 {
    69		return 0
    70	}
    71	return sum.Sum(a, b)
    72}
    73
    74-- proj/some_func_test.go --
    75package proj
    76
    77import (
    78	"testing"
    79)
    80
    81func Test_SomeFunc(t *testing.T) {
    82	t.Run("test1", func(t *testing.T) {
    83		result := SomeFunc(1, 1)
    84		if result != 2 {
    85			t.Errorf("Expected 2, got %d", result)
    86		}
    87	})
    88}
    89
    90-- proj/sub/sub.go --
    91package sub
    92
    93func Sub(a, b int) int {
    94	if a == 0 && b == 0 {
    95		return 0
    96	}
    97	return a - b
    98}
    99
   100-- proj/sub/sub_test.go --
   101package sub
   102
   103import (
   104	"testing"
   105)
   106
   107func Test_Sub(t *testing.T) {
   108	t.Run("test_sub1", func(t *testing.T) {
   109		result := Sub(1, 1)
   110		if result != 0 {
   111			t.Errorf("Expected 0, got %d", result)
   112		}
   113	})
   114}
   115
   116-- proj/sum/sum.go --
   117package sum
   118
   119func Sum(a, b int) int {
   120	if a == 0 {
   121		return b
   122	}
   123	return a + b
   124}
   125
   126-- sub_modified.go --
   127package sub
   128
   129func Sub(a, b int) int {
   130	if a == 0 && b == 0 || a == -100 {
   131		return 0
   132	}
   133	return a - b
   134}

View as plain text