@@ -230,118 +230,116 @@ func TestTemplatePull_LatestStdout(t *testing.T) {
230
230
231
231
// ToDir tests that 'templates pull' pulls down the active template
232
232
// and writes it to the correct directory.
233
+ //
234
+ // nolint: paralleltest // The subtests cannot be run in parallel; see the inner loop.
233
235
func TestTemplatePull_ToDir (t * testing.T ) {
234
- t .Parallel ()
235
-
236
- client := coderdtest .New (t , & coderdtest.Options {
237
- IncludeProvisionerDaemon : true ,
238
- })
239
- owner := coderdtest .CreateFirstUser (t , client )
240
- templateAdmin , _ := coderdtest .CreateAnotherUser (t , client , owner .OrganizationID , rbac .RoleTemplateAdmin ())
241
-
242
- // Create an initial template bundle.
243
- source1 := genTemplateVersionSource ()
244
- // Create an updated template bundle. This will be used to ensure
245
- // that templates are correctly returned in order from latest to oldest.
246
- source2 := genTemplateVersionSource ()
247
-
248
- expected , err := echo .Tar (source2 )
249
- require .NoError (t , err )
250
-
251
- version1 := coderdtest .CreateTemplateVersion (t , client , owner .OrganizationID , source1 )
252
- _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , version1 .ID )
253
-
254
- template := coderdtest .CreateTemplate (t , client , owner .OrganizationID , version1 .ID )
255
-
256
- // Update the template version so that we can assert that templates
257
- // are being sorted correctly.
258
- updatedVersion := coderdtest .UpdateTemplateVersion (t , client , owner .OrganizationID , source2 , template .ID )
259
- _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , updatedVersion .ID )
260
- coderdtest .UpdateActiveTemplateVersion (t , client , template .ID , updatedVersion .ID )
261
-
262
- dir := t .TempDir ()
263
-
264
- expectedDest := filepath .Join (dir , "expected" )
265
- actualDest := filepath .Join (dir , "actual" )
266
- ctx := context .Background ()
267
-
268
- err = extract .Tar (ctx , bytes .NewReader (expected ), expectedDest , nil )
269
- require .NoError (t , err )
270
-
271
- inv , root := clitest .New (t , "templates" , "pull" , template .Name , actualDest )
272
- clitest .SetupConfig (t , templateAdmin , root )
273
-
274
- ptytest .New (t ).Attach (inv )
275
-
276
- require .NoError (t , inv .Run ())
277
-
278
- require .Equal (t ,
279
- dirSum (t , expectedDest ),
280
- dirSum (t , actualDest ),
281
- )
282
- }
283
-
284
- // ToDir tests that 'templates pull' pulls down the active template and writes
285
- // it to a directory with the name of the template if the path is not implicitly
286
- // supplied.
287
- // nolint: paralleltest
288
- func TestTemplatePull_ToImplicit (t * testing.T ) {
289
- client := coderdtest .New (t , & coderdtest.Options {
290
- IncludeProvisionerDaemon : true ,
291
- })
292
- owner := coderdtest .CreateFirstUser (t , client )
293
- templateAdmin , _ := coderdtest .CreateAnotherUser (t , client , owner .OrganizationID , rbac .RoleTemplateAdmin ())
294
-
295
- // Create an initial template bundle.
296
- source1 := genTemplateVersionSource ()
297
- // Create an updated template bundle. This will be used to ensure
298
- // that templates are correctly returned in order from latest to oldest.
299
- source2 := genTemplateVersionSource ()
300
-
301
- expected , err := echo .Tar (source2 )
302
- require .NoError (t , err )
303
-
304
- version1 := coderdtest .CreateTemplateVersion (t , client , owner .OrganizationID , source1 )
305
- _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , version1 .ID )
306
-
307
- template := coderdtest .CreateTemplate (t , client , owner .OrganizationID , version1 .ID )
308
-
309
- // Update the template version so that we can assert that templates
310
- // are being sorted correctly.
311
- updatedVersion := coderdtest .UpdateTemplateVersion (t , client , owner .OrganizationID , source2 , template .ID )
312
- _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , updatedVersion .ID )
313
- coderdtest .UpdateActiveTemplateVersion (t , client , template .ID , updatedVersion .ID )
314
-
315
- // create a tempdir and change the working directory to it for the duration of the test (cannot run in parallel)
316
- dir := t .TempDir ()
317
- wd , err := os .Getwd ()
318
- require .NoError (t , err )
319
- err = os .Chdir (dir )
320
- require .NoError (t , err )
321
- defer func () {
322
- err := os .Chdir (wd )
323
- require .NoError (t , err , "if this fails, it can break other subsequent tests due to wrong working directory" )
324
- }()
325
-
326
- expectedDest := filepath .Join (dir , "expected" )
327
- actualDest := filepath .Join (dir , template .Name )
328
-
329
- ctx := context .Background ()
330
-
331
- err = extract .Tar (ctx , bytes .NewReader (expected ), expectedDest , nil )
332
- require .NoError (t , err )
333
-
334
- inv , root := clitest .New (t , "templates" , "pull" , template .Name )
335
- clitest .SetupConfig (t , templateAdmin , root )
336
-
337
- ptytest .New (t ).Attach (inv )
338
-
339
- require .NoError (t , inv .Run ())
236
+ tests := []struct {
237
+ name string
238
+ destPath string
239
+ useDefaultDest bool
240
+ }{
241
+ {
242
+ name : "absolute path works" ,
243
+ useDefaultDest : true ,
244
+ },
245
+ {
246
+ name : "relative path to specific dir is sanitized" ,
247
+ destPath : "./pulltmp" ,
248
+ },
249
+ {
250
+ name : "relative path to current dir is sanitized" ,
251
+ destPath : "." ,
252
+ },
253
+ {
254
+ name : "directory traversal is acceptable" ,
255
+ destPath : "../mytmpl" ,
256
+ },
257
+ {
258
+ name : "empty path falls back to using template name" ,
259
+ destPath : "" ,
260
+ },
261
+ }
340
262
341
- require .Equal (t ,
342
- dirSum (t , expectedDest ),
343
- dirSum (t , actualDest ),
344
- )
263
+ // nolint: paralleltest // These tests change the current working dir, and is therefore unsuitable for parallelisation.
264
+ for _ , tc := range tests {
265
+ tc := tc
266
+
267
+ t .Run (tc .name , func (t * testing.T ) {
268
+ dir := t .TempDir ()
269
+
270
+ cwd , err := os .Getwd ()
271
+ require .NoError (t , err )
272
+ t .Cleanup (func () {
273
+ require .NoError (t , os .Chdir (cwd ))
274
+ })
275
+
276
+ // Change working directory so that relative path tests don't affect the original working directory.
277
+ newWd := filepath .Join (dir , "new-cwd" )
278
+ require .NoError (t , os .MkdirAll (newWd , 0o750 ))
279
+ require .NoError (t , os .Chdir (newWd ))
280
+
281
+ expectedDest := filepath .Join (dir , "expected" )
282
+ actualDest := tc .destPath
283
+ if tc .useDefaultDest {
284
+ actualDest = filepath .Join (dir , "actual" )
285
+ }
286
+
287
+ client := coderdtest .New (t , & coderdtest.Options {
288
+ IncludeProvisionerDaemon : true ,
289
+ })
290
+ owner := coderdtest .CreateFirstUser (t , client )
291
+ templateAdmin , _ := coderdtest .CreateAnotherUser (t , client , owner .OrganizationID , rbac .RoleTemplateAdmin ())
292
+
293
+ // Create an initial template bundle.
294
+ source1 := genTemplateVersionSource ()
295
+ // Create an updated template bundle. This will be used to ensure
296
+ // that templates are correctly returned in order from latest to oldest.
297
+ source2 := genTemplateVersionSource ()
298
+
299
+ expected , err := echo .Tar (source2 )
300
+ require .NoError (t , err )
301
+
302
+ version1 := coderdtest .CreateTemplateVersion (t , client , owner .OrganizationID , source1 )
303
+ _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , version1 .ID )
304
+
305
+ template := coderdtest .CreateTemplate (t , client , owner .OrganizationID , version1 .ID )
306
+
307
+ // Update the template version so that we can assert that templates
308
+ // are being sorted correctly.
309
+ updatedVersion := coderdtest .UpdateTemplateVersion (t , client , owner .OrganizationID , source2 , template .ID )
310
+ _ = coderdtest .AwaitTemplateVersionJobCompleted (t , client , updatedVersion .ID )
311
+ coderdtest .UpdateActiveTemplateVersion (t , client , template .ID , updatedVersion .ID )
312
+
313
+ ctx := context .Background ()
314
+
315
+ err = extract .Tar (ctx , bytes .NewReader (expected ), expectedDest , nil )
316
+ require .NoError (t , err )
317
+
318
+ ents , _ := os .ReadDir (actualDest )
319
+ if len (ents ) > 0 {
320
+ t .Logf ("%s is not empty" , actualDest )
321
+ t .FailNow ()
322
+ }
323
+
324
+ inv , root := clitest .New (t , "templates" , "pull" , template .Name , actualDest )
325
+ clitest .SetupConfig (t , templateAdmin , root )
326
+
327
+ ptytest .New (t ).Attach (inv )
328
+
329
+ require .NoError (t , inv .Run ())
330
+
331
+ // Validate behaviour of choosing template name in the absence of an output path argument.
332
+ destPath := actualDest
333
+ if destPath == "" {
334
+ destPath = template .Name
335
+ }
336
+
337
+ require .Equal (t ,
338
+ dirSum (t , expectedDest ),
339
+ dirSum (t , destPath ),
340
+ )
341
+ })
342
+ }
345
343
}
346
344
347
345
// FolderConflict tests that 'templates pull' fails when a folder with has
0 commit comments