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