Files
route-switcher/doc/TESTING.md
Michal Humpula 5fbd72b370 working base
2026-02-15 17:36:08 +01:00

7.3 KiB

Testing Guide

Overview

This document describes the testing strategy and environment for the Route-Switcher project.

Testing Environment

Podman-Compose Setup

The testing environment uses podman-compose to create a realistic network topology with routers and a single ICMP target:

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  Route-Switcher │    │   Primary Router│    │                 │
│                 │    │                 │    │                 │
│ eth0 ────────────┼────►│ eth0 ──────────┼────►│  ICMP Target    │
│ eth1 ────────────┼────►│ eth1 ──────────┼────►│                 │
│                 │    │                 │    │                 │
└─────────────────┘    └─────────────────┘    └─────────────────┘
    │                       │                       │
    │                       │                       │
    ▼                       ▼                       ▼
primary-net           secondary-net           target-net
192.168.1.0/24        192.168.2.0/24        10.0.0.0/24

Container Architecture

  • route-switcher: Dual interfaces (eth0→primary-net, eth1→secondary-net)
  • primary-router: Connects primary-net ↔ target-net (192.168.1.1 ↔ 10.0.0.1)
  • secondary-router: Connects secondary-net ↔ target-net (192.168.2.1 ↔ 10.0.0.2)
  • icmp-target: Single IP on target-net (10.0.0.100), reachable via either router

Quick Start

# Start the testing environment
podman-compose up -d

# Run automated failover test
./scripts/test-failover.sh

# View logs
podman-compose logs -f route-switcher

# Stop environment
podman-compose down

Network Configuration

Route-Switcher:

  • eth0: 192.168.1.10 (primary network)
  • eth1: 192.168.2.10 (secondary network)
  • Default gateway: 192.168.1.1 (primary router)

Primary Router:

  • eth0: 192.168.1.1 (primary network)
  • eth1: 10.0.0.1 (target network)
  • Routes traffic between networks with NAT

Secondary Router:

  • eth0: 192.168.2.1 (secondary network)
  • eth1: 10.0.0.2 (target network)
  • Routes traffic between networks with NAT

ICMP Target:

  • Single IP: 10.0.0.100
  • Default route: 10.0.0.1 (primary router)
  • Responds to ping from both routers

Test Scenarios

1. Basic Connectivity Test

Objective: Verify basic ping functionality on both interfaces

# Start environment
podman-compose up -d

# Test primary connectivity
podman-compose exec route-switcher ping -c 3 -I eth0 10.0.0.100

# Test secondary connectivity  
podman-compose exec route-switcher ping -c 3 -I eth1 10.0.0.100

# Check routing table
podman-compose exec route-switcher ip route show

2. Failover Test

Objective: Verify automatic failover when primary router fails

# Start monitoring logs
podman-compose logs -f route-switcher &

# Simulate primary router failure
podman-compose exec primary-router ip link set eth0 down

# Verify failover occurs (should see in logs)
# Wait for state change to Fallback

# Check routing table after failover
podman-compose exec route-switcher ip route show

# Test connectivity via secondary router
podman-compose exec route-switcher ping -c 3 10.0.0.100

# Restore primary router
podman-compose exec primary-router ip link set eth0 up

# Verify failback after 60 seconds

3. Dual Failure Test

Objective: Verify system doesn't failover when both routers fail

# Start monitoring logs
podman-compose logs -f route-switcher &

# Fail both routers
podman-compose exec primary-router ip link set eth0 down
podman-compose exec secondary-router ip link set eth0 down

# Verify no routing changes occur
# System should remain in current state

# Restore routers
podman-compose exec primary-router ip link set eth0 up
podman-compose exec secondary-router ip link set eth0 up

4. Router Target Interface Failure

Objective: Test upstream network failure simulation

# Fail primary router's connection to target network
podman-compose exec primary-router ip link set eth1 down

# Should trigger failover to secondary router
# Verify connectivity still works via secondary path

# Restore primary router's target connection
podman-compose exec primary-router ip link set eth1 up

5. Automated Failover Test

Objective: Run complete automated test sequence

# Run the comprehensive test script
./scripts/test-failover.sh

# This script will:
# 1. Start the environment
# 2. Verify initial connectivity
# 3. Simulate primary router failure
# 4. Monitor failover
# 5. Restore primary router
# 6. Verify failback after 60 seconds

Unit Tests

Running Tests

# Run all tests
cargo test

# Run specific test module
cargo test pinger

# Run with coverage
cargo tarpaulin --out Html

Test Structure

tests/
├── unit/
│   ├── pinger_tests.rs
│   ├── routing_tests.rs
│   └── state_machine_tests.rs
├── integration/
│   ├── netlink_tests.rs
│   └── dual_interface_tests.rs
└── e2e/
    └── failover_tests.rs

Performance Testing

Load Testing

# Test with multiple ping targets
cargo run -- --ping-target 8.8.8.8

# Monitor resource usage
podman stats route-switcher

# Test long-running stability
# Run for 24 hours and monitor for memory leaks

Network Latency Testing

# Measure failover time
# Start script to time the state transition
start_time=$(date +%s%N)
# Trigger failure
# Wait for state change
end_time=$(date +%s%N)
failover_time=$((($end_time - $start_time) / 1000000))
echo "Failover time: ${failover_time}ms"

Debugging Tests

Common Issues

  1. Permission Denied: Ensure containers run with privileged mode
  2. Interface Not Found: Check network configuration in compose file
  3. Netlink Errors: Verify kernel supports required operations
  4. Timing Issues: Adjust test timeouts for your environment

Debug Commands

# Check container network interfaces
podman-compose exec route-switcher ip addr show

# Check routing table
podman-compose exec route-switcher ip route show

# Monitor network traffic
podman-compose exec route-switcher tcpdump -i any icmp

# Check system logs
podman-compose exec route-switcher dmesg | tail -20

Test Data

Sample Ping Results

// Mock data for testing
let mock_ping_results = vec![
    PingResult::Ok,      // Normal operation
    PingResult::Failed,   // Single failure
    PingResult::Failed,   // Consecutive failure
    PingResult::Failed,   // Trigger failover
];

Network Configuration

# Test network setup
ip addr add 192.168.1.10/24 dev eth0
ip addr add 192.168.2.10/24 dev eth1
ip route add default via 192.168.1.1 dev eth0 metric 10
ip route add default via 192.168.2.1 dev eth1 metric 20

Test Coverage Goals

  • Unit Tests: 90%+ code coverage
  • Integration Tests: All major component interactions
  • E2E Tests: All user scenarios and edge cases
  • Performance Tests: Resource usage and timing validation