8000 Add comments and unit tests · coder/coder@931e7d5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 931e7d5

Browse files
committed
Add comments and unit tests
1 parent dc80543 commit 931e7d5

File tree

5 files changed

+306
-0
lines changed

5 files changed

+306
-0
lines changed

cli/create.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ func create() *cobra.Command {
118118
return err
119119
}
120120

121+
// parameterMap can be nil if the file is not specified or invalid
121122
var parameterMap map[string]string
122123
if parameterFile != "" {
123124
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("Attempting to read the variables from the parameter file.")+"\r\n")

cli/create_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cli_test
22

33
import (
4+
"os"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -158,4 +159,101 @@ func TestCreate(t *testing.T) {
158159
}
159160
<-doneChan
160161
})
162+
t.Run("WithParameterFileContainingTheValue", func(t *testing.T) {
163+
t.Parallel()
164+
client := coderdtest.New(t, nil)
165+
user := coderdtest.CreateFirstUser(t, client)
166+
coderdtest.NewProvisionerDaemon(t, client)
167+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
168+
Parse: []*proto.Parse_Response{{
169+
Type: &proto.Parse_Response_Complete{
170+
Complete: &proto.Parse_Complete{
171+
ParameterSchemas: []*proto.ParameterSchema{{
172+
AllowOverrideSource: true,
173+
Name: "region",
174+
Description: "description",
175+
DefaultSource: &proto.ParameterSource{
176+
Scheme: proto.ParameterSource_DATA,
177+
Value: "something",
178+
},
179+
DefaultDestination: &proto.ParameterDestination{
180+
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
181+
},
182+
}},
183+
},
184+
},
185+
}},
186+
Provision: echo.ProvisionComplete,
187+
ProvisionDryRun: echo.ProvisionComplete,
188+
})
189+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
190+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
191+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
192+
_, _ = parameterFile.WriteString("region: \"bananas\"")
193+
cmd, root := clitest.New(t, "create", "my-workspace", "--template", template.Name, "--parameter-file", parameterFile.Name())
194+
clitest.SetupConfig(t, client, root)
195+
doneChan := make(chan struct{})
196+
pty := ptytest.New(t)
197+
cmd.SetIn(pty.Input())
198+
cmd.SetOut(pty.Output())
199+
go func() {
< A3E2 code>200+
defer close(doneChan)
201+
err := cmd.Execute()
202+
require.NoError(t, err)
203+
}()
204+
matches := []string{
205+
"Confirm create?", "yes",
206+
}
207+
for i := 0; i < len(matches); i += 2 {
208+
match := matches[i]
209+
value := matches[i+1]
210+
pty.ExpectMatch(match)
211+
pty.WriteLine(value)
212+
}
213+
<-doneChan
214+
})
215+
t.Run("WithParameterFileNotContainingTheValue", func(t *testing.T) {
216+
t.Parallel()
217+
client := coderdtest.New(t, nil)
218+
user := coderdtest.CreateFirstUser(t, client)
219+
coderdtest.NewProvisionerDaemon(t, client)
220+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
221+
Parse: []*proto.Parse_Response{{
222+
Type: &proto.Parse_Response_Complete{
223+
Complete: &proto.Parse_Complete{
224+
ParameterSchemas: []*proto.ParameterSchema{{
225+
AllowOverrideSource: true,
226+
Name: "region",
227+
Description: "description",
228+
DefaultSource: &proto.ParameterSource{
229+
Scheme: proto.ParameterSource_DATA,
230+
Value: "something",
231+
},
232+
DefaultDestination: &proto.ParameterDestination{
233+
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
234+
},
235+
}},
236+
},
237+
},
238+
}},
239+
Provision: echo.ProvisionComplete,
240+
ProvisionDryRun: echo.ProvisionComplete,
241+
})
242+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
243+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
244+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
245+
_, _ = parameterFile.WriteString("zone: \"bananas\"")
246+
cmd, root := clitest.New(t, "create", "my-workspace", "--template", template.Name, "--parameter-file", parameterFile.Name())
247+
clitest.SetupConfig(t, client, root)
248+
doneChan := make(chan struct{})
249+
pty := ptytest.New(t)
250+
cmd.SetIn(pty.Input())
251+
cmd.SetOut(pty.Output())
252+
go func() {
253+
defer close(doneChan)
254+
err := cmd.Execute()
255+
require.EqualError(t, err, "Parameter value absent in parameter file for \"region\"!")
256+
}()
257+
<-doneChan
258+
})
161259
}

cli/parameter_internal_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cli
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestCreateParameterMapFromFile(t *testing.T) {
11+
t.Parallel()
12+
t.Run("CreateParameterMapFromFile", func(t *testing.T) {
13+
t.Parallel()
14+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
15+
_, _ = parameterFile.WriteString("region: \"bananas\"\ndisk: \"20\"\n")
16+
17+
parameterMapFromFile, err := createParameterMapFromFile(parameterFile.Name())
18+
19+
expectedMap := map[string]string{
20+
"region": "bananas",
21+
"disk": "20",
22+
}
23+
24+
assert.Equal(t, expectedMap, parameterMapFromFile)
25+
assert.Nil(t, err)
26+
})
27+
t.Run("WithEmptyFilename", func(t *testing.T) {
28+
t.Parallel()
29+
30+
parameterMapFromFile, err := createParameterMapFromFile("")
31+
32+
assert.Nil(t, parameterMapFromFile)
33+
assert.EqualError(t, err, "Parameter file name is not specified")
34+
})
35+
t.Run("WithInvalidFilename", func(t *testing.T) {
36+
t.Parallel()
37+
38+
parameterMapFromFile, err := createParameterMapFromFile("invalidFile.yaml")
39+
40+
assert.Nil(t, parameterMapFromFile)
41+
assert.EqualError(t, err, "open invalidFile.yaml: no such file or directory")
42+
})
43+
t.Run("WithInvalidYAML", func(t *testing.T) {
44+
t.Parallel()
45+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
46+
_, _ = parameterFile.WriteString("region = \"bananas\"\ndisk = \"20\"\n")
47+
48+
parameterMapFromFile, err := createParameterMapFromFile(parameterFile.Name())
49+
50+
assert.Nil(t, parameterMap F42D FromFile)
51+
assert.EqualError(t, err, "yaml: unmarshal errors:\n line 1: cannot unmarshal !!str `region ...` into map[string]string")
52+
})
53+
}

cli/templatecreate.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func createValidTemplateVersion(cmd *cobra.Command, client *codersdk.Client, org
187187
}
188188
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("This template has required variables! They are scoped to the template, and not viewable after being set.")+"\r\n")
189189

190+
// parameterMap can be nil if the file is not specified or invalid
190191
var parameterMap map[string]string
191192
if parameterFile != "" {
192193
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("Attempting to read the variables from the parameter file.")+"\r\n")
@@ -208,6 +209,9 @@ func createValidTemplateVersion(cmd *cobra.Command, client *codersdk.Client, org
208209
})
209210
_, _ = fmt.Fprintln(cmd.OutOrStdout())
210211
}
212+
213+
// This recursion is only 1 level deep in practice.
214+
// The first pass populates the missing parameters, so it does not enter this `if` block again.
211215
return createValidTemplateVersion(cmd, client, organization, provisioner, hash, parameterFile, parameters...)
212216
}
213217

cli/templatecreate_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cli_test
22

33
import (
4+
"os"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -9,6 +10,7 @@ import (
910
"github.com/coder/coder/coderd/coderdtest"
1011
"github.com/coder/coder/coderd/database"
1112
"github.com/coder/coder/provisioner/echo"
13+
"github.com/coder/coder/provisionersdk/proto"
1214
"github.com/coder/coder/pty/ptytest"
1315
)
1416

@@ -48,4 +50,152 @@ func TestTemplateCreate(t *testing.T) {
4850

4951
require.NoError(t, <-execDone)
5052
})
53+
t.Run("WithParameter", func(t *testing.T) {
54+
t.Parallel()
55+
client := coderdtest.New(t, nil)
56+
coderdtest.CreateFirstUser(t, client)
57+
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
58+
Parse: []*proto.Parse_Response{{
59+
Type: &proto.Parse_Response_Complete{
60+
Complete: &proto.Parse_Complete{
61+
ParameterSchemas: []*proto.ParameterSchema{{
62+
AllowOverrideSource: true,
63+
Name: "region",
64+
Description: "description",
65+
DefaultDestination: &proto.ParameterDestination{
66+
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
67+
},
68+
}},
69+
},
70+
},
71+
}},
72+
Provision: echo.ProvisionComplete,
73+
ProvisionDryRun: echo.ProvisionComplete,
74+
})
75+
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
76+
clitest.SetupConfig(t, client, root)
77+
_ = coderdtest.NewProvisionerDaemon(t, client)
78+
pty := ptytest.New(t)
79+
cmd.SetIn(pty.Input())
80+
cmd.SetOut(pty.Output())
81+
82+
execDone := make(chan error)
83+
go func() {
84+
execDone <- cmd.Execute()
85+
}()
86+
87+
matches := []struct {
88+
match string
89+
write string
90+
}{
91+
{match: "Create and upload", write: "yes"},
92+
{match: "Enter a value:", write: "bananas"},
93+
{match: "Confirm create?", write: "yes"},
94+
}
95+
for _, m := range matches {
96+
pty.ExpectMatch(m.match)
97+
pty.WriteLine(m.write)
98+
}
99+
100+
require.NoError(t, <-execDone)
101+
})
102+
t.Run("WithParameterFileContainingTheValue", func(t *testing.T) {
103+
t.Parallel()
104+
client := coderdtest.New(t, nil)
105+
coderdtest.CreateFirstUser(t, client)
106+
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
107+
Parse: []*proto.Parse_Response{{
108+
Type: &proto.Parse_Response_Complete{
109+
Complete: &proto.Parse_Complete{
110+
ParameterSchemas: []*proto.ParameterSchema{{
111+
AllowOverrideSource: true,
112+
Name: "region",
113+
Description: "description",
114+
DefaultDestination: &proto.ParameterDestination{
115+
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
116+
},
117+
}},
118+
},
119+
},
120+
}},
121+
Provision: echo.ProvisionComplete,
122+
ProvisionDryRun: echo.ProvisionComplete,
123+
})
124+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
125+
_, _ = parameterFile.WriteString("region: \"bananas\"")
126+
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name())
127+
clitest.SetupConfig(t, client, root)
128+
_ = coderdtest.NewProvisionerDaemon(t, client)
129+
pty := ptytest.New(t)
130+
cmd.SetIn(pty.Input())
131+
cmd.SetOut(pty.Output())
132+
133+
execDone := make(chan error)
134+
go func() {
135+
execDone <- cmd.Execute()
136+
}()
137+
138+
matches := []struct {
139+
match string
140+
write string
141+
}{
142+
{match: "Create and upload", write: "yes"},
143+
{match: "Confirm create?", write: "yes"},
144+
}
145+
for _, m := range matches {
146+
pty.ExpectMatch(m.match)
147+
pty.WriteLine(m.write)
148+
}
149+
150+
require.NoError(t, <-execDone)
151+
})
152+
t.Run("WithParameterFileNotContainingTheValue", func(t *testing.T) {
153+
t.Parallel()
154+
client := coderdtest.New(t, nil)
155+
coderdtest.CreateFirstUser(t, client)
156+
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
157+
Parse: []*proto.Parse_Response{{
158+
Type: &proto.Parse_Response_Complete{
159+
Complete: &proto.Parse_Complete{
160+
ParameterSchemas: []*proto.ParameterSchema{{
161+
AllowOverrideSource: true,
162+
Name: "region",
163+
Description: "description",
164+
DefaultDestination: &proto.ParameterDestination{
165+
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
166+
},
167+
}},
168+
},
169+
},
170+
}},
171+
Provision: echo.ProvisionComplete,
172+
ProvisionDryRun: echo.ProvisionComplete,
173+
})
174+
parameterFile, _ := os.CreateTemp(t.TempDir(), "testParameterFile*.yaml")
175+
_, _ = parameterFile.WriteString("zone: \"bananas\"")
176+
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name())
177+
clitest.SetupConfig(t, client, root)
178+
_ = coderdtest.NewProvisionerDaemon(t, client)
179+
pty := ptytest.New(t)
180+
cmd.SetIn(pty.Input())
181+
cmd.SetOut(pty.Output())
182+
183+
execDone := make(chan error)
184+
go func() {
185+
execDone <- cmd.Execute()
186+
}()
187+
188+
matches := []struct {
189+
match string
190+
write string
191+
}{
192+
{match: "Create and upload", write: "yes"},
193+
}
194+
for _, m := range matches {
195+
pty.ExpectMatch(m.match)
196+
pty.WriteLine(m.write)
197+
}
198+
199+
require.EqualError(t, <-execDone, "Parameter value absent in parameter file for \"region\"!")
200+
})
51201
}

0 commit comments

Comments
 (0)
0