Browse Source

Implement the 'test print-cfg' sub-test.

Move the CFG tests into the filetests directory.

Remove the tests directory, there are no more shell-driven tests left.
pull/3/head
Jakob Stoklund Olesen 8 years ago
parent
commit
78a2e47d95
  1. 1
      filetests/cfg/loop.cton
  2. 1
      filetests/cfg/traps_early.cton
  3. 1
      filetests/cfg/unused_node.cton
  4. 2
      src/tools/filetest/subtest.rs
  5. 31
      src/tools/print_cfg.rs
  6. 5
      test-all.sh
  7. 14
      tests/cfg/README.rst
  8. 36
      tests/cfg/run.sh

1
tests/cfg/loop.cton → filetests/cfg/loop.cton

@ -1,4 +1,5 @@
; For testing cfg generation. This code is nonsense. ; For testing cfg generation. This code is nonsense.
test print-cfg
function nonsense(i32, i32) -> f32 { function nonsense(i32, i32) -> f32 {
; check: digraph nonsense { ; check: digraph nonsense {

1
tests/cfg/traps_early.cton → filetests/cfg/traps_early.cton

@ -1,5 +1,6 @@
; For testing cfg generation. This code explores the implications of encountering ; For testing cfg generation. This code explores the implications of encountering
; a terminating instruction before any connections have been made. ; a terminating instruction before any connections have been made.
test print-cfg
function nonsense(i32) { function nonsense(i32) {
; check: digraph nonsense { ; check: digraph nonsense {

1
tests/cfg/unused_node.cton → filetests/cfg/unused_node.cton

@ -1,4 +1,5 @@
; For testing cfg generation where some block is never reached. ; For testing cfg generation where some block is never reached.
test print-cfg
function not_reached(i32) -> i32 { function not_reached(i32) -> i32 {
; check: digraph not_reached { ; check: digraph not_reached {

2
src/tools/filetest/subtest.rs

@ -11,8 +11,10 @@ pub type Result<T> = result::Result<T, String>;
/// Create a new subcommand trait object to match `parsed.command`. /// Create a new subcommand trait object to match `parsed.command`.
pub fn new(parsed: &TestCommand) -> Result<Box<SubTest>> { pub fn new(parsed: &TestCommand) -> Result<Box<SubTest>> {
use cat; use cat;
use print_cfg;
match parsed.command { match parsed.command {
"cat" => cat::subtest(parsed), "cat" => cat::subtest(parsed),
"print-cfg" => print_cfg::subtest(parsed),
_ => Err(format!("unknown test command '{}'", parsed.command)), _ => Err(format!("unknown test command '{}'", parsed.command)),
} }
} }

31
src/tools/print_cfg.rs

@ -2,14 +2,17 @@
//! //!
//! Read a series of Cretonne IL files and print their control flow graphs //! Read a series of Cretonne IL files and print their control flow graphs
//! in graphviz format. //! in graphviz format.
use std::borrow::Cow;
use std::fmt::{Result, Write, Display, Formatter}; use std::fmt::{Result, Write, Display, Formatter};
use CommandResult; use CommandResult;
use utils::read_to_string; use utils::read_to_string;
use filetest::subtest::{self, SubTest, Context, Result as STResult};
use cretonne::ir::Function; use cretonne::ir::Function;
use cretonne::cfg::ControlFlowGraph; use cretonne::cfg::ControlFlowGraph;
use cretonne::ir::instructions::BranchInfo; use cretonne::ir::instructions::BranchInfo;
use cton_reader::parse_functions; use cton_reader::{parse_functions, TestCommand};
pub fn run(files: Vec<String>) -> CommandResult { pub fn run(files: Vec<String>) -> CommandResult {
for (i, f) in files.into_iter().enumerate() { for (i, f) in files.into_iter().enumerate() {
@ -100,3 +103,29 @@ fn print_cfg(filename: String) -> CommandResult {
Ok(()) Ok(())
} }
/// Object implementing the `test print-cfg` sub-test.
struct TestPrintCfg;
pub fn subtest(parsed: &TestCommand) -> STResult<Box<SubTest>> {
assert_eq!(parsed.command, "print-cfg");
if !parsed.options.is_empty() {
Err(format!("No options allowed on {}", parsed))
} else {
Ok(Box::new(TestPrintCfg))
}
}
impl SubTest for TestPrintCfg {
fn name(&self) -> Cow<str> {
Cow::from("print-cfg")
}
fn needs_verifier(&self) -> bool {
false
}
fn run(&self, func: Cow<Function>, context: &Context) -> STResult<()> {
subtest::run_filecheck(&CFGPrinter::new(&func).to_string(), context)
}
}

5
test-all.sh

@ -62,9 +62,4 @@ cd "$topdir"
banner "File tests" banner "File tests"
"$CTONUTIL" test filetests "$CTONUTIL" test filetests
# Run the parser tests.
cd "$topdir/tests"
banner "CFG tests"
cfg/run.sh
banner "OK" banner "OK"

14
tests/cfg/README.rst

@ -1,14 +0,0 @@
CFG tests
============
This directory contains test cases for the Cretonne cfg printer.
Each test case consists of a `foo.cton` input file annotated with its expected connections.
Annotations are comments of the form: `ebbx:insty -> ebbz` where ebbx is connected to ebbz via
a branch or jump instruction at line y. Instructions are labeled by line number starting from zero: `inst0` .. `instn`.
Each input file is run through the `cton-util print-cfg` command and the
output is compared against the specially formatted comments to ensure that
expected connections exist. This scheme allows for changes to graph style
without the need to update tests.

36
tests/cfg/run.sh

@ -1,36 +0,0 @@
#!/bin/bash
# Go to tests directory.
cd $(dirname "$0")/..
# The path to cton-util should be in $CTONUTIL.
if [ -z "$CTONUTIL" ]; then
CTONUTIL=../src/tools/target/debug/cton-util
fi
if [ ! -x "$CTONUTIL" ]; then
echo "Can't fund executable cton-util: $CTONUTIL" 1>&2
exit 1
fi
declare -a fails
for testcase in $(find cfg -name '*.cton'); do
if "${CTONUTIL}" print-cfg "$testcase" | "${CTONUTIL}" filecheck "$testcase"; then
echo OK $testcase
else
fails=(${fails[@]} "$testcase")
echo FAIL $testcase
fi
done
if [ ${#fails[@]} -ne 0 ]; then
echo
echo Failures:
for f in "${fails[@]}"; do
echo " $f"
done
exit 1
else
echo "All passed"
fi
Loading…
Cancel
Save