Files
Pulse/docs/development/MOCK_MODE.md
2025-10-11 23:29:47 +00:00

8.0 KiB

Mock Mode Development Guide

Mock mode allows you to develop and test Pulse without requiring real Proxmox infrastructure. It generates realistic mock data including nodes, VMs, containers, storage, backups, and alerts.

Quick Start

Toggling Mock Mode

During hot-dev mode (scripts/hot-dev.sh), use these npm commands to toggle mock mode:

# Enable mock mode
npm run mock:on

# Disable mock mode (use real infrastructure)
npm run mock:off

# Check current status
npm run mock:status

# Edit mock configuration
npm run mock:edit

The backend will automatically reload when you toggle mock mode - no manual restarts needed!

Configuration

Mock mode is configured via mock.env in the project root. This file is tracked in the repository with sensible defaults, so mock mode works out of the box for all developers.

Default configuration (mock.env):

PULSE_MOCK_MODE=false              # Disabled by default
PULSE_MOCK_NODES=7
PULSE_MOCK_VMS_PER_NODE=5
PULSE_MOCK_LXCS_PER_NODE=8
PULSE_MOCK_DOCKER_HOSTS=3
PULSE_MOCK_DOCKER_CONTAINERS=12
PULSE_MOCK_RANDOM_METRICS=true
PULSE_MOCK_STOPPED_PERCENT=20

Local overrides (not tracked): Create mock.env.local for personal settings that won't be committed:

# mock.env.local - your personal settings
PULSE_MOCK_MODE=true              # Always start in mock mode
PULSE_MOCK_NODES=3                # Fewer nodes for faster startup

The .local file overrides values from mock.env, and is gitignored to keep your personal preferences private.

Configuration options:

  • PULSE_MOCK_MODE: Enable/disable mock mode (true/false)
  • PULSE_MOCK_NODES: Number of nodes to generate (default: 7)
  • PULSE_MOCK_VMS_PER_NODE: Average VMs per node (default: 5)
  • PULSE_MOCK_LXCS_PER_NODE: Average containers per node (default: 8)
  • PULSE_MOCK_DOCKER_HOSTS: Number of Docker hosts to generate (default: 3)
  • PULSE_MOCK_DOCKER_CONTAINERS: Average containers per Docker host (default: 12)
  • PULSE_MOCK_RANDOM_METRICS: Enable metric fluctuations (true/false)
  • PULSE_MOCK_STOPPED_PERCENT: Percentage of guests in stopped state (default: 20)

Data Isolation

Hot-dev mode now isolates mock data from production credentials automatically:

  • Mock mode: data lives in /opt/pulse/tmp/mock-data
  • Production mode: data lives in /etc/pulse

The toggle script exports PULSE_DATA_DIR before launching the backend, creates the temporary directory if needed, and cleans up on exit. This guarantees mock credentials never overwrite your real cluster configuration and makes it safe to flip between datasets repeatedly during a session.

Hot-Dev Workflow

  1. Start hot-dev mode:

    scripts/hot-dev.sh
    
  2. Toggle mock mode as needed:

    npm run mock:on   # Backend auto-reloads with mock data
    npm run mock:off  # Backend auto-reloads with real data
    
  3. Edit mock configuration:

    npm run mock:edit  # Opens mock.env in your editor
    # Save and exit - backend auto-reloads!
    
  4. Frontend changes: Just save your files - Vite hot-reloads instantly

No port changes. No manual restarts. Everything just works!

Mock Data Generation

Mock mode generates:

  • Nodes: Mix of clustered and standalone nodes
  • Cluster: First 5 nodes form mock-cluster, rest are standalone
  • VMs & Containers: Realistic distribution with various states
  • Storage: Local, ZFS, PBS, and shared NFS storage
  • Backups: Both PVE and PBS backups with realistic metadata
  • Mail Gateway: PMG instances with mail throughput, spam/virus totals, and quarantine counts
  • Alerts: CPU, memory, disk, and connectivity alerts
  • Metrics: Live-updating metrics every 2 seconds

Node Characteristics

  • Clustered nodes (pve1-pve5): Part of mock-cluster
  • Standalone nodes (standalone1, etc.): Independent instances
  • Offline nodes: pve3 is always offline to test error handling
  • Host URLs: Each node has Host field set (e.g., https://pve1.local:8006)
  • Cluster fields: IsClusterMember and ClusterName properly set

API Behavior in Mock Mode

Fast, Cached Responses

In mock mode, /api/state returns cached data instantly - no locks, no delays, no timeouts. The mock data is stored in memory and updated every 2 seconds with realistic metric fluctuations.

WebSocket Updates

The WebSocket connection receives updates every 2 seconds with changing metrics, just like production.

Dashboard Grouping

Mock nodes include all required fields for proper dashboard grouping:

  • isClusterMember: Boolean indicating cluster membership
  • clusterName: Name of the cluster (e.g., "mock-cluster")
  • host: Full node URL (e.g., "https://pve1.local:8006")

Demo Server Usage

On the demo server, mock mode works the same way:

Systemd Service

If using systemd (pulse-dev service):

# Toggle mock mode (restarts service)
sudo /opt/pulse/scripts/toggle-mock.sh on
sudo /opt/pulse/scripts/toggle-mock.sh off

# Check status
/opt/pulse/scripts/toggle-mock.sh status

Manual Mode

If running the backend manually:

# Edit mock.env
nano /opt/pulse/mock.env

# The file watcher will detect changes and auto-reload the backend
# within 5 seconds (or immediately if fsnotify is working)

File Watcher Details

The backend watches mock.env using:

  1. Primary: fsnotify (instant notification on file changes)
  2. Fallback: Polling every 5 seconds (if fsnotify fails)

When mock.env changes:

  • Environment variables are updated
  • Monitor is reloaded with new configuration
  • New mock data is generated
  • WebSocket clients receive updated state

No manual process restarts required!

Troubleshooting

Mock mode not updating

  1. Check that mock.env exists: ls -la /opt/pulse/mock.env
  2. Check file watcher logs: Look for "Detected mock.env file change" in logs
  3. Verify environment variables: env | grep PULSE_MOCK
  4. Try touching the file: touch /opt/pulse/mock.env

Backend not reloading

  1. Ensure hot-dev mode is running (not systemd service)
  2. Check for errors in backend logs
  3. Verify file watcher started successfully
  4. Fall back to manual restart if needed

Missing cluster grouping

  1. Verify mock data includes isClusterMember and clusterName
  2. Check API response: curl http://localhost:7656/api/state | jq '.nodes[0]'
  3. Ensure frontend is receiving WebSocket updates

Implementation Details

Backend Components

  • Config Watcher (internal/config/watcher.go): Watches both .env and mock.env
  • Mock Integration (internal/mock/integration.go): Manages mock state and updates
  • Mock Generator (internal/mock/generator.go): Generates realistic mock data
  • Monitor (internal/monitoring/monitor.go): Returns cached mock data when enabled

Auto-Reload Flow

  1. User runs npm run mock:on (or edits mock.env)
  2. toggle-mock.sh updates mock.env and touches the file
  3. Config watcher detects file change (via fsnotify or polling)
  4. Watcher triggers reload callback
  5. ReloadableMonitor reloads with fresh config
  6. New monitor instance starts with updated mock mode
  7. WebSocket broadcasts new state to connected clients

Performance

  • Mock data generation: < 100ms for 7 nodes with 90+ guests
  • State snapshot: Instant (returns cached data)
  • Memory usage: ~50MB additional for mock data
  • Update interval: 2 seconds for metric fluctuations

Best Practices

  1. Use mock mode for frontend development - Fast, predictable data
  2. Test with real data before PRs - Ensure real infrastructure works
  3. Adjust mock config to test edge cases - High load, many nodes, etc.
  4. Use mock.env.local for personal settings - Your preferences won't be committed
  5. Keep mock.env defaults reasonable - Other developers will use them
  6. Document any mock data assumptions - Help other developers

See Also