Skip to content

Commit

Permalink
Improve CL interface and test failure output
Browse files Browse the repository at this point in the history
  • Loading branch information
metopa committed Mar 17, 2018
1 parent c84ec34 commit 26ea636
Show file tree
Hide file tree
Showing 24 changed files with 143 additions and 61 deletions.
3 changes: 2 additions & 1 deletion epi_judge_cpp/test_framework/generic_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ TestResult RunTests(GenericTestHandler<Function, Comparator>& handler,
test_failure = e;
} catch (TimeoutException& e) {
result = TIMEOUT;
test_timer = e.GetTimer();
} catch (std::runtime_error& e) {
throw;
} catch (std::exception& e) {
Expand All @@ -105,7 +106,7 @@ TestResult RunTests(GenericTestHandler<Function, Comparator>& handler,
}
PrintFailedTest(handler.ParamNames(), test_case, test_failure);
}
if (config.stop_on_error) {
if (!config.run_all_tests) {
break;
}
}
Expand Down
14 changes: 13 additions & 1 deletion epi_judge_cpp/test_framework/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* function.
*/

#include <iostream>

#ifdef _WINDOWS
#include <io.h>
#include <sys/stat.h>
Expand All @@ -16,7 +18,7 @@
#include <unistd.h>
#endif

#include "tribool.h"
#include "tri_bool.h"

namespace platform {

Expand All @@ -39,6 +41,16 @@ int IsATty(int fd) {
#endif
}

void StdOutClearLine() {
#ifdef _WINDOWS
// TODO Use WinApi to clear line
std::cout << '\r';
#else
const char* clear_line_sequence = "\033[2K";
std::cout << clear_line_sequence << '\r';
#endif
}

void SetOutputOpts(TriBool tty_mode, TriBool color_mode) {
ENABLE_TTY_OUTPUT =
GetTriBoolOrDefault(tty_mode, static_cast<bool>(IsATty(StdOutFd())));
Expand Down
14 changes: 7 additions & 7 deletions epi_judge_cpp/test_framework/test_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include "platform.h"
#include "test_utils.h"
#include "tribool.h"
#include "tri_bool.h"

std::string GetParam(const std::vector<std::string>& commandline_args,
size_t i, const char* arg_name) {
Expand All @@ -24,15 +24,15 @@ void PrintUsageAndExit() {
const char* usage_string =
""
"usage: <program name> [-h] [--test-data-dir [TEST_DATA_DIR]]\n"
" [--no-stop-on-error] [--no-verbose]\n"
" [--run-all-tests] [--no-verbose]\n"
" [--force-tty] [--no-tty] [--force-color] "
"[--no-color]\n"
"\n"
"optional arguments:\n"
" -h, --help show this help message and exit\n"
" --test-data-dir [TEST_DATA_DIR]\n"
" path to test_data directory\n"
" --no-stop-on-error continue execution even if one or several "
" --run-all-tests continue execution even if one or several "
"tests failed\n"
" --no-verbose suppress failure description on test failure\n"
" --force-tty enable tty features (like printing output on "
Expand All @@ -52,7 +52,7 @@ struct TestConfig {
TestConfig(const std::string& test_data_file,
const std::chrono::milliseconds& timeout)
: test_data_file(test_data_file),
stop_on_error(true),
run_all_tests(false),
verbose(true),
tty_mode(TriBool::INDETERMINATE),
color_mode(TriBool::INDETERMINATE),
Expand All @@ -67,8 +67,8 @@ struct TestConfig {
if (commandline_args[i] == "--test-data-dir") {
config.test_data_dir =
GetParam(commandline_args, ++i, "--test-data-dir");
} else if (commandline_args[i] == "--no-stop-on-error") {
config.stop_on_error = false;
} else if (commandline_args[i] == "--run-all-tests") {
config.run_all_tests = true;
} else if (commandline_args[i] == "--no-verbose") {
config.verbose = false;
} else if (commandline_args[i] == "--force-tty") {
Expand Down Expand Up @@ -106,7 +106,7 @@ struct TestConfig {

std::string test_data_dir;
std::string test_data_file;
bool stop_on_error;
bool run_all_tests;
bool verbose;
TriBool tty_mode;
TriBool color_mode;
Expand Down
7 changes: 7 additions & 0 deletions epi_judge_cpp/test_framework/test_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

class TestTimer {
public:
TestTimer() = default;

explicit TestTimer(const std::chrono::milliseconds& duration_ms) {
stop_ = clock_t::now();
start_ = stop_ - duration_ms;
}

void Start() { start_ = clock_t::now(); }

void Stop() {
Expand Down
18 changes: 8 additions & 10 deletions epi_judge_cpp/test_framework/test_utils_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ struct EscapeNewline {
}
};

void ReturnCaretIfTtyOutput(std::ostream& os) {
void ClearLineIfTty() {
if (platform::UseTtyOutput()) {
os << '\r';
platform::StdOutClearLine();
} else {
os << '\n';
std::cout << '\n';
};
}

Expand Down Expand Up @@ -65,7 +65,7 @@ void PrintTestInfo(const TestResult& test_result, int test_nr,
static bool caret_at_line_start = true;

if (!caret_at_line_start) {
ReturnCaretIfTtyOutput(std::cout);
ClearLineIfTty();
}

auto total_tests_str = std::to_string(total_tests);
Expand Down Expand Up @@ -105,8 +105,7 @@ void PrintFailedTest(const std::vector<std::string>& param_names,
for (unsigned int i = 0; i < arguments.size(); ++i) {
std::cout << '\t';
PrintStdOutColored(ConsoleColor::FG_YELLOW, param_names[i]);
std::cout << ": "
<< GenSpaces(max_col_size - param_names[i].size())
std::cout << ": " << GenSpaces(max_col_size - param_names[i].size())
<< EscapeNewline{arguments[i]} << std::endl;
}

Expand All @@ -115,10 +114,9 @@ void PrintFailedTest(const std::vector<std::string>& param_names,

for (auto& prop : properties) {
std::cout << '\t';
PrintStdOutColored(ConsoleColor::FG_YELLOW,prop.Name());
std::cout << ": "
<< GenSpaces(max_col_size -prop.Name().size())
<< prop.Value()<< std::endl;
PrintStdOutColored(ConsoleColor::FG_YELLOW, prop.Name());
std::cout << ": " << GenSpaces(max_col_size - prop.Name().size())
<< prop.Value() << std::endl;
}
}

Expand Down
2 changes: 1 addition & 1 deletion epi_judge_cpp/test_framework/timed_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TimedExecutor {
if (future.wait_for(timeout_) == std::future_status::ready) {
return future.get();
} else {
throw TimeoutException();
throw TimeoutException(timeout_);
}
}
}
Expand Down
14 changes: 13 additions & 1 deletion epi_judge_cpp/test_framework/timeout_exception.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
// @library
#pragma once

class TimeoutException {};
#include <chrono>

#include "test_timer.h"

class TimeoutException {
public:
explicit TimeoutException(const std::chrono::milliseconds& ms)
: timer_(ms) {}
const TestTimer& GetTimer() const { return timer_; }

private:
TestTimer timer_;
};
File renamed without changes.
3 changes: 2 additions & 1 deletion epi_judge_java/epi/test_framework/GenericTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public static TestResult runTests(GenericTestHandler handler,
testFailure = e;
} catch (TimeoutException e) {
result = TestResult.TIMEOUT;
testTimer = e.getTimer();
} catch (StackOverflowError e) {
result = TestResult.STACK_OVERFLOW;
} catch (RuntimeException e) {
Expand Down Expand Up @@ -108,7 +109,7 @@ public static TestResult runTests(GenericTestHandler handler,
testFailure);
}

if (config.stopOnError) {
if (!config.runAllTests) {
break;
}
}
Expand Down
9 changes: 9 additions & 0 deletions epi_judge_java/epi/test_framework/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ public class Platform {
private static boolean enableTtyOutput = false;
private static boolean enableColorOutput = false;

public static void stdOutClearLine() {
if (runningOnWin()) {
System.out.print("\r");
} else {
String clearLineSequence = "\033[2K";
System.out.print(clearLineSequence + "\r");
}
}

public static void setOutputOpts(TriBool ttyMode, TriBool colorMode) {
enableTtyOutput = ttyMode.getOrDefault(System.console() != null);
enableColorOutput = colorMode.getOrDefault(enableTtyOutput);
Expand Down
12 changes: 6 additions & 6 deletions epi_judge_java/epi/test_framework/TestConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
public class TestConfig {
public String testDataDir;
public String testDataFile;
public boolean stopOnError;
public boolean runAllTests;
public boolean verbose;
public TriBool ttyMode;
public TriBool colorMode;
public long timeout;

public TestConfig(String testDataFile, long timeout) {
this.testDataFile = testDataFile;
this.stopOnError = true;
this.runAllTests = false;
this.verbose = true;
this.ttyMode = TriBool.INDETERMINATE;
this.colorMode = TriBool.INDETERMINATE;
Expand All @@ -35,7 +35,7 @@ private static String getParam(String[] commandlineArgs, int i,
private static void printUsageAndExit() {
String usageString =
"usage: <program name> [-h] [--test-data-dir [TEST_DATA_DIR]]\n"
+ " [--no-stop-on-error] [--no-verbose]\n"
+ " [--run-all-tests] [--no-verbose]\n"
+
" [--force-tty] [--no-tty] [--force-color] [--no-color]\n"
+ "\n"
Expand All @@ -44,7 +44,7 @@ private static void printUsageAndExit() {
+ " --test-data-dir [TEST_DATA_DIR]\n"
+ " path to test_data directory\n"
+
" --no-stop-on-error continue execution even if one or several tests failed\n"
" --run-all-tests continue execution even if one or several tests failed\n"
+
" --no-verbose suppress failure description on test failure\n"
+
Expand All @@ -70,8 +70,8 @@ public static TestConfig fromCommandLine(String testDataFile, long timeoutMs,
config.testDataDir =
getParam(commandlineArgs, ++i, "--test-data-dir");
break;
case "--no-stop-on-error":
config.stopOnError = false;
case "--run-all-tests":
config.runAllTests = true;
break;
case "--no-verbose":
config.verbose = false;
Expand Down
7 changes: 7 additions & 0 deletions epi_judge_java/epi/test_framework/TestTimer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ public class TestTimer {
private long start;
private long stop;

public TestTimer() {}

public TestTimer(long durationMs) {
stop = System.nanoTime();
start = stop - durationMs * 1000000;
}

public void start() { start = System.nanoTime(); }

public void stop() {
Expand Down
24 changes: 15 additions & 9 deletions epi_judge_java/epi/test_framework/TestUtilsConsole.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public static String escapeNewline(String s) {
return s.replace("\n", "\\n").replace("\r", "\\r");
}

public static void returnCaretIfTtyOutput() {
public static void clearLineIfTty() {
if (Platform.useTtyOutput()) {
System.out.print('\r');
Platform.stdOutClearLine();
} else {
System.out.print('\n');
}
Expand Down Expand Up @@ -46,7 +46,7 @@ public static void printTestInfo(TestResult testResult, int testNr,
int totalTests, String diagnostic,
TestTimer timer) {
if (!caretAtLineStart) {
returnCaretIfTtyOutput();
clearLineIfTty();
}

String totalTestsStr = String.valueOf(totalTests);
Expand Down Expand Up @@ -82,22 +82,28 @@ public static void printFailedTest(List<String> paramNames,
}
}

ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW, "Arguments\n");
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW,
"Arguments\n");

for (int i = 0; i < arguments.size(); i++) {
System.out.print("\t");
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW, paramNames.get(i));
System.out.printf(": %s%s\n", genSpaces(maxColSize - paramNames.get(i).length()),
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW,
paramNames.get(i));
System.out.printf(": %s%s\n",
genSpaces(maxColSize - paramNames.get(i).length()),
escapeNewline(arguments.get(i)));
}

List<TestFailure.Property> properties = testFailure.getProperties();

ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW, "\nFailure info\n");
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW,
"\nFailure info\n");
for (TestFailure.Property prop : properties) {
System.out.print("\t");
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW, prop.name());
System.out.printf(": %s%s\n", genSpaces(maxColSize - prop.name().length()),
ConsoleColor.printStdOutColored(ConsoleColor.Color.FG_YELLOW,
prop.name());
System.out.printf(": %s%s\n",
genSpaces(maxColSize - prop.name().length()),
escapeNewline(String.valueOf(prop.value())));
}
}
Expand Down
2 changes: 1 addition & 1 deletion epi_judge_java/epi/test_framework/TimedExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public <ReturnType> ReturnType run(Callable<ReturnType> func)
return future.get(timeoutMs, TimeUnit.MILLISECONDS);

} catch (java.util.concurrent.TimeoutException e) {
throw new epi.test_framework.TimeoutException();
throw new epi.test_framework.TimeoutException(timeoutMs);
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage());
} catch (ExecutionException e) {
Expand Down
8 changes: 7 additions & 1 deletion epi_judge_java/epi/test_framework/TimeoutException.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// @library
package epi.test_framework;

public class TimeoutException extends Exception {}
public class TimeoutException extends Exception {
private TestTimer timer;

TimeoutException(long durationMs) { timer = new TestTimer(durationMs); }

TestTimer getTimer() { return timer; }
}
5 changes: 3 additions & 2 deletions epi_judge_python/test_framework/generic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def run_tests(handler, config, res_printer):
except TestFailure as exc:
result = TestResult.FAILED
test_failure = exc
except TimeoutException:
except TimeoutException as exc:
result = TestResult.TIMEOUT
test_timer = exc.get_timer()
except RecursionError:
result = TestResult.STACK_OVERFLOW
except RuntimeError:
Expand All @@ -94,7 +95,7 @@ def run_tests(handler, config, res_printer):
test_explanation)
print_failed_test(handler.param_names(), test_case,
test_failure, res_printer)
if config.stop_on_error:
if not config.run_all_tests:
break

print()
Expand Down
Loading

0 comments on commit 26ea636

Please sign in to comment.