add Lua sandbox with timer system (milestones 1-5 complete)

This commit is contained in:
2026-01-18 14:28:44 +01:00
parent 2c36ac005d
commit a4ecb0f132
36 changed files with 10884 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
#include "test_harness.h"
#include <nlohmann/json.hpp>
#include <fstream>
#include <iomanip>
#include <ctime>
void TestHarness::AddTest(const std::string& name, std::function<bool(std::string&)> func) {
m_tests.push_back({name, func});
}
std::vector<TestResult> TestHarness::Run(const std::string& filter) {
std::vector<TestResult> results;
for (const auto& test : m_tests) {
// Filter check
if (!filter.empty() && test.name.find(filter) == std::string::npos) {
continue;
}
TestResult result;
result.name = test.name;
std::cout << "Running: " << test.name << "... " << std::flush;
auto start = std::chrono::steady_clock::now();
try {
std::string error;
result.passed = test.func(error);
result.error_message = error;
} catch (const std::exception& e) {
result.passed = false;
result.error_message = std::string("Exception: ") + e.what();
} catch (...) {
result.passed = false;
result.error_message = "Unknown exception";
}
auto end = std::chrono::steady_clock::now();
result.duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
if (result.passed) {
std::cout << "PASSED (" << result.duration_ms << "ms)\n";
} else {
std::cout << "FAILED\n";
std::cout << " Error: " << result.error_message << "\n";
}
results.push_back(result);
}
return results;
}
void TestHarness::WriteJsonReport(const std::vector<TestResult>& results, const std::string& path) {
nlohmann::json report;
// Get timestamp
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::gmtime(&time), "%Y-%m-%dT%H:%M:%SZ");
report["name"] = "Lua Sandbox Security Tests";
report["timestamp"] = ss.str();
int passed = 0, failed = 0;
for (const auto& r : results) {
if (r.passed) passed++;
else failed++;
}
report["summary"]["passed"] = passed;
report["summary"]["failed"] = failed;
report["summary"]["total"] = static_cast<int>(results.size());
nlohmann::json tests = nlohmann::json::array();
for (const auto& r : results) {
nlohmann::json t;
t["name"] = r.name;
t["status"] = r.passed ? "passed" : "failed";
t["duration_ms"] = r.duration_ms;
if (!r.passed && !r.error_message.empty()) {
t["error"] = r.error_message;
}
tests.push_back(t);
}
report["tests"] = tests;
std::ofstream f(path);
f << report.dump(2);
}
void TestHarness::PrintResults(const std::vector<TestResult>& results) {
std::cout << "\n";
std::cout << "========================================\n";
std::cout << " TEST RESULTS\n";
std::cout << "========================================\n\n";
int passed = 0, failed = 0;
for (const auto& r : results) {
if (r.passed) passed++;
else failed++;
}
std::cout << "Total: " << results.size() << "\n";
std::cout << "Passed: " << passed << "\n";
std::cout << "Failed: " << failed << "\n\n";
if (failed > 0) {
std::cout << "FAILED TESTS:\n";
for (const auto& r : results) {
if (!r.passed) {
std::cout << " - " << r.name << "\n";
std::cout << " " << r.error_message << "\n";
}
}
std::cout << "\n";
}
if (failed == 0) {
std::cout << "ALL TESTS PASSED!\n";
} else {
std::cout << "SOME TESTS FAILED!\n";
}
std::cout << "========================================\n";
}