tstest/integration: get TestOneNodeUpAuth to pass when offline

How TestOneNodeUpAuth works:

* it starts a test version of tailscaled
* it runs `tailscale up`
* it checks that tailscaled becomes "Running"

However, if the network is down, the test either fails or times out,
because tailscaled never becomes Running.

## Why does the test fail?

ipn only becomes Running when it sees at least one live peer or DERP
connection:
0cc1b2ff76/ipn/ipnlocal/local.go (L5861-L5866)

The test only uses a single node, so it's never going to see a peer --
it has to wait to see a DERP server.  The test environment does have
a DERP map of in-memory DERP nodes, but we aren't connecting to them.

magicsock sets the preferred DERP server in `updateNetInfo()`, but this
function returns early if the network is down.
0cc1b2ff76/wgengine/magicsock/magicsock.go (L1053-L1106)

Because we're checking the real network, this prevents ipn from entering
"Running" and causes the test to fail.

## What's the fix?

In tests, we can assume the network is up unless we're explicitly testing
the behaviour of tailscaled when the network is down.

We do something similar in magicsock/derp.go, where we assume we're
connected to control unless explicitly testing otherwise:
7d2101f352/wgengine/magicsock/derp.go (L166-L177)

This is the template for the changes to `networkDown()`.

Additionally, the `testenv.InTest()` function currently checks for the
`-test.v` flag, but this isn't visible to the version of tailscaled
running in the test environment.  Instead, we add a new `TEST` env var
so this process knows it's inside a test.

Fixes #17122

Signed-off-by: Alex Chan <alexc@tailscale.com>
alexc/offline-integration-test
Alex Chan 3 months ago
parent 82cf5591dc
commit 7953592f40

@ -838,6 +838,7 @@ func (n *TestNode) StartDaemonAsIPNGOOS(ipnGOOS string) *Daemon {
"TS_PANIC_IF_HIT_MAIN_CONTROL=1",
"TS_DISABLE_PORTMAPPER=1", // shouldn't be needed; test is all localhost
"TS_DEBUG_LOG_RATE=all",
"TEST=1",
)
if n.env.loopbackPort != nil {
cmd.Env = append(cmd.Env, "TS_DEBUG_NETSTACK_LOOPBACK_PORT="+strconv.Itoa(*n.env.loopbackPort))

@ -8,6 +8,7 @@ package testenv
import (
"context"
"flag"
"os"
"tailscale.com/types/lazy"
)
@ -17,7 +18,7 @@ var lazyInTest lazy.SyncValue[bool]
// InTest reports whether the current binary is a test binary.
func InTest() bool {
return lazyInTest.Get(func() bool {
return flag.Lookup("test.v") != nil
return flag.Lookup("test.v") != nil || os.Getenv("TEST") == "1"
})
}

@ -1450,7 +1450,19 @@ func (c *Conn) LocalPort() uint16 {
var errNetworkDown = errors.New("magicsock: network down")
func (c *Conn) networkDown() bool { return !c.networkUp.Load() }
// This allows existing tests to pass, but allows us to still test the
// behaviour during tests.
var checkNetworkDownDuringTests = false
func (c *Conn) networkDown() bool {
// For tests, always assume the network is up unless we're explicitly
// testing this behaviour.
if testenv.InTest() && !checkNetworkDownDuringTests {
return false
} else {
return !c.networkUp.Load()
}
}
// Send implements conn.Bind.
//

@ -3164,6 +3164,8 @@ func TestNetworkSendErrors(t *testing.T) {
t.Skipf("skipping on %s", runtime.GOOS)
}
tstest.Replace(t, &checkNetworkDownDuringTests, true)
reg := new(usermetric.Registry)
conn.metrics = registerMetrics(reg)

Loading…
Cancel
Save