From 0586ab225620d5fe2e78d832cf56d6e490e4e1c8 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Thu, 2 Nov 2023 17:42:23 +0000 Subject: [PATCH] chore: migrate CLI tests to use `dbfake` --- cli/configssh_test.go | 94 ++++++++++++-------------------- cli/gitssh_test.go | 21 +++---- cli/list_test.go | 36 ++++++------ cli/portforward_test.go | 40 +++++--------- cli/root_test.go | 6 +- coderd/database/dbfake/dbfake.go | 1 + 6 files changed, 78 insertions(+), 120 deletions(-) diff --git a/cli/configssh_test.go b/cli/configssh_test.go index a39afe606f873..d9ac073665108 100644 --- a/cli/configssh_test.go +++ b/cli/configssh_test.go @@ -22,8 +22,9 @@ import ( "github.com/coder/coder/v2/agent/agenttest" "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/codersdk" - "github.com/coder/coder/v2/provisioner/echo" "github.com/coder/coder/v2/provisionersdk/proto" "github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/testutil" @@ -64,8 +65,7 @@ func TestConfigSSH(t *testing.T) { const hostname = "test-coder." const expectedKey = "ConnectionAttempts" const removeKey = "ConnectionTimeout" - client := coderdtest.New(t, &coderdtest.Options{ - IncludeProvisionerDaemon: true, + client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{ ConfigSSH: codersdk.SSHConfigResponse{ HostnamePrefix: hostname, SSHConfigOptions: map[string]string{ @@ -76,32 +76,13 @@ func TestConfigSSH(t *testing.T) { }, }) owner := coderdtest.CreateFirstUser(t, client) - member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) - authToken := uuid.NewString() - version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionPlan: []*proto.Response{{ - Type: &proto.Response_Plan{ - Plan: &proto.PlanComplete{ - Resources: []*proto.Resource{{ - Name: "example", - Type: "aws_instance", - Agents: []*proto.Agent{{ - Id: uuid.NewString(), - Name: "example", - }}, - }}, - }, - }, - }}, - ProvisionApply: echo.ProvisionApplyWithAgent(authToken), + member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + ws, authToken := dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: owner.OrganizationID, + OwnerID: memberUser.ID, }) - coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) - workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) _ = agenttest.New(t, client.URL, authToken) - resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID) + resources := coderdtest.AwaitWorkspaceAgents(t, client, ws.ID) agentConn, err := client.DialWorkspaceAgent(context.Background(), resources[0].Agents[0].ID, nil) require.NoError(t, err) defer agentConn.Close() @@ -172,7 +153,7 @@ func TestConfigSSH(t *testing.T) { home := filepath.Dir(filepath.Dir(sshConfigFile)) // #nosec - sshCmd := exec.Command("ssh", "-F", sshConfigFile, hostname+workspace.Name, "echo", "test") + sshCmd := exec.Command("ssh", "-F", sshConfigFile, hostname+ws.Name, "echo", "test") pty = ptytest.New(t) // Set HOME because coder config is included from ~/.ssh/coder. sshCmd.Env = append(sshCmd.Env, fmt.Sprintf("HOME=%s", home)) @@ -213,13 +194,13 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) { match, write string } tests := []struct { - name string - args []string - matches []match - writeConfig writeConfig - wantConfig wantConfig - wantErr bool - echoResponse *echo.Responses + name string + args []string + matches []match + writeConfig writeConfig + wantConfig wantConfig + wantErr bool + hasAgent bool }{ { name: "Config file is created", @@ -576,11 +557,8 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) { args: []string{ "-y", "--coder-binary-path", "/foo/bar/coder", }, - wantErr: false, - echoResponse: &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionApply: echo.ProvisionApplyWithAgent(""), - }, + wantErr: false, + hasAgent: true, wantConfig: wantConfig{ regexMatch: "ProxyCommand /foo/bar/coder", }, @@ -591,15 +569,14 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - var ( - client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) - user = coderdtest.CreateFirstUser(t, client) - version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, tt.echoResponse) - _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID) - _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) - ) + client, db := coderdtest.NewWithDatabase(t, nil) + user := coderdtest.CreateFirstUser(t, client) + if tt.hasAgent { + _, _ = dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: user.OrganizationID, + OwnerID: user.UserID, + }) + } // Prepare ssh config files. sshConfigName := sshConfigFileName(t) @@ -613,6 +590,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) { } args = append(args, tt.args...) inv, root := clitest.New(t, args...) + //nolint:gocritic // This has always ran with the admin user. clitest.SetupConfig(t, client, root) pty := ptytest.New(t) @@ -710,17 +688,15 @@ func TestConfigSSH_Hostnames(t *testing.T) { resources = append(resources, resource) } - client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + client, db := coderdtest.NewWithDatabase(t, nil) owner := coderdtest.CreateFirstUser(t, client) - member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) - // authToken := uuid.NewString() - version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, - echo.WithResources(resources)) - coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) - workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) + member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + ws := dbfake.Workspace(t, db, database.Workspace{ + OrganizationID: owner.OrganizationID, + OwnerID: memberUser.ID, + }) + dbfake.WorkspaceBuild(t, db, ws, database.WorkspaceBuild{}, resources...) sshConfigFile := sshConfigFileName(t) inv, root := clitest.New(t, "config-ssh", "--ssh-config-file", sshConfigFile) @@ -745,7 +721,7 @@ func TestConfigSSH_Hostnames(t *testing.T) { var expectedHosts []string for _, hostnamePattern := range tt.expected { - hostname := strings.ReplaceAll(hostnamePattern, "@", workspace.Name) + hostname := strings.ReplaceAll(hostnamePattern, "@", ws.Name) expectedHosts = append(expectedHosts, hostname) } diff --git a/cli/gitssh_test.go b/cli/gitssh_test.go index 354a57c732953..6203f79b6e322 100644 --- a/cli/gitssh_test.go +++ b/cli/gitssh_test.go @@ -16,7 +16,6 @@ import ( "testing" "github.com/gliderlabs/ssh" - "github.com/google/uuid" "github.com/stretchr/testify/require" gossh "golang.org/x/crypto/ssh" @@ -24,9 +23,10 @@ import ( "github.com/coder/coder/v2/agent/agenttest" "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" - "github.com/coder/coder/v2/provisioner/echo" "github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/testutil" ) @@ -34,7 +34,7 @@ import ( func prepareTestGitSSH(ctx context.Context, t *testing.T) (*agentsdk.Client, string, gossh.PublicKey) { t.Helper() - client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + client, db := coderdtest.NewWithDatabase(t, nil) user := coderdtest.CreateFirstUser(t, client) ctx, cancel := context.WithCancel(ctx) @@ -48,24 +48,17 @@ func prepareTestGitSSH(ctx context.Context, t *testing.T) (*agentsdk.Client, str require.NoError(t, err) // setup template - agentToken := uuid.NewString() - version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionPlan: echo.PlanComplete, - ProvisionApply: echo.ProvisionApplyWithAgent(agentToken), + ws, agentToken := dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: user.OrganizationID, + OwnerID: user.UserID, }) - template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) - // start workspace agent agentClient := agentsdk.New(client.URL) agentClient.SetSessionToken(agentToken) _ = agenttest.New(t, client.URL, agentToken, func(o *agent.Options) { o.Client = agentClient }) - _ = coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID) + _ = coderdtest.AwaitWorkspaceAgents(t, client, ws.ID) return agentClient, agentToken, pubkey } diff --git a/cli/list_test.go b/cli/list_test.go index cdc47821b0ced..52f13e7e397e2 100644 --- a/cli/list_test.go +++ b/cli/list_test.go @@ -11,6 +11,8 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/testutil" @@ -20,14 +22,13 @@ func TestList(t *testing.T) { t.Parallel() t.Run("Single", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + client, db := coderdtest.NewWithDatabase(t, nil) owner := coderdtest.CreateFirstUser(t, client) - member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) - version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) - coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) - workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) + member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + ws, _ := dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: owner.OrganizationID, + OwnerID: memberUser.ID, + }) inv, root := clitest.New(t, "ls") clitest.SetupConfig(t, member, root) pty := ptytest.New(t).Attach(inv) @@ -40,7 +41,7 @@ func TestList(t *testing.T) { assert.NoError(t, errC) close(done) }() - pty.ExpectMatch(workspace.Name) + pty.ExpectMatch(ws.Name) pty.ExpectMatch("Started") cancelFunc() <-done @@ -48,14 +49,13 @@ func TestList(t *testing.T) { t.Run("JSON", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + client, db := coderdtest.NewWithDatabase(t, nil) owner := coderdtest.CreateFirstUser(t, client) - member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) - version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) - coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) - workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) + member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: owner.OrganizationID, + OwnerID: memberUser.ID, + }) inv, root := clitest.New(t, "list", "--output=json") clitest.SetupConfig(t, member, root) @@ -68,8 +68,8 @@ func TestList(t *testing.T) { err := inv.WithContext(ctx).Run() require.NoError(t, err) - var templates []codersdk.Workspace - require.NoError(t, json.Unmarshal(out.Bytes(), &templates)) - require.Len(t, templates, 1) + var workspaces []codersdk.Workspace + require.NoError(t, json.Unmarshal(out.Bytes(), &workspaces)) + require.Len(t, workspaces, 1) }) } diff --git a/cli/portforward_test.go b/cli/portforward_test.go index 6dc6bb131d62f..19a4b503d3906 100644 --- a/cli/portforward_test.go +++ b/cli/portforward_test.go @@ -18,8 +18,9 @@ import ( "github.com/coder/coder/v2/agent/agenttest" "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/codersdk" - "github.com/coder/coder/v2/provisioner/echo" "github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/testutil" ) @@ -132,10 +133,10 @@ func TestPortForward(t *testing.T) { // Setup agent once to be shared between test-cases (avoid expensive // non-parallel setup). var ( - client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) - admin = coderdtest.CreateFirstUser(t, client) - member, _ = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) - workspace = runAgent(t, client, member) + client, db = coderdtest.NewWithDatabase(t, nil) + admin = coderdtest.CreateFirstUser(t, client) + member, memberUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) + workspace = runAgent(t, client, memberUser.ID, db) ) for _, c := range cases { @@ -299,35 +300,22 @@ func TestPortForward(t *testing.T) { // runAgent creates a fake workspace and starts an agent locally for that // workspace. The agent will be cleaned up on test completion. // nolint:unused -func runAgent(t *testing.T, adminClient, userClient *codersdk.Client) codersdk.Workspace { - ctx := context.Background() - user, err := userClient.User(ctx, codersdk.Me) +func runAgent(t *testing.T, client *codersdk.Client, owner uuid.UUID, db database.Store) database.Workspace { + user, err := client.User(context.Background(), codersdk.Me) require.NoError(t, err, "specified user does not exist") require.Greater(t, len(user.OrganizationIDs), 0, "user has no organizations") orgID := user.OrganizationIDs[0] - - // Setup template - agentToken := uuid.NewString() - version := coderdtest.CreateTemplateVersion(t, adminClient, orgID, &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionPlan: echo.PlanComplete, - ProvisionApply: echo.ProvisionApplyWithAgent(agentToken), + ws, agentToken := dbfake.WorkspaceWithAgent(t, db, database.Workspace{ + OrganizationID: orgID, + OwnerID: owner, }) - - // Create template and workspace - template := coderdtest.CreateTemplate(t, adminClient, orgID, version.ID) - coderdtest.AwaitTemplateVersionJobCompleted(t, adminClient, version.ID) - workspace := coderdtest.CreateWorkspace(t, userClient, orgID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, adminClient, workspace.LatestBuild.ID) - - _ = agenttest.New(t, adminClient.URL, agentToken, + _ = agenttest.New(t, client.URL, agentToken, func(o *agent.Options) { o.SSHMaxTimeout = 60 * time.Second }, ) - coderdtest.AwaitWorkspaceAgents(t, adminClient, workspace.ID) - - return workspace + coderdtest.AwaitWorkspaceAgents(t, client, ws.ID) + return ws } // setupTestListener starts accepting connections and echoing a single packet. diff --git a/cli/root_test.go b/cli/root_test.go index 4d95e5381b578..ff564e5858529 100644 --- a/cli/root_test.go +++ b/cli/root_test.go @@ -136,9 +136,9 @@ func TestDERPHeaders(t *testing.T) { }) var ( - admin = coderdtest.CreateFirstUser(t, client) - member, _ = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) - workspace = runAgent(t, client, member) + admin = coderdtest.CreateFirstUser(t, client) + member, memberUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) + workspace = runAgent(t, client, memberUser.ID, newOptions.Database) ) // Inject custom /derp handler so we can inspect the headers. diff --git a/coderd/database/dbfake/dbfake.go b/coderd/database/dbfake/dbfake.go index 442361de36834..9d7e0946d64a9 100644 --- a/coderd/database/dbfake/dbfake.go +++ b/coderd/database/dbfake/dbfake.go @@ -124,6 +124,7 @@ func WorkspaceBuild(t testing.TB, db database.Store, ws database.Workspace, seed Valid: true, }, }) + ProvisionerJobResources(t, db, jobID, seed.Transition, resources...) seed.TemplateVersionID = templateVersion.ID } build := dbgen.WorkspaceBuild(t, db, seed)