Index: llvm/utils/lit/lit/TestRunner.py =================================================================== --- llvm/utils/lit/lit/TestRunner.py +++ llvm/utils/lit/lit/TestRunner.py @@ -236,7 +236,9 @@ return ''.join(result) # args are from 'export' or 'env' command. -# Returns copy of args without those commands or their arguments. +# Skips the command, and parses its arguments. +# Modifies env accordingly. +# Returns copy of args without the command or its arguments. def updateEnv(env, args): arg_idx_next = len(args) unset_next_env_var = False @@ -840,12 +842,16 @@ # Reference the global environment by default. cmd_shenv = shenv args = list(j.args) - if j.args[0] == 'env': + while args[0] == 'env': # Create a copy of the global environment and modify it for this one - # command. There might be multiple envs in a pipeline: + # command. There might be multiple envs in a pipeline, and + # there might be multiple envs in a command (usually when one comes + # from a substitution): # env FOO=1 llc < %s | env BAR=2 llvm-mc | FileCheck %s - cmd_shenv = ShellEnvironment(shenv.cwd, shenv.env) - args = updateEnv(cmd_shenv, j.args) + # env FOO=1 %{another_env_plus_cmd} | FileCheck %s + if cmd_shenv is shenv: + cmd_shenv = ShellEnvironment(shenv.cwd, shenv.env) + args = updateEnv(cmd_shenv, args) if not args: raise InternalShellError(j, "Error: 'env' requires a subcommand") Index: llvm/utils/lit/tests/Inputs/shtest-env/env-args-nested-none.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-args-nested-none.txt @@ -0,0 +1 @@ +# RUN: env env env Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-cd.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-cd.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 cd foobar Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-colon.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-colon.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 : Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-diff.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-diff.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 diff foo.txt bar.txt Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-echo.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-echo.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 echo hello world Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-env.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-env.txt @@ -0,0 +1,32 @@ +# Check that internal env can call internal env. + +# RUN: env env %{python} print_environment.py \ +# RUN: | FileCheck -check-prefix=CHECK-2-EMPTY %s +# +# CHECK-2-EMPTY: BAR = 2 +# CHECK-2-EMPTY: FOO = 1 + +# RUN: env FOO=2 env BAR=1 %{python} print_environment.py \ +# RUN: | FileCheck -check-prefix=CHECK-2-VAL %s +# +# CHECK-2-VAL: BAR = 1 +# CHECK-2-VAL: FOO = 2 + +# RUN: env -u FOO env -u BAR %{python} print_environment.py \ +# RUN: | FileCheck -check-prefix=CHECK-2-U %s +# +# CHECK-2-U-NOT: BAR +# CHECK-2-U-NOT: FOO + +# RUN: env -u FOO BAR=1 env -u BAR FOO=2 %{python} print_environment.py \ +# RUN: | FileCheck -check-prefix=CHECK-2-U-VAL %s +# +# CHECK-2-U-VAL-NOT: BAR +# CHECK-2-U-VAL: FOO = 2 + +# RUN: env -u FOO BAR=1 env -u BAR FOO=2 env BAZ=3 %{python} print_environment.py \ +# RUN: | FileCheck -check-prefix=CHECK-3 %s +# +# CHECK-3-NOT: BAR +# CHECK-3: BAZ = 3 +# CHECK-3: FOO = 2 Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-export.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-export.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 export BAZ=3 Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-mkdir.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-mkdir.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 mkdir foobar Index: llvm/utils/lit/tests/Inputs/shtest-env/env-calls-rm.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-env/env-calls-rm.txt @@ -0,0 +1 @@ +# RUN: env -u FOO BAR=3 rm foobar Index: llvm/utils/lit/tests/shtest-env.py =================================================================== --- llvm/utils/lit/tests/shtest-env.py +++ llvm/utils/lit/tests/shtest-env.py @@ -7,7 +7,7 @@ # Make sure env commands are included in printed commands. -# CHECK: -- Testing: 7 tests{{.*}} +# CHECK: -- Testing: 16 tests{{.*}} # CHECK: FAIL: shtest-env :: env-args-last-is-assign.txt ({{[^)]*}}) # CHECK: Error: 'env' requires a subcommand @@ -21,23 +21,66 @@ # CHECK: Error: 'env' requires a subcommand # CHECK: error: command failed with exit status: {{.*}} +# CHECK: FAIL: shtest-env :: env-args-nested-none.txt ({{[^)]*}}) +# CHECK: Error: 'env' requires a subcommand +# CHECK: error: command failed with exit status: {{.*}} + # CHECK: FAIL: shtest-env :: env-args-none.txt ({{[^)]*}}) # CHECK: Error: 'env' requires a subcommand # CHECK: error: command failed with exit status: {{.*}} +# CHECK: FAIL: shtest-env :: env-calls-cd.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'cd' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: FAIL: shtest-env :: env-calls-colon.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call ':' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: FAIL: shtest-env :: env-calls-diff.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'diff' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: FAIL: shtest-env :: env-calls-echo.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'echo' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: PASS: shtest-env :: env-calls-env.txt ({{[^)]*}}) +# CHECK: $ "env" "env" "{{[^"]*}}" "print_environment.py" +# CHECK: $ "env" "FOO=2" "env" "BAR=1" "{{[^"]*}}" "print_environment.py" +# CHECK: $ "env" "-u" "FOO" "env" "-u" "BAR" "{{[^"]*}}" "print_environment.py" +# CHECK: $ "env" "-u" "FOO" "BAR=1" "env" "-u" "BAR" "FOO=2" "{{[^"]*}}" "print_environment.py" +# CHECK: $ "env" "-u" "FOO" "BAR=1" "env" "-u" "BAR" "FOO=2" "env" "BAZ=3" "{{[^"]*}}" "print_environment.py" +# CHECK-NOT: ${{.*}}print_environment.py + +# CHECK: FAIL: shtest-env :: env-calls-export.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'export' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: FAIL: shtest-env :: env-calls-mkdir.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'mkdir' +# CHECK: error: command failed with exit status: {{.*}} + +# CHECK: FAIL: shtest-env :: env-calls-rm.txt ({{[^)]*}}) +# CHECK: Error: 'env' cannot call 'rm' +# CHECK: error: command failed with exit status: {{.*}} + # CHECK: PASS: shtest-env :: env-u.txt ({{[^)]*}}) # CHECK: $ "{{[^"]*}}" "print_environment.py" # CHECK: $ "env" "-u" "FOO" "{{[^"]*}}" "print_environment.py" # CHECK: $ "env" "-u" "FOO" "-u" "BAR" "{{[^"]*}}" "print_environment.py" +# CHECK-NOT: ${{.*}}print_environment.py # CHECK: PASS: shtest-env :: env.txt ({{[^)]*}}) # CHECK: $ "env" "A_FOO=999" "{{[^"]*}}" "print_environment.py" # CHECK: $ "env" "A_FOO=1" "B_BAR=2" "C_OOF=3" "{{[^"]*}}" "print_environment.py" +# CHECK-NOT: ${{.*}}print_environment.py # CHECK: PASS: shtest-env :: mixed.txt ({{[^)]*}}) # CHECK: $ "env" "A_FOO=999" "-u" "FOO" "{{[^"]*}}" "print_environment.py" # CHECK: $ "env" "A_FOO=1" "-u" "FOO" "B_BAR=2" "-u" "BAR" "C_OOF=3" "{{[^"]*}}" "print_environment.py" +# CHECK-NOT: ${{.*}}print_environment.py -# CHECK: Expected Passes : 3 -# CHECK: Unexpected Failures: 4 +# CHECK: Expected Passes : 4 +# CHECK: Unexpected Failures: 12 # CHECK-NOT: {{.}}