Skip to content

Latest commit

 

History

History
399 lines (292 loc) · 7.37 KB

File metadata and controls

399 lines (292 loc) · 7.37 KB

Testing Guide

Quick Start Testing

1. Start the Server

go run cmd/server/main.go

You should see:

HTTP REST API server listening on 0.0.0.0:8080
QUIC collaboration server listening on 0.0.0.0:4433

2. Create a Document

curl -X POST http://localhost:8080/api/documents \
  -H "Content-Type: application/json" \
  -d '{"title":"Test Document","content":"Hello World"}' \
  | jq

Save the returned id for the next steps.

3. Test Collaboration with Multiple Clients

Terminal 1 (Client A):

go run cmd/client/main.go <document-id>

Terminal 2 (Client B):

go run cmd/client/main.go <document-id>

Terminal 3 (Client C):

go run cmd/client/main.go <document-id>

4. Test Real-time Collaboration

In Client A:

> insert 0 Hello

In Client B:

> insert 5 World

In Client C:

> delete 0 5

All clients should see the operations in real-time!


REST API Testing

Create Multiple Documents

# Create document 1
curl -X POST http://localhost:8080/api/documents \
  -H "Content-Type: application/json" \
  -d '{"title":"Doc 1","content":"Content 1"}'

# Create document 2
curl -X POST http://localhost:8080/api/documents \
  -H "Content-Type: application/json" \
  -d '{"title":"Doc 2","content":"Content 2"}'

# Create document 3
curl -X POST http://localhost:8080/api/documents \
  -H "Content-Type: application/json" \
  -d '{"title":"Doc 3","content":"Content 3"}'

List All Documents

curl http://localhost:8080/api/documents | jq

Get Specific Document

curl http://localhost:8080/api/documents/<document-id> | jq

Update Document

curl -X PUT http://localhost:8080/api/documents/<document-id> \
  -H "Content-Type: application/json" \
  -d '{"content":"Updated content"}' | jq

Delete Document

curl -X DELETE http://localhost:8080/api/documents/<document-id>

Health Check

curl http://localhost:8080/health | jq

Load Testing

Test 100 Concurrent Users

Create a load test script:

# load_test.sh
#!/bin/bash

DOCUMENT_ID=$1
NUM_CLIENTS=100

if [ -z "$DOCUMENT_ID" ]; then
    echo "Usage: ./load_test.sh <document-id>"
    exit 1
fi

echo "Starting $NUM_CLIENTS concurrent clients..."

for i in $(seq 1 $NUM_CLIENTS); do
    (
        echo "insert 0 Client$i" | go run cmd/client/main.go $DOCUMENT_ID &
    ) &
done

wait
echo "Load test complete!"

Run it:

chmod +x load_test.sh
./load_test.sh <document-id>

HTTP Load Testing with Vegeta

# Install vegeta
go install github.com/tsenart/vegeta@latest

# Create target file
cat > targets.txt << EOF
POST http://localhost:8080/api/documents
Content-Type: application/json
@create_doc.json

GET http://localhost:8080/api/documents
EOF

# Create request body
cat > create_doc.json << EOF
{"title":"Load Test","content":"Testing"}
EOF

# Run load test
vegeta attack -targets=targets.txt -rate=100 -duration=30s | vegeta report

Performance Benchmarks

Latency Test

Create a benchmark script:

// cmd/benchmark/latency_test.go
package main

import (
    "context"
    "crypto/tls"
    "encoding/json"
    "testing"
    "time"

    "github.com/quic-go/quic-go"
)

func BenchmarkOperationLatency(b *testing.B) {
    tlsConfig := &tls.Config{
        InsecureSkipVerify: true,
        NextProtos:         []string{"collaborative-doc-quic"},
    }

    conn, _ := quic.DialAddr(context.Background(), "localhost:4433", tlsConfig, nil)
    defer conn.CloseWithError(0, "")

    stream, _ := conn.OpenStreamSync(context.Background())
    defer stream.Close()

    // Join document
    joinMsg := map[string]string{
        "type":       "join",
        "documentId": "test-doc-id",
        "clientId":   "bench-client",
    }
    data, _ := json.Marshal(joinMsg)
    stream.Write(data)

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        start := time.Now()

        op := map[string]interface{}{
            "type": "operation",
            "operation": map[string]interface{}{
                "type":     "insert",
                "position": 0,
                "text":     "x",
            },
        }

        data, _ := json.Marshal(op)
        stream.Write(data)

        latency := time.Since(start)
        b.ReportMetric(float64(latency.Microseconds()), "µs/op")
    }
}

Run benchmark:

go test -bench=. -benchmem cmd/benchmark/latency_test.go

Unit Tests

Test Document Store

go test ./internal/models -v

Test Collaboration Session

go test ./internal/collaboration -v

Test Handlers

go test ./internal/handlers -v

Run All Tests

go test ./... -v

Integration Tests

End-to-End Test Script

#!/bin/bash

echo "=== Integration Test ==="

# Start server in background
go run cmd/server/main.go &
SERVER_PID=$!
sleep 2

# Test 1: Create document
echo "Test 1: Creating document..."
DOC_ID=$(curl -s -X POST http://localhost:8080/api/documents \
  -H "Content-Type: application/json" \
  -d '{"title":"Test","content":"Hello"}' | jq -r '.id')

if [ -z "$DOC_ID" ]; then
    echo "FAIL: Could not create document"
    kill $SERVER_PID
    exit 1
fi
echo "PASS: Document created with ID $DOC_ID"

# Test 2: Get document
echo "Test 2: Getting document..."
CONTENT=$(curl -s http://localhost:8080/api/documents/$DOC_ID | jq -r '.content')

if [ "$CONTENT" != "Hello" ]; then
    echo "FAIL: Content mismatch"
    kill $SERVER_PID
    exit 1
fi
echo "PASS: Document retrieved successfully"

# Test 3: Update document
echo "Test 3: Updating document..."
curl -s -X PUT http://localhost:8080/api/documents/$DOC_ID \
  -H "Content-Type: application/json" \
  -d '{"content":"Updated"}' > /dev/null

CONTENT=$(curl -s http://localhost:8080/api/documents/$DOC_ID | jq -r '.content')

if [ "$CONTENT" != "Updated" ]; then
    echo "FAIL: Update failed"
    kill $SERVER_PID
    exit 1
fi
echo "PASS: Document updated successfully"

# Test 4: Delete document
echo "Test 4: Deleting document..."
curl -s -X DELETE http://localhost:8080/api/documents/$DOC_ID

STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/documents/$DOC_ID)

if [ "$STATUS" != "404" ]; then
    echo "FAIL: Document not deleted"
    kill $SERVER_PID
    exit 1
fi
echo "PASS: Document deleted successfully"

# Cleanup
kill $SERVER_PID
echo "=== All tests passed! ==="

Expected Performance Metrics

Target Metrics

  • Latency: < 200ms (target), typically < 50ms on localhost
  • Throughput: 1000+ operations/second
  • Concurrent Users: 100 per document
  • Memory: < 100MB for 1000 documents
  • CPU: < 50% on 4-core system

Monitoring During Tests

# Monitor memory usage
watch -n 1 'ps aux | grep server'

# Monitor network
netstat -an | grep 4433

# Monitor goroutines (add to server)
curl http://localhost:8080/debug/pprof/goroutine?debug=1

Troubleshooting Tests

Server won't start

  • Check if ports 8080 and 4433 are available
  • Run: lsof -i :8080 and lsof -i :4433

Client can't connect

  • Verify server is running
  • Check firewall settings
  • Ensure QUIC (UDP) traffic is allowed

High latency

  • Check network conditions
  • Monitor CPU/memory usage
  • Reduce number of concurrent clients

Operations not syncing

  • Check server logs
  • Verify document ID is correct
  • Ensure all clients are connected to same document