Repository: digitalocean/doctl
Pull request #1287 (2022-10-20 11:51:19)

Fix bugs in credentials directory management and connection checking
As reported in issue #1284, it is possible for `serverless connect` to work but subsequent commands to report "not connected".   This only happens when `doctl` is installed via `snap` and only in some system configurations (most seem to work, which is why this has not been noticed before).

There is clearly a snap-specific bug in the handling of the credentials directory.   The type `serverlessService` contains two fields, `serverlessDir` which represents where the plugin is installed, and `credsDir` which represents where credentials should be stored.   Except under `snap`, these are the same, but for `snap` installs they are different.    The fields are initialized correctly.   They are also used correctly in _some_ places but, sadly, not _all_ places.   In particular, the status check for being connected ends up re-forming the credentials directory from the install directory, which is incorrect under snap.

Among the two fixes in this PR is the completion of the program for using `credsDir` consistently everywhere.   As a corollary, the function to check status no longer needs a hashed token argument because this is handled in the initialization of `credsDir`.   That, in turn, results in hitting a bunch of call sites: those changes are trivial (simply dropping the argument).

So, why didn't this break all `snap` users always?    Because, the check for whether the credential store exists was narrowly looking for a "not found" error.   The `snap` assembly had a `creds` directory but it is empty (no leaf directories, no credentials files) and also protected to only be searchable by the user.  Depending on details like the the OS filesystem setup and what privileges the process executing the command has, there might be a "not found" error (which surfaces the bug) or, in many cases, rather, an "access denied" error, which ends up being ignored.   In the latter case, if the code that was guarded by the check ends up using the `credsDir` field correctly, then no harm no foul.    In my case, the ignore path was taken which is why I could not reproduce the error reported in the issue.

This PR also changes the check to be broader: any file system error in accessing the credential store will result in a "not connected" state.   If that had been in place, then the other bug would have broken all `snap` users always and any reasonable test would have found it. 

Testing the adequacy of this fix may involve using a tool like `strace`.   For many/most users, things worked fine before and all you can determine now is that they still work fine.   But, before the change, you will find cases in an `strace` looking at file activity where `credentials.json` is being looked for under `/snap` (improper) and you will see the access denied error (which is subsequently ignored).


Patch:
diff --git a/commands/namespaces.go b/commands/namespaces.go
index 7b91fc3b..a496e779 100644
--- a/commands/namespaces.go
+++ b/commands/namespaces.go
@@ -95,7 +95,7 @@ func RunNamespacesCreate(c *CmdConfig) error {
 	if !uniq {
 		return fmt.Errorf("you are using  label '%s' for another namespace; labels should be unique", label)
 	}
-	if !skipConnect && ss.CheckServerlessStatus(hashAccessToken(c)) == do.ErrServerlessNotInstalled {
+	if !skipConnect && ss.CheckServerlessStatus() == do.ErrServerlessNotInstalled {
 		skipConnect = true
 		fmt.Fprintln(c.Out, "Warning: namespace will be created but not connected (serverless software is not installed)")
 	}
diff --git a/commands/serverless.go b/commands/serverless.go
index 134e5acc..fae99786 100644
--- a/commands/serverless.go
+++ b/commands/serverless.go
@@ -142,7 +142,7 @@ func RunServerlessInstall(c *CmdConfig) error {
 		}
 		credsLeafDir = hashAccessToken(c)
 		serverless = c.Serverless()
-		status = serverless.CheckServerlessStatus(credsLeafDir)
+		status = serverless.CheckServerlessStatus()
 	}
 	switch status {
 	case nil:
@@ -164,7 +164,7 @@ func RunServerlessInstall(c *CmdConfig) error {
 func RunServerlessUpgrade(c *CmdConfig) error {
 	credsLeafDir := hashAccessToken(c)
 	serverless := c.Serverless()
-	status := serverless.CheckServerlessStatus(credsLeafDir)
+	status := serverless.CheckServerlessStatus()
 	switch status {
 	case nil:
 		fmt.Fprintln(c.Out, "Serverless support is already installed at an appropriate version.  No action needed.")
@@ -182,7 +182,7 @@ func RunServerlessUpgrade(c *CmdConfig) error {
 
 // RunServerlessUninstall removes the serverless support and any stored credentials
 func RunServerlessUninstall(c *CmdConfig) error {
-	err := c.Serverless().CheckServerlessStatus(hashAccessToken(c))
+	err := c.Serverless().CheckServerlessStatus()
 	if err == do.ErrServerlessNotInstalled {
 		return errors.New("Nothing to uninstall: no serverless support was found")
 	}
@@ -202,7 +202,7 @@ func RunServerlessConnect(c *CmdConfig) error {
 	sls := c.Serverless()
 
 	// Non-standard check for the connect command (only): it's ok to not be connected.
-	err = sls.CheckServerlessStatus(hashAccessToken(c))
+	err = sls.CheckServerlessStatus()
 	if err != nil && err != do.ErrServerlessNotConnected {
 		return err
 	}
@@ -298,7 +298,7 @@ func finishConnecting(sls do.ServerlessService, creds do.ServerlessCredentials,
 
 // RunServerlessStatus gives a report on the status of the serverless (installed, up to date, connected)
 func RunServerlessStatus(c *CmdConfig) error {
-	status := c.Serverless().CheckServerlessStatus(hashAccessToken(c))
+	status := c.Serverless().CheckServerlessStatus()
 	if status == do.ErrServerlessNotInstalled {
 		return status
 	}
diff --git a/commands/serverless_util.go b/commands/serverless_util.go
index b0869e5b..716df037 100644
--- a/commands/serverless_util.go
+++ b/commands/serverless_util.go
@@ -32,7 +32,7 @@ const (
 // ServerlessExec executes a serverless command
 func ServerlessExec(c *CmdConfig, command string, args ...string) (do.ServerlessOutput, error) {
 	serverless := c.Serverless()
-	err := serverless.CheckServerlessStatus(hashAccessToken(c))
+	err := serverless.CheckServerlessStatus()
 	if err != nil {
 		return do.ServerlessOutput{}, err
 	}
@@ -51,7 +51,7 @@ func serverlessExecNoCheck(serverless do.ServerlessService, command string, args
 // Sets up the arguments and (especially) the flags for the actual call
 func RunServerlessExec(command string, c *CmdConfig, booleanFlags []string, stringFlags []string) (do.ServerlessOutput, error) {
 	serverless := c.Serverless()
-	err := serverless.CheckServerlessStatus(hashAccessToken(c))
+	err := serverless.CheckServerlessStatus()
 	if err != nil {
 		return do.ServerlessOutput{}, err
 	}
@@ -68,7 +68,7 @@ func RunServerlessExec(command string, c *CmdConfig, booleanFlags []string, stri
 // RunServerlessExecStreaming is like RunServerlessExec but assumes that output will not be captured and can be streamed.
 func RunServerlessExecStreaming(command string, c *CmdConfig, booleanFlags []string, stringFlags []string) error {
 	serverless := c.Serverless()
-	err := serverless.CheckServerlessStatus(hashAccessToken(c))
+	err := serverless.CheckServerlessStatus()
 	if err != nil {
 		return err
 	}
diff --git a/do/mocks/ServerlessService.go b/do/mocks/ServerlessService.go
index 9926b7f3..4c02b965 100644
--- a/do/mocks/ServerlessService.go
+++ b/do/mocks/ServerlessService.go
@@ -38,17 +38,17 @@ func (m *MockServerlessService) EXPECT() *MockServerlessServiceMockRecorder {
 }
 
 // CheckServerlessStatus mocks base method.
-func (m *MockServerlessService) CheckServerlessStatus(arg0 string) error {
+func (m *MockServerlessService) CheckServerlessStatus() error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CheckServerlessStatus", arg0)
+	ret := m.ctrl.Call(m, "CheckServerlessStatus")
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // CheckServerlessStatus indicates an expected call of CheckServerlessStatus.
-func (mr *MockServerlessServiceMockRecorder) CheckServerlessStatus(arg0 interface{}) *gomock.Call {
+func (mr *MockServerlessServiceMockRecorder) CheckServerlessStatus() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckServerlessStatus", reflect.TypeOf((*MockServerlessService)(nil).CheckServerlessStatus), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckServerlessStatus", reflect.TypeOf((*MockServerlessService)(nil).CheckServerlessStatus))
 }
 
 // Cmd mocks base method.
diff --git a/do/serverless.go b/do/serverless.go
index 0bb42a8a..1fb8ecb0 100644
--- a/do/serverless.go
+++ b/do/serverless.go
@@ -214,7 +214,7 @@ type ServerlessService interface {
 	WriteCredentials(ServerlessCredentials) error
 	ReadCredentials() (ServerlessCredentials, error)
 	GetHostInfo(string) (ServerlessHostInfo, error)
-	CheckServerlessStatus(string) error
+	CheckServerlessStatus() error
 	InstallServerless(string, bool) error
 	GetFunction(string, bool) (whisk.Action, []FunctionParameter, error)
 	InvokeFunction(string, interface{}, bool, bool) (map[string]interface{}, error)
@@ -357,7 +357,7 @@ func initWhisk(s *serverlessService) error {
 	return nil
 }
 
-func (s *serverlessService) CheckServerlessStatus(leafCredsDir string) error {
+func (s *serverlessService) CheckServerlessStatus() error {
 	_, err := os.Stat(s.serverlessDir)
 	if os.IsNotExist(err) {
 		return ErrServerlessNotInstalled
@@ -365,7 +365,7 @@ func (s *serverlessService) CheckServerlessStatus(leafCredsDir string) error {
 	if !serverlessUptodate(s.serverlessDir) {
 		return ErrServerlessNeedsUpgrade
 	}
-	if !isServerlessConnected(leafCredsDir, s.serverlessDir) {
+	if !isServerlessConnected(s.credsDir) {
 		return ErrServerlessNotConnected
 	}
 	return nil
@@ -788,7 +788,7 @@ func (s *serverlessService) WriteProject(project ServerlessProject) (string, err
 // of that function are listed.  If 'fcn' is empty all triggers are listed.
 func (s *serverlessService) ListTriggers(ctx context.Context, fcn string) ([]ServerlessTrigger, error) {
 	empty := []ServerlessTrigger{}
-	err := s.CheckServerlessStatus(HashAccessToken(s.accessToken))
+	err := s.CheckServerlessStatus()
 	if err != nil {
 		return empty, err
 	}
@@ -842,7 +842,7 @@ func fixBaseDate(trigger ServerlessTrigger) ServerlessTrigger {
 // GetTrigger gets the contents of a trigger for display
 func (s *serverlessService) GetTrigger(ctx context.Context, name string) (ServerlessTrigger, error) {
 	empty := ServerlessTrigger{}
-	err := s.CheckServerlessStatus(HashAccessToken(s.accessToken))
+	err := s.CheckServerlessStatus()
 	if err != nil {
 		return empty, err
 	}
@@ -1007,11 +1007,12 @@ func (s *serverlessService) ReadCredentials() (ServerlessCredentials, error) {
 // asking the plugin to validate credentials), so the test is not foolproof.
 // It merely tests whether a credentials directory has been created for the
 // current doctl access token and appears to have a credentials.json in it.
-func isServerlessConnected(leafCredsDir string, serverlessDir string) bool {
-	creds := GetCredentialDirectory(leafCredsDir, serverlessDir)
-	credsFile := filepath.Join(creds, CredentialsFile)
+func isServerlessConnected(credsDir string) bool {
+	credsFile := filepath.Join(credsDir, CredentialsFile)
 	_, err := os.Stat(credsFile)
-	return !os.IsNotExist(err)
+	// We used to test specifically for "not found" here but in fact any error is enough to
+	// prevent connections from working.
+	return err == nil
 }
 
 // serverlessUptodate answers whether the installed version of the serverlessUptodate is at least


Test patch:
diff --git a/commands/activations_test.go b/commands/activations_test.go
index 53fb9a81..8987a5f6 100644
--- a/commands/activations_test.go
+++ b/commands/activations_test.go
@@ -95,7 +95,7 @@ func TestActivationsGet(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("activation/get", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{}, nil)
 
@@ -175,7 +175,7 @@ func TestActivationsList(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("activation/list", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{}, nil)
 
@@ -257,7 +257,7 @@ func TestActivationsLogs(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				if tt.expectStream {
 					expectedArgs := append([]string{"activation/logs"}, tt.expectedNimArgs...)
 					tm.serverless.EXPECT().Cmd("nocapture", expectedArgs).Return(fakeCmd, nil)
@@ -333,7 +333,7 @@ func TestActivationsResult(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("activation/result", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{}, nil)
 
diff --git a/commands/functions_test.go b/commands/functions_test.go
index 1b05a025..1d2d98d2 100644
--- a/commands/functions_test.go
+++ b/commands/functions_test.go
@@ -308,7 +308,7 @@ func TestFunctionsList(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("action/list", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{}, nil)
 
diff --git a/commands/namespaces_test.go b/commands/namespaces_test.go
index 08ef7427..46deccae 100644
--- a/commands/namespaces_test.go
+++ b/commands/namespaces_test.go
@@ -114,7 +114,7 @@ func TestNamespacesCreate(t *testing.T) {
 					tm.serverless.EXPECT().ListNamespaces(ctx).Return(initialList, nil)
 				}
 				if tt.willConnect {
-					tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(nil)
+					tm.serverless.EXPECT().CheckServerlessStatus().Return(nil)
 					creds := do.ServerlessCredentials{Namespace: "hello", APIHost: "https://api.example.com"}
 					tm.serverless.EXPECT().WriteCredentials(creds).Return(nil)
 				}
diff --git a/commands/serverless_test.go b/commands/serverless_test.go
index d1f9fe65..80f66412 100644
--- a/commands/serverless_test.go
+++ b/commands/serverless_test.go
@@ -100,7 +100,7 @@ func TestServerlessConnect(t *testing.T) {
 				nsResponse := do.NamespaceListResponse{Namespaces: tt.namespaceList}
 				creds := do.ServerlessCredentials{Namespace: "ns1", APIHost: "https://api.example.com"}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(do.ErrServerlessNotConnected)
+				tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNotConnected)
 				ctx := context.TODO()
 				tm.serverless.EXPECT().ListNamespaces(ctx).Return(nsResponse, nil)
 				if tt.expectedError == nil {
@@ -131,7 +131,7 @@ func TestServerlessStatusWhenConnected(t *testing.T) {
 			Stdout: config.Out,
 		}
 
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+		tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 		tm.serverless.EXPECT().Cmd("auth/current", []string{"--apihost", "--name"}).Return(fakeCmd, nil)
 		tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{
 			Entity: map[string]interface{}{
@@ -183,7 +183,7 @@ func TestServerlessStatusWithLanguages(t *testing.T) {
     go:1.22 (go:default)
 `
 
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+		tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 		tm.serverless.EXPECT().Cmd("auth/current", []string{"--apihost", "--name"}).Return(fakeCmd, nil)
 		tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{
 			Entity: map[string]interface{}{
@@ -204,7 +204,7 @@ func TestServerlessStatusWhenNotConnected(t *testing.T) {
 			Stdout: config.Out,
 		}
 
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+		tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 		tm.serverless.EXPECT().Cmd("auth/current", []string{"--apihost", "--name"}).Return(fakeCmd, nil)
 		tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{
 			Error: "403",
@@ -218,7 +218,7 @@ func TestServerlessStatusWhenNotConnected(t *testing.T) {
 
 func TestServerlessStatusWhenNotInstalled(t *testing.T) {
 	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(do.ErrServerlessNotInstalled)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNotInstalled)
 
 		err := RunServerlessStatus(config)
 
@@ -229,7 +229,7 @@ func TestServerlessStatusWhenNotInstalled(t *testing.T) {
 
 func TestServerlessStatusWhenNotUpToDate(t *testing.T) {
 	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(do.ErrServerlessNeedsUpgrade)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNeedsUpgrade)
 
 		err := RunServerlessStatus(config)
 
@@ -244,7 +244,7 @@ func TestServerlessInstallFromScratch(t *testing.T) {
 		config.Out = buf
 
 		credsToken := hashAccessToken(config)
-		tm.serverless.EXPECT().CheckServerlessStatus(credsToken).Return(do.ErrServerlessNotInstalled)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNotInstalled)
 		tm.serverless.EXPECT().InstallServerless(credsToken, false).Return(nil)
 
 		err := RunServerlessInstall(config)
@@ -257,8 +257,7 @@ func TestServerlessInstallWhenInstalledNotCurrent(t *testing.T) {
 		buf := &bytes.Buffer{}
 		config.Out = buf
 
-		credsToken := hashAccessToken(config)
-		tm.serverless.EXPECT().CheckServerlessStatus(credsToken).Return(do.ErrServerlessNeedsUpgrade)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNeedsUpgrade)
 
 		err := RunServerlessInstall(config)
 		require.NoError(t, err)
@@ -271,7 +270,7 @@ func TestServerlessInstallWhenInstalledAndCurrent(t *testing.T) {
 		buf := &bytes.Buffer{}
 		config.Out = buf
 
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(nil)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(nil)
 
 		err := RunServerlessInstall(config)
 		require.NoError(t, err)
@@ -284,8 +283,7 @@ func TestServerlessUpgradeWhenNotInstalled(t *testing.T) {
 		buf := &bytes.Buffer{}
 		config.Out = buf
 
-		credsToken := hashAccessToken(config)
-		tm.serverless.EXPECT().CheckServerlessStatus(credsToken).Return(do.ErrServerlessNotInstalled)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNotInstalled)
 
 		err := RunServerlessUpgrade(config)
 		require.NoError(t, err)
@@ -298,7 +296,7 @@ func TestServerlessUpgradeWhenInstalledAndCurrent(t *testing.T) {
 		buf := &bytes.Buffer{}
 		config.Out = buf
 
-		tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).Return(nil)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(nil)
 
 		err := RunServerlessUpgrade(config)
 		require.NoError(t, err)
@@ -312,7 +310,7 @@ func TestServerlessUpgradeWhenInstalledAndNotCurrent(t *testing.T) {
 		config.Out = buf
 
 		credsToken := hashAccessToken(config)
-		tm.serverless.EXPECT().CheckServerlessStatus(credsToken).Return(do.ErrServerlessNeedsUpgrade)
+		tm.serverless.EXPECT().CheckServerlessStatus().Return(do.ErrServerlessNeedsUpgrade)
 		tm.serverless.EXPECT().InstallServerless(credsToken, true).Return(nil)
 
 		err := RunServerlessUpgrade(config)
@@ -373,7 +371,7 @@ func TestServerlessInit(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("project/create", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{
 					Entity: tt.out,
@@ -437,7 +435,7 @@ func TestServerlessDeploy(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("project/deploy", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Exec(fakeCmd).Return(do.ServerlessOutput{}, nil)
 
@@ -573,7 +571,7 @@ func TestServerlessUndeploy(t *testing.T) {
 				}
 
 				if tt.expectedError == nil && len(tt.expectedNimCmds) > 0 {
-					tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+					tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				}
 				if tt.expectTriggerList {
 					tm.serverless.EXPECT().ListTriggers(context.TODO(), "").Return(cannedTriggerList, nil)
@@ -633,7 +631,7 @@ func TestServerlessWatch(t *testing.T) {
 					}
 				}
 
-				tm.serverless.EXPECT().CheckServerlessStatus(hashAccessToken(config)).MinTimes(1).Return(nil)
+				tm.serverless.EXPECT().CheckServerlessStatus().MinTimes(1).Return(nil)
 				tm.serverless.EXPECT().Cmd("nocapture", tt.expectedNimArgs).Return(fakeCmd, nil)
 				tm.serverless.EXPECT().Stream(fakeCmd).Return(nil)