Temporal Simulation (Time Travel)
Temporal Simulation allows you to control time in your mock environment, enabling time-based data mutations, scheduled events, and time-travel debugging. Test time-dependent behavior without waiting for real time to pass.
Overview
Time travel in MockForge works through a virtual clock that can be:
- Enabled/disabled at runtime
- Set to any specific point in time
- Advanced by arbitrary durations instantly
- Scaled to run faster or slower than real time
When time travel is enabled, all time-related features use the virtual clock instead of the system clock.
Quick Start
Enable Time Travel
# config.yaml
core:
time_travel:
enabled: true
initial_time: "2025-01-01T00:00:00Z"
scale_factor: 1.0
enable_scheduling: true
Control Time via CLI
# Get time travel status
mockforge time status
# Enable time travel at a specific time
mockforge time enable --time "2025-01-01T00:00:00Z"
# Advance time by 1 month (instantly!)
mockforge time advance 1month
# Advance time by 2 hours
mockforge time advance 2h
# Set time to a specific point
mockforge time set "2025-06-01T12:00:00Z"
# Reset to real time
mockforge time reset
Use Time-Based Templates
Time-aware template tokens automatically use the virtual clock:
{
"timestamp": "{{now}}",
"expires_at": "{{now+1h}}",
"created_at": "{{now-30m}}"
}
Virtual Clock
The virtual clock is the core of temporal simulation. It provides:
Basic Operations
#![allow(unused)] fn main() { use mockforge_core::time_travel::VirtualClock; let clock = VirtualClock::new(); // Enable and set time clock.enable_and_set(DateTime::parse_from_rfc3339("2025-01-01T00:00:00Z")?); // Advance time clock.advance(Duration::from_secs(3600)); // Advance 1 hour // Get current virtual time let now = clock.now(); // Disable (return to real time) clock.disable(); }
Time Scale
Run time faster or slower than real time:
# Run at 2x speed
mockforge time scale 2.0
# Run at 0.5x speed (half speed)
mockforge time scale 0.5
Cron Scheduler
Schedule recurring events using cron expressions:
Create Cron Job
# Via CLI (action metadata is read from a JSON file)
echo '{"status": 200, "body": {"event": "cleanup"}}' > cleanup-action.json
mockforge time cron create cleanup-job \
--name "Cleanup" \
--schedule "0 */6 * * *" \
--action-type "response" \
--action-metadata cleanup-action.json
# Via API
curl -X POST http://localhost:9080/__mockforge/time-travel/cron \
-H "Content-Type: application/json" \
-d '{
"id": "cleanup-job",
"name": "Cleanup",
"schedule": "0 */6 * * *",
"action_type": "response",
"action_metadata": {"status": 200, "body": {"event": "cleanup"}}
}'
Supported action types are callback (logs the execution), response (metadata keys body, status, headers), and mutation.
Cron Expression Format
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
* * * * *
Examples:
0 */6 * * *- Every 6 hours0 0 * * *- Daily at midnight*/15 * * * *- Every 15 minutes0 9 * * 1-5- Weekdays at 9 AM
List Cron Jobs
# Via CLI
mockforge time cron list
# Via API
curl http://localhost:9080/__mockforge/time-travel/cron
Mutation Rules
Automatically mutate data based on time triggers:
Interval-Based Mutations
Mutate data at regular intervals:
# Create mutation rule (trigger and operation configs are JSON files)
echo '{"duration_seconds": 3600}' > trigger.json
echo '{"status": "shipped"}' > operation.json
mockforge time mutation create ship-orders \
--entity "orders" \
--trigger-type interval \
--trigger-config trigger.json \
--operation-type status \
--operation-config operation.json
# Via API
curl -X POST http://localhost:9080/__mockforge/time-travel/mutations \
-H "Content-Type: application/json" \
-d '{
"id": "ship-orders",
"entity_name": "orders",
"trigger": {
"type": "interval",
"duration_seconds": 3600
},
"operation": {
"type": "updatestatus",
"status": "shipped"
}
}'
Time-Based Mutations
Mutate data at specific times:
{
"entity": "tokens",
"trigger": {
"type": "at_time",
"time": "2025-01-01T12:00:00Z"
},
"operation": {
"type": "set",
"field": "expired",
"value": true
}
}
Field Threshold Mutations
Mutate when a field reaches a threshold:
{
"entity": "orders",
"trigger": {
"type": "field_threshold",
"field": "age_days",
"operator": ">=",
"value": 30
},
"operation": {
"type": "set",
"field": "status",
"value": "archived"
}
}
Scheduled Responses
Schedule responses to be sent at specific times:
# Schedule a response for 30 minutes from now
curl -X POST http://localhost:9080/__mockforge/time-travel/schedule \
-H "Content-Type: application/json" \
-d '{
"trigger_time": "+30m",
"path": "/api/notifications",
"method": "POST",
"body": {"event": "token_expired"},
"status": 401
}'
VBR Integration
Temporal simulation integrates with the VBR Engine for time-based data mutations:
Snapshot with Time Travel
Create snapshots that include time travel state:
#![allow(unused)] fn main() { use mockforge_vbr::VbrEngine; // Create snapshot with time travel state engine.create_snapshot_with_time_travel( "snapshot1", Some("Description".to_string()), "./snapshots", &clock ).await?; // Restore snapshot with time travel state engine.restore_snapshot_with_time_travel( "snapshot1", "./snapshots", &clock ).await?; }
Mutation Rules in VBR
VBR automatically executes mutation rules based on virtual time:
vbr:
entities:
- name: orders
mutation_rules:
- trigger: "interval:1h"
operation: "update_status"
field: "status"
value: "processing"
Admin API
Time Travel Status
GET /__mockforge/time-travel/status
Response:
{
"enabled": true,
"virtual_time": "2025-01-15T10:30:00Z",
"real_time": "2025-01-01T10:30:00Z",
"scale_factor": 1.0
}
Advance Time
POST /__mockforge/time-travel/advance
Content-Type: application/json
{
"duration": "2h" # or "1month", "30m", etc.
}
Set Time
POST /__mockforge/time-travel/set
Content-Type: application/json
{
"time": "2025-06-01T12:00:00Z"
}
Enable/Disable
POST /__mockforge/time-travel/enable
Content-Type: application/json
{
"time": "2025-01-01T00:00:00Z" # Optional initial time
}
POST /__mockforge/time-travel/disable
CLI Commands
Time Control
# Status
mockforge time status
# Enable
mockforge time enable [--time "2025-01-01T00:00:00Z"]
# Disable
mockforge time disable
# Advance
mockforge time advance <duration> # e.g., "1month", "2h", "30m"
# Set
mockforge time set <time> # ISO 8601 format
# Scale
mockforge time scale <factor> # e.g., 2.0 for 2x speed
# Reset
mockforge time reset
Cron Jobs
# List
mockforge time cron list
# Create
mockforge time cron create <id> --name "<name>" --schedule "<cron>" --action-type <callback|response|mutation> [--action-metadata <file.json>]
# Get
mockforge time cron get <id>
# Enable / disable
mockforge time cron enable <id>
mockforge time cron disable <id>
# Delete
mockforge time cron delete <id>
Mutation Rules
# List
mockforge time mutation list
# Create
mockforge time mutation create <id> --entity "<entity>" \
--trigger-type <interval|attime> --trigger-config <trigger.json> \
--operation-type <set|increment|decrement|status> --operation-config <operation.json>
# Get
mockforge time mutation get <id>
# Enable / disable
mockforge time mutation enable <id>
mockforge time mutation disable <id>
# Delete
mockforge time mutation delete <id>
Use Cases
Token Expiration
Test token expiration without waiting:
# Create token that expires in 1 hour
mockforge time enable --time "2025-01-01T00:00:00Z"
# Advance 1 hour
mockforge time advance 1h
# Token is now expired
Session Timeouts
Test session timeout behavior:
vbr:
entities:
- name: sessions
ttl_seconds: 3600 # 1 hour
aging_enabled: true
Scheduled Events
Test scheduled notifications:
# Schedule a daily report response at midnight
echo '{"status": 200, "body": {"event": "daily_report"}}' > daily-report.json
mockforge time cron create daily-report \
--name "Daily report" \
--schedule "0 0 * * *" \
--action-type "response" \
--action-metadata daily-report.json
Data Aging
Test data that changes over time:
# Create mutation rule to age orders once per day
echo '{"duration_seconds": 86400}' > daily.json
echo '{"field": "age_days", "amount": 1}' > increment.json
mockforge time mutation create age-orders \
--entity "orders" \
--trigger-type interval \
--trigger-config daily.json \
--operation-type increment \
--operation-config increment.json
Best Practices
- Start with Simple Scenarios: Begin with basic time advancement before using cron or mutations
- Use Snapshots: Save important time states for quick restoration
- Test Edge Cases: Test behavior at midnight, month boundaries, etc.
- Monitor Performance: Time-based features add minimal overhead
- Combine with VBR: Use VBR entities with time-based mutations for realistic scenarios
Troubleshooting
Time Not Advancing
- Ensure time travel is enabled:
mockforge time status - Check that scheduling is enabled in configuration
- Verify cron jobs are enabled
Mutations Not Executing
- Check mutation rule is enabled
- Verify trigger conditions are met
- Review server logs for errors
Cron Jobs Not Running
- Ensure cron scheduler background task is running
- Check cron expression is valid
- Verify job is enabled
Related Documentation
- VBR Engine - State management with time-based mutations
- Scenario State Machines - Time-based state transitions
- Configuration Guide - Complete configuration reference