End-to-end testing framework for Mau P2P file synchronization system with interactive CLI and automated testing.
1# Install CLI tool
2cd e2e
3go install ./cmd/mau-e2e
4
5# Start 3 Mau peers
6mau-e2e up --peers 3
7
8# Make them friends
9mau-e2e friend add peer-0 peer-1
10mau-e2e friend add peer-1 peer-2
11
12# Add a file
13mau-e2e file add peer-0 hello.txt
14# Type content, Ctrl-D to finish
15
16# Watch sync happen in real-time
17mau-e2e file watch
18
19# Inspect peer state
20mau-e2e peer inspect peer-1
21
22# Clean up
23mau-e2e down
Why Interactive Mode?
1# Run all E2E tests
2make test-e2e
3
4# Run specific test suite
5cd e2e
6go test -v ./scenarios/basic/...
7
8# Run with race detector
9go test -race ./scenarios/...
10
11# CI mode (optimized for GitHub Actions)
12make test-e2e-ci
| Document | Purpose |
|---|---|
| PLAN.md | Comprehensive testing framework design (automated tests) |
| CLI_DESIGN.md | Interactive CLI architecture and usage |
| docs/writing-tests.md | How to add new test scenarios |
| docs/debugging.md | Troubleshooting failed tests |
| docs/toxiproxy-guide.md | Network simulation with Toxiproxy |
The framework operates in two complementary modes sharing the same core library:
βββββββββββββββββββββββββββββββββββββββββββ
β Interactive CLI Mode β
β (mau-e2e command-line tool) β
β β
β β’ Manual control β
β β’ Real-time monitoring β
β β’ Network simulation β
β β’ Exploratory testing β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β Shared testenv library
β
ββββββββββββββββ΄βββββββββββββββββββββββββββ
β Automated Testing Mode β
β (go test) β
β β
β β’ CI/CD integration β
β β’ Regression detection β
β β’ Performance benchmarks β
β β’ Chaos engineering β
βββββββββββββββββββββββββββββββββββββββββββ
mau-e2e) ΒΆ 1$ mau-e2e up --peers 2
2β Started peers: alice, bob
3
4$ mau-e2e friend add alice bob
5β Friendship established
6
7$ mau-e2e file add alice test.txt <<< "Hello, Bob!"
8β File created and encrypted
9
10$ mau-e2e file watch
11[15:30:12] bob: Downloading test.txt from alice...
12[15:30:13] bob: β Sync complete: test.txt
13
14$ mau-e2e file cat bob test.txt
15Hello, Bob!
1$ mau-e2e up --peers 4
2
3# Create two groups
4$ mau-e2e friend add peer-0 peer-1
5$ mau-e2e friend add peer-2 peer-3
6
7# Partition network: {0,1} vs {2,3}
8$ mau-e2e net partition peer-0,peer-1 peer-2,peer-3
9
10# Add files on both sides
11$ mau-e2e file add peer-0 fileA.txt <<< "Group A"
12$ mau-e2e file add peer-2 fileB.txt <<< "Group B"
13
14# Verify isolation
15$ mau-e2e file list peer-1 # Has fileA only
16$ mau-e2e file list peer-3 # Has fileB only
17
18# Heal partition
19$ mau-e2e net heal
20
21# Verify convergence (if cross-group friends exist)
22$ mau-e2e file watch
1// e2e/scenarios/basic/friend_sync_test.go
2func TestTwoP eerFriendSync(t *testing.T) {
3 env := testenv.NewTestEnvironment(t)
4 defer env.Cleanup()
5
6 alice, _ := env.AddPeer("alice")
7 bob, _ := env.AddPeer("bob")
8 env.MakeFriends(alice, bob)
9
10 alice.AddFile("hello.txt", strings.NewReader("Hello!"))
11
12 assert.Eventually(t, func() bool {
13 return bob.HasFile("hello.txt")
14 }, 30*time.Second, 1*time.Second)
15
16 content, _ := bob.ReadFile("hello.txt")
17 assert.Equal(t, "Hello!", content)
18}
1# Clone repository
2git clone https://github.com/mau-network/mau
3cd mau
4
5# Switch to E2E branch
6git checkout e2e-tests-framework
7
8# Build Mau E2E Docker image
9cd e2e
10make build-image
11
12# Install CLI tool
13go install ./cmd/mau-e2e
14
15# Verify installation
16mau-e2e --version
1# Environment
2mau-e2e up [--peers N] # Start environment
3mau-e2e down # Tear down
4mau-e2e status [--watch] # Show status
5
6# Peers
7mau-e2e peer add <name> # Add peer
8mau-e2e peer list # List peers
9mau-e2e peer inspect <name> # Show peer details
10mau-e2e peer restart <name> # Restart peer
11
12# Friends
13mau-e2e friend add <p1> <p2> # Make friends
14mau-e2e friend list <peer> # List friends
15
16# Files
17mau-e2e file add <peer> <file> # Add file
18mau-e2e file list <peer> # List files
19mau-e2e file cat <peer> <file> # Show content
20mau-e2e file watch # Watch sync events
21
22# Network
23mau-e2e net partition <g1> <g2> # Create partition
24mau-e2e net heal # Heal partition
25mau-e2e net latency <peer> <ms> # Add latency
26mau-e2e net reset # Remove all toxics
27
28# Utilities
29mau-e2e scenario <name> # Run scenario
30mau-e2e snapshot <dir> # Capture snapshot
31mau-e2e shell # Interactive shell
1# Run all tests
2make test-e2e
3
4# Run specific suite
5make test-e2e-basic # Basic functionality
6make test-e2e-resilience # Resilience tests
7make test-e2e-stress # Stress tests (slow)
8
9# Run individual test
10cd e2e
11go test -v -run TestTwoPeerFriendSync ./scenarios/basic/
File: ~/.mau-e2e/config.json
1{
2 "default_peers": 3,
3 "docker_image": "mau-e2e:latest",
4 "enable_toxiproxy": true,
5 "log_level": "info",
6 "auto_cleanup": true
7}
File: e2e/configs/default.json
1{
2 "timeout": "30s",
3 "sync_timeout": "60s",
4 "docker_image": "mau-e2e:latest",
5 "network_name_prefix": "mau-test",
6 "log_level": "debug"
7}
The framework runs automatically in GitHub Actions on every PR:
1# .github/workflows/e2e-tests.yml
2name: E2E Tests
3
4on: [pull_request]
5
6jobs:
7 test-basic:
8 runs-on: ubuntu-latest
9 steps:
10 - uses: actions/checkout@v4
11 - name: Build image
12 run: make -C e2e build-image
13 - name: Run tests
14 run: make -C e2e test-basic
1# Download test artifacts from GitHub Actions
2# Extract logs:
3cd test-results/TestTwoPeerFriendSync/logs
4jq '. | select(.component == "sync")' peer-*.json
5
6# Reproduce locally
7mau-e2e up --peers 2
8# ... manually trigger the failing scenario
1# Check state file
2cat ~/.mau-e2e/current-env.json
3
4# List Docker containers
5docker ps -a --filter label=mau-e2e
6
7# Force cleanup
8docker rm -f $(docker ps -aq --filter label=mau-e2e)
9rm ~/.mau-e2e/current-env.json
1# Watch logs in real-time
2mau-e2e logs peer-0 --follow
3
4# Check DHT connectivity
5mau-e2e dht table peer-0
6
7# Verify friendship
8mau-e2e friend list peer-0
e2e/scenarios/<category>/<name>_test.gotestenv.NewTestEnvironment(t)go test -v ./<category>/Example:
1func TestMyScenario(t *testing.T) {
2 env := testenv.NewTestEnvironment(t)
3 defer env.Cleanup()
4
5 // Your test logic here
6}
See docs/writing-tests.md for details.
e2e/cmd/mau-e2e/commands/<name>.gocobra.Commandmain.gocommands/<name>_test.goSee PLAN.md for detailed roadmap.
See CONTRIBUTING.md for general contribution guidelines.
E2E-specific guidelines:
Same as Mau project: GPLv3
Status: π§ Under Development
Version: 0.1.0 (Design Phase)
Last Updated: 19 February 2026