pub pretty_mode: String,
// Only compare pretty output and don't try compiling
pub pretty_compare_only: bool,
+ // Patterns which must not appear in the output of a cfail test.
+ pub forbid_output: Vec<String>,
}
// Load any test directives embedded in the file
let mut no_pretty_expanded = false;
let mut pretty_mode = None;
let mut pretty_compare_only = false;
+ let mut forbid_output = Vec::new();
iter_header(testfile, |ln| {
match parse_error_pattern(ln) {
Some(ep) => error_patterns.push(ep),
None => ()
};
+ match parse_forbid_output(ln) {
+ Some(of) => forbid_output.push(of),
+ None => (),
+ }
+
true
});
no_prefer_dynamic: no_prefer_dynamic,
no_pretty_expanded: no_pretty_expanded,
pretty_mode: pretty_mode.unwrap_or("normal".to_string()),
- pretty_compare_only: pretty_compare_only
+ pretty_compare_only: pretty_compare_only,
+ forbid_output: forbid_output,
}
}
parse_name_value_directive(line, "error-pattern")
}
+fn parse_forbid_output(line: &str) -> Option<String> {
+ parse_name_value_directive(line, "forbid-output")
+}
+
fn parse_aux_build(line: &str) -> Option<String> {
parse_name_value_directive(line, "aux-build")
}
}
}
+fn get_output(props: &TestProps, proc_res: &ProcRes) -> String {
+ if props.check_stdout {
+ format!("{}{}", proc_res.stdout, proc_res.stderr)
+ } else {
+ proc_res.stderr.clone()
+ }
+}
+
fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
let proc_res = compile_test(config, props, testfile);
check_correct_failure_status(&proc_res);
+ if proc_res.status.success() {
+ fatal("process did not return an error status");
+ }
+
+ let output_to_check = get_output(props, &proc_res);
let expected_errors = errors::load_errors(&config.cfail_regex, testfile);
if !expected_errors.is_empty() {
if !props.error_patterns.is_empty() {
}
check_expected_errors(expected_errors, testfile, &proc_res);
} else {
- check_error_patterns(props, testfile, &proc_res);
+ check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res);
}
check_no_compiler_crash(&proc_res);
+ check_forbid_output(props, output_to_check.as_slice(), &proc_res);
}
fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
}
+ let output_to_check = get_output(props, &proc_res);
check_correct_failure_status(&proc_res);
- check_error_patterns(props, testfile, &proc_res);
+ check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res);
}
fn check_correct_failure_status(proc_res: &ProcRes) {
fn check_error_patterns(props: &TestProps,
testfile: &Path,
+ output_to_check: &str,
proc_res: &ProcRes) {
if props.error_patterns.is_empty() {
fatal(format!("no error pattern specified in {}",
testfile.display()).as_slice());
}
-
- if proc_res.status.success() {
- fatal("process did not return an error status");
- }
-
let mut next_err_idx = 0u;
let mut next_err_pat = &props.error_patterns[next_err_idx];
let mut done = false;
- let output_to_check = if props.check_stdout {
- format!("{}{}", proc_res.stdout, proc_res.stderr)
- } else {
- proc_res.stderr.clone()
- };
for line in output_to_check.as_slice().lines() {
if line.contains(next_err_pat.as_slice()) {
debug!("found error pattern {}", next_err_pat);
}
}
+fn check_forbid_output(props: &TestProps,
+ output_to_check: &str,
+ proc_res: &ProcRes) {
+ for pat in props.forbid_output.iter() {
+ if output_to_check.contains(pat.as_slice()) {
+ fatal_proc_rec("forbidden pattern found in compiler output", proc_res);
+ }
+ }
+}
+
fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
testfile: &Path,
proc_res: &ProcRes) {