version_test.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tailscaleroot
  4. import (
  5. "fmt"
  6. "os"
  7. "os/exec"
  8. "runtime"
  9. "strings"
  10. "testing"
  11. "golang.org/x/mod/modfile"
  12. )
  13. func TestDockerfileVersion(t *testing.T) {
  14. goVersion := mustGetGoModVersion(t, false)
  15. dockerFile, err := os.ReadFile("Dockerfile")
  16. if err != nil {
  17. t.Fatal(err)
  18. }
  19. wantSub := fmt.Sprintf("FROM golang:%s-alpine AS build-env", goVersion)
  20. if !strings.Contains(string(dockerFile), wantSub) {
  21. t.Errorf("didn't find %q in Dockerfile", wantSub)
  22. }
  23. }
  24. // TestGoVersion tests that the Go version specified in go.mod matches ./tool/go version.
  25. func TestGoVersion(t *testing.T) {
  26. // We could special-case ./tool/go path for Windows, but really there is no
  27. // need to run it there.
  28. if runtime.GOOS == "windows" {
  29. t.Skip("Skipping test on Windows")
  30. }
  31. goModVersion := mustGetGoModVersion(t, true)
  32. goToolCmd := exec.Command("./tool/go", "version")
  33. goToolOutput, err := goToolCmd.Output()
  34. if err != nil {
  35. t.Fatalf("Failed to get ./tool/go version: %v", err)
  36. }
  37. // Version info will approximately look like 'go version go1.24.4 linux/amd64'.
  38. parts := strings.Fields(string(goToolOutput))
  39. if len(parts) < 4 {
  40. t.Fatalf("Unexpected ./tool/go version output format: %s", goToolOutput)
  41. }
  42. goToolVersion := strings.TrimPrefix(parts[2], "go")
  43. if goModVersion != goToolVersion {
  44. t.Errorf("Go version in go.mod (%q) does not match the version of ./tool/go (%q).\nEnsure that the go.mod refers to the same Go version as ./go.toolchain.rev.",
  45. goModVersion, goToolVersion)
  46. }
  47. }
  48. func mustGetGoModVersion(t *testing.T, includePatchVersion bool) string {
  49. t.Helper()
  50. goModBytes, err := os.ReadFile("go.mod")
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. modFile, err := modfile.Parse("go.mod", goModBytes, nil)
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. if modFile.Go == nil {
  59. t.Fatal("no Go version found in go.mod")
  60. }
  61. version := modFile.Go.Version
  62. parts := strings.Split(version, ".")
  63. if !includePatchVersion {
  64. if len(parts) >= 2 {
  65. version = parts[0] + "." + parts[1]
  66. }
  67. }
  68. return version
  69. }