experiment_toolid_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build explicit
  5. // +build explicit
  6. // Package experiment_toolid_test verifies that GOEXPERIMENT settings built
  7. // into the toolchain influence tool ids in the Go command.
  8. // This test requires bootstrapping the toolchain twice, so it's very expensive.
  9. // It must be run explicitly with -tags=explicit.
  10. // Verifies golang.org/issue/33091.
  11. package reboot_test
  12. import (
  13. "bytes"
  14. "os"
  15. "os/exec"
  16. "path/filepath"
  17. "runtime"
  18. "testing"
  19. )
  20. func TestExperimentToolID(t *testing.T) {
  21. // Set up GOROOT
  22. goroot, err := os.MkdirTemp("", "experiment-goroot")
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. defer os.RemoveAll(goroot)
  27. gorootSrc := filepath.Join(goroot, "src")
  28. if err := overlayDir(gorootSrc, filepath.Join(runtime.GOROOT(), "src")); err != nil {
  29. t.Fatal(err)
  30. }
  31. if err := os.WriteFile(filepath.Join(goroot, "VERSION"), []byte("go1.999"), 0666); err != nil {
  32. t.Fatal(err)
  33. }
  34. env := append(os.Environ(), "GOROOT=", "GOROOT_BOOTSTRAP="+runtime.GOROOT())
  35. // Use a clean cache.
  36. gocache, err := os.MkdirTemp("", "experiment-gocache")
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. defer os.RemoveAll(gocache)
  41. env = append(env, "GOCACHE="+gocache)
  42. // Build the toolchain without GOEXPERIMENT.
  43. var makeScript string
  44. switch runtime.GOOS {
  45. case "windows":
  46. makeScript = "make.bat"
  47. case "plan9":
  48. makeScript = "make.rc"
  49. default:
  50. makeScript = "make.bash"
  51. }
  52. makeScriptPath := filepath.Join(runtime.GOROOT(), "src", makeScript)
  53. runCmd(t, gorootSrc, env, makeScriptPath)
  54. // Verify compiler version string.
  55. goCmdPath := filepath.Join(goroot, "bin", "go")
  56. if runtime.GOOS == "windows" {
  57. goCmdPath += ".exe"
  58. }
  59. gotVersion := bytes.TrimSpace(runCmd(t, gorootSrc, env, goCmdPath, "tool", "compile", "-V=full"))
  60. wantVersion := []byte(`compile version go1.999`)
  61. if !bytes.Equal(gotVersion, wantVersion) {
  62. t.Errorf("compile version without experiment: got %q, want %q", gotVersion, wantVersion)
  63. }
  64. // Build a package in a mode not handled by the make script.
  65. runCmd(t, gorootSrc, env, goCmdPath, "build", "-race", "archive/tar")
  66. // Rebuild the toolchain with GOEXPERIMENT.
  67. env = append(env, "GOEXPERIMENT=fieldtrack")
  68. runCmd(t, gorootSrc, env, makeScriptPath)
  69. // Verify compiler version string.
  70. gotVersion = bytes.TrimSpace(runCmd(t, gorootSrc, env, goCmdPath, "tool", "compile", "-V=full"))
  71. wantVersion = []byte(`compile version go1.999 X:fieldtrack,framepointer`)
  72. if !bytes.Equal(gotVersion, wantVersion) {
  73. t.Errorf("compile version with experiment: got %q, want %q", gotVersion, wantVersion)
  74. }
  75. // Build the same package. We should not get a cache conflict.
  76. runCmd(t, gorootSrc, env, goCmdPath, "build", "-race", "archive/tar")
  77. }
  78. func runCmd(t *testing.T, dir string, env []string, path string, args ...string) []byte {
  79. cmd := exec.Command(path, args...)
  80. cmd.Dir = dir
  81. cmd.Env = env
  82. out, err := cmd.Output()
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. return out
  87. }