Skip to content

Commit c0ae7ef

Browse files
committed
e2e: Add SINGULARITYENV_ evaluation test cases
1 parent ceb99ec commit c0ae7ef

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed

e2e/env/env.go

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ package singularityenv
1010

1111
import (
1212
"io/ioutil"
13+
"os"
1314
"path/filepath"
15+
"strconv"
1416
"strings"
1517
"testing"
1618

@@ -457,6 +459,191 @@ func (c ctx) singularityEnvFile(t *testing.T) {
457459
}
458460
}
459461

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+
460647
// E2ETests is the main func to trigger the test suite
461648
func E2ETests(env e2e.TestEnv) testhelper.Tests {
462649
c := ctx{
@@ -467,6 +654,7 @@ func E2ETests(env e2e.TestEnv) testhelper.Tests {
467654
"environment manipulation": c.singularityEnv,
468655
"environment option": c.singularityEnvOption,
469656
"environment file": c.singularityEnvFile,
657+
"env eval": c.singularityEnvEval,
470658
"issue 5057": c.issue5057, // https://github.com/sylabs/hpcng/issues/5057
471659
"issue 5426": c.issue5426, // https://github.com/sylabs/hpcng/issues/5426
472660
"issue 43": c.issue43, // https://github.com/sylabs/singularity/issues/43

0 commit comments

Comments
 (0)