[Testing] add skip file support to cpu/ppc tests
This commit is contained in:
@@ -21,6 +21,11 @@
|
|||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#if XE_ARCH_AMD64
|
#if XE_ARCH_AMD64
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
#endif // XE_ARCH
|
#endif // XE_ARCH
|
||||||
@@ -36,6 +41,8 @@ DEFINE_path(test_path, "src/xenia/cpu/ppc/testing/",
|
|||||||
"Directory scanned for test files.", "Other");
|
"Directory scanned for test files.", "Other");
|
||||||
DEFINE_path(test_bin_path, "src/xenia/cpu/ppc/testing/bin/",
|
DEFINE_path(test_bin_path, "src/xenia/cpu/ppc/testing/bin/",
|
||||||
"Directory with binary outputs of the test files.", "Other");
|
"Directory with binary outputs of the test files.", "Other");
|
||||||
|
DEFINE_path(test_skip_file, "src/xenia/cpu/ppc/testing/skip.txt",
|
||||||
|
"File containing test case names to skip (one per line).", "Other");
|
||||||
DEFINE_transient_string(test_name, "", "Test suite name.", "General");
|
DEFINE_transient_string(test_name, "", "Test suite name.", "General");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
@@ -49,6 +56,39 @@ typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
|
|||||||
|
|
||||||
constexpr uint32_t START_ADDRESS = 0x80000000;
|
constexpr uint32_t START_ADDRESS = 0x80000000;
|
||||||
|
|
||||||
|
// Load skip list from file
|
||||||
|
std::unordered_set<std::string> LoadSkipList(
|
||||||
|
const std::filesystem::path& skip_file_path) {
|
||||||
|
std::unordered_set<std::string> skip_list;
|
||||||
|
|
||||||
|
FILE* f = filesystem::OpenFile(skip_file_path, "r");
|
||||||
|
if (!f) {
|
||||||
|
// Skip file doesn't exist or can't be opened - that's okay
|
||||||
|
return skip_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line_buffer[BUFSIZ];
|
||||||
|
while (fgets(line_buffer, sizeof(line_buffer), f)) {
|
||||||
|
// Remove trailing whitespace/newline
|
||||||
|
char* end = line_buffer + strlen(line_buffer) - 1;
|
||||||
|
while (end >= line_buffer &&
|
||||||
|
(*end == '\n' || *end == '\r' || *end == ' ' || *end == '\t')) {
|
||||||
|
*end = '\0';
|
||||||
|
--end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip empty lines and comments
|
||||||
|
if (strlen(line_buffer) == 0 || line_buffer[0] == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_list.insert(std::string(line_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return skip_list;
|
||||||
|
}
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
TestCase(uint32_t address, std::string& name)
|
TestCase(uint32_t address, std::string& name)
|
||||||
: address(address), name(name) {}
|
: address(address), name(name) {}
|
||||||
@@ -514,18 +554,25 @@ void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
|||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
__try {
|
__try {
|
||||||
if (!runner.Setup(test_suite)) {
|
if (!runner.Setup(test_suite)) {
|
||||||
XELOGE(" [{}] TEST FAILED SETUP", test_case.name);
|
fprintf(stderr, " [%s] FAILED SETUP\n", test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
++failed_count;
|
++failed_count;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (runner.Run(test_case)) {
|
if (runner.Run(test_case)) {
|
||||||
++passed_count;
|
++passed_count;
|
||||||
|
// Print progress dot
|
||||||
|
fprintf(stdout, ".");
|
||||||
|
fflush(stdout);
|
||||||
} else {
|
} else {
|
||||||
XELOGE(" [{}] TEST FAILED", test_case.name);
|
fprintf(stderr, " [%s] FAILED\n", test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
} __except (filter(GetExceptionCode())) {
|
} __except (filter(GetExceptionCode())) {
|
||||||
XELOGE(" [{}] TEST FAILED (UNSUPPORTED INSTRUCTION)", test_case.name);
|
fprintf(stderr, " [%s] FAILED (UNSUPPORTED INSTRUCTION)\n",
|
||||||
|
test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -551,6 +598,12 @@ bool RunTests(const std::string_view test_name) {
|
|||||||
XELOGI("Instruction feature mask {}.", cvars::x64_extension_mask);
|
XELOGI("Instruction feature mask {}.", cvars::x64_extension_mask);
|
||||||
#endif // XE_ARCH_AMD64
|
#endif // XE_ARCH_AMD64
|
||||||
|
|
||||||
|
// Load skip list
|
||||||
|
auto skip_list = LoadSkipList(cvars::test_skip_file);
|
||||||
|
if (!skip_list.empty()) {
|
||||||
|
XELOGI("Loaded skip list with {} test cases to skip.", skip_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
auto test_path_root = cvars::test_path;
|
auto test_path_root = cvars::test_path;
|
||||||
std::vector<std::filesystem::path> test_files;
|
std::vector<std::filesystem::path> test_files;
|
||||||
if (!DiscoverTests(test_path_root, test_files)) {
|
if (!DiscoverTests(test_path_root, test_files)) {
|
||||||
@@ -582,6 +635,24 @@ bool RunTests(const std::string_view test_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XELOGI("{} tests loaded.", test_suites.size());
|
XELOGI("{} tests loaded.", test_suites.size());
|
||||||
|
|
||||||
|
// Collect all test cases across all suites, filtering out skipped tests
|
||||||
|
std::vector<std::pair<TestSuite*, TestCase*>> all_tests;
|
||||||
|
int skipped_count = 0;
|
||||||
|
for (auto& test_suite : test_suites) {
|
||||||
|
for (auto& test_case : test_suite.test_cases()) {
|
||||||
|
if (skip_list.find(test_case.name) != skip_list.end()) {
|
||||||
|
++skipped_count;
|
||||||
|
continue; // Skip this test
|
||||||
|
}
|
||||||
|
all_tests.push_back({&test_suite, &test_case});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipped_count > 0) {
|
||||||
|
XELOGI("{} test cases skipped based on skip list.", skipped_count);
|
||||||
|
}
|
||||||
|
|
||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
// On Windows, use a single shared test runner
|
// On Windows, use a single shared test runner
|
||||||
TestRunner runner;
|
TestRunner runner;
|
||||||
@@ -591,11 +662,9 @@ bool RunTests(const std::string_view test_name) {
|
|||||||
TestRunner* runner_ptr = nullptr;
|
TestRunner* runner_ptr = nullptr;
|
||||||
TestRunner& runner = *runner_ptr; // Never dereferenced on POSIX
|
TestRunner& runner = *runner_ptr; // Never dereferenced on POSIX
|
||||||
#endif
|
#endif
|
||||||
for (auto& test_suite : test_suites) {
|
for (auto& [suite, tcase] : all_tests) {
|
||||||
for (auto& test_case : test_suite.test_cases()) {
|
ProtectedRunTest(*suite, runner, *tcase, failed_count,
|
||||||
ProtectedRunTest(test_suite, runner, test_case, failed_count,
|
passed_count);
|
||||||
passed_count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|||||||
28713
src/xenia/cpu/ppc/testing/skip.txt
Normal file
28713
src/xenia/cpu/ppc/testing/skip.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user