JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 17
  • Score
    100M100P100Q50879F
  • License MIT

Test utilities for validating durable-execution storage implementations

Package Exports

  • durable-execution-storage-test-utils
  • durable-execution-storage-test-utils/package.json

Readme

durable-execution-storage-test-utils

NPM Version License Coverage

Test utilities for validating durable-execution storage implementations.

Installation

  • npm
npm install effect durable-execution durable-execution-storage-test-utils
  • pnpm
pnpm add effect durable-execution durable-execution-storage-test-utils

Usage

Testing

The primary use case is validating that your storage implementation correctly handles all aspects of durable task execution:

import { describe, test } from 'vitest'
import { runStorageTest } from 'durable-execution-storage-test-utils'
import { MyDatabaseStorage } from './my-storage'

describe('MyDatabaseStorage', () => {
  test('validates complete storage behavior', async () => {
    const storage = new MyDatabaseStorage(connectionString)

    await runStorageTest(storage, {
      storageCleanup: async () => {
        // Cleanup database after tests
        await storage.close()
      },
    })
  })
})

The test suite will automatically verify:

  • ✅ Task lifecycle management (ready → running → completed/failed)
  • ✅ Parent-child task relationships and coordination
  • ✅ Retry logic with exponential backoff
  • ✅ Concurrent execution handling
  • ✅ Error propagation and status transitions
  • ✅ Background processing (expiration, closure)
  • ✅ Storage consistency under high concurrency

See tests/index.test.ts for a complete example using InMemoryTaskExecutionsStorage. The suite internally spins up a DurableExecutor and validates storage behavior across many scenarios.

Benchmarking

The benchmark suite measures the performance of storage implementations under various workloads.

import { runStorageBench } from 'durable-execution-storage-test-utils'
import { InMemoryTaskExecutionsStorage } from 'durable-execution'

await runStorageBench("in memory", () => new InMemoryTaskExecutionsStorage())

See scripts/bench.ts for a complete example using InMemoryTaskExecutionsStorage. Benchmarks report per-executor timing stats aggregated across runs.

API Reference

runStorageTest

The main test suite that comprehensively validates storage implementations through complex scenarios.

Parameters:

  • storage: TaskExecutionsStorage - The storage implementation to test
  • options?: object - Optional configuration options
    • storageCleanup?: () => void | Promise<void> - Cleanup function called after tests complete (default: no cleanup)
    • enableStorageBatching?: boolean - Whether to enable storage batching (default: false)
    • storageBackgroundBatchingProcessIntraBatchSleepMs?: number - Artificial delay to add to storage batching operations (default: 10ms)

Features tested:

  • DurableExecutor integration: Complex task hierarchies with parent-child relationships
  • Concurrency: 250+ concurrent tasks with proper coordination
  • Retry mechanisms: Automatic retry logic with configurable options
  • Error handling: Various error types and failure scenarios
  • Task types: Simple tasks, parent tasks, sequential tasks, finalize tasks
  • Storage operations: CRUD operations, batch updates, status transitions
  • Parent-child relationships: Nested task hierarchies and active child tracking
  • Background processing: Task expiration, closure processes, and cleanup

Example:

import { runStorageTest } from 'durable-execution-storage-test-utils'
import { InMemoryTaskExecutionsStorage } from 'durable-execution'

describe('My Storage Implementation', () => {
  test('comprehensive storage test', async () => {
    const storage = new InMemoryTaskExecutionsStorage()
    await runStorageTest(storage)
  })
})

runStorageBench

The benchmark suite that measures the performance of storage implementations under various workloads.

Parameters:

  • name: string - The name of the storage implementation
  • getStorage: () => TaskExecutionsStorage | Promise<TaskExecutionsStorage> - A function that returns the storage implementation to test
  • options?: object - Optional configuration options
    • storageCleanup?: (storage: TaskExecutionsStorage) => void | Promise<void> - Cleanup function called after benchmark completes (default: no cleanup)
    • storageSlowdownMs?: number - Artificial delay to add to storage operations (default: 0)
    • executorsCount?: number - Number of concurrent executors to run (default: 1)
    • enableStorageBatching?: boolean - Whether to enable storage batching. (default: false)
    • storageBackgroundBatchingProcessIntraBatchSleepMs?: number - Artificial delay to add to storage batching operations (default: 10ms)
    • childTasksCount?: number - Number of child tasks per parent task (default: 50)
    • parentTasksCount?: number - Number of parent tasks to create (default: 100)
    • sequentialTasksCount?: number - Number of sequential tasks to create (default: 100)
    • pollingTasksCount?: number - Number of polling tasks to create (default: 100)

Example:

import { runStorageBench } from 'durable-execution-storage-test-utils'
import { InMemoryTaskExecutionsStorage } from 'durable-execution'

await runStorageBench("in memory", () => new InMemoryTaskExecutionsStorage())

// With cleanup for database storage
await runStorageBench(
  "custom",
  () => new CustomTaskExecutionsStorage({ url: process.env.DATABASE_URL! }),
  {
    storageCleanup: async (storage) => {
      // Clean up database after benchmark
      await storage.close()
    },
    executorsCount: 1,
    parentTasksCount: 50,
    childTasksCount: 25,
  },
)

Temporary Resource Helpers

Utilities for managing temporary files and directories in tests:

  • withTemporaryDirectory(fn: (dirPath: string) => Promise<void>) - Creates and cleans up a temporary directory
  • withTemporaryFile(filename: string, fn: (filePath: string) => Promise<void>) - Creates and cleans up a temporary file
  • cleanupTemporaryFiles() - Removes any leftover temporary files

License

This project is licensed under the MIT License. See the LICENSE file for details.