diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-21 15:54:07 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-21 15:54:07 +0300 |
| commit | d3b697218773eaa5a3dd368705184726dbc0fa38 (patch) | |
| tree | e466fb78829c957f70e88ab92651896b49120856 /src/main/java/testing/SimulationResult.java | |
| parent | dedec9b18bafa2bcfdb05429f717f95f2236d811 (diff) | |
Implement headless testing framework for DS-Sim protocol simulations
- Created HeadlessSimulationRunner that loads and runs simulations without GUI
- Implemented LogCapture to intercept and store all simulation logs
- Added ProtocolVerifier for flexible pattern-based log verification
- Created test runners: standard, with logs, and clean (filters GUI errors)
- Implemented tests for all non-Raft protocols
- Added DummySimulatorFrame to satisfy GUI dependencies during loading
- Created CleanHeadlessRunner that filters GUI-related errors from output
- Updated run-tests.sh script with quiet mode option
- Documented the framework architecture and usage
The framework successfully runs protocol tests and verifies behavior through
log analysis. GUI errors occur internally due to tight coupling in DS-Sim
but are filtered in quiet mode for clean output.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'src/main/java/testing/SimulationResult.java')
| -rw-r--r-- | src/main/java/testing/SimulationResult.java | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/main/java/testing/SimulationResult.java b/src/main/java/testing/SimulationResult.java new file mode 100644 index 0000000..4cab8ee --- /dev/null +++ b/src/main/java/testing/SimulationResult.java @@ -0,0 +1,94 @@ +package testing; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Contains the results of a headless simulation run, including + * captured logs and execution metrics. + */ +public class SimulationResult { + private final List<LogEntry> allLogs; + private final Map<Integer, List<LogEntry>> processLogs; + private final SimulationMetrics metrics; + + public SimulationResult(List<LogEntry> allLogs, + Map<Integer, List<LogEntry>> processLogs, + SimulationMetrics metrics) { + this.allLogs = Collections.unmodifiableList(allLogs); + this.processLogs = Collections.unmodifiableMap(processLogs); + this.metrics = metrics; + } + + public List<LogEntry> getAllLogs() { + return allLogs; + } + + public List<LogEntry> getLogsForProcess(int processNum) { + return processLogs.getOrDefault(processNum, Collections.emptyList()); + } + + public Map<Integer, List<LogEntry>> getProcessLogs() { + return processLogs; + } + + public SimulationMetrics getMetrics() { + return metrics; + } + + /** + * Count logs matching a pattern + */ + public int countLogs(String pattern) { + return (int) allLogs.stream() + .filter(log -> log.getMessage().contains(pattern)) + .count(); + } + + /** + * Find first log matching pattern + */ + public Optional<LogEntry> findFirst(String pattern) { + return allLogs.stream() + .filter(log -> log.getMessage().contains(pattern)) + .findFirst(); + } + + /** + * Find all logs matching pattern + */ + public List<LogEntry> findAll(String pattern) { + return allLogs.stream() + .filter(log -> log.getMessage().contains(pattern)) + .collect(Collectors.toList()); + } + + /** + * Get logs in time range + */ + public List<LogEntry> getLogsInTimeRange(long startTime, long endTime) { + return allLogs.stream() + .filter(log -> log.getTimestamp() >= startTime && + log.getTimestamp() <= endTime) + .collect(Collectors.toList()); + } + + /** + * Generate summary report + */ + public String generateSummary() { + StringBuilder sb = new StringBuilder(); + sb.append("=== Simulation Result Summary ===\n"); + sb.append("Total logs: ").append(allLogs.size()).append("\n"); + sb.append("Processes: ").append(metrics.getNumProcesses()).append("\n"); + sb.append("\nLogs per process:\n"); + + for (Map.Entry<Integer, Integer> entry : + metrics.getProcessMessageCounts().entrySet()) { + sb.append(" Process ").append(entry.getKey()) + .append(": ").append(entry.getValue()).append(" logs\n"); + } + + return sb.toString(); + } +}
\ No newline at end of file |
