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.
18 go run ./which clang
19 cp stdout $WORK/.realclang
20
21 # Build a fake clang and ensure that it is the one in $PATH.
22 mkdir $WORK/bin
23 go 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.
29 env 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.
37 env GOCACHE=$WORK${/}.cache
38 mkdir $GOCACHE
39
40 go 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.
46 env GO_BREAK_CLANG=1
47 ! go build -x runtime/cgo
48 stderr '# runtime/cgo\nGO_BREAK_CLANG is set'
49
50 -- go.mod --
51 module example/issue64589
52 go 1.20
53 -- which/main.go --
54 package main
55
56 import (
57 "os"
58 "os/exec"
59 )
60
61 func 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 --
69 package main
70
71 import (
72 "bytes"
73 "log"
74 "os"
75 "os/exec"
76 "path/filepath"
77 "slices"
78 )
79
80 func 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 }
101
View as plain text