package gotool import ( "context" "encoding/json" "os" "path/filepath" "runtime" "strings" "testing" ) func TestNativeAndStaticCommandsUseOwnedBaseline(t *testing.T) { clearGoSettings(t) t.Setenv("GOENV", "off") t.Setenv("GOFLAGS", "-run=^$") t.Setenv("GOOS", "windows") t.Setenv("GOARCH", "arm64") t.Setenv("GOAMD64", "v2") t.Setenv("GOEXPERIMENT", "loopvar") tool, err := New(context.Background(), t.TempDir()) if err != nil { t.Fatal(err) } if tool.HostTarget() != (Target{OS: runtime.GOOS, Arch: runtime.GOARCH}) { t.Fatalf("Go host = %#v, want runtime host %s/%s", tool.HostTarget(), runtime.GOOS, runtime.GOARCH) } native := readSettings(t, tool, Native, Target{}, "GOENV", "GOOS", "GOARCH", "GOFLAGS", "GOAMD64", "GOEXPERIMENT", "CGO_ENABLED") if native["GOENV"] != "" || native["GOOS"] != runtime.GOOS || native["GOARCH"] != runtime.GOARCH { t.Fatalf("native environment = %#v", native) } if native["GOFLAGS"] != "-mod=readonly" || native["GOAMD64"] == "v2" || native["GOEXPERIMENT"] != "" { t.Fatalf("native Go settings = %#v", native) } if native["CGO_ENABLED"] == "" { t.Fatalf("native cgo setting was not resolved: %#v", native) } static := readSettings(t, tool, Static, Target{OS: "linux", Arch: "amd64"}, "GOOS", "GOARCH", "GOFLAGS", "CGO_ENABLED", "GOAMD64", "GOEXPERIMENT") if static["GOOS"] != "linux" || static["GOARCH"] != "amd64" || static["CGO_ENABLED"] != "0" { t.Fatalf("static environment = %#v", static) } if static["GOFLAGS"] != "-mod=readonly" || static["GOAMD64"] != "v1" || static["GOEXPERIMENT"] != "" { t.Fatalf("static baseline settings = %#v", static) } } func TestPersistentSettingsPreserveCachesAndNativeCTools(t *testing.T) { clearGoSettings(t) cache := filepath.Join(t.TempDir(), "configured-cache") moduleCache := filepath.Join(t.TempDir(), "configured-module-cache") temporary := filepath.Join(t.TempDir(), "configured-temporary") if err := os.Mkdir(temporary, 0o700); err != nil { t.Fatal(err) } goEnv := filepath.Join(t.TempDir(), "go-env") contents := strings.Join([]string{ "GOFLAGS=-run=^$", "GOOS=windows", "GOARCH=arm64", "GOAMD64=v2", "GOEXPERIMENT=loopvar", "GOCACHE=" + cache, "GOMODCACHE=" + moduleCache, "GOTMPDIR=" + temporary, "CGO_ENABLED=1", "CC=releasekit-test-cc", "CXX=releasekit-test-cxx", "CGO_CFLAGS=-O0 -g", "PKG_CONFIG=releasekit-test-pkg-config", }, "\n") + "\n" if err := os.WriteFile(goEnv, []byte(contents), 0o600); err != nil { t.Fatal(err) } t.Setenv("GOENV", goEnv) tool, err := New(context.Background(), t.TempDir()) if err != nil { t.Fatal(err) } if tool.HostTarget() != (Target{OS: runtime.GOOS, Arch: runtime.GOARCH}) { t.Fatalf("Go host = %#v, want runtime host %s/%s", tool.HostTarget(), runtime.GOOS, runtime.GOARCH) } native := readSettings(t, tool, Native, Target{}, "GOENV", "GOOS", "GOARCH", "GOFLAGS", "GOAMD64", "GOEXPERIMENT", "CGO_ENABLED", "CC", "CXX", "CGO_CFLAGS", "GOCACHE", "GOMODCACHE", "GOTMPDIR", "PKG_CONFIG") if native["GOENV"] != "" || native["GOOS"] != runtime.GOOS || native["GOARCH"] != runtime.GOARCH { t.Fatalf("native environment = %#v", native) } if native["GOFLAGS"] != "-mod=readonly" || native["GOAMD64"] == "v2" || native["GOEXPERIMENT"] != "" { t.Fatalf("persisted overrides were not cleared: %#v", native) } if native["CGO_ENABLED"] != "1" || native["CC"] != "releasekit-test-cc" || native["CXX"] != "releasekit-test-cxx" || native["CGO_CFLAGS"] != "-O0 -g" || native["PKG_CONFIG"] != "releasekit-test-pkg-config" { t.Fatalf("persistent native C settings = %#v", native) } if native["GOCACHE"] != cache || native["GOMODCACHE"] != moduleCache || native["GOTMPDIR"] != temporary { t.Fatalf("persistent cache settings = %#v", native) } static := readSettings(t, tool, Static, Target{OS: "linux", Arch: "amd64"}, "GOENV", "GOOS", "GOARCH", "GOFLAGS", "CGO_ENABLED", "GOAMD64", "GOEXPERIMENT", "GOCACHE") if static["GOENV"] != "" || static["GOOS"] != "linux" || static["GOARCH"] != "amd64" || static["CGO_ENABLED"] != "0" || static["GOAMD64"] != "v1" || static["GOEXPERIMENT"] != "" || static["GOCACHE"] != cache { t.Fatalf("persistent static environment = %#v", static) } } func readSettings(t *testing.T, tool *Tool, mode Mode, target Target, names ...string) map[string]string { t.Helper() args := append([]string{"env", "-json"}, names...) output, err := tool.Run(context.Background(), t.TempDir(), mode, target, nil, args...) if err != nil { t.Fatal(err) } var settings map[string]string if err := json.Unmarshal(output, &settings); err != nil { t.Fatalf("decode Go environment %q: %v", output, err) } return settings } func clearGoSettings(t *testing.T) { t.Helper() for _, key := range []string{ "GOENV", "GOFLAGS", "GOWORK", "GOTOOLCHAIN", "GOPROXY", "GONOPROXY", "GOSUMDB", "GOOS", "GOARCH", "GOEXPERIMENT", "GOAMD64", "GOARM", "GOARM64", "GO386", "GOMIPS", "GOMIPS64", "GOPPC64", "GORISCV64", "GOWASM", "CGO_ENABLED", "CC", "CXX", "CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS", "GOCACHE", "GOCACHEPROG", "GOMODCACHE", "GOPATH", "GOROOT", "GOTMPDIR", "PKG_CONFIG", } { value, exists := os.LookupEnv(key) if err := os.Unsetenv(key); err != nil { t.Fatal(err) } t.Cleanup(func() { if exists { _ = os.Setenv(key, value) } else { _ = os.Unsetenv(key) } }) } }