Skip to content
cloudemu
Features

Fake Clock

Deterministic time control for TTL, dedup, and alarms

Advance or set the clock by hand to test TTL expiry, dedup windows, and alarms — no time.Sleep.

config.WithClock(config.NewFakeClock(t0))

clock.Advance(48 * time.Hour)TTLs expire · dedup windows roll · alarms fire

Setup#

import "github.com/stackshy/cloudemu/v2/config"

clock := config.NewFakeClock(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC))

aws := cloudemu.NewAWS(
    config.WithClock(clock),
)

Manipulating time#

// Move forward by a duration
clock.Advance(5 * time.Minute)

// Jump to a specific time
clock.Set(time.Date(2025, 6, 15, 12, 0, 0, 0, time.UTC))

// Check current fake time
now := clock.Now()

Use cases#

TTL expiry#

clock := config.NewFakeClock(time.Now())
aws := cloudemu.NewAWS(config.WithClock(clock))

// Set item with TTL
aws.DynamoDB.PutItem(ctx, "sessions", map[string]any{
    "id": "s-1", "expiresAt": clock.Now().Add(1 * time.Hour).Unix(),
})

// Item exists now
item, _ := aws.DynamoDB.GetItem(ctx, "sessions", map[string]any{"id": "s-1"})
// item != nil

// Advance past TTL
clock.Advance(2 * time.Hour)

// Item is now expired
item, _ = aws.DynamoDB.GetItem(ctx, "sessions", map[string]any{"id": "s-1"})
// item == nil

FIFO deduplication#

// Send a message
aws.SQS.SendMessage(ctx, "queue.fifo", mqdriver.SendMessageInput{
    Body: "order-1", MessageDeduplicationId: "dedup-1",
})

// Same dedup ID within 5 minutes — deduplicated
aws.SQS.SendMessage(ctx, "queue.fifo", mqdriver.SendMessageInput{
    Body: "order-1", MessageDeduplicationId: "dedup-1",
})
// Only 1 message in queue

// Advance past dedup window
clock.Advance(6 * time.Minute)

// Now the same ID can be used again
aws.SQS.SendMessage(ctx, "queue.fifo", mqdriver.SendMessageInput{
    Body: "order-1", MessageDeduplicationId: "dedup-1",
})
// 2 messages in queue

Thread safety#

FakeClock is thread-safe — it uses a mutex internally. You can safely share one clock across multiple goroutines and providers.

On this page

On this page