@@ -10,7 +10,9 @@ package singularityenv
10
10
11
11
import (
12
12
"io/ioutil"
13
+ "os"
13
14
"path/filepath"
15
+ "strconv"
14
16
"strings"
15
17
"testing"
16
18
@@ -457,6 +459,191 @@ func (c ctx) singularityEnvFile(t *testing.T) {
457
459
}
458
460
}
459
461
462
+ // Check for evaluation of env vars with / without `--no-eval`. By default,
463
+ // Singularity will evaluate the value of injected env vars when sourcing the
464
+ // shell script that injects them. With --no-eval it should match Docker, with
465
+ // no evaluation:
466
+ //
467
+ // WHO='$(id -u)' docker run -it --env WHO --rm alpine sh -c 'echo $WHO'
468
+ // $(id -u)
469
+ //
470
+ func (c ctx ) singularityEnvEval (t * testing.T ) {
471
+ e2e .EnsureImage (t , c .env )
472
+
473
+ testArgs := []string {"/bin/sh" , "-c" , "echo $WHO" }
474
+
475
+ tests := []struct {
476
+ name string
477
+ env []string
478
+ args []string
479
+ noeval bool
480
+ expectOutput string
481
+ }{
482
+ // Singularity historic behavior (without --no-eval)
483
+ {
484
+ name : "no env" ,
485
+ args : testArgs ,
486
+ env : []string {},
487
+ noeval : false ,
488
+ expectOutput : "" ,
489
+ },
490
+ {
491
+ name : "string env" ,
492
+ args : testArgs ,
493
+ env : []string {"SINGULARITYENV_WHO=ME" },
494
+ noeval : false ,
495
+ expectOutput : "ME" ,
496
+ },
497
+ {
498
+ name : "env var" ,
499
+ args : testArgs ,
500
+ env : []string {"SINGULARITYENV_WHO=$UID" },
501
+ noeval : false ,
502
+ expectOutput : strconv .Itoa (os .Getuid ()),
503
+ },
504
+ {
505
+ name : "double quoted env var" ,
506
+ args : testArgs ,
507
+ env : []string {"SINGULARITYENV_WHO=\" $UID\" " },
508
+ noeval : false ,
509
+ expectOutput : "\" " + strconv .Itoa (os .Getuid ()) + "\" " ,
510
+ },
511
+ {
512
+ name : "single quoted env var" ,
513
+ args : testArgs ,
514
+ env : []string {"SINGULARITYENV_WHO='$UID'" },
515
+ noeval : false ,
516
+ expectOutput : "'" + strconv .Itoa (os .Getuid ()) + "'" ,
517
+ },
518
+ {
519
+ name : "escaped env var" ,
520
+ args : testArgs ,
521
+ env : []string {"SINGULARITYENV_WHO=\\ $UID" },
522
+ noeval : false ,
523
+ expectOutput : "$UID" ,
524
+ },
525
+ {
526
+ name : "subshell env" ,
527
+ args : testArgs ,
528
+ env : []string {"SINGULARITYENV_WHO=$(id -u)" },
529
+ noeval : false ,
530
+ expectOutput : strconv .Itoa (os .Getuid ()),
531
+ },
532
+ {
533
+ name : "double quoted subshell env" ,
534
+ args : testArgs ,
535
+ env : []string {"SINGULARITYENV_WHO=\" $(id -u)\" " },
536
+ noeval : false ,
537
+ expectOutput : "\" " + strconv .Itoa (os .Getuid ()) + "\" " ,
538
+ },
539
+ {
540
+ name : "single quoted subshell env" ,
541
+ args : testArgs ,
542
+ env : []string {"SINGULARITYENV_WHO='$(id -u)'" },
543
+ noeval : false ,
544
+ expectOutput : "'" + strconv .Itoa (os .Getuid ()) + "'" ,
545
+ },
546
+ {
547
+ name : "escaped subshell env" ,
548
+ args : testArgs ,
549
+ env : []string {"SINGULARITYENV_WHO=\\ $(id -u)" },
550
+ noeval : false ,
551
+ expectOutput : "$(id -u)" ,
552
+ },
553
+ // Docker/OCI behavior (with --no-eval)
554
+ {
555
+ name : "no-eval/no env" ,
556
+ args : testArgs ,
557
+ env : []string {},
558
+ noeval : false ,
559
+ expectOutput : "" ,
560
+ },
561
+ {
562
+ name : "no-eval/string env" ,
563
+ args : testArgs ,
564
+ env : []string {"SINGULARITYENV_WHO=ME" },
565
+ noeval : false ,
566
+ expectOutput : "ME" ,
567
+ },
568
+ {
569
+ name : "no-eval/env var" ,
570
+ args : testArgs ,
571
+ env : []string {"SINGULARITYENV_WHO=$UID" },
572
+ noeval : true ,
573
+ expectOutput : "$UID" ,
574
+ },
575
+ {
576
+ name : "no-eval/double quoted env var" ,
577
+ args : testArgs ,
578
+ env : []string {"SINGULARITYENV_WHO=\" $UID\" " },
579
+ noeval : true ,
580
+ expectOutput : "\" $UID\" " ,
581
+ },
582
+ {
583
+ name : "no-eval/single quoted env var" ,
584
+ args : testArgs ,
585
+ env : []string {"SINGULARITYENV_WHO='$UID'" },
586
+ noeval : true ,
587
+ expectOutput : "'$UID'" ,
588
+ },
589
+ {
590
+ name : "no-eval/escaped env var" ,
591
+ args : testArgs ,
592
+ env : []string {"SINGULARITYENV_WHO=\\ $UID" },
593
+ noeval : true ,
594
+ expectOutput : "\\ $UID" ,
595
+ },
596
+ {
597
+ name : "no-eval/subshell env" ,
598
+ args : testArgs ,
599
+ env : []string {"SINGULARITYENV_WHO=$(id -u)" },
600
+ noeval : true ,
601
+ expectOutput : "$(id -u)" ,
602
+ },
603
+ {
604
+ name : "no-eval/double quoted subshell env" ,
605
+ args : testArgs ,
606
+ env : []string {"SINGULARITYENV_WHO=\" $(id -u)\" " },
607
+ noeval : true ,
608
+ expectOutput : "\" $(id -u)\" " ,
609
+ },
610
+ {
611
+ name : "no-eval/single quoted subshell env" ,
612
+ args : testArgs ,
613
+ env : []string {"SINGULARITYENV_WHO='$(id -u)'" },
614
+ noeval : true ,
615
+ expectOutput : "'$(id -u)'" ,
616
+ },
617
+ {
618
+ name : "no-eval/escaped subshell env" ,
619
+ args : testArgs ,
620
+ env : []string {"SINGULARITYENV_WHO=\\ $(id -u)" },
621
+ noeval : true ,
622
+ expectOutput : "\\ $(id -u)" ,
623
+ },
624
+ }
625
+
626
+ for _ , tt := range tests {
627
+ cmdArgs := []string {}
628
+ if tt .noeval {
629
+ cmdArgs = append (cmdArgs , "--no-eval" )
630
+ }
631
+ cmdArgs = append (cmdArgs , c .env .ImagePath )
632
+ cmdArgs = append (cmdArgs , tt .args ... )
633
+ c .env .RunSingularity (
634
+ t ,
635
+ e2e .AsSubtest (tt .name ),
636
+ e2e .WithEnv (tt .env ),
637
+ e2e .WithProfile (e2e .UserProfile ),
638
+ e2e .WithCommand ("exec" ),
639
+ e2e .WithArgs (cmdArgs ... ),
640
+ e2e .ExpectExit (0 ,
641
+ e2e .ExpectOutput (e2e .ExactMatch , tt .expectOutput ),
642
+ ),
643
+ )
644
+ }
645
+ }
646
+
460
647
// E2ETests is the main func to trigger the test suite
461
648
func E2ETests (env e2e.TestEnv ) testhelper.Tests {
462
649
c := ctx {
@@ -467,6 +654,7 @@ func E2ETests(env e2e.TestEnv) testhelper.Tests {
467
654
"environment manipulation" : c .singularityEnv ,
468
655
"environment option" : c .singularityEnvOption ,
469
656
"environment file" : c .singularityEnvFile ,
657
+ "env eval" : c .singularityEnvEval ,
470
658
"issue 5057" : c .issue5057 , // https://github.com/sylabs/hpcng/issues/5057
471
659
"issue 5426" : c .issue5426 , // https://github.com/sylabs/hpcng/issues/5426
472
660
"issue 43" : c .issue43 , // https://github.com/sylabs/singularity/issues/43
0 commit comments