From 0ad7d4ee40d2fde8b8a58945112f28548d3e8ccb Mon Sep 17 00:00:00 2001 From: James Sanderson Date: Thu, 2 Oct 2025 15:56:55 +0100 Subject: [PATCH] wip: fix TestWGEngineStatusRace At the moment the test itself is broken, so it's hard to tell if the code under test is fixed or not. Maybe it is? --- ipn/ipnlocal/state_test.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/ipn/ipnlocal/state_test.go b/ipn/ipnlocal/state_test.go index 347aaf8b8..768012fb3 100644 --- a/ipn/ipnlocal/state_test.go +++ b/ipn/ipnlocal/state_test.go @@ -1064,13 +1064,13 @@ func (s *testStateStorage) sawWrite() bool { } func TestWGEngineStatusRace(t *testing.T) { - t.Skip("test fails") + // t.Skip("test fails") c := qt.New(t) logf := tstest.WhileTestRunningLogger(t) sys := tsd.NewSystem() sys.Set(new(mem.Store)) - eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.Bus.Get()) + eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker.Get(), sys.UserMetricsRegistry(), sys.Bus.Get()) c.Assert(err, qt.IsNil) t.Cleanup(eng.Close) sys.Set(eng) @@ -1087,27 +1087,37 @@ func TestWGEngineStatusRace(t *testing.T) { var state ipn.State b.SetNotifyCallback(func(n ipn.Notify) { if n.State != nil { + t.Logf("Notify: %v", n.State) state = *n.State } }) wantState := func(want ipn.State) { - c.Assert(want, qt.Equals, state) + t.Helper() + c.Assert(state, qt.Equals, want) } // Start with the zero value. wantState(ipn.NoState) // Start the backend. - err = b.Start(ipn.Options{}) + err = b.Start(ipn.Options{ + UpdatePrefs: &ipn.Prefs{ + WantRunning: true, + }, + }) c.Assert(err, qt.IsNil) wantState(ipn.NeedsLogin) // Assert that we are logged in and authorized. + cc.persist.UserProfile.LoginName = "user1" + cc.persist.NodeID = "node1" cc.send(nil, "", true, &netmap.NetworkMap{ SelfNode: (&tailcfg.Node{MachineAuthorized: true}).View(), }) wantState(ipn.Starting) + timestamp := time.Now() + // Simulate multiple concurrent callbacks from wgengine. // Any single callback with DERPS > 0 is enough to transition // from Starting to Running, at which point we stay there. @@ -1123,11 +1133,20 @@ func TestWGEngineStatusRace(t *testing.T) { if i == 0 { n = 1 } - b.setWgengineStatus(&wgengine.Status{AsOf: time.Now(), DERPs: n}, nil) + b.setWgengineStatus(&wgengine.Status{AsOf: timestamp, DERPs: n}, nil) }(i) } wg.Wait() - wantState(ipn.Running) + + err = tstest.WaitFor(100*time.Millisecond, func() error { + if state == ipn.Running { + return nil + } + return fmt.Errorf("got state = %v; want Running", state) + }) + if err != nil { + t.Error(err) + } } // TestEngineReconfigOnStateChange verifies that wgengine is properly reconfigured