Skip to content

Commit 4ff6a5b

Browse files
committed
update some tests
1 parent c274b27 commit 4ff6a5b

File tree

4 files changed

+162
-73
lines changed

4 files changed

+162
-73
lines changed

cli/clitest/clitest.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import (
99
"path/filepath"
1010
"testing"
1111

12+
"github.com/google/uuid"
1213
"github.com/spf13/cobra"
1314
"github.com/stretchr/testify/require"
1415

1516
"github.com/coder/coder/cli"
1617
"github.com/coder/coder/cli/config"
1718
"github.com/coder/coder/codersdk"
1819
"github.com/coder/coder/provisioner/echo"
20+
"github.com/coder/coder/provisionersdk/proto"
1921
)
2022

2123
// New creates a CLI instance with a configuration pointed to a
@@ -46,6 +48,29 @@ func CreateTemplateVersionSource(t *testing.T, responses *echo.Responses) string
4648
return directory
4749
}
4850

51+
// GenTemplateVersion returns a unique bundle that can be used to create
52+
// a template version source.
53+
func GenTemplateVersion() *echo.Responses {
54+
return &echo.Responses{
55+
Parse: []*proto.Parse_Response{
56+
{
57+
Type: &proto.Parse_Response_Log{
58+
Log: &proto.Log{
59+
Output: uuid.NewString(),
60+
},
61+
},
62+
},
63+
64+
{
65+
Type: &proto.Parse_Response_Complete{
66+
Complete: &proto.Parse_Complete{},
67+
},
68+
},
69+
},
70+
Provision: echo.ProvisionComplete,
71+
}
72+
}
73+
4974
func extractTar(t *testing.T, data []byte, directory string) {
5075
reader := tar.NewReader(bytes.NewBuffer(data))
5176
for {

cli/templatepull.go

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ package cli
22

33
import (
44
"fmt"
5+
"io/fs"
56
"os"
6-
"path/filepath"
7+
"sort"
78

89
"github.com/spf13/cobra"
910
"golang.org/x/xerrors"
1011

12+
"github.com/coder/coder/cli/cliui"
1113
"github.com/coder/coder/codersdk"
1214
)
1315

@@ -54,6 +56,11 @@ func templatePull() *cobra.Command {
5456
return xerrors.Errorf("no template versions for template %q", templateName)
5557
}
5658

59+
// Sort the slice from newest to oldest template.
60+
sort.SliceStable(versions, func(i, j int) bool {
61+
return versions[i].CreatedAt.After(versions[j].CreatedAt)
62+
})
63+
5764
// TemplateVersionsByTemplate returns the versions in order from newest
5865
// to oldest.
5966
latest := versions[0]
@@ -67,6 +74,8 @@ func templatePull() *cobra.Command {
6774
return xerrors.Errorf("unexpected Content-Type %q, expecting %q", ctype, codersdk.ContentTypeTar)
6875
}
6976

77+
// If the destination is empty then we write to stdout
78+
// and bail early.
7079
if dest == "" {
7180
_, err = cmd.OutOrStdout().Write(raw)
7281
if err != nil {
@@ -75,17 +84,39 @@ func templatePull() *cobra.Command {
7584
return nil
7685
}
7786

78-
name := fmt.Sprintf("%s.tar", templateName)
79-
err = os.WriteFile(filepath.Join(dest, name), raw, 0600)
87+
// Stat the destination to ensure nothing exists already.
88+
fi, err := os.Stat(dest)
89+
if err != nil && !xerrors.Is(err, fs.ErrNotExist) {
90+
return xerrors.Errorf("stat destination: %w", err)
91+
}
92+
93+
if fi != nil && fi.IsDir() {
94+
// If the destination is a directory we just bail.
95+
return xerrors.Errorf("%q already exists.", dest)
96+
}
97+
98+
// If a file exists at the destination prompt the user
99+
// to ensure we don't overwrite something valuable.
100+
if fi != nil {
101+
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
102+
Text: fmt.Sprintf("%q already exists, do you want to overwrite it?", dest),
103+
IsConfirm: true,
104+
})
105+
if err != nil {
106+
return xerrors.Errorf("parse prompt: %w", err)
107+
}
108+
}
109+
110+
err = os.WriteFile(dest, raw, 0600)
80111
if err != nil {
81112
return xerrors.Errorf("write to path: %w", err)
82113
}
83114

84-
// TODO(Handle '~')
85-
86115
return nil
87116
},
88117
}
89118

119+
cliui.AllowSkipPrompt(cmd)
120+
90121
return cmd
91122
}

cli/templatepull_test.go

Lines changed: 101 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,117 @@ package cli_test
22

33
import (
44
"bytes"
5+
"os"
6+
"path/filepath"
57
"testing"
68

79
"github.com/stretchr/testify/require"
810

911
"github.com/coder/coder/cli/clitest"
1012
"github.com/coder/coder/coderd/coderdtest"
1113
"github.com/coder/coder/provisioner/echo"
12-
"github.com/coder/coder/provisionersdk/proto"
14+
"github.com/coder/coder/pty/ptytest"
1315
)
1416

1517
func TestTemplatePull(t *testing.T) {
1618
t.Parallel()
1719

18-
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
19-
user := coderdtest.CreateFirstUser(t, client)
20-
21-
// Create an initial template bundle.
22-
templateSource := &echo.Responses{
23-
Parse: []*proto.Parse_Response{
24-
{
25-
Type: &proto.Parse_Response_Log{
26-
Log: &proto.Log{Output: "yahoo"},
27-
},
28-
},
29-
30-
{
31-
Type: &proto.Parse_Response_Complete{
32-
Complete: &proto.Parse_Complete{},
33-
},
34-
},
35-
},
36-
Provision: echo.ProvisionComplete,
37-
}
38-
39-
// Create an updated template bundle. This will be used to ensure
40-
// that templates are correctly returned in order from latest to oldest.
41-
templateSource2 := &echo.Responses{
42-
Parse: []*proto.Parse_Response{
43-
{
44-
Type: &proto.Parse_Response_Log{
45-
Log: &proto.Log{Output: "wahoo"},
46-
},
47-
},
48-
49-
{
50-
Type: &proto.Parse_Response_Complete{
51-
Complete: &proto.Parse_Complete{},
52-
},
53-
},
54-
},
55-
Provision: echo.ProvisionComplete,
56-
}
57-
58-
expected, err := echo.Tar(templateSource2)
59-
require.NoError(t, err)
60-
61-
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, templateSource)
62-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
63-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
64-
65-
// Update the template version so that we can assert that templates
66-
// are being sorted correctly.
67-
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, templateSource2, template.ID)
68-
69-
cmd, root := clitest.New(t, "templates", "pull", template.Name)
70-
clitest.SetupConfig(t, client, root)
71-
72-
buf := &bytes.Buffer{}
73-
cmd.SetOut(buf)
74-
75-
err = cmd.Execute()
76-
require.NoError(t, err)
77-
78-
require.True(t, bytes.Equal(expected, buf.Bytes()), "Bytes differ")
20+
// Stdout tests that 'templates pull' pulls down the latest template
21+
// and writes it to stdout.
22+
t.Run("Stdout", func(t *testing.T) {
23+
t.Parallel()
24+
25+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
26+
user := coderdtest.CreateFirstUser(t, client)
27+
28+
// Create an initial template bundle.
29+
source1 := clitest.GenTemplateVersion()
30+
// Create an updated template bundle. This will be used to ensure
31+
// that templates are correctly returned in order from latest to oldest.
32+
source2 := clitest.GenTemplateVersion()
33+
34+
expected, err := echo.Tar(source2)
35+
require.NoError(t, err)
36+
37+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
38+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
39+
40+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
41+
42+
// Update the template version so that we can assert that templates
43+
// are being sorted correctly.
44+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
45+
46+
cmd, root := clitest.New(t, "templates", "pull", template.Name)
47+
clitest.SetupConfig(t, client, root)
48+
49+
var buf bytes.Buffer
50+
cmd.SetOut(&buf)
51+
52+
err = cmd.Execute()
53+
require.NoError(t, err)
54+
55+
require.True(t, bytes.Equal(expected, buf.Bytes()), "tar files differ")
56+
})
57+
58+
// ToFile tests that 'templates pull' pulls down the latest template
59+
// and writes it to the correct directory.
60+
t.Run("ToFile", func(t *testing.T) {
61+
t.Parallel()
62+
63+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
64+
user := coderdtest.CreateFirstUser(t, client)
65+
66+
// Create an initial template bundle.
67+
source1 := clitest.GenTemplateVersion()
68+
// Create an updated template bundle. This will be used to ensure
69+
// that templates are correctly returned in order from latest to oldest.
70+
source2 := clitest.GenTemplateVersion()
71+
72+
expected, err := echo.Tar(source2)
73+
require.NoError(t, err)
74+
75+
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, source1)
76+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
77+
78+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
79+
80+
// Update the template version so that we can assert that templates
81+
// are being sorted correctly.
82+
_ = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, source2, template.ID)
83+
84+
dir := t.TempDir()
85+
86+
dest := filepath.Join(dir, "actual.tar")
87+
88+
// Create the file so that we can test that the command
89+
// warns the user before overwriting a preexisting file.
90+
fi, err := os.OpenFile(dest, os.O_CREATE|os.O_RDONLY, 0600)
91+
require.NoError(t, err)
92+
_ = fi.Close()
93+
94+
cmd, root := clitest.New(t, "templates", "pull", template.Name, dest)
95+
clitest.SetupConfig(t, client, root)
96+
97+
pty := ptytest.New(t)
98+
cmd.SetIn(pty.Input())
99+
cmd.SetOut(pty.Output())
100+
101+
errChan := make(chan error)
102+
go func() {
103+
defer close(errChan)
104+
errChan <- cmd.Execute()
105+
}()
106+
107+
// We expect to be prompted that a file already exists.
108+
pty.ExpectMatch("already exists")
109+
pty.WriteLine("yes")
110+
111+
require.NoError(t, <-errChan)
112+
113+
actual, err := os.ReadFile(dest)
114+
require.NoError(t, err)
115+
116+
require.True(t, bytes.Equal(actual, expected), "tar files differ")
117+
})
79118
}

coderd/templateversions.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"errors"
77
"fmt"
88
"net/http"
9-
"sort"
109

1110
"github.com/go-chi/chi/v5"
1211
"github.com/google/uuid"
@@ -474,11 +473,6 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
474473
return
475474
}
476475

477-
// Sort the slice from newest to oldest template.
478-
sort.SliceStable(apiVersions, func(i, j int) bool {
479-
return apiVersions[i].CreatedAt.After(apiVersions[j].CreatedAt)
480-
})
481-
482476
httpapi.Write(rw, http.StatusOK, apiVersions)
483477
}
484478

0 commit comments

Comments
 (0)