about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-04-13 09:19:07 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-04-13 12:41:37 -0700
commitdfc548dddafbf4e58a568329ebbe29f1eb36a0e8 (patch)
tree2a5556c9569230186275df690e96c1f5318f5128 /src
parentd2482fd7631d05b1888e3beac0df3f25d33867b8 (diff)
downloadrust-dfc548dddafbf4e58a568329ebbe29f1eb36a0e8.tar.gz
rust-dfc548dddafbf4e58a568329ebbe29f1eb36a0e8.zip
add option exec-env to set env variables during test execution
Diffstat (limited to 'src')
-rw-r--r--src/compiletest/header.rs24
-rw-r--r--src/compiletest/procsrv.rs18
-rw-r--r--src/compiletest/runtest.rs47
-rw-r--r--src/libcore/run.rs8
-rw-r--r--src/test/run-pass/exec-env.rs6
5 files changed, 69 insertions, 34 deletions
diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs
index 75f4eb98050..0db9672f50d 100644
--- a/src/compiletest/header.rs
+++ b/src/compiletest/header.rs
@@ -17,13 +17,16 @@ type test_props = {
     // pretty-printed
     pp_exact: option<str>,
     // Modules from aux directory that should be compiled
-    aux_builds: [str]
+    aux_builds: [str],
+    // Environment settings to use during execution
+    exec_env: [(str,str)]
 };
 
 // Load any test directives embedded in the file
 fn load_props(testfile: str) -> test_props {
     let mut error_patterns = [];
     let mut aux_builds = [];
+    let mut exec_env = [];
     let mut compile_flags = option::none;
     let mut pp_exact = option::none;
     iter_header(testfile) {|ln|
@@ -43,12 +46,17 @@ fn load_props(testfile: str) -> test_props {
         option::iter(parse_aux_build(ln)) {|ab|
             aux_builds += [ab];
         }
+
+        option::iter(parse_exec_env(ln)) {|ee|
+            exec_env += [ee];
+        }
     };
     ret {
         error_patterns: error_patterns,
         compile_flags: compile_flags,
         pp_exact: pp_exact,
-        aux_builds: aux_builds
+        aux_builds: aux_builds,
+        exec_env: exec_env
     };
 }
 
@@ -97,6 +105,18 @@ fn parse_compile_flags(line: str) -> option<str> {
     parse_name_value_directive(line, "compile-flags")
 }
 
+fn parse_exec_env(line: str) -> option<(str, str)> {
+    parse_name_value_directive(line, "exec-env").map {|nv|
+        // nv is either FOO or FOO=BAR
+        let strs = str::splitn_char(nv, '=', 1u);
+        alt strs.len() {
+          1u { (strs[0], "") }
+          2u { (strs[0], strs[1]) }
+          n { fail #fmt["Expected 1 or 2 strings, not %u", n]; }
+        }
+    }
+}
+
 fn parse_pp_exact(line: str, testfile: str) -> option<str> {
     alt parse_name_value_directive(line, "pp-exact") {
       option::some(s) { option::some(s) }
diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs
index d9a27b405de..dc7a3f384cc 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/compiletest/procsrv.rs
@@ -5,7 +5,7 @@ import libc::{c_int, pid_t};
 export run;
 
 #[cfg(target_os = "win32")]
-fn target_env(lib_path: str, prog: str) -> option<[(str,str)]> {
+fn target_env(lib_path: str, prog: str) -> [(str,str)] {
 
     let env = os::env();
 
@@ -17,25 +17,29 @@ fn target_env(lib_path: str, prog: str) -> option<[(str,str)]> {
     if str::ends_with(prog, "rustc.exe") {
         env += [("RUST_THREADS", "1")]
     }
-    ret some(env);
+    ret env;
 }
 
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
-fn target_env(_lib_path: str, _prog: str) -> option<[(str,str)]> {
-    none
+fn target_env(_lib_path: str, _prog: str) -> [(str,str)] {
+    []
 }
 
 
-fn run(lib_path: str, prog: str, args: [str],
+fn run(lib_path: str,
+       prog: str,
+       args: [str],
+       env: [(str, str)],
        input: option<str>) -> {status: int, out: str, err: str} {
 
     let pipe_in = os::pipe();
     let pipe_out = os::pipe();
     let pipe_err = os::pipe();
-    let pid = spawn_process(prog, args, target_env(lib_path, prog), none,
-                            pipe_in.in, pipe_out.out, pipe_err.out);
+    let pid = spawn_process(prog, args,
+                            some(env + target_env(lib_path, prog)),
+                            none, pipe_in.in, pipe_out.out, pipe_err.out);
 
     os::close(pipe_in.in);
     os::close(pipe_out.out);
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 390facbec3d..b86cd334c79 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -81,7 +81,6 @@ fn run_rpass_test(config: config, props: test_props, testfile: str) {
 
     procres = exec_compiled_test(config, props, testfile);
 
-
     if procres.status != 0 { fatal_procres("test run failed!", procres); }
 }
 
@@ -139,8 +138,8 @@ fn run_pretty_test(config: config, props: test_props, testfile: str) {
     ret;
 
     fn print_source(config: config, testfile: str, src: str) -> procres {
-        compose_and_run(config, testfile, make_pp_args,
-                        config.compile_lib_path, option::some(src))
+        compose_and_run(config, testfile, make_pp_args(config, testfile),
+                        [], config.compile_lib_path, option::some(src))
     }
 
     fn make_pp_args(config: config, _testfile: str) -> procargs {
@@ -172,7 +171,9 @@ actual:\n\
     fn typecheck_source(config: config, props: test_props,
                         testfile: str, src: str) -> procres {
         compose_and_run_compiler(
-            config, props, testfile, make_typecheck_args, option::some(src))
+            config, props, testfile,
+            make_typecheck_args(config, testfile),
+            option::some(src))
     }
 
     fn make_typecheck_args(config: config, testfile: str) -> procargs {
@@ -292,24 +293,26 @@ type procres = {status: int, stdout: str, stderr: str, cmdline: str};
 fn compile_test(config: config, props: test_props,
                 testfile: str) -> procres {
     let link_args = ["-L", aux_output_dir_name(config, testfile)];
-    compose_and_run_compiler(config, props, testfile,
-                             make_compile_args(_, props, link_args,
-                                               make_exe_name, _),
-                             none)
+    compose_and_run_compiler(
+        config, props, testfile,
+        make_compile_args(config, props, link_args,
+                          make_exe_name, testfile),
+        none)
 }
 
 fn exec_compiled_test(config: config, props: test_props,
                       testfile: str) -> procres {
     compose_and_run(config, testfile,
-                             bind make_run_args(_, props, _),
-                             config.run_lib_path, option::none)
+                    make_run_args(config, props, testfile),
+                    props.exec_env,
+                    config.run_lib_path, option::none)
 }
 
 fn compose_and_run_compiler(
     config: config,
     props: test_props,
     testfile: str,
-    mk_args: fn(config: config, _testfile: str) -> procargs,
+    args: procargs,
     input: option<str>) -> procres {
 
     if props.aux_builds.is_not_empty() {
@@ -320,10 +323,10 @@ fn compose_and_run_compiler(
 
     vec::iter(props.aux_builds) {|rel_ab|
         let abs_ab = path::connect(config.aux_base, rel_ab);
-        let mk_compile_args =
-            make_compile_args(_, props, ["--lib"] + extra_link_args,
-                              bind make_lib_name(_, _, testfile), _);
-        let auxres = compose_and_run(config, abs_ab, mk_compile_args,
+        let aux_args =
+            make_compile_args(config, props, ["--lib"] + extra_link_args,
+                              bind make_lib_name(_, _, testfile), abs_ab);
+        let auxres = compose_and_run(config, abs_ab, aux_args, [],
                                      config.compile_lib_path, option::none);
         if auxres.status != 0 {
             fatal_procres(
@@ -332,7 +335,7 @@ fn compose_and_run_compiler(
         }
     }
 
-    compose_and_run(config, testfile, mk_args,
+    compose_and_run(config, testfile, args, [],
                     config.compile_lib_path, input)
 }
 
@@ -344,11 +347,12 @@ fn ensure_dir(path: path) {
 }
 
 fn compose_and_run(config: config, testfile: str,
-                   make_args: fn(config, str) -> procargs, lib_path: str,
+                   procargs: procargs,
+                   procenv: [(str, str)],
+                   lib_path: str,
                    input: option<str>) -> procres {
-    let procargs = make_args(config, testfile);
     ret program_output(config, testfile, lib_path,
-                       procargs.prog, procargs.args, input);
+                       procargs.prog, procargs.args, procenv, input);
 }
 
 fn make_compile_args(config: config, props: test_props, extras: [str],
@@ -405,14 +409,15 @@ fn split_maybe_args(argstr: option<str>) -> [str] {
 }
 
 fn program_output(config: config, testfile: str, lib_path: str, prog: str,
-                  args: [str], input: option<str>) -> procres {
+                  args: [str], env: [(str, str)],
+                  input: option<str>) -> procres {
     let cmdline =
         {
             let cmdline = make_cmdline(lib_path, prog, args);
             logv(config, #fmt["executing %s", cmdline]);
             cmdline
         };
-    let res = procsrv::run(lib_path, prog, args, input);
+    let res = procsrv::run(lib_path, prog, args, env, input);
     dump_output(config, testfile, res.out, res.err);
     ret {status: res.status,
          stdout: res.out,
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index 0b82d79b331..34ba16844d8 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -98,7 +98,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
     // On posixy systems we can pass a char** for envp, which is
     // a null-terminated array of "k=v\n" strings.
     alt env {
-      some (es) {
+      some(es) if !vec::is_empty(es) {
         let mut tmps = [];
         let mut ptrs = [];
 
@@ -111,7 +111,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
         ptrs += [ptr::null()];
         vec::as_buf(ptrs) { |p| cb(::unsafe::reinterpret_cast(p)) }
       }
-      none {
+      _ {
         cb(ptr::null())
       }
     }
@@ -124,7 +124,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
     // \0 to terminate.
     alt env {
-      some (es) {
+      some(es) if !vec::is_empty(es) {
         let mut blk : [u8] = [];
         for vec::each(es) {|e|
             let (k,v) = e;
@@ -136,7 +136,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
         blk += [0_u8];
         vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
       }
-      none {
+      _ {
         cb(ptr::null())
       }
     }
diff --git a/src/test/run-pass/exec-env.rs b/src/test/run-pass/exec-env.rs
new file mode 100644
index 00000000000..cddcd4987e5
--- /dev/null
+++ b/src/test/run-pass/exec-env.rs
@@ -0,0 +1,6 @@
+// xfail-fast (exec-env not supported in fast mode)
+// exec-env:TEST_EXEC_ENV=22
+
+fn main() {
+    assert os::getenv("TEST_EXEC_ENV") == some("22");
+}