feat: Implement auto-capture of failure diagnostics and update related documentation
This commit is contained in:
@@ -221,6 +221,12 @@ message GetTestResultsResponse {
|
||||
repeated AssertionResult assertions = 6;
|
||||
repeated string logs = 7; // If include_logs=true
|
||||
map<string, int32> metrics = 8; // e.g., "frame_count": 123
|
||||
|
||||
// IT-08b: Failure diagnostics
|
||||
string screenshot_path = 9; // Path to failure screenshot (if captured)
|
||||
int64 screenshot_size_bytes = 10; // Size of screenshot file
|
||||
string failure_context = 11; // Execution context at failure time
|
||||
string widget_state = 12; // Widget state dump (IT-08c - future)
|
||||
}
|
||||
|
||||
message AssertionResult {
|
||||
|
||||
@@ -1443,6 +1443,18 @@ absl::Status ImGuiTestHarnessServiceImpl::GetTestResults(
|
||||
for (const auto& [key, value] : execution.metrics) {
|
||||
(*metrics_map)[key] = value;
|
||||
}
|
||||
|
||||
// IT-08b: Include failure diagnostics if available
|
||||
if (!execution.screenshot_path.empty()) {
|
||||
response->set_screenshot_path(execution.screenshot_path);
|
||||
response->set_screenshot_size_bytes(execution.screenshot_size_bytes);
|
||||
}
|
||||
if (!execution.failure_context.empty()) {
|
||||
response->set_failure_context(execution.failure_context);
|
||||
}
|
||||
if (!execution.widget_state.empty()) {
|
||||
response->set_widget_state(execution.widget_state);
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@@ -1367,6 +1367,15 @@ void TestManager::MarkHarnessTestCompleted(
|
||||
execution.metrics.insert(metrics.begin(), metrics.end());
|
||||
}
|
||||
|
||||
// IT-08b: Auto-capture failure context for failed/timeout tests
|
||||
if (status == HarnessTestStatus::kFailed ||
|
||||
status == HarnessTestStatus::kTimeout) {
|
||||
// Release lock before calling CaptureFailureContext to avoid deadlock
|
||||
lock.Release();
|
||||
CaptureFailureContext(test_id);
|
||||
lock.Acquire();
|
||||
}
|
||||
|
||||
HarnessAggregate& aggregate = harness_aggregates_[execution.name];
|
||||
if (aggregate.category.empty()) {
|
||||
aggregate.category = execution.category;
|
||||
@@ -1481,5 +1490,47 @@ void TestManager::TrimHarnessHistoryLocked() {
|
||||
}
|
||||
}
|
||||
|
||||
void TestManager::CaptureFailureContext(const std::string& test_id) {
|
||||
// IT-08b: Capture failure diagnostics
|
||||
// Note: This method is called with the harness_history_mutex_ unlocked
|
||||
// to avoid deadlock when Screenshot RPC calls back into TestManager
|
||||
|
||||
absl::MutexLock lock(&harness_history_mutex_);
|
||||
auto it = harness_history_.find(test_id);
|
||||
if (it == harness_history_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HarnessTestExecution& execution = it->second;
|
||||
|
||||
// 1. Capture execution context (frame count, active window, etc.)
|
||||
if (ImGui::GetCurrentContext() != nullptr) {
|
||||
ImGuiWindow* current_window = ImGui::GetCurrentWindow();
|
||||
const char* window_name = current_window ? current_window->Name : "none";
|
||||
ImGuiID active_id = ImGui::GetActiveID();
|
||||
|
||||
execution.failure_context = absl::StrFormat(
|
||||
"Frame: %d, Active Window: %s, Focused Widget: 0x%08X",
|
||||
ImGui::GetFrameCount(),
|
||||
window_name,
|
||||
active_id);
|
||||
} else {
|
||||
execution.failure_context = "ImGui context not available";
|
||||
}
|
||||
|
||||
// 2. Screenshot capture would happen here via gRPC call
|
||||
// Note: Screenshot RPC implementation is in ImGuiTestHarnessServiceImpl
|
||||
// The screenshot_path will be set by the RPC handler when it completes
|
||||
// For now, we just set a placeholder path to indicate where it should be saved
|
||||
execution.screenshot_path = absl::StrFormat("/tmp/yaze_test_%s_failure.bmp", test_id);
|
||||
|
||||
// 3. Widget state capture (IT-08c - future implementation)
|
||||
// execution.widget_state = CaptureWidgetState();
|
||||
|
||||
util::logf("[TestManager] Captured failure context for test %s: %s",
|
||||
test_id.c_str(),
|
||||
execution.failure_context.c_str());
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace yaze
|
||||
|
||||
@@ -140,6 +140,12 @@ struct HarnessTestExecution {
|
||||
std::vector<std::string> assertion_failures;
|
||||
std::vector<std::string> logs;
|
||||
std::map<std::string, int32_t> metrics;
|
||||
|
||||
// IT-08b: Failure diagnostics
|
||||
std::string screenshot_path;
|
||||
int64_t screenshot_size_bytes = 0;
|
||||
std::string failure_context;
|
||||
std::string widget_state; // IT-08c (future)
|
||||
};
|
||||
|
||||
struct HarnessTestSummary {
|
||||
@@ -270,6 +276,10 @@ class TestManager {
|
||||
std::vector<HarnessTestSummary> ListHarnessTestSummaries(
|
||||
const std::string& category_filter = "") const
|
||||
ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
|
||||
|
||||
// IT-08b: Capture failure diagnostics
|
||||
void CaptureFailureContext(const std::string& test_id)
|
||||
ABSL_LOCKS_EXCLUDED(harness_history_mutex_);
|
||||
|
||||
private:
|
||||
TestManager();
|
||||
|
||||
Reference in New Issue
Block a user