sots-engine/tests/shim_trace/harness.h

62 lines
1.9 KiB
C++

// Running the Python oracle (sots-re/verify/harness/compare) from a host test.
//
// The harness directory comes from -DSOTS_TRACECMP_DIR (CMake) or the SOTS_TRACECMP_DIR
// environment variable; when neither points at a directory holding tracecmp.py the
// python steps are skipped (returning kSkipped) and the test still passes.
#pragma once
#include <cstdio>
#include <cstdlib>
#include <string>
namespace tracetest {
constexpr int kSkipped = -1;
inline std::string harness_dir() {
if (const char* e = std::getenv("SOTS_TRACECMP_DIR"); e && *e) return e;
#ifdef SOTS_TRACECMP_DIR
return SOTS_TRACECMP_DIR;
#else
return "";
#endif
}
inline bool file_exists(const std::string& p) {
if (std::FILE* f = std::fopen(p.c_str(), "rb")) {
std::fclose(f);
return true;
}
return false;
}
inline bool harness_present() { return file_exists(harness_dir() + "/tracecmp.py"); }
// Exit status of `python3 <script> <args>` (kSkipped when unavailable, 127 if it failed to run).
inline int run_python(const std::string& script, const std::string& args) {
if (!file_exists(script)) {
std::printf(" SKIP (no %s)\n", script.c_str());
return kSkipped;
}
const std::string cmd = "/usr/bin/python3 " + script + " " + args;
std::printf(" $ %s\n", cmd.c_str());
std::fflush(stdout);
const int rc = std::system(cmd.c_str());
if (rc == -1) return 127;
#if defined(_WIN32)
return rc;
#else
return WIFEXITED(rc) ? WEXITSTATUS(rc) : 127;
#endif
}
// tracecmp.py LOG [flags]: 0 clean, 1 divergence, 2 invalid.
inline int run_tracecmp(const std::string& log, const std::string& flags = "") {
if (!harness_present()) {
std::printf(" SKIP tracecmp (SOTS_TRACECMP_DIR not set / harness absent)\n");
return kSkipped;
}
return run_python(harness_dir() + "/tracecmp.py", log + " --quiet " + flags);
}
} // namespace tracetest