test-bd - Test Block Device with Procedural Data Generation
A library and CLI tool for creating deterministic, procedurally generated test block devices using ublk (userspace block device). Perfect for testing storage management tools, backup utilities, compression algorithms, and deduplication systems.
Features
- Procedural Data Generation: Deterministic data patterns based on seeds - same seed always produces same data
- Three Data Types: Fill (zeros), Duplicate (repeating patterns), and Random (pseudo-random)
- Configurable Size and Segments: Create devices of any size with customizable segment distribution
- No Storage Required: Generate data on-the-fly without consuming disk space
- High Performance: Fast reads, ~3.6 GB/s on modern hardware
- Unprivileged Mode: Run without root when kernel supports UBLK_F_UNPRIVILEGED_DEV
- JSON Output: Export segment information for automated testing
- Library + CLI: Use as a Rust library or command-line tool
Quick Start
Library Usage
Add to your Cargo.toml:
[]
= "0.1"
Create a test device:
use ;
CLI Usage
Create a test device:
# Create a 4 GiB device with default settings
# Create with custom data distribution and JSON output
# Delete a device
Use Cases
Testing Backup Tools
Create large test devices to verify backup tools correctly handle different data types:
use ;
// Create a 1 TiB device for backup testing
let config = TestBlockDeviceConfig ;
run.unwrap;
// Device is now available at /dev/ublkb0
// Run: dd if=/dev/ublkb0 | your-backup-tool
Testing Compression Algorithms
Verify compression ratios with known data distributions:
# Create device with 80% duplicate data (should compress well)
# Test compression
|
Reproducible Testing
Same seed produces identical data every time:
# Device 1 with seed 12345
# Device 2 with same seed - identical data
# Verify they're identical
Using Callbacks
Get segment information when device is ready:
use ;
let config = TestBlockDeviceConfig ;
run_with_callback.unwrap;
Data Patterns
Fill Pattern
- Data: All zeros
- Compressibility: Highly compressible
- Use Case: Testing same data pattern
Duplicate Pattern
- Data: Repeating 8-byte values (0-255)
- Compressibility: Moderately compressible
- Use Case: Testing deduplication and compression
Random Pattern
- Data: Pseudo-random data based on seed
- Compressibility: Not compressible
- Use Case: Testing worst-case scenarios
Performance
- Read Throughput: Varies based on hardware (CPU constrained)
- Write Support: Read-only (writes return EINVAL)
- Memory Usage: Minimal - data generated on demand
- Storage Usage: Zero - no backing store required
# Benchmark example
)
Requirements
- Linux kernel 6.0+ with
CONFIG_BLK_DEV_UBLKenabled - For unprivileged mode:
UBLK_F_UNPRIVILEGED_DEVsupport in kernel - io_uring support
Check if ublk is available:
# Check if ublk module is loaded
|
# Load if needed
CLI Reference
Add Command
)
Delete Command
JSON Output
Export device configuration and segment information:
{
{
}
{
}
{
}
}
Safety and Limitations
- Read-Only: Devices are read-only by design
- Deterministic: Same seed always produces same data
- No Persistence: Data exists only while device is running
- Maximum Size: Limited to i64::MAX bytes (~8 EiB)
- Segments: Must be less than device_size / 512
Examples
See the examples directory:
# Run the simple example
Development
# Build
# Run tests
# Build documentation
# For local development with path dependency:
# Uncomment the libublk path dependency in Cargo.toml
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Acknowledgments
Based on the libublk-rs example ramdisk target