|  | // Copyright 2019 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // Package reboot_test verifies that the current GOROOT can be used to bootstrap | 
|  | // itself. | 
|  | package reboot_test | 
|  |  | 
|  | import ( | 
|  | "os" | 
|  | "os/exec" | 
|  | "path/filepath" | 
|  | "runtime" | 
|  | "testing" | 
|  | "time" | 
|  | ) | 
|  |  | 
|  | func TestRepeatBootstrap(t *testing.T) { | 
|  | if testing.Short() { | 
|  | t.Skipf("skipping test that rebuilds the entire toolchain") | 
|  | } | 
|  |  | 
|  | realGoroot, err := filepath.Abs(filepath.Join("..", "..")) | 
|  | if err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  |  | 
|  | // To ensure that bootstrapping doesn't unexpectedly depend | 
|  | // on the Go repo's git metadata, add a fake (unreadable) git | 
|  | // directory above the simulated GOROOT. | 
|  | // This mimics the configuration one much have when | 
|  | // building from distro-packaged source code | 
|  | // (see https://go.dev/issue/54852). | 
|  | parent := t.TempDir() | 
|  | dotGit := filepath.Join(parent, ".git") | 
|  | if err := os.Mkdir(dotGit, 000); err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  |  | 
|  | overlayStart := time.Now() | 
|  |  | 
|  | goroot := filepath.Join(parent, "goroot") | 
|  |  | 
|  | gorootSrc := filepath.Join(goroot, "src") | 
|  | if err := overlayDir(gorootSrc, filepath.Join(realGoroot, "src")); err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  |  | 
|  | gorootLib := filepath.Join(goroot, "lib") | 
|  | if err := overlayDir(gorootLib, filepath.Join(realGoroot, "lib")); err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  |  | 
|  | t.Logf("GOROOT overlay set up in %s", time.Since(overlayStart)) | 
|  |  | 
|  | if err := os.WriteFile(filepath.Join(goroot, "VERSION"), []byte(runtime.Version()), 0666); err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  |  | 
|  | var makeScript string | 
|  | switch runtime.GOOS { | 
|  | case "windows": | 
|  | makeScript = "make.bat" | 
|  | case "plan9": | 
|  | makeScript = "make.rc" | 
|  | default: | 
|  | makeScript = "make.bash" | 
|  | } | 
|  |  | 
|  | cmd := exec.Command(filepath.Join(goroot, "src", makeScript)) | 
|  | cmd.Dir = gorootSrc | 
|  | cmd.Env = append(cmd.Environ(), "GOROOT=", "GOROOT_BOOTSTRAP="+realGoroot) | 
|  | cmd.Stderr = os.Stderr | 
|  | cmd.Stdout = os.Stdout | 
|  | if err := cmd.Run(); err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  | } |