mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-17 16:50:32 -04:00
tstest/integration: run Windows integration tests against the service by default (#20565)
Updates #20464 Signed-off-by: Yaruk Asghar <yaruk@tailscale.com>
This commit is contained in:
1 parent
8052bb2c53
commit
cfe32b8be6
5 files changed
+75
-31
No files matched your search
@@ -9,6 +9,7 @@
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -40,6 +41,9 @@ func TestTaildropIntegration_Fresh(t *testing.T) {
|
||||
//
|
||||
// This exercises an ipnext hook ordering issue we hit earlier.
|
||||
func testTaildropIntegration(t *testing.T, freshProfiles bool) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
controlOpt := integration.ConfigureControl(func(s *testcontrol.Server) {
|
||||
s.AllNodesSameUser = true // required for Taildrop
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -14,6 +15,9 @@
|
||||
|
||||
// TestPeerCapMap tests that the node capability map (CapMap) is included in peer information.
|
||||
func TestPeerCapMap(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
@@ -96,6 +100,9 @@ func TestPeerCapMap(t *testing.T) {
|
||||
|
||||
// TestSetNodeCapMap tests that SetNodeCapMap updates are propagated to peers.
|
||||
func TestSetNodeCapMap(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
@@ -26,6 +27,7 @@
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -60,8 +62,7 @@
|
||||
verboseTailscaled = flag.Bool("verbose-tailscaled", false, "verbose tailscaled logging")
|
||||
verboseTailscale = flag.Bool("verbose-tailscale", false, "verbose tailscale CLI logging")
|
||||
|
||||
// runWindowsServiceTests enables the Windows service-mode integration tests.
|
||||
// On by default in CI; tests opt in via NewTestEnv(t, canRunAsServiceOnWindows()).
|
||||
// runWindowsServiceTests enables the Windows service-mode integration tests, on by default in CI.
|
||||
runWindowsServiceTests = flag.Bool("run-windows-service-tests", cibuild.On(), "run Windows service-mode integration tests")
|
||||
)
|
||||
|
||||
@@ -541,37 +542,10 @@ func (f ConfigureControl) ModifyTestEnv(te *TestEnv) {
|
||||
f(te.Control)
|
||||
}
|
||||
|
||||
// canRunAsServiceOnWindowsOpt is the TestEnvOpt returned by canRunAsServiceOnWindows.
|
||||
type canRunAsServiceOnWindowsOpt struct{}
|
||||
|
||||
func (canRunAsServiceOnWindowsOpt) ModifyTestEnv(te *TestEnv) {
|
||||
// Only run as a service on Windows; on other platforms the test runs
|
||||
// the normal userspace daemon with a faked Windows GOOS, as it always has.
|
||||
if runtime.GOOS == "windows" {
|
||||
te.windowsService = true
|
||||
}
|
||||
}
|
||||
|
||||
// canRunAsServiceOnWindows enables the test to run on Windows.
|
||||
// TODO(#20464): remove this and explicitly skip tests that need more work
|
||||
// before they can run on Windows, instead of requiring tests to opt in with this option.
|
||||
func canRunAsServiceOnWindows() TestEnvOpt { return canRunAsServiceOnWindowsOpt{} }
|
||||
|
||||
// NewTestEnv starts a bunch of services and returns a new test environment.
|
||||
// NewTestEnv arranges for the environment's resources to be cleaned up on exit.
|
||||
func NewTestEnv(t testing.TB, opts ...TestEnvOpt) *TestEnv {
|
||||
// Integration tests skip on Windows unless a test opts in via canRunAsServiceOnWindows.
|
||||
// Pre-scan the opts before starting any servers so a skip leaks nothing.
|
||||
canRunAsService := false
|
||||
for _, o := range opts {
|
||||
if _, ok := o.(canRunAsServiceOnWindowsOpt); ok {
|
||||
canRunAsService = true
|
||||
}
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
if !canRunAsService {
|
||||
t.Skip("integration tests skip on Windows unless the test calls canRunAsServiceOnWindows")
|
||||
}
|
||||
if !*runWindowsServiceTests {
|
||||
t.Skip("Windows service tests disabled (--run-windows-service-tests=false)")
|
||||
}
|
||||
@@ -587,6 +561,7 @@ func NewTestEnv(t testing.TB, opts ...TestEnvOpt) *TestEnv {
|
||||
binaries := GetBinaries(t)
|
||||
e := &TestEnv{
|
||||
t: t,
|
||||
windowsService: runtime.GOOS == "windows",
|
||||
cli: binaries.Tailscale.Path,
|
||||
daemon: binaries.Tailscaled.Path,
|
||||
LogCatcher: logc,
|
||||
@@ -1130,6 +1105,16 @@ func (n *TestNode) TailscaleForOutput(arg ...string) *exec.Cmd {
|
||||
// Tailscale returns a command that runs the tailscale CLI with the provided arguments.
|
||||
// It does not start the process.
|
||||
func (n *TestNode) Tailscale(arg ...string) *exec.Cmd {
|
||||
isUp := len(arg) > 0 && arg[0] == "up"
|
||||
if isUp && cmp.Or(n.upFlagGOOS, runtime.GOOS) == "windows" {
|
||||
isBareUp := len(arg) == 1
|
||||
// --unattended keeps the current profile after the CLI exits; without it
|
||||
// Windows switches to an empty background profile and the node drops to NoState.
|
||||
// TODO(yaruk): also run tests without --unattended; see #20751.
|
||||
if !isBareUp && !slices.Contains(arg, "--unattended") {
|
||||
arg = append(arg, "--unattended")
|
||||
}
|
||||
}
|
||||
cmd := exec.Command(n.env.cli)
|
||||
cmd.Args = append(cmd.Args, "--socket="+n.sockFile)
|
||||
cmd.Args = append(cmd.Args, arg...)
|
||||
|
||||
@@ -207,6 +207,9 @@ func TestExpectedFeaturesLinked(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectPanic(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("has a Windows panic-capture race; see #20443")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
n := NewTestNode(t, env)
|
||||
@@ -846,6 +849,9 @@ func(control *testcontrol.Server) {
|
||||
}
|
||||
|
||||
func TestConfigFileAuthKey(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("--config is unsupported by the Windows service; see #20871")
|
||||
}
|
||||
t.Parallel()
|
||||
const authKey = "opensesame"
|
||||
env := NewTestEnv(t, ConfigureControl(func(control *testcontrol.Server) {
|
||||
@@ -871,6 +877,9 @@ func TestConfigFileAuthKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTwoNodes(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
@@ -956,6 +965,9 @@ func TestTwoNodes(t *testing.T) {
|
||||
// tests two nodes where the first gets a incremental MapResponse (with only
|
||||
// PeersRemoved set) saying that the second node disappeared.
|
||||
func TestIncrementalMapUpdatePeersRemoved(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
@@ -1043,6 +1055,9 @@ func TestIncrementalMapUpdatePeersRemoved(t *testing.T) {
|
||||
// This covers VIP additions at runtime, where the VIP route is not reachable
|
||||
// before the map mutation but is reachable over TSMP afterward.
|
||||
func TestIncrementalMapUpdatePeerAllowedIPsReachability(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
@@ -1268,6 +1283,9 @@ func TestC2NPingRequest(t *testing.T) {
|
||||
// Issue 2434: when "down" (WantRunning false), tailscaled shouldn't
|
||||
// be connected to control.
|
||||
func TestNoControlConnWhenDown(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("restarting the daemon with preserved state needs harness support; see #20750")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
n1 := NewTestNode(t, env)
|
||||
@@ -1317,7 +1335,7 @@ func TestNoControlConnWhenDown(t *testing.T) {
|
||||
// without the GUI to kick off a Start.
|
||||
func TestOneNodeUpWindowsStyle(t *testing.T) {
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t, canRunAsServiceOnWindows())
|
||||
env := NewTestEnv(t)
|
||||
n1 := NewTestNode(t, env)
|
||||
n1.upFlagGOOS = "windows"
|
||||
|
||||
@@ -1335,6 +1353,9 @@ func TestOneNodeUpWindowsStyle(t *testing.T) {
|
||||
// jailed node cannot initiate connections to the other node however the other
|
||||
// node can initiate connections to the jailed node.
|
||||
func TestClientSideJailing(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/17419")
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
@@ -1447,6 +1468,9 @@ func TestClientSideJailing(t *testing.T) {
|
||||
// TestNATPing creates two nodes, n1 and n2, sets up masquerades for both and
|
||||
// tries to do bi-directional pings between them.
|
||||
func TestNATPing(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/12169")
|
||||
tstest.Parallel(t)
|
||||
for _, v6 := range []bool{false, true} {
|
||||
@@ -1575,6 +1599,9 @@ func TestNATPing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLogoutRemovesAllPeers(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
// Spin up some nodes.
|
||||
@@ -1634,6 +1661,9 @@ func TestAutoUpdateDefaults_cap(t *testing.T) { testAutoUpdateDefaults(t, true)
|
||||
// useCap is whether to use NodeAttrDefaultAutoUpdate (as opposed to the old
|
||||
// DeprecatedDefaultAutoUpdate top-level MapResponse field).
|
||||
func testAutoUpdateDefaults(t *testing.T, useCap bool) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
t.Cleanup(feature.HookCanAutoUpdate.SetForTest(func() bool { return true }))
|
||||
|
||||
env := NewTestEnv(t)
|
||||
@@ -2118,6 +2148,9 @@ func TestNetstackUDPLoopback(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEncryptStateMigration(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("--encrypt-state is unsupported by the Windows service; see #20872")
|
||||
}
|
||||
if !hostinfo.New().TPM.Present() {
|
||||
t.Skip("TPM not available")
|
||||
}
|
||||
@@ -2178,6 +2211,9 @@ func TestEncryptStateMigration(t *testing.T) {
|
||||
// relay between all 3 nodes, and "tailscale debug peer-relay-sessions" returns
|
||||
// expected values.
|
||||
func TestPeerRelayPing(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/17251")
|
||||
tstest.Parallel(t)
|
||||
|
||||
@@ -2318,6 +2354,9 @@ func TestPeerRelayPing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestC2NDebugNetmap(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t, ConfigureControl(func(s *testcontrol.Server) {
|
||||
s.CollectServices = opt.False
|
||||
@@ -2456,7 +2495,9 @@ func TestC2NDebugNetmap(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTailnetLock(t *testing.T) {
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
// If you run `tailscale lock log` on a node where Tailnet Lock isn't
|
||||
// enabled, you get an error explaining that.
|
||||
t.Run("log-when-not-enabled", func(t *testing.T) {
|
||||
@@ -2598,6 +2639,9 @@ func TestTailnetLock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNodeWithBadStateFile(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("service harness can't seed a corrupt state file before start; see #20750")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
n1 := NewTestNode(t, env)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -21,6 +22,9 @@
|
||||
// netstack forwards the connection to localhost, and the listener
|
||||
// calls WhoIs on n2's LocalAPI to identify the remote peer as n1.
|
||||
func TestUserspaceWhoIsProxyMap(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("multiple nodes need the userspace-peer harness; see #20711")
|
||||
}
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
|
||||
|
||||
Reference in new issue
Block a user