tstest/integration: add tests for auto-update defaulting behavior (#10763)

Updates #16244

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
Andrew Lytvynov 2024-01-08 09:32:18 -08:00 committed by GitHub
parent 55d302b48e
commit d96e0a553f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 95 additions and 0 deletions

View File

@ -29,6 +29,7 @@ import (
"time"
"go4.org/mem"
"tailscale.com/clientupdate"
"tailscale.com/cmd/testwrapper/flakytest"
"tailscale.com/ipn"
"tailscale.com/ipn/ipnlocal"
@ -41,6 +42,7 @@ import (
"tailscale.com/tstest/integration/testcontrol"
"tailscale.com/types/key"
"tailscale.com/types/logger"
"tailscale.com/types/opt"
"tailscale.com/types/ptr"
"tailscale.com/util/must"
"tailscale.com/util/rands"
@ -872,6 +874,99 @@ func TestLogoutRemovesAllPeers(t *testing.T) {
wantNode0PeerCount(expectedPeers) // all existing peers and the new node
}
func TestAutoUpdateDefaults(t *testing.T) {
if !clientupdate.CanAutoUpdate() {
t.Skip("auto-updates not supported on this platform")
}
tstest.Shard(t)
tstest.Parallel(t)
env := newTestEnv(t)
checkDefault := func(n *testNode, want bool) error {
enabled, ok := n.diskPrefs().AutoUpdate.Apply.Get()
if !ok {
return fmt.Errorf("auto-update for node is unset, should be set as %v", want)
}
if enabled != want {
return fmt.Errorf("auto-update for node is %v, should be set as %v", enabled, want)
}
return nil
}
sendAndCheckDefault := func(t *testing.T, n *testNode, send, want bool) {
t.Helper()
if !env.Control.AddRawMapResponse(n.MustStatus().Self.PublicKey, &tailcfg.MapResponse{
DefaultAutoUpdate: opt.NewBool(send),
}) {
t.Fatal("failed to send MapResponse to node")
}
if err := tstest.WaitFor(2*time.Second, func() error {
return checkDefault(n, want)
}); err != nil {
t.Fatal(err)
}
}
tests := []struct {
desc string
run func(t *testing.T, n *testNode)
}{
{
desc: "tailnet-default-false",
run: func(t *testing.T, n *testNode) {
// First received default "false".
sendAndCheckDefault(t, n, false, false)
// Should not be changed even if sent "true" later.
sendAndCheckDefault(t, n, true, false)
// But can be changed explicitly by the user.
if out, err := n.Tailscale("set", "--auto-update").CombinedOutput(); err != nil {
t.Fatalf("failed to enable auto-update on node: %v\noutput: %s", err, out)
}
sendAndCheckDefault(t, n, false, true)
},
},
{
desc: "tailnet-default-true",
run: func(t *testing.T, n *testNode) {
// First received default "true".
sendAndCheckDefault(t, n, true, true)
// Should not be changed even if sent "false" later.
sendAndCheckDefault(t, n, false, true)
// But can be changed explicitly by the user.
if out, err := n.Tailscale("set", "--auto-update=false").CombinedOutput(); err != nil {
t.Fatalf("failed to disable auto-update on node: %v\noutput: %s", err, out)
}
sendAndCheckDefault(t, n, true, false)
},
},
{
desc: "user-sets-first",
run: func(t *testing.T, n *testNode) {
// User sets auto-update first, before receiving defaults.
if out, err := n.Tailscale("set", "--auto-update=false").CombinedOutput(); err != nil {
t.Fatalf("failed to disable auto-update on node: %v\noutput: %s", err, out)
}
// Defaults sent from control should be ignored.
sendAndCheckDefault(t, n, true, false)
sendAndCheckDefault(t, n, false, false)
},
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
n := newTestNode(t, env)
d := n.StartDaemon()
defer d.MustCleanShutdown(t)
n.AwaitResponding()
n.MustUp()
n.AwaitRunning()
tt.run(t, n)
})
}
}
// testEnv contains the test environment (set of servers) used by one
// or more nodes.
type testEnv struct {