@@ -190,12 +190,6 @@ func TestCompileDevContainer(t *testing.T) {
190
190
})
191
191
}
192
192
193
- func TestUserFromDockerfile (t * testing.T ) {
194
- t .Parallel ()
195
- user := devcontainer .UserFromDockerfile ("FROM ubuntu\n USER kyle" )
196
- require .Equal (t , "kyle" , user )
197
- }
198
-
199
193
func TestImageFromDockerfile (t * testing.T ) {
200
194
t .Parallel ()
201
195
for _ , tc := range []struct {
@@ -224,27 +218,156 @@ func TestImageFromDockerfile(t *testing.T) {
224
218
}
225
219
}
226
220
227
- func TestUserFromImage (t * testing.T ) {
221
+ func TestUserFrom (t * testing.T ) {
228
222
t .Parallel ()
229
- registry := registrytest .New (t )
230
- image , err := partial .UncompressedToImage (emptyImage {configFile : & v1.ConfigFile {
231
- Config : v1.Config {
232
- User : "example" ,
233
- },
234
- }})
235
- require .NoError (t , err )
236
223
237
- parsed , err := url .Parse (registry )
238
- require .NoError (t , err )
239
- parsed .Path = "coder/test:latest"
240
- ref , err := name .ParseReference (strings .TrimPrefix (parsed .String (), "http://" ))
241
- require .NoError (t , err )
242
- err = remote .Write (ref , image )
243
- require .NoError (t , err )
224
+ t .Run ("Image" , func (t * testing.T ) {
225
+ t .Parallel ()
226
+ registry := registrytest .New (t )
227
+ image , err := partial .UncompressedToImage (emptyImage {configFile : & v1.ConfigFile {
228
+ Config : v1.Config {
229
+ User : "example" ,
230
+ },
231
+ }})
232
+ require .NoError (t , err )
244
233
245
- user , err := devcontainer .UserFromImage (ref )
246
- require .NoError (t , err )
247
- require .Equal (t , "example" , user )
234
+ parsed , err := url .Parse (registry )
235
+ require .NoError (t , err )
236
+ parsed .Path = "coder/test:latest"
237
+ ref , err := name .ParseReference (strings .TrimPrefix (parsed .String (), "http://" ))
238
+ require .NoError (t , err )
239
+ err = remote .Write (ref , image )
240
+ require .NoError (t , err )
241
+
242
+ user , err := devcontainer .UserFromImage (ref )
243
+ require .NoError (t , err )
244
+ require .Equal (t , "example" , user )
245
+ })
246
+
247
+ t .Run ("Dockerfile table based test" , func (t * testing.T ) {
248
+ t .Parallel ()
249
+ tests := []struct {
250
+ name string
251
+ content string
252
+ user string
253
+ }{
254
+ {
255
+ name : "Empty" ,
256
+ content : "FROM scratch" ,
257
+ user : "" ,
258
+ },
259
+ {
260
+ name : "User" ,
261
+ content : "FROM scrach\n USER kyle" ,
262
+ user : "kyle" ,
263
+ },
264
+ {
265
+ name : "Env with default" ,
266
+ content : "FROM scratch\n ENV MYUSER=maf\n USER ${MYUSER}" ,
267
+ user : "${MYUSER}" , // This should be "maf" but the current implementation doesn't support this.
268
+ },
269
+ {
270
+ name : "Env var with default" ,
271
+ content : "FROM scratch\n USER ${MYUSER:-maf}" ,
272
+ user : "${MYUSER:-maf}" , // This should be "maf" but the current implementation doesn't support this.
273
+ },
274
+ {
275
+ name : "Arg" ,
276
+ content : "FROM scratch\n ARG MYUSER\n USER ${MYUSER}" ,
277
+ user : "${MYUSER}" , // This should be "" or populated but the current implementation doesn't support this.
278
+ },
279
+ {
280
+ name : "Arg with default" ,
281
+ content : "FROM scratch\n ARG MYUSER=maf\n USER ${MYUSER}" ,
282
+ user : "${MYUSER}" , // This should be "maf" but the current implementation doesn't support this.
283
+ },
284
+ }
285
+ for _ , tt := range tests {
286
+ t .Run (tt .name , func (t * testing.T ) {
287
+ t .Parallel ()
288
+ user , err := devcontainer .UserFromDockerfile (tt .content )
289
+ require .NoError (t , err )
290
+ require .Equal (t , tt .user , user )
291
+ })
292
+ }
293
+ })
294
+
295
+ t .Run ("Multi-stage" , func (t * testing.T ) {
296
+ t .Parallel ()
297
+
298
+ registry := registrytest .New (t )
299
+ for tag , user := range map [string ]string {
300
+ "one" : "maf" ,
301
+ "two" : "fam" ,
302
+ } {
303
+ image , err := partial .UncompressedToImage (emptyImage {configFile : & v1.ConfigFile {
304
+ Config : v1.Config {
305
+ User : user ,
306
+ },
307
+ }})
308
+ require .NoError (t , err )
309
+ parsed , err := url .Parse (registry )
310
+ require .NoError (t , err )
311
+ parsed .Path = "coder/test:" + tag
312
+ ref , err := name .ParseReference (strings .TrimPrefix (parsed .String (), "http://" ))
313
+ fmt .Println (ref )
314
+ require .NoError (t , err )
315
+ err = remote .Write (ref , image )
316
+ require .NoError (t , err )
317
+ }
318
+
319
+ tests := []struct {
320
+ name string
321
+ images map [string ]string
322
+ content string
323
+ user string
324
+ }{
325
+ {
326
+ name : "Single" ,
327
+ content : "FROM coder/test:one" ,
328
+ user : "maf" ,
329
+ },
330
+ {
331
+ name : "Multi" ,
332
+ content : "FROM ubuntu AS u\n FROM coder/test:two" ,
333
+ user : "fam" ,
334
+ },
335
+ {
336
+ name : "Multi-2" ,
337
+ content : "FROM coder/test:two AS two\n USER maffam\n FROM coder/test:one AS one" ,
338
+ user : "maf" ,
339
+ },
340
+ {
341
+ name : "Multi-3" ,
342
+ content : "FROM coder/test:two AS two\n FROM coder/test:one AS one\n USER fammaf" ,
343
+ user : "fammaf" ,
344
+ },
345
+ {
346
+ name : "Multi-4" ,
347
+ content : `FROM ubuntu AS a
348
+ USER root
349
+ RUN useradd --create-home pickme
350
+ USER pickme
351
+ FROM a AS other
352
+ USER root
353
+ RUN useradd --create-home notme
354
+ USER notme
355
+ FROM a` ,
356
+ user : "pickme" ,
357
+ },
358
+ }
359
+ for _ , tt := range tests {
360
+ t .Run (tt .name , func (t * testing.T ) {
361
+ t .Parallel ()
362
+
363
+ content := strings .ReplaceAll (tt .content , "coder/test" , strings .TrimPrefix (registry , "http://" )+ "/coder/test" )
364
+
365
+ user , err := devcontainer .UserFromDockerfile (content )
366
+ require .NoError (t , err )
367
+ require .Equal (t , tt .user , user )
368
+ })
369
+ }
370
+ })
248
371
}
249
372
250
373
type emptyImage struct {
0 commit comments