From 96ef8d34ef7a3b61f68bc6e3110f40f48827d2ad Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 30 Apr 2021 14:47:16 -0700 Subject: [PATCH] ipn/ipnlocal: switch from testify to quicktest Per discussion, we want to have only one test assertion library, and we want to start by exploring quicktest. This was a mostly mechanical translation. I think we could make this nicer by defining a few helper closures at the beginning of the test. Later. Signed-off-by: Josh Bleecher Snyder --- go.mod | 4 +- go.sum | 6 + ipn/ipnlocal/state_test.go | 272 ++++++++++++++++++------------------- 3 files changed, 138 insertions(+), 144 deletions(-) diff --git a/go.mod b/go.mod index 7be4a5440..2f66a8075 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,13 @@ require ( github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect github.com/coreos/go-iptables v0.4.5 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect + github.com/frankban/quicktest v1.12.1 github.com/github/certstore v0.1.0 github.com/gliderlabs/ssh v0.2.2 github.com/go-multierror/multierror v1.0.2 github.com/go-ole/go-ole v1.2.4 github.com/godbus/dbus/v5 v5.0.3 - github.com/google/go-cmp v0.5.4 + github.com/google/go-cmp v0.5.5 github.com/goreleaser/nfpm v1.1.10 github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 @@ -24,7 +25,6 @@ require ( github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3 github.com/peterbourgon/ff/v2 v2.0.0 github.com/pkg/errors v0.9.1 // indirect - github.com/stretchr/testify v1.4.0 github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027 github.com/tailscale/wireguard-go v0.0.0-20210429195722-6cd106ab1339 github.com/tcnksm/go-httpstat v0.2.0 diff --git a/go.sum b/go.sum index c19043ed6..459e70158 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dvyukov/go-fuzz v0.0.0-20201127111758-49e582c6c23d/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/frankban/quicktest v1.12.1 h1:P6vQcHwZYgVGIpUzKB5DXzkEeYJppJOStPLuh9aB89c= +github.com/frankban/quicktest v1.12.1/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= @@ -44,6 +46,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0 h1:BW6OvS3kpT5UEPbCZ+KyX/OB4Ks9/MNMhWjqPPkZxsE= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= @@ -68,6 +72,8 @@ github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= diff --git a/ipn/ipnlocal/state_test.go b/ipn/ipnlocal/state_test.go index 2f860c566..57a44c1b2 100644 --- a/ipn/ipnlocal/state_test.go +++ b/ipn/ipnlocal/state_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + qt "github.com/frankban/quicktest" "tailscale.com/control/controlclient" "tailscale.com/ipn" @@ -268,7 +268,7 @@ func (cc *mockControl) UpdateEndpoints(localPort uint16, endpoints []tailcfg.End // predictable, but maybe a bit less thorough. This is more of an overall // state machine test than a test of the wgengine+magicsock integration. func TestStateMachine(t *testing.T) { - assert := assert.New(t) + c := qt.New(t) logf := t.Logf store := new(ipn.MemoryStore) @@ -312,32 +312,30 @@ func TestStateMachine(t *testing.T) { // Check that it hasn't called us right away. // The state machine should be idle until we call Start(). - assert.Equal(cc.getCalls(), []string{}) + c.Assert(cc.getCalls(), qt.HasLen, 0) // Start the state machine. // Since !WantRunning by default, it'll create a controlclient, // but not ask it to do anything yet. t.Logf("\n\nStart") notifies.expect(2) - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { // BUG: strictly, it should pause, not unpause, here, since !WantRunning. - assert.Equal([]string{"New", "unpause"}, cc.getCalls()) + c.Assert([]string{"New", "unpause"}, qt.DeepEquals, cc.getCalls()) nn := notifies.drain(2) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.NotNil(nn[1].State) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) prefs := *nn[0].Prefs // Note: a totally fresh system has Prefs.LoggedOut=false by // default. We are logged out, but not because the user asked // for it, so it doesn't count as Prefs.LoggedOut==true. - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(false, prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, *nn[1].State) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(prefs.WantRunning, qt.IsFalse) + c.Assert(ipn.NeedsLogin, qt.Equals, *nn[1].State) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Restart the state machine. @@ -346,21 +344,19 @@ func TestStateMachine(t *testing.T) { // events as the first time, so UIs always know what to expect. t.Logf("\n\nStart2") notifies.expect(2) - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { // BUG: strictly, it should pause, not unpause, here, since !WantRunning. - assert.Equal([]string{"Shutdown", "New", "unpause"}, cc.getCalls()) + c.Assert([]string{"Shutdown", "New", "unpause"}, qt.DeepEquals, cc.getCalls()) nn := notifies.drain(2) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.NotNil(nn[1].State) - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(false, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, *nn[1].State) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(nn[0].Prefs.WantRunning, qt.IsFalse) + c.Assert(ipn.NeedsLogin, qt.Equals, *nn[1].State) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Start non-interactive login with no token. @@ -370,7 +366,7 @@ func TestStateMachine(t *testing.T) { notifies.expect(0) b.Login(nil) { - assert.Equal(cc.getCalls(), []string{"Login"}) + c.Assert(cc.getCalls(), qt.DeepEquals, []string{"Login"}) notifies.drain(0) // BUG: this should immediately set WantRunning to true. // Users don't log in if they don't want to also connect. @@ -388,7 +384,7 @@ func TestStateMachine(t *testing.T) { url1 := "http://localhost:1/1" cc.send(nil, url1, false, nil) { - assert.Equal([]string{}, cc.getCalls()) + c.Assert(cc.getCalls(), qt.HasLen, 0) // ...but backend eats that notification, because the user // didn't explicitly request interactive login yet, and @@ -397,9 +393,9 @@ func TestStateMachine(t *testing.T) { // Trying to log in automatically sets WantRunning. // BUG: that should have happened right after Login(). - assert.NotNil(nn[0].Prefs) - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(true, nn[0].Prefs.WantRunning) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) } // Now we'll try an interactive login. @@ -415,9 +411,9 @@ func TestStateMachine(t *testing.T) { // We're still not logged in so there's nothing we can do // with it. (And empirically, it's providing an empty list // of endpoints.) - assert.Equal([]string{"UpdateEndpoints"}, cc.getCalls()) - assert.NotNil(nn[0].BrowseToURL) - assert.Equal(url1, *nn[0].BrowseToURL) + c.Assert([]string{"UpdateEndpoints"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].BrowseToURL, qt.Not(qt.IsNil)) + c.Assert(url1, qt.Equals, *nn[0].BrowseToURL) } // Sometimes users press the Login button again, in the middle of @@ -431,7 +427,7 @@ func TestStateMachine(t *testing.T) { { notifies.drain(0) // backend asks control for another login sequence - assert.Equal([]string{"Login"}, cc.getCalls()) + c.Assert([]string{"Login"}, qt.DeepEquals, cc.getCalls()) } // Provide a new interactive login URL. @@ -441,13 +437,13 @@ func TestStateMachine(t *testing.T) { cc.send(nil, url2, false, nil) { // BUG: UpdateEndpoints again, this is getting silly. - assert.Equal([]string{"UpdateEndpoints"}, cc.getCalls()) + c.Assert([]string{"UpdateEndpoints"}, qt.DeepEquals, cc.getCalls()) // This time, backend should emit it to the UI right away, // because the UI is anxiously awaiting a new URL to visit. nn := notifies.drain(1) - assert.NotNil(nn[0].BrowseToURL) - assert.Equal(url2, *nn[0].BrowseToURL) + c.Assert(nn[0].BrowseToURL, qt.Not(qt.IsNil)) + c.Assert(url2, qt.Equals, *nn[0].BrowseToURL) } // Pretend that the interactive login actually happened. @@ -470,10 +466,10 @@ func TestStateMachine(t *testing.T) { // wait until it gets into Starting. // TODO: (Currently this test doesn't detect that bug, but // it's visible in the logs) - assert.Equal([]string{"unpause", "UpdateEndpoints"}, cc.getCalls()) - assert.NotNil(nn[0].LoginFinished) - assert.NotNil(nn[1].State) - assert.Equal(ipn.NeedsMachineAuth, *nn[1].State) + c.Assert([]string{"unpause", "UpdateEndpoints"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].LoginFinished, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) + c.Assert(ipn.NeedsMachineAuth, qt.Equals, *nn[1].State) } // TODO: check that the logged-in username propagates from control @@ -495,9 +491,9 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(1) - assert.Equal([]string{"unpause", "UpdateEndpoints"}, cc.getCalls()) - assert.NotNil(nn[0].State) - assert.Equal(ipn.Starting, *nn[0].State) + c.Assert([]string{"unpause", "UpdateEndpoints"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(ipn.Starting, qt.Equals, *nn[0].State) } // TODO: add a fake DERP server to our fake netmap, so we can @@ -518,11 +514,11 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(2) - assert.Equal([]string{"pause"}, cc.getCalls()) + c.Assert([]string{"pause"}, qt.DeepEquals, cc.getCalls()) // BUG: I would expect Prefs to change first, and state after. - assert.NotNil(nn[0].State) - assert.NotNil(nn[1].Prefs) - assert.Equal(ipn.Stopped, *nn[0].State) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[1].Prefs, qt.Not(qt.IsNil)) + c.Assert(ipn.Stopped, qt.Equals, *nn[0].State) } // The user changes their preference to WantRunning after all. @@ -536,11 +532,11 @@ func TestStateMachine(t *testing.T) { nn := notifies.drain(2) // BUG: UpdateEndpoints isn't needed here. // BUG: Login isn't needed here. We never logged out. - assert.Equal([]string{"Login", "unpause", "UpdateEndpoints"}, cc.getCalls()) + c.Assert([]string{"Login", "unpause", "UpdateEndpoints"}, qt.DeepEquals, cc.getCalls()) // BUG: I would expect Prefs to change first, and state after. - assert.NotNil(nn[0].State) - assert.NotNil(nn[1].Prefs) - assert.Equal(ipn.Starting, *nn[0].State) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[1].Prefs, qt.Not(qt.IsNil)) + c.Assert(ipn.Starting, qt.Equals, *nn[0].State) } // Test the fast-path frontend reconnection. @@ -551,15 +547,13 @@ func TestStateMachine(t *testing.T) { t.Logf("\n\nFastpath Start()") notifies.expect(1) b.state = ipn.Running - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { nn := notifies.drain(1) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].State) - assert.NotNil(nn[0].LoginFinished) - assert.NotNil(nn[0].NetMap) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[0].LoginFinished, qt.Not(qt.IsNil)) + c.Assert(nn[0].NetMap, qt.Not(qt.IsNil)) // BUG: Prefs should be sent too, or the UI could end up in // a bad state. (iOS, the only current user of this feature, // probably wouldn't notice because it happens to not display @@ -576,13 +570,13 @@ func TestStateMachine(t *testing.T) { { nn := notifies.drain(2) // BUG: now is not the time to unpause. - assert.Equal([]string{"unpause", "StartLogout"}, cc.getCalls()) - assert.NotNil(nn[0].State) - assert.NotNil(nn[1].Prefs) - assert.Equal(ipn.NeedsLogin, *nn[0].State) - assert.Equal(true, nn[1].Prefs.LoggedOut) - assert.Equal(false, nn[1].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert([]string{"unpause", "StartLogout"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[1].Prefs, qt.Not(qt.IsNil)) + c.Assert(ipn.NeedsLogin, qt.Equals, *nn[0].State) + c.Assert(nn[1].Prefs.LoggedOut, qt.IsTrue) + c.Assert(nn[1].Prefs.WantRunning, qt.IsFalse) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Let's make the logout succeed. @@ -592,12 +586,12 @@ func TestStateMachine(t *testing.T) { cc.send(nil, "", false, nil) { nn := notifies.drain(1) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.Equal(true, nn[0].Prefs.LoggedOut) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) // BUG: WantRunning should be false after manual logout. - assert.Equal(true, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // A second logout should do nothing, since the prefs haven't changed. @@ -608,12 +602,12 @@ func TestStateMachine(t *testing.T) { nn := notifies.drain(1) // BUG: the backend has already called StartLogout, and we're // still logged out. So it shouldn't call it again. - assert.Equal([]string{"StartLogout"}, cc.getCalls()) + c.Assert([]string{"StartLogout"}, qt.DeepEquals, cc.getCalls()) // BUG: Prefs should not change here. Already logged out. - assert.NotNil(nn[0].Prefs) - assert.Equal(true, nn[0].Prefs.LoggedOut) - assert.Equal(false, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) + c.Assert(nn[0].Prefs.WantRunning, qt.IsFalse) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Let's acknowledge the second logout too. @@ -623,12 +617,12 @@ func TestStateMachine(t *testing.T) { cc.send(nil, "", false, nil) { nn := notifies.drain(1) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.Equal(true, nn[0].Prefs.LoggedOut) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) // BUG: second logout shouldn't cause WantRunning->true !! - assert.Equal(true, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Try the synchronous logout feature. @@ -639,11 +633,11 @@ func TestStateMachine(t *testing.T) { // I guess, since that's supposed to be synchronous. { nn := notifies.drain(1) - assert.Equal([]string{"Logout"}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.Equal(true, nn[0].Prefs.LoggedOut) - assert.Equal(false, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert([]string{"Logout"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) + c.Assert(nn[0].Prefs.WantRunning, qt.IsFalse) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Generate the third logout event. @@ -653,12 +647,12 @@ func TestStateMachine(t *testing.T) { cc.send(nil, "", false, nil) { nn := notifies.drain(1) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.Equal(true, nn[0].Prefs.LoggedOut) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) // BUG: third logout shouldn't cause WantRunning->true !! - assert.Equal(true, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Shut down the backend. @@ -668,7 +662,7 @@ func TestStateMachine(t *testing.T) { { notifies.drain(0) // BUG: I expect a transition to ipn.NoState here. - assert.Equal(cc.getCalls(), []string{"Shutdown"}) + c.Assert(cc.getCalls(), qt.DeepEquals, []string{"Shutdown"}) } // Oh, you thought we were done? Ha! Now we have to test what @@ -685,23 +679,21 @@ func TestStateMachine(t *testing.T) { // The frontend restarts! t.Logf("\n\nStart3") notifies.expect(2) - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { // BUG: We already called Shutdown(), no need to do it again. // BUG: Way too soon for UpdateEndpoints. // BUG: don't unpause because we're not logged in. - assert.Equal([]string{"Shutdown", "New", "UpdateEndpoints", "unpause"}, cc.getCalls()) + c.Assert([]string{"Shutdown", "New", "UpdateEndpoints", "unpause"}, qt.DeepEquals, cc.getCalls()) nn := notifies.drain(2) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.NotNil(nn[1].State) - assert.Equal(true, nn[0].Prefs.LoggedOut) - assert.Equal(true, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NeedsLogin, *nn[1].State) - assert.Equal(ipn.NeedsLogin, b.State()) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsTrue) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) + c.Assert(ipn.NeedsLogin, qt.Equals, *nn[1].State) + c.Assert(ipn.NeedsLogin, qt.Equals, b.State()) } // Let's break the rules a little. Our control server accepts @@ -716,12 +708,12 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(3) - assert.Equal([]string{"unpause"}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.NotNil(nn[1].LoginFinished) - assert.NotNil(nn[2].State) - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(ipn.Starting, *nn[2].State) + c.Assert([]string{"unpause"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[1].LoginFinished, qt.Not(qt.IsNil)) + c.Assert(nn[2].State, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(ipn.Starting, qt.Equals, *nn[2].State) } // Now we've logged in successfully. Let's disconnect. @@ -733,20 +725,18 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(2) - assert.Equal([]string{"pause"}, cc.getCalls()) + c.Assert([]string{"pause"}, qt.DeepEquals, cc.getCalls()) // BUG: I would expect Prefs to change first, and state after. - assert.NotNil(nn[0].State) - assert.NotNil(nn[1].Prefs) - assert.Equal(ipn.Stopped, *nn[0].State) - assert.Equal(false, nn[1].Prefs.LoggedOut) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[1].Prefs, qt.Not(qt.IsNil)) + c.Assert(ipn.Stopped, qt.Equals, *nn[0].State) + c.Assert(nn[1].Prefs.LoggedOut, qt.IsFalse) } // One more restart, this time with a valid key, but WantRunning=false. t.Logf("\n\nStart4") notifies.expect(2) - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { // NOTE: cc.Shutdown() is correct here, since we didn't call // b.Shutdown() explicitly ourselves. @@ -755,15 +745,15 @@ func TestStateMachine(t *testing.T) { // on startup, otherwise UIs can't show the node list, login // name, etc when in state ipn.Stopped. // Arguably they shouldn't try. But they currently do. - assert.Equal([]string{"Shutdown", "New", "UpdateEndpoints", "Login", "unpause"}, cc.getCalls()) + c.Assert([]string{"Shutdown", "New", "UpdateEndpoints", "Login", "unpause"}, qt.DeepEquals, cc.getCalls()) nn := notifies.drain(2) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.NotNil(nn[1].State) - assert.Equal(false, nn[0].Prefs.WantRunning) - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(ipn.Stopped, *nn[1].State) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.WantRunning, qt.IsFalse) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(ipn.Stopped, qt.Equals, *nn[1].State) } // Request connection. @@ -776,31 +766,29 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(2) - assert.Equal([]string{"Login", "unpause"}, cc.getCalls()) + c.Assert([]string{"Login", "unpause"}, qt.DeepEquals, cc.getCalls()) // BUG: I would expect Prefs to change first, and state after. - assert.NotNil(nn[0].State) - assert.NotNil(nn[1].Prefs) - assert.Equal(ipn.Starting, *nn[0].State) + c.Assert(nn[0].State, qt.Not(qt.IsNil)) + c.Assert(nn[1].Prefs, qt.Not(qt.IsNil)) + c.Assert(ipn.Starting, qt.Equals, *nn[0].State) } // The last test case is the most common one: restarting when both // logged in and WantRunning. t.Logf("\n\nStart5") notifies.expect(1) - assert.Nil(b.Start(ipn.Options{ - StateKey: ipn.GlobalDaemonStateKey, - })) + c.Assert(b.Start(ipn.Options{StateKey: ipn.GlobalDaemonStateKey}), qt.IsNil) { // NOTE: cc.Shutdown() is correct here, since we didn't call // b.Shutdown() ourselves. - assert.Equal([]string{"Shutdown", "New", "UpdateEndpoints", "Login"}, cc.getCalls()) + c.Assert([]string{"Shutdown", "New", "UpdateEndpoints", "Login"}, qt.DeepEquals, cc.getCalls()) nn := notifies.drain(1) - assert.Equal([]string{}, cc.getCalls()) - assert.NotNil(nn[0].Prefs) - assert.Equal(false, nn[0].Prefs.LoggedOut) - assert.Equal(true, nn[0].Prefs.WantRunning) - assert.Equal(ipn.NoState, b.State()) + c.Assert(cc.getCalls(), qt.HasLen, 0) + c.Assert(nn[0].Prefs, qt.Not(qt.IsNil)) + c.Assert(nn[0].Prefs.LoggedOut, qt.IsFalse) + c.Assert(nn[0].Prefs.WantRunning, qt.IsTrue) + c.Assert(ipn.NoState, qt.Equals, b.State()) } // Control server accepts our valid key from before. @@ -812,13 +800,13 @@ func TestStateMachine(t *testing.T) { }) { nn := notifies.drain(2) - assert.Equal([]string{"unpause"}, cc.getCalls()) - assert.NotNil(nn[0].LoginFinished) - assert.NotNil(nn[1].State) - assert.Equal(ipn.Starting, *nn[1].State) + c.Assert([]string{"unpause"}, qt.DeepEquals, cc.getCalls()) + c.Assert(nn[0].LoginFinished, qt.Not(qt.IsNil)) + c.Assert(nn[1].State, qt.Not(qt.IsNil)) + c.Assert(ipn.Starting, qt.Equals, *nn[1].State) // NOTE: No prefs change this time. WantRunning stays true. // We were in Starting in the first place, so that doesn't // change either. - assert.Equal(ipn.Starting, b.State()) + c.Assert(ipn.Starting, qt.Equals, b.State()) } }