| Crates.io | qlean |
| lib.rs | qlean |
| version | 0.1.1 |
| created_at | 2026-01-12 03:17:27.480716+00 |
| updated_at | 2026-01-24 14:39:38.192728+00 |
| description | A system-level isolation testing library based on QEMU/KVM. |
| homepage | |
| repository | https://github.com/buck2hub/qlean |
| max_upload_size | |
| id | 2036939 |
| size | 204,777 |
Qlean is a system-level isolation testing library based on QEMU/KVM, providing complete virtual machine isolation environments for Rust projects.
Qlean provides a comprehensive testing solution for projects requiring system-level isolation by launching lightweight virtual machines during tests. It addresses two major challenges:
1. Complete Resource Isolation
Many projects require root privileges or direct manipulation of system-level resources. Traditional single-machine tests can easily crash the host system if tests fail. Qlean uses virtual machine isolation to completely isolate these operations within the VM, ensuring host system stability.
2. Convenient Multi-Machine Testing
For projects requiring multi-machine collaboration, Qlean provides a simple API that allows you to easily create and manage multiple VM instances in test code without complex infrastructure configuration.
Before using Qlean, ensure that QEMU, guestfish, libguestfs-tools and some other utils are properly installed on your Linux host. You can verify the installation with the following commands:
qemu-system-x86_64 --version
qemu-img --version
guestfish --version
virt-copy-out --version
xorriso --version
sha256sum --version
sha512sum --version
Add the dependency to your Cargo.toml:
[dev-dependencies]
qlean = "0.1"
tokio = { version = "1", features = ["full"] }
Here's a simple test example with single machine:
use anyhow::Result;
use qlean::{Distro, MachineConfig, create_image, with_machine};
#[tokio::test]
async fn test_with_vm() -> Result<()> {
// Create VM image and config
let image = create_image(Distro::Debian, "debian-13-generic-amd64").await?;
let config = MachineConfig::default();
// Execute tests in the virtual machine
with_machine(&image, &config, |vm| {
Box::pin(async {
// Execute a command
let result = vm.exec("whoami").await?;
assert!(result.status.success());
assert_eq!(str::from_utf8(&result.stdout)?.trim(), "root");
Ok(())
})
})
.await?;
Ok(())
}
For more examples, please refer to the tests directory.
create_image(distro, name) - Create or retrieve a VM image from the specified distribution
with_machine(image, config, f) - Execute an async closure in a virtual machine with automatic resource cleanup
MachineConfig - Configuration for virtual machine resources (CPU, memory, disk)
pub struct MachineConfig {
pub core: u32, // Number of CPU cores
pub mem: u32, // Memory size in MB
pub disk: Option<u32>, // Disk size in GB (optional)
pub clear: bool, // Clear resources after use
}
Machine::new(image, config) - Create a new machine instanceMachine::init() - Initialize the machine (first boot with cloud-init)Machine::spawn() - Start the machine (normal boot)Machine::exec(command) - Execute a command in the VM and return the outputMachine::shutdown() - Gracefully shutdown the virtual machineMachine::upload(src, dst) - Upload a file or directory to the VMMachine::download(src, dst) - Download a file or directory from the VMThe following methods provide filesystem operations compatible with std::fs semantics:
Machine::copy(from, to) - Copy a file within the VMMachine::create_dir(path) - Create a directoryMachine::create_dir_all(path) - Create a directory and all missing parent directoriesMachine::exists(path) - Check if a path existsMachine::hard_link(src, dst) - Create a hard linkMachine::metadata(path) - Get file/directory metadataMachine::read(path) - Read file contents as bytesMachine::read_dir(path) - Read directory entriesMachine::read_link(path) - Read symbolic link targetMachine::read_to_string(path) - Read file contents as stringMachine::remove_dir_all(path) - Remove a directory after removing all its contentsMachine::remove_file(path) - Remove a fileMachine::rename(from, to) - Rename or move a file/directoryMachine::set_permissions(path, perm) - Set file/directory permissionsMachine::write(path, contents) - Write bytes to a fileThis project is licensed under the MIT license.