Implement test that pretty-printed code converges. Issue #789
This commit is contained in:
parent
4828d8f73f
commit
1653f3f1a9
@ -26,9 +26,12 @@ type reqchan = chan[request];
|
||||
|
||||
type handle = {task: option::t[task], chan: reqchan};
|
||||
|
||||
tag request { exec(str, str, str[], chan[response]); stop; }
|
||||
tag request {
|
||||
exec(str, str, str[], chan[response]);
|
||||
stop;
|
||||
}
|
||||
|
||||
type response = {pid: int, outfd: int, errfd: int};
|
||||
type response = {pid: int, infd: int, outfd: int, errfd: int};
|
||||
|
||||
fn mk() -> handle {
|
||||
let setupport = port();
|
||||
@ -50,7 +53,8 @@ fn close(handle: &handle) {
|
||||
task::join(option::get(handle.task));
|
||||
}
|
||||
|
||||
fn run(handle: &handle, lib_path: &str, prog: &str, args: &vec[str]) ->
|
||||
fn run(handle: &handle, lib_path: &str,
|
||||
prog: &str, args: &vec[str], input: &option::t[str]) ->
|
||||
{status: int, out: str, err: str} {
|
||||
let p = port[response]();
|
||||
let ch = chan(p);
|
||||
@ -59,12 +63,24 @@ fn run(handle: &handle, lib_path: &str, prog: &str, args: &vec[str]) ->
|
||||
clone_ivecstr(ivec::from_vec(args)),
|
||||
task::clone_chan(ch)));
|
||||
let resp = task::recv(p);
|
||||
|
||||
writeclose(resp.infd, input);
|
||||
let output = readclose(resp.outfd);
|
||||
let errput = readclose(resp.errfd);
|
||||
let status = os::waitpid(resp.pid);
|
||||
ret {status: status, out: output, err: errput};
|
||||
}
|
||||
|
||||
fn writeclose(fd: int, s: &option::t[str]) {
|
||||
if option::is_some(s) {
|
||||
let writer = io::new_writer(
|
||||
io::fd_buf_writer(fd, option::none));
|
||||
writer.write_str(option::get(s));
|
||||
}
|
||||
|
||||
os::libc::close(fd);
|
||||
}
|
||||
|
||||
fn readclose(fd: int) -> str {
|
||||
// Copied from run::program_output
|
||||
let file = os::fd_FILE(fd);
|
||||
@ -128,17 +144,20 @@ fn worker(p: port[request]) {
|
||||
pipe_out.out,
|
||||
pipe_err.out);
|
||||
let pid = with_lib_path(execparms.lib_path, spawnproc);
|
||||
|
||||
os::libc::close(pipe_in.in);
|
||||
os::libc::close(pipe_in.out);
|
||||
os::libc::close(pipe_out.out);
|
||||
os::libc::close(pipe_err.out);
|
||||
if pid == -1 {
|
||||
os::libc::close(pipe_in.out);
|
||||
os::libc::close(pipe_out.in);
|
||||
os::libc::close(pipe_err.in);
|
||||
fail;
|
||||
}
|
||||
|
||||
task::send(execparms.respchan,
|
||||
{pid: pid,
|
||||
infd: pipe_in.out,
|
||||
outfd: pipe_out.in,
|
||||
errfd: pipe_err.in});
|
||||
}
|
||||
|
@ -75,6 +75,74 @@ fn run_rpass_test(cx: &cx, props: &test_props, testfile: &str) {
|
||||
}
|
||||
|
||||
fn run_pretty_test(cx: &cx, props: &test_props, testfile: &str) {
|
||||
const rounds: int = 2;
|
||||
|
||||
let srcs = ~[str::unsafe_from_bytes(
|
||||
io::file_reader(testfile).read_whole_stream())];
|
||||
|
||||
let round = 0;
|
||||
while round < rounds {
|
||||
logv(cx.config, #fmt("pretty-printing round %d", round));
|
||||
let procres = print_source(cx, testfile, srcs.(round));
|
||||
|
||||
if procres.status != 0 {
|
||||
fatal_procres(#fmt("pretty-printing failed in round %d", round),
|
||||
procres);
|
||||
}
|
||||
|
||||
srcs += ~[procres.stdout];
|
||||
round += 1;
|
||||
}
|
||||
|
||||
let expected = srcs.(ivec::len(srcs) - 2u);
|
||||
let actual = srcs.(ivec::len(srcs) - 1u);
|
||||
|
||||
compare_source(expected, actual);
|
||||
|
||||
// Finally, let's make sure it actually appears to remain valid code
|
||||
let procres = typecheck_source(cx, actual);
|
||||
|
||||
if procres.status != 0 {
|
||||
fatal_procres("pretty-printed source does not typecheck",
|
||||
procres);
|
||||
}
|
||||
|
||||
ret;
|
||||
|
||||
fn print_source(cx: &cx, testfile: &str, src: &str) -> procres {
|
||||
compose_and_run(cx, testfile, make_pp_args,
|
||||
cx.config.compile_lib_path, option::some(src))
|
||||
}
|
||||
|
||||
fn make_pp_args(config: &config, testfile: &str) -> procargs {
|
||||
let prog = config.rustc_path;
|
||||
let args = ["-", "--pretty", "normal"];
|
||||
ret {prog: prog, args: args};
|
||||
}
|
||||
|
||||
fn compare_source(expected: &str, actual: &str) {
|
||||
if expected != actual {
|
||||
error("pretty-printed source does not converge");
|
||||
let msg = #fmt("\n\
|
||||
expected:\n\
|
||||
------------------------------------------\n\
|
||||
%s\n\
|
||||
------------------------------------------\n\
|
||||
actual:\n\
|
||||
------------------------------------------\n\
|
||||
%s\n\
|
||||
------------------------------------------\n\
|
||||
\n",
|
||||
expected, actual);
|
||||
io::stdout().write_str(msg);
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
||||
fn typecheck_source(cx: &cx, src: &str) -> procres {
|
||||
// FIXME
|
||||
ret {status: 0, stdout: src, stderr: "", cmdline: ""};
|
||||
}
|
||||
}
|
||||
|
||||
fn check_error_patterns(props: &test_props, testfile: &str,
|
||||
@ -117,19 +185,22 @@ type procres = {status: int, stdout: str, stderr: str, cmdline: str};
|
||||
|
||||
fn compile_test(cx: &cx, props: &test_props, testfile: &str) -> procres {
|
||||
compose_and_run(cx, testfile, bind make_compile_args(_, props, _),
|
||||
cx.config.compile_lib_path)
|
||||
cx.config.compile_lib_path, option::none)
|
||||
}
|
||||
|
||||
fn exec_compiled_test(cx: &cx, testfile: &str) -> procres {
|
||||
compose_and_run(cx, testfile, make_run_args, cx.config.run_lib_path)
|
||||
compose_and_run(cx, testfile, make_run_args,
|
||||
cx.config.run_lib_path, option::none)
|
||||
}
|
||||
|
||||
fn compose_and_run(cx: &cx, testfile: &str,
|
||||
make_args: fn(&config, &str) -> procargs ,
|
||||
lib_path: &str) -> procres {
|
||||
lib_path: &str,
|
||||
input: option::t[str]) -> procres {
|
||||
let procargs = make_args(cx.config, testfile);
|
||||
ret program_output(cx, testfile, lib_path,
|
||||
procargs.prog, procargs.args);
|
||||
procargs.prog, procargs.args,
|
||||
input);
|
||||
}
|
||||
|
||||
fn make_compile_args(config: &config,
|
||||
@ -182,14 +253,15 @@ fn split_maybe_args(argstr: &option::t[str]) -> vec[str] {
|
||||
}
|
||||
|
||||
fn program_output(cx: &cx, testfile: &str, lib_path: &str, prog: &str,
|
||||
args: &vec[str]) -> procres {
|
||||
args: &vec[str], input: option::t[str]) -> procres {
|
||||
let cmdline =
|
||||
{
|
||||
let cmdline = make_cmdline(lib_path, prog, args);
|
||||
logv(cx.config, #fmt("executing %s", cmdline));
|
||||
cmdline
|
||||
};
|
||||
let res = procsrv::run(cx.procsrv, lib_path, prog, args);
|
||||
let res = procsrv::run(cx.procsrv, lib_path,
|
||||
prog, args, input);
|
||||
dump_output(cx.config, testfile, res.out, res.err);
|
||||
ret {status: res.status, stdout: res.out,
|
||||
stderr: res.err, cmdline: cmdline};
|
||||
|
Loading…
Reference in New Issue
Block a user