mock-ocserv

command
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2025 License: MIT Imports: 14 Imported by: 0

README

Mock ocserv Unix Socket Server

Mock implementation of ocserv's occtl Unix socket interface for integration testing.

Overview

This mock server simulates the ocserv Unix socket that occtl uses to communicate with the ocserv daemon. It's designed for integration testing of ocserv-agent without requiring a real ocserv installation.

Key Features:

  • ✅ Listens on Unix domain socket (like real ocserv)
  • ✅ Supports all 13 occtl commands with -j (JSON) flag
  • ✅ Returns realistic responses from production fixtures
  • ✅ Handles multiple concurrent connections
  • ✅ Graceful shutdown on SIGINT/SIGTERM
  • ✅ Configurable socket path and fixtures directory

Quick Start

# From repository root
make compose-mock-ocserv

# View logs
podman logs -f mock-ocserv

# Stop
cd deploy/compose && podman-compose -f mock-ocserv.yml down

Container Details:

  • Image: ocserv-agent-mock-ocserv:latest
  • Socket: /var/run/occtl.socket (inside container)
  • Fixtures: /fixtures/ocserv/occtl (mounted read-only)
  • Network: ocserv-agent-test
  • Health check: Every 5s
Run Locally (Development Only)
# From repository root
cd test/mock-ocserv
go run . -socket /tmp/occtl-test.socket

# Or with custom fixtures path
go run . -socket /tmp/occtl-test.socket -fixtures ../fixtures/ocserv/occtl

# Enable verbose logging
go run . -verbose

⚠️ Note: Local runs are for development only. All testing should use podman-compose.

Test with nc (netcat)
# In another terminal
echo '{"command": ["show", "-j", "users"]}' | nc -U /tmp/occtl-test.socket

# Or plain text format
echo 'show -j users' | nc -U /tmp/occtl-test.socket
Test with ocserv-agent (in Compose)
# Start mock server
make compose-mock-ocserv

# In another terminal, run tests that connect to mock socket
# Tests should use the shared volume or network to access socket

# Integration tests will use mock-ocserv via shared volume
# See docker-compose.test.yml for configuration
Test Locally (Development)
# Configure ocserv-agent to use mock socket
export OCSERV_SOCKET=/tmp/occtl-test.socket

# Run integration tests
go test -v ./internal/ocserv/...

Supported Commands

The mock server supports all 13 occtl commands found in production ocserv 1.3:

User Management
  • show -j users - List all connected users
  • show -j user <username> - Show details for specific user
  • show -j id <id> - Show connection by ID
Session Management
  • show -j sessions all - All sessions
  • show -j sessions valid - Valid sessions (reconnectable)
  • show -j session <session-id> - Specific session details
  • show -j cookies all - All session cookies (alias for sessions)
  • show -j cookies valid - Valid cookies
Server Status
  • show -j status - Server statistics and uptime
  • show -j iroutes - User-provided routes
  • show -j events - Real-time connection events (streaming)
  • show -j ip ban points - IP ban list and scores
Plain Text Commands
  • show id <id> - Connection details (plain text format)

Input Format

The mock server accepts two input formats:

1. JSON Format (Real ocserv Protocol)
{"command": ["show", "-j", "users"]}
2. Plain Text Format (For Testing)
show -j users

Both formats are equivalent and produce the same output.

Output Format

Responses are returned as newline-terminated JSON, matching real ocserv behavior:

[{
  "ID": 836873,
  "Username": "lpa",
  "State": "connected",
  "Remote IP": "90.156.164.225",
  "IPv4": "10.0.16.23",
  ...
}]

Fixtures

Fixtures are loaded from ../fixtures/ocserv/occtl/ directory:

fixtures/ocserv/occtl/
├── occtl -j show users          # User list
├── occtl -j show status         # Server stats
├── occtl -j show user           # User details (single)
├── occtl -j show id             # Connection by ID
├── occtl -j show sessions all   # All sessions
├── occtl -j show sessions valid # Valid sessions
├── occtl -j show iroutes        # User routes
├── occtl -j show events         # Events stream
├── occtl -j show ip ban points  # IP bans
├── occtl -j show cookies all    # All cookies
├── occtl -j show cookies valid  # Valid cookies
├── occtl -j show session        # Session details
└── occtl show id                # Plain text ID lookup

Note: Fixtures are from production ocserv 1.3.0 server (Oracle Linux 10) with sanitized data.

Command-Line Flags

-socket string
    Unix socket path (default "/tmp/occtl-test.socket")

-fixtures string
    Path to fixtures directory (default "../fixtures/ocserv/occtl")

-verbose
    Enable verbose logging (default false)

Architecture

┌─────────────┐      Unix Socket       ┌──────────────┐
│             │◄──────────────────────►│              │
│  Client     │  JSON commands         │  Mock Server │
│ (ocserv-   │  JSON responses        │              │
│  agent)     │                         │              │
└─────────────┘                         └──────┬───────┘
                                               │
                                               │ Loads
                                               ▼
                                        ┌──────────────┐
                                        │   Fixtures   │
                                        │  (JSON files)│
                                        └──────────────┘
Components
  1. main.go - Server setup, signal handling, socket lifecycle
  2. handler.go - Connection handling, command execution
  3. command.go - Command parsing (JSON and plain text)
  4. fixtures.go - Fixture loading and lookup

Integration Testing

Example Test
func TestOcctlIntegration(t *testing.T) {
    // Start mock server
    socketPath := "/tmp/occtl-test.socket"
    fixturesPath := "../../test/fixtures/ocserv/occtl"

    // ... start mock server in background

    // Create ocserv manager
    mgr := ocserv.NewOcctlManager(socketPath)

    // Test commands
    users, err := mgr.ShowUsers(context.Background())
    require.NoError(t, err)
    assert.Len(t, users, 2)
    assert.Equal(t, "lpa", users[0].Username)
}
Usage in CI/CD
# .github/workflows/test.yml
- name: Run Integration Tests
  run: |
    # Start mock server in background
    cd test/mock-ocserv
    go run . -socket /tmp/occtl-test.socket &
    MOCK_PID=$!

    # Wait for socket
    sleep 1

    # Run tests
    cd ../..
    go test -v -tags=integration ./...

    # Cleanup
    kill $MOCK_PID

Troubleshooting

Socket Permission Denied
# Check socket exists and has correct permissions
ls -l /tmp/occtl-test.socket
# Should show: srw-rw-rw-

# If needed, set permissions manually
chmod 666 /tmp/occtl-test.socket
Fixtures Not Found
# Check fixtures directory
ls ../fixtures/ocserv/occtl/
# Should list 13 files starting with "occtl"

# Use absolute path
go run . -fixtures /full/path/to/fixtures/ocserv/occtl
Connection Refused
# Check if socket is listening
lsof | grep occtl-test.socket

# Check if another process is using the socket
fuser /tmp/occtl-test.socket

# Remove old socket
rm -f /tmp/occtl-test.socket

Differences from Real ocserv

  1. No Authentication - Mock server does not verify client permissions
  2. Static Responses - Returns pre-recorded fixtures, not live data
  3. No State Changes - Commands like disconnect return success but don't affect state
  4. Fixed Data - User list, status, etc. never change during runtime
  5. No Events Streaming - show events returns static data, not real-time stream

These differences are intentional for testing purposes.

Performance

  • Startup time: <100ms (including fixture loading)
  • Memory usage: ~5MB (with all fixtures loaded)
  • Latency: <1ms per command
  • Concurrency: Handles 100+ concurrent connections

Development

Adding New Fixtures
  1. Run real occtl command on production server:
occtl -j show users > fixtures/ocserv/occtl/"occtl -j show users"
  1. Sanitize data if needed (remove sensitive info)
  2. Place file in fixtures/ocserv/occtl/ directory
  3. Restart mock server (it will auto-load new fixture)
Testing Changes
# Run with verbose logging
go run . -verbose

# Test specific command
echo 'show -j users' | nc -U /tmp/occtl-test.socket

Future Enhancements

  • Support for non-JSON commands (plain text)
  • State management (track "connected" users)
  • Event streaming support
  • Config file support
  • Metrics/statistics endpoint

References


Last Updated: 2025-10-23 Status: Production-ready for integration testing

Documentation

Overview

mock-ocserv: Mock ocserv Unix socket server for integration testing

This server simulates occtl Unix socket interface by: - Listening on a Unix socket (default: /tmp/occtl-test.socket) - Accepting JSON-formatted occtl commands - Returning realistic responses from test fixtures

Usage:

go run main.go -socket /tmp/occtl-test.socket
go run main.go -fixtures ./test/fixtures/ocserv/occtl

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL