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

Updates #3233

Change-Id: Ia224c90490d41e50a1d547eeea709b0d9171c1f9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/3191/head
Brad Fitzpatrick 3 years ago committed by Brad Fitzpatrick
parent b02eb1d5c5
commit c18b9d58aa

@ -28,6 +28,15 @@ jobs:
- name: Basic build - name: Basic build
run: go build ./cmd/... 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 - name: Run tests on linux
run: go test -bench=. -benchtime=1x ./... run: go test -bench=. -benchtime=1x ./...

@ -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)
}
}

@ -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)
}
})
}
}
Loading…
Cancel
Save