Просмотр исходного кода

tstest/archtest: add GOARCH-specific tests, run via qemu-user

Updates #3233

Change-Id: Ia224c90490d41e50a1d547eeea709b0d9171c1f9
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 4 лет назад
Родитель
Сommit
c18b9d58aa
3 измененных файлов с 116 добавлено и 0 удалено
  1. 9 0
      .github/workflows/linux.yml
  2. 32 0
      tstest/archtest/archtest_test.go
  3. 75 0
      tstest/archtest/qemu_test.go

+ 9 - 0
.github/workflows/linux.yml

@@ -28,6 +28,15 @@ jobs:
     - name: Basic build
       run: go build ./cmd/...
 
+    - name: Get QEMU
+      run: |
+        # The qemu in Ubuntu 20.04 (Focal) is too old; we need 5.x something
+        # to run Go binaries. 5.2.0 (Debian bullseye) empirically works, and
+        # use this PPA which brings in a modern qemu.
+        sudo add-apt-repository -y ppa:jacob/virtualisation
+        sudo apt-get -y update
+        sudo apt-get -y install qemu-user
+
     - name: Run tests on linux
       run: go test -bench=. -benchtime=1x ./...
 

+ 32 - 0
tstest/archtest/archtest_test.go

@@ -0,0 +1,32 @@
+// Copyright (c) 2021 Tailscale Inc & 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 archtest
+
+import (
+	"runtime"
+	"testing"
+
+	"inet.af/netstack/atomicbitops"
+)
+
+// tests netstack's AlignedAtomicInt64.
+func TestAlignedAtomicInt64(t *testing.T) {
+	type T struct {
+		A atomicbitops.AlignedAtomicInt64
+		x int32
+		B atomicbitops.AlignedAtomicInt64
+	}
+
+	t.Logf("I am %v/%v\n", runtime.GOOS, runtime.GOARCH)
+	var x T
+	x.A.Store(1)
+	x.B.Store(2)
+	if got, want := x.A.Load(), int64(1); got != want {
+		t.Errorf("A = %v; want %v", got, want)
+	}
+	if got, want := x.B.Load(), int64(2); got != want {
+		t.Errorf("A = %v; want %v", got, want)
+	}
+}

+ 75 - 0
tstest/archtest/qemu_test.go

@@ -0,0 +1,75 @@
+// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && amd64 && !race
+// +build linux,amd64,!race
+
+package archtest
+
+import (
+	"bytes"
+	"fmt"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func TestInQemu(t *testing.T) {
+	t.Parallel()
+	type Arch struct {
+		Goarch string // GOARCH value
+		Qarch  string // qemu name
+	}
+	arches := []Arch{
+		{"arm", "arm"},
+		{"arm64", "aarch64"},
+		{"mips", "mips"},
+		//{"mipsle", "mipsel"}, // Broken: https://github.com/tailscale/tailscale/issues/3233
+		{"mips64", "mips64"},
+		{"mips64le", "mips64el"},
+		{"386", "386"},
+	}
+	inCI := os.Getenv("CI") == "true"
+	for _, arch := range arches {
+		arch := arch
+		t.Run(arch.Goarch, func(t *testing.T) {
+			t.Parallel()
+			qemuUser := "qemu-" + arch.Qarch
+			execVia := qemuUser
+			if arch.Goarch == "386" {
+				execVia = "" // amd64 can run it fine
+			} else {
+				look, err := exec.LookPath(qemuUser)
+				if err != nil {
+					if inCI {
+						t.Fatalf("in CI and qemu not available: %v", err)
+					}
+					t.Skipf("%s not found; skipping test. error was: %v", qemuUser, err)
+				}
+				t.Logf("using %v", look)
+			}
+			cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"),
+				"test",
+				"--exec="+execVia,
+				"-v",
+				"tailscale.com/tstest/archtest",
+			)
+			cmd.Env = append(os.Environ(), "GOARCH="+arch.Goarch)
+			out, err := cmd.CombinedOutput()
+			if err != nil {
+				if strings.Contains(string(out), "fatal error: sigaction failed") && !inCI {
+					t.Skip("skipping; qemu too old. use 5.x.")
+				}
+				t.Errorf("failed: %s", out)
+			}
+			sub := fmt.Sprintf("I am linux/%s", arch.Goarch)
+			if !bytes.Contains(out, []byte(sub)) {
+				t.Errorf("output didn't contain %q: %s", sub, out)
+			}
+		})
+	}
+}