Skip to content

Commit dfc548d

Browse files
committed
add option exec-env to set env variables during test execution
1 parent d2482fd commit dfc548d

File tree

5 files changed

+69
-34
lines changed

5 files changed

+69
-34
lines changed

src/compiletest/header.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ type test_props = {
1717
// pretty-printed
1818
pp_exact: option<str>,
1919
// Modules from aux directory that should be compiled
20-
aux_builds: [str]
20+
aux_builds: [str],
21+
// Environment settings to use during execution
22+
exec_env: [(str,str)]
2123
};
2224

2325
// Load any test directives embedded in the file
2426
fn load_props(testfile: str) -> test_props {
2527
let mut error_patterns = [];
2628
let mut aux_builds = [];
29+
let mut exec_env = [];
2730
let mut compile_flags = option::none;
2831
let mut pp_exact = option::none;
2932
iter_header(testfile) {|ln|
@@ -43,12 +46,17 @@ fn load_props(testfile: str) -> test_props {
4346
option::iter(parse_aux_build(ln)) {|ab|
4447
aux_builds += [ab];
4548
}
49+
50+
option::iter(parse_exec_env(ln)) {|ee|
51+
exec_env += [ee];
52+
}
4653
};
4754
ret {
4855
error_patterns: error_patterns,
4956
compile_flags: compile_flags,
5057
pp_exact: pp_exact,
51-
aux_builds: aux_builds
58+
aux_builds: aux_builds,
59+
exec_env: exec_env
5260
};
5361
}
5462

@@ -97,6 +105,18 @@ fn parse_compile_flags(line: str) -> option<str> {
97105
parse_name_value_directive(line, "compile-flags")
98106
}
99107

108+
fn parse_exec_env(line: str) -> option<(str, str)> {
109+
parse_name_value_directive(line, "exec-env").map {|nv|
110+
// nv is either FOO or FOO=BAR
111+
let strs = str::splitn_char(nv, '=', 1u);
112+
alt strs.len() {
113+
1u { (strs[0], "") }
114+
2u { (strs[0], strs[1]) }
115+
n { fail #fmt["Expected 1 or 2 strings, not %u", n]; }
116+
}
117+
}
118+
}
119+
100120
fn parse_pp_exact(line: str, testfile: str) -> option<str> {
101121
alt parse_name_value_directive(line, "pp-exact") {
102122
option::some(s) { option::some(s) }

src/compiletest/procsrv.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import libc::{c_int, pid_t};
55
export run;
66

77
#[cfg(target_os = "win32")]
8-
fn target_env(lib_path: str, prog: str) -> option<[(str,str)]> {
8+
fn target_env(lib_path: str, prog: str) -> [(str,str)] {
99

1010
let env = os::env();
1111

@@ -17,25 +17,29 @@ fn target_env(lib_path: str, prog: str) -> option<[(str,str)]> {
1717
if str::ends_with(prog, "rustc.exe") {
1818
env += [("RUST_THREADS", "1")]
1919
}
20-
ret some(env);
20+
ret env;
2121
}
2222

2323
#[cfg(target_os = "linux")]
2424
#[cfg(target_os = "macos")]
2525
#[cfg(target_os = "freebsd")]
26-
fn target_env(_lib_path: str, _prog: str) -> option<[(str,str)]> {
27-
none
26+
fn target_env(_lib_path: str, _prog: str) -> [(str,str)] {
27+
[]
2828
}
2929

3030

31-
fn run(lib_path: str, prog: str, args: [str],
31+
fn run(lib_path: str,
32+
prog: str,
33+
args: [str],
34+
env: [(str, str)],
3235
input: option<str>) -> {status: int, out: str, err: str} {
3336

3437
let pipe_in = os::pipe();
3538
let pipe_out = os::pipe();
3639
let pipe_err = os::pipe();
37-
let pid = spawn_process(prog, args, target_env(lib_path, prog), none,
38-
pipe_in.in, pipe_out.out, pipe_err.out);
40+
let pid = spawn_process(prog, args,
41+
some(env + target_env(lib_path, prog)),
42+
none, pipe_in.in, pipe_out.out, pipe_err.out);
3943

4044
os::close(pipe_in.in);
4145
os::close(pipe_out.out);

src/compiletest/runtest.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ fn run_rpass_test(config: config, props: test_props, testfile: str) {
8181

8282
procres = exec_compiled_test(config, props, testfile);
8383

84-
8584
if procres.status != 0 { fatal_procres("test run failed!", procres); }
8685
}
8786

@@ -139,8 +138,8 @@ fn run_pretty_test(config: config, props: test_props, testfile: str) {
139138
ret;
140139

141140
fn print_source(config: config, testfile: str, src: str) -> procres {
142-
compose_and_run(config, testfile, make_pp_args,
143-
config.compile_lib_path, option::some(src))
141+
compose_and_run(config, testfile, make_pp_args(config, testfile),
142+
[], config.compile_lib_path, option::some(src))
144143
}
145144

146145
fn make_pp_args(config: config, _testfile: str) -> procargs {
@@ -172,7 +171,9 @@ actual:\n\
172171
fn typecheck_source(config: config, props: test_props,
173172
testfile: str, src: str) -> procres {
174173
compose_and_run_compiler(
175-
config, props, testfile, make_typecheck_args, option::some(src))
174+
config, props, testfile,
175+
make_typecheck_args(config, testfile),
176+
option::some(src))
176177
}
177178

178179
fn make_typecheck_args(config: config, testfile: str) -> procargs {
@@ -292,24 +293,26 @@ type procres = {status: int, stdout: str, stderr: str, cmdline: str};
292293
fn compile_test(config: config, props: test_props,
293294
testfile: str) -> procres {
294295
let link_args = ["-L", aux_output_dir_name(config, testfile)];
295-
compose_and_run_compiler(config, props, testfile,
296-
make_compile_args(_, props, link_args,
297-
make_exe_name, _),
298-
none)
296+
compose_and_run_compiler(
297+
config, props, testfile,
298+
make_compile_args(config, props, link_args,
299+
make_exe_name, testfile),
300+
none)
299301
}
300302

301303
fn exec_compiled_test(config: config, props: test_props,
302304
testfile: str) -> procres {
303305
compose_and_run(config, testfile,
304-
bind make_run_args(_, props, _),
305-
config.run_lib_path, option::none)
306+
make_run_args(config, props, testfile),
307+
props.exec_env,
308+
config.run_lib_path, option::none)
306309
}
307310

308311
fn compose_and_run_compiler(
309312
config: config,
310313
props: test_props,
311314
testfile: str,
312-
mk_args: fn(config: config, _testfile: str) -> procargs,
315+
args: procargs,
313316
input: option<str>) -> procres {
314317

315318
if props.aux_builds.is_not_empty() {
@@ -320,10 +323,10 @@ fn compose_and_run_compiler(
320323

321324
vec::iter(props.aux_builds) {|rel_ab|
322325
let abs_ab = path::connect(config.aux_base, rel_ab);
323-
let mk_compile_args =
324-
make_compile_args(_, props, ["--lib"] + extra_link_args,
325-
bind make_lib_name(_, _, testfile), _);
326-
let auxres = compose_and_run(config, abs_ab, mk_compile_args,
326+
let aux_args =
327+
make_compile_args(config, props, ["--lib"] + extra_link_args,
328+
bind make_lib_name(_, _, testfile), abs_ab);
329+
let auxres = compose_and_run(config, abs_ab, aux_args, [],
327330
config.compile_lib_path, option::none);
328331
if auxres.status != 0 {
329332
fatal_procres(
@@ -332,7 +335,7 @@ fn compose_and_run_compiler(
332335
}
333336
}
334337

335-
compose_and_run(config, testfile, mk_args,
338+
compose_and_run(config, testfile, args, [],
336339
config.compile_lib_path, input)
337340
}
338341

@@ -344,11 +347,12 @@ fn ensure_dir(path: path) {
344347
}
345348

346349
fn compose_and_run(config: config, testfile: str,
347-
make_args: fn(config, str) -> procargs, lib_path: str,
350+
procargs: procargs,
351+
procenv: [(str, str)],
352+
lib_path: str,
348353
input: option<str>) -> procres {
349-
let procargs = make_args(config, testfile);
350354
ret program_output(config, testfile, lib_path,
351-
procargs.prog, procargs.args, input);
355+
procargs.prog, procargs.args, procenv, input);
352356
}
353357

354358
fn make_compile_args(config: config, props: test_props, extras: [str],
@@ -405,14 +409,15 @@ fn split_maybe_args(argstr: option<str>) -> [str] {
405409
}
406410

407411
fn program_output(config: config, testfile: str, lib_path: str, prog: str,
408-
args: [str], input: option<str>) -> procres {
412+
args: [str], env: [(str, str)],
413+
input: option<str>) -> procres {
409414
let cmdline =
410415
{
411416
let cmdline = make_cmdline(lib_path, prog, args);
412417
logv(config, #fmt["executing %s", cmdline]);
413418
cmdline
414419
};
415-
let res = procsrv::run(lib_path, prog, args, input);
420+
let res = procsrv::run(lib_path, prog, args, env, input);
416421
dump_output(config, testfile, res.out, res.err);
417422
ret {status: res.status,
418423
stdout: res.out,

src/libcore/run.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
9898
// On posixy systems we can pass a char** for envp, which is
9999
// a null-terminated array of "k=v\n" strings.
100100
alt env {
101-
some (es) {
101+
some(es) if !vec::is_empty(es) {
102102
let mut tmps = [];
103103
let mut ptrs = [];
104104

@@ -111,7 +111,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
111111
ptrs += [ptr::null()];
112112
vec::as_buf(ptrs) { |p| cb(::unsafe::reinterpret_cast(p)) }
113113
}
114-
none {
114+
_ {
115115
cb(ptr::null())
116116
}
117117
}
@@ -124,7 +124,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
124124
// rather a concatenation of null-terminated k=v\0 sequences, with a final
125125
// \0 to terminate.
126126
alt env {
127-
some (es) {
127+
some(es) if !vec::is_empty(es) {
128128
let mut blk : [u8] = [];
129129
for vec::each(es) {|e|
130130
let (k,v) = e;
@@ -136,7 +136,7 @@ fn with_envp<T>(env: option<[(str,str)]>,
136136
blk += [0_u8];
137137
vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
138138
}
139-
none {
139+
_ {
140140
cb(ptr::null())
141141
}
142142
}

src/test/run-pass/exec-env.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// xfail-fast (exec-env not supported in fast mode)
2+
// exec-env:TEST_EXEC_ENV=22
3+
4+
fn main() {
5+
assert os::getenv("TEST_EXEC_ENV") == some("22");
6+
}

0 commit comments

Comments
 (0)