1#ifndef YAZE_APP_TEST_TEST_MANAGER_H
2#define YAZE_APP_TEST_TEST_MANAGER_H
10#include <unordered_map>
13#include "absl/status/status.h"
14#include "absl/status/statusor.h"
15#include "absl/strings/string_view.h"
16#include "absl/synchronization/mutex.h"
17#include "absl/time/time.h"
20#define IMGUI_DEFINE_MATH_OPERATORS
31#if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE
32#if __has_include("imgui_test_engine/imgui_te_engine.h")
33#include "imgui_test_engine/imgui_te_engine.h"
34#elif __has_include("imgui_te_engine.h")
35#include "imgui_te_engine.h"
37#error "ImGui Test Engine headers not found"
41struct ImGuiTestEngine;
61 std::chrono::time_point<std::chrono::steady_clock>
timestamp;
125 std::chrono::time_point<std::chrono::steady_clock>
timestamp;
129#if defined(YAZE_WITH_GRPC)
130enum class HarnessTestStatus {
139const char* HarnessStatusToString(HarnessTestStatus status);
140HarnessTestStatus HarnessStatusFromString(absl::string_view status);
142struct HarnessTestExecution {
145 std::string category;
146 HarnessTestStatus status = HarnessTestStatus::kUnspecified;
147 absl::Time queued_at;
148 absl::Time started_at;
149 absl::Time completed_at;
150 absl::Duration duration = absl::ZeroDuration();
151 std::string error_message;
152 std::vector<std::string> assertion_failures;
153 std::vector<std::string> logs;
154 std::map<std::string, int32_t> metrics;
157 std::string screenshot_path;
158 int64_t screenshot_size_bytes = 0;
159 std::string failure_context;
160 std::string widget_state;
163struct HarnessTestSummary {
164 HarnessTestExecution latest_execution;
168 absl::Duration total_duration = absl::ZeroDuration();
171class HarnessListener {
173 virtual ~HarnessListener() =
default;
174 virtual void OnHarnessTestUpdated(
const HarnessTestExecution& execution) = 0;
175 virtual void OnHarnessPlanSummary(
const std::string& summary) = 0;
187 absl::Status
RunTestSuite(
const std::string& suite_name);
211#if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE
238 LOG_INFO(
"TestManager",
"SetCurrentRom called with ROM: %p", (
void*)rom);
240 LOG_INFO(
"TestManager",
"ROM title: '%s', loaded: %s",
255 std::unique_ptr<Rom>& test_rom);
264 std::function<absl::Status(
Rom*)> test_function);
280#if defined(YAZE_WITH_GRPC)
282 const std::string& category)
283 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
284 void MarkHarnessTestRunning(
const std::string& test_id)
285 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
286 void MarkHarnessTestCompleted(
287 const std::string& test_id, HarnessTestStatus status,
288 const std::string& error_message =
"",
289 const std::vector<std::string>& assertion_failures = {},
290 const std::vector<std::string>& logs = {},
291 const std::map<std::string, int32_t>& metrics = {})
292 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
293 void AppendHarnessTestLog(
const std::string& test_id,
294 const std::string& log_entry)
295 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
296 absl::StatusOr<HarnessTestExecution> GetHarnessTestExecution(
297 const std::string& test_id)
const
298 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
299 std::vector<HarnessTestSummary> ListHarnessTestSummaries(
300 const std::string& category_filter =
"") const
301 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
305 ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
307 void SetHarnessListener(HarnessListener* listener);
313 const std::string& category);
353#ifdef YAZE_ENABLE_IMGUI_TEST_ENGINE
354 ImGuiTestEngine* ui_test_engine_ =
nullptr;
379#if defined(YAZE_WITH_GRPC)
380 struct HarnessAggregate {
384 absl::Duration total_duration = absl::ZeroDuration();
385 std::string category;
387 HarnessTestExecution latest_execution;
390 std::unordered_map<std::string, HarnessTestExecution> harness_history_
391 ABSL_GUARDED_BY(harness_history_mutex_);
392 std::unordered_map<std::string, HarnessAggregate> harness_aggregates_
393 ABSL_GUARDED_BY(harness_history_mutex_);
394 std::deque<std::string> harness_history_order_;
395 size_t harness_history_limit_ = 200;
396 mutable absl::Mutex harness_history_mutex_;
397#if defined(YAZE_WITH_GRPC)
398 HarnessListener* harness_listener_ ABSL_GUARDED_BY(
mutex_) =
nullptr;
402#if defined(YAZE_WITH_GRPC)
403 std::string GenerateHarnessTestIdLocked(absl::string_view prefix)
404 ABSL_EXCLUSIVE_LOCKS_REQUIRED(harness_history_mutex_);
405 void TrimHarnessHistoryLocked()
406 ABSL_EXCLUSIVE_LOCKS_REQUIRED(harness_history_mutex_);
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
bool show_resource_monitor_
bool IsTestRunning() const
std::string GenerateTestRomFilename(const std::string &base_name)
void CaptureFailureContext(const std::string &test_id)
std::string current_test_name_
bool show_test_configuration_
Rom * GetCurrentRom() const
const TestResults & GetLastResults() const
bool show_test_session_dialog_
absl::Status ShowHarnessActiveTests()
size_t max_concurrent_tests_
TestCategory category_filter_
absl::Status ShowHarnessDashboard()
std::vector< ResourceStats > resource_history_
void RegisterTestSuite(std::unique_ptr< TestSuite > suite)
void RecordPlanSummary(const std::string &summary)
absl::Status TestRomWithCopy(Rom *source_rom, std::function< absl::Status(Rom *)> test_function)
std::unordered_map< std::string, TestSuite * > suite_lookup_
absl::Status CreateTestRomCopy(Rom *source_rom, std::unique_ptr< Rom > &test_rom)
bool IsTestEnabled(const std::string &test_name) const
absl::Status RunTestSuite(const std::string &suite_name)
std::string RegisterHarnessTest(const std::string &name, const std::string &category)
absl::Status ExecuteTestSuite(TestSuite *suite)
bool show_rom_test_results_
void DestroyUITestingContext()
void SetCurrentRom(Rom *rom)
std::string test_rom_path_for_session_
bool show_rom_file_dialog_
absl::Status TestRomDataIntegrity(Rom *rom)
static constexpr size_t kMaxResourceHistorySize
void TrimResourceHistory()
float GetProgress() const
void DrawTestDashboard(bool *show_dashboard=nullptr)
TestSuite * GetTestSuite(const std::string &name)
absl::Status RunAllTests()
static TestManager & Get()
void OfferTestSessionCreation(const std::string &test_rom_path)
TestResults last_results_
void EnableTest(const std::string &test_name)
const std::vector< ResourceStats > & GetResourceHistory() const
void CollectResourceStats()
void DisableTest(const std::string &test_name)
void SetTestTimeout(std::chrono::seconds timeout)
std::vector< std::unique_ptr< TestSuite > > test_suites_
absl::Status TestRomSaveLoad(Rom *rom)
void SetMaxConcurrentTests(size_t max_concurrent)
std::chrono::seconds test_timeout_
absl::Status RunTestsByCategory(TestCategory category)
void UpdateResourceStats()
void ShowRomComparisonResults(const Rom &before, const Rom &after)
std::unordered_map< std::string, bool > disabled_tests_
const std::string & GetCurrentTestName() const
void InitializeUITesting()
absl::Status ReplayLastPlan()
std::vector< std::string > GetTestSuiteNames() const
absl::Status LoadRomForTesting(const std::string &filename)
virtual void DrawConfiguration()
virtual ~TestSuite()=default
virtual void SetEnabled(bool enabled)
virtual std::string GetName() const =0
virtual bool IsEnabled() const
virtual TestCategory GetCategory() const =0
virtual absl::Status RunTests(TestResults &results)=0
#define LOG_INFO(category, format,...)
const char * TestStatusToString(TestStatus status)
const char * TestCategoryToString(TestCategory category)
ImVec4 GetTestStatusColor(TestStatus status)
std::chrono::time_point< std::chrono::steady_clock > timestamp
std::chrono::milliseconds duration
std::string error_message
std::chrono::time_point< std::chrono::steady_clock > timestamp
std::vector< TestResult > individual_results
std::chrono::milliseconds total_duration
void AddResult(const TestResult &result)
float GetPassRate() const