...
1# Regression test for https://go.dev/issue/64589:
2# This test is very similar to build_cc_cache_issue64423. Issue #64423
3# was that we weren't properly parsing the versions output by the compiler.
4# That test checked that we could parse the version and incorporate the
5# version into the hash for the action id. This issue #64589 is that
6# we treat all errors getting the version of the compiler the same, so
7# we'd get the same action id for a missing compiler vs one whose
8# version is unparseable. So the test now first does a run with a compiler
9# that produces unparseable version output, and then runs it again with a missing
10# compiler and ensures the command doesn't return the cached output for the
11# first run when running the second run.
12
13[!cgo] skip
14[short] skip 'builds and links a fake clang binary'
15[!cc:clang] skip 'test is specific to clang version parsing'
16
17# Save the location of the real clang command for our fake one to use.
18go run ./which clang
19cp stdout $WORK/.realclang
20
21# Build a fake clang and ensure that it is the one in $PATH.
22mkdir $WORK/bin
23go build -o $WORK/bin/clang$GOEXE ./fakeclang
24[!GOOS:plan9] env PATH=$WORK${/}bin
25[GOOS:plan9] env path=$WORK${/}bin
26
27# Force CGO_ENABLED=1 so that the following commands should error
28# out if the fake clang doesn't work.
29env CGO_ENABLED=1
30
31# The bug in https://go.dev/issue/64589 resulted in cache keys that
32# didn't contain any information about the error getting the compiler version.
33# Since the bug was in cache key computation, isolate the cache:
34# if we change the way caching works, we want the test to fail
35# instead of accidentally reusing the cached information from a
36# previous test run.
37env GOCACHE=$WORK${/}.cache
38mkdir $GOCACHE
39
40go build -x runtime/cgo
41
42 # Tell our fake clang to stop working.
43 # Previously, 'go build -x runtime/cgo' would continue to
44 # succeed because both the broken clang and the non-broken one
45 # resulted in a cache key with no clang version information.
46env GO_BREAK_CLANG=1
47! go build -x runtime/cgo
48stderr '# runtime/cgo\nGO_BREAK_CLANG is set'
49
50-- go.mod --
51module example/issue64589
52go 1.20
53-- which/main.go --
54package main
55
56import (
57 "os"
58 "os/exec"
59)
60
61func main() {
62 path, err := exec.LookPath(os.Args[1])
63 if err != nil {
64 panic(err)
65 }
66 os.Stdout.WriteString(path)
67}
68-- fakeclang/main.go --
69package main
70
71import (
72 "bytes"
73 "log"
74 "os"
75 "os/exec"
76 "path/filepath"
77 "slices"
78)
79
80func main() {
81 if os.Getenv("GO_BREAK_CLANG") != "" {
82 os.Stderr.WriteString("GO_BREAK_CLANG is set\n")
83 os.Exit(1)
84 }
85
86 b, err := os.ReadFile(filepath.Join(os.Getenv("WORK"), ".realclang"))
87 if err != nil {
88 log.Fatal(err)
89 }
90 if slices.Contains(os.Args, "-###") { // We are being run by gccToolID to determine the tool id used in the action id.
91 return // The important thing is that we don't print the string "version"!
92 }
93 clang := string(bytes.TrimSpace(b))
94 cmd := exec.Command(clang, os.Args[1:]...)
95 cmd.Stdout = os.Stdout
96 cmd.Stderr = os.Stderr
97 if err := cmd.Run(); err != nil {
98 log.Fatal(err)
99 }
100}
View as plain text