Skip to content

Add comprehensive tests for TUI and streaming execution #82

@inureyes

Description

@inureyes

Problem / Background

Issue #68 (Real-time streaming output with interactive multi-node UI) implemented extensive TUI functionality and streaming execution infrastructure. While basic unit tests exist, comprehensive test coverage is lacking, particularly for:

  • TUI rendering and interaction tests
  • Streaming execution integration tests
  • Performance tests for large output handling

Related: #68

Proposed Solution

Implement a comprehensive test suite covering the TUI module and streaming execution:

  1. TUI Snapshot Tests

    • Use ratatui's TestBackend for deterministic rendering tests
    • Test all view modes (Summary, Detail, Split, Diff)
    • Verify correct rendering at different terminal sizes
    • Test edge cases (empty output, very long lines, unicode)
  2. TUI Event Handling Tests

    • Test keyboard navigation between views
    • Verify scroll behavior in detail view
    • Test follow mode toggle
    • Test node selection in split/diff modes
  3. Streaming Execution Integration Tests

    • Test execute_streaming() with mock SSH connections
    • Verify correct stdout/stderr separation
    • Test partial output handling
    • Test connection failure scenarios
  4. Performance Tests

    • Benchmark large output handling (>10MB)
    • Test RollingBuffer overflow behavior
    • Measure memory usage under load
    • Test concurrent multi-node streaming

Acceptance Criteria

  • TUI snapshot tests implemented
    • Summary view renders correctly with various node states
    • Detail view shows output with proper scrolling
    • Split view divides screen correctly
    • Diff view shows side-by-side comparison
  • TUI event tests pass
    • All keyboard shortcuts trigger correct actions
    • View transitions work correctly
    • Edge cases handled (e.g., selecting invalid node)
  • Streaming integration tests pass
    • Output streaming works end-to-end
    • Error conditions are handled gracefully
    • Concurrent execution maintains stream isolation
  • Performance tests establish baselines
    • RollingBuffer handles 10MB+ output without panic
    • Memory usage stays bounded during long operations
    • No significant performance regression in benchmarks

Technical Considerations

Files to Create/Modify

New Test Files:

  • tests/tui_snapshot_tests.rs - TUI rendering tests
  • tests/tui_event_tests.rs - Keyboard and interaction tests
  • tests/streaming_integration_tests.rs - End-to-end streaming tests
  • benches/large_output_benchmark.rs - Performance benchmarks

Source Files to Reference:

  • src/ui/tui/app.rs - TuiApp for state management tests
  • src/ui/tui/event.rs - Event handling to test
  • src/ui/tui/views/ - View rendering to snapshot
  • src/executor/stream_manager.rs - NodeStream, RollingBuffer
  • src/ssh/tokio_client/channel_manager.rs - CommandOutput

Testing Approach

// TUI Snapshot Test Example
use ratatui::backend::TestBackend;
use ratatui::Terminal;

#[test]
fn test_summary_view_renders_correctly() {
    let backend = TestBackend::new(80, 24);
    let mut terminal = Terminal::new(backend).unwrap();
    
    let app = TuiApp::new(/* test data */);
    terminal.draw(|f| app.render_summary(f)).unwrap();
    
    let buffer = terminal.backend().buffer();
    // Assert expected content at specific positions
    assert_eq!(buffer.get(0, 0).symbol(), "┌");
    // Or use insta for snapshot testing
    insta::assert_snapshot!(buffer_to_string(buffer));
}

// Streaming Integration Test Example
#[tokio::test]
async fn test_streaming_execution() {
    let (tx, mut rx) = mpsc::channel(100);
    
    // Mock or real SSH client
    let client = create_test_client().await;
    client.execute_streaming("echo hello", tx).await.unwrap();
    
    let output = rx.recv().await.unwrap();
    assert!(matches!(output, CommandOutput::StdOut(_)));
}

// Performance Benchmark Example
#[bench]
fn bench_rolling_buffer_large_write(b: &mut Bencher) {
    let mut buffer = RollingBuffer::new(10 * 1024 * 1024); // 10MB
    let chunk = vec![b'x'; 1024]; // 1KB chunks
    
    b.iter(|| {
        for _ in 0..10240 { // Write 10MB
            buffer.write(&chunk);
        }
    });
}

Dependencies to Add

[dev-dependencies]
insta = "1.34"  # Snapshot testing
criterion = "0.5"  # Benchmarking
mockall = "0.12"  # Mocking for integration tests

Additional Context

Test Coverage Goals

  • TUI module: >80% line coverage
  • stream_manager.rs: >90% line coverage
  • channel_manager.rs: >85% line coverage

CI Integration

  • Snapshot tests should run in CI
  • Performance benchmarks should run on release branches
  • Consider using cargo-tarpaulin for coverage reports

Related Documentation

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions