summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-04-01 22:56:55 +0200
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2016-04-25 22:19:29 +0200
commite11db1977941706682ef9433994feb3040871842 (patch)
tree67cee78a9f37ae461c5a2811dca3c68e31cb1a37 /test
parent0e3cf1963a4c5fa28f12a70b7d2f25c33580c182 (diff)
Write actual output to out.osxml file in the Testing/Integration directory (to facilitate creating the expected output file and for later analysis)
Diffstat (limited to 'test')
-rw-r--r--test/integration/Main.cpp122
1 files changed, 89 insertions, 33 deletions
diff --git a/test/integration/Main.cpp b/test/integration/Main.cpp
index 06e1c4a..373a7ed 100644
--- a/test/integration/Main.cpp
+++ b/test/integration/Main.cpp
@@ -72,10 +72,30 @@ const size_t SUCCESS = 0;
const size_t ERROR = 1;
/**
+ * Removes the prefix string "prefix" from the given string "s".
+ *
+ * @param s is the string from which the prefix should be removed.
+ * @param prefix is the prefix that should be removed from s.
+ * @return s with the prefix removed.
+ */
+std::string removePrefix(const std::string &s, const std::string &prefix)
+{
+ if (s.size() > prefix.size()) {
+ return s.substr(prefix.size(), s.size() - prefix.size());
+ }
+ return std::string{};
+}
+
+/**
* Structure representing a single test case.
*/
struct Test {
/**
+ * Test name.
+ */
+ std::string name;
+
+ /**
* Input file.
*/
std::string infile;
@@ -103,21 +123,28 @@ struct Test {
/**
* Constructor for a standard test.
*
+ * @param name is the name of the test.
* @param infile is the input file.
* @param outfile is the output file containing the expected input.
*/
- Test(const std::string &infile, const std::string &outfile)
- : infile(infile), outfile(outfile), shouldFail(false), success(false)
+ Test(const std::string &name, const std::string &infile,
+ const std::string &outfile)
+ : name(name),
+ infile(infile),
+ outfile(outfile),
+ shouldFail(false),
+ success(false)
{
}
/**
* Constructor for a test with expected failure.
*
+ * @param name is the name of the test.
* @param infile is the input file.
*/
- Test(const std::string &infile)
- : infile(infile), shouldFail(true), success(false)
+ Test(const std::string &name, const std::string &infile)
+ : name(name), infile(infile), shouldFail(true), success(false)
{
}
};
@@ -172,12 +199,20 @@ static bool parseFile(const std::string &infile, std::ostream &os)
return true;
}
-static bool runTest(test::Logger &logger, const Test &test)
+static bool runTest(test::Logger &logger, const Test &test,
+ const std::string &targetFile)
{
// Parse the infile and dump it as OSXML to a string stream
std::stringstream actual_output;
bool res = parseFile(test.infile, actual_output);
+ // Write the actual_output to disk
+ {
+ logger.note("Writing serialized output to " + targetFile);
+ std::ofstream target(targetFile);
+ target << actual_output.str();
+ }
+
// If this is a test with expected failure, check whether this failure
// occured.
if (test.shouldFail) {
@@ -194,9 +229,6 @@ static bool runTest(test::Logger &logger, const Test &test)
return false;
}
- // Write the actual_output to disk
-
-
// Parse both the actual output and the expected output stream
std::ifstream expected_output(test.outfile);
logger.note("Parsing serialized XML");
@@ -255,33 +287,38 @@ static std::vector<Test> gatherTests(fs::path root)
dirs.emplace(p);
} else if (fs::is_regular_file(p)) {
// Fetch the filename
- const std::string &fn = p.native();
+ std::string inPath = p.native();
+ std::string testName = p.filename().native();
+ std::string testPath;
// Check whether the test ends with ".in.osml" or ".in.osxml"
- std::string testname;
bool shouldFail = false;
- if (Utils::endsWith(fn, ".in.osml")) {
- testname = fn.substr(0, fn.size() - 8);
- } else if (Utils::endsWith(fn, ".in.osxml")) {
- testname = fn.substr(0, fn.size() - 9);
- } else if (Utils::endsWith(fn, ".fail.osml")) {
- testname = fn.substr(0, fn.size() - 10);
+ if (Utils::endsWith(inPath, ".in.osml")) {
+ testPath = inPath.substr(0, inPath.size() - 8);
+ testName = testName.substr(0, testName.size() - 8);
+ } else if (Utils::endsWith(inPath, ".in.osxml")) {
+ testPath = inPath.substr(0, inPath.size() - 9);
+ testName = testName.substr(0, testName.size() - 9);
+ } else if (Utils::endsWith(inPath, ".fail.osml")) {
+ testPath = inPath.substr(0, inPath.size() - 10);
+ testName = testName.substr(0, testName.size() - 10);
shouldFail = true;
- } else if (Utils::endsWith(fn, ".fail.osxml")) {
- testname = fn.substr(0, fn.size() - 11);
+ } else if (Utils::endsWith(inPath, ".fail.osxml")) {
+ testPath = inPath.substr(0, inPath.size() - 11);
+ testName = testName.substr(0, testName.size() - 11);
shouldFail = true;
}
// If yes, check whether the same file exists ending with
// .out.osxml -- if this is the case, add the resulting test
- // case to the result
- if (!testname.empty()) {
+ // case filename the result
+ if (!testPath.empty()) {
if (shouldFail) {
- res.emplace_back(fn);
+ res.emplace_back(testName, testPath);
} else {
- const std::string outFn = testname + ".out.osxml";
- if (fs::is_regular_file(outFn)) {
- res.emplace_back(fn, outFn);
+ const std::string outPath = testPath + ".out.osxml";
+ if (fs::is_regular_file(outPath)) {
+ res.emplace_back(testName, inPath, outPath);
}
}
}
@@ -303,7 +340,7 @@ int main(int argc, char **argv)
logger.note("(c) Benjamin Paaßen, Andreas Stöckel 2015");
logger.note("This program is free software licensed under the GPLv3");
- // Use boost filesystem to recursively iterate over all files
+ // Check whether the root path exists, make it a canonical path
fs::path root =
fs::path(SpecialPaths::getDebugTestdataDir()) / "integration";
if (!fs::is_directory(root)) {
@@ -311,6 +348,7 @@ int main(int argc, char **argv)
root.native());
return ERROR;
}
+ root = fs::canonical(root);
// Fetch all test cases
logger.headline("GATHER TESTS");
@@ -318,25 +356,43 @@ int main(int argc, char **argv)
std::string testsWord = tests.size() == 1 ? " test" : " tests";
logger.note(std::to_string(tests.size()) + testsWord + " found");
+ // Run them, count the number of successes and failures
logger.headline("RUN TESTS");
size_t successCount = 0;
- size_t failCount = 0;
+ size_t failureCount = 0;
for (auto &test : tests) {
logger.note("Running test " + test.infile);
- if (runTest(logger, test)) {
+
+ // Create the target directory (use CTest folder)
+ fs::path target =
+ fs::path("Testing") / fs::path("Integration") /
+ removePrefix(fs::path(test.infile).parent_path().native(),
+ root.native()) /
+ (test.name + ".out.osxml");
+ fs::path targetDir = target.parent_path();
+ if (!fs::is_directory(targetDir) &&
+ !fs::create_directories(targetDir)) {
+ logger.fail("Cannot create or access directory " +
+ targetDir.native());
+ return ERROR;
+ }
+
+ // Assemble the full target file path
+ if (runTest(logger, test, target.native())) {
test.success = true;
successCount++;
} else {
- failCount++;
+ failureCount++;
}
}
- // Write the final error messages
+ // Write the summary
logger.headline("TEST SUMMARY");
- logger.note(std::string("Ran ") + std::to_string(failCount + successCount) +
- testsWord + ", " + std::to_string(failCount) + " failed, " +
+ logger.note(std::string("Ran ") +
+ std::to_string(failureCount + successCount) + testsWord + ", " +
+ std::to_string(failureCount) + " failed, " +
std::to_string(successCount) + " succeeded");
- if (failCount > 0) {
+ if (failureCount > 0) {
logger.note("The following tests failed:");
for (const auto &test : tests) {
if (!test.success) {
@@ -348,6 +404,6 @@ int main(int argc, char **argv)
}
// Inform the shell about failing integration tests
- return failCount > 0 ? ERROR : SUCCESS;
+ return failureCount > 0 ? ERROR : SUCCESS;
}