karapace/crates/karapace-core/benches/engine_benchmarks.rs

203 lines
7 KiB
Rust
Raw Permalink Normal View History

use criterion::{criterion_group, criterion_main, Criterion};
use std::fs;
use std::path::Path;
fn create_test_manifest(dir: &Path) -> std::path::PathBuf {
let manifest_path = dir.join("karapace.toml");
fs::write(
&manifest_path,
r#"
manifest_version = 1
[base]
image = "rolling"
[system]
packages = ["git", "clang"]
[runtime]
backend = "mock"
"#,
)
.unwrap();
manifest_path
}
fn bench_build(c: &mut Criterion) {
c.bench_function("engine_build_mock_2pkg", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let project_dir = tempfile::tempdir().unwrap();
let manifest = create_test_manifest(project_dir.path());
let engine = karapace_core::Engine::new(store_dir.path());
(store_dir, project_dir, manifest, engine)
},
|(_sd, _pd, manifest, engine)| {
engine.build(&manifest).unwrap();
},
);
});
}
fn bench_rebuild_unchanged(c: &mut Criterion) {
c.bench_function("engine_rebuild_unchanged", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let project_dir = tempfile::tempdir().unwrap();
let manifest = create_test_manifest(project_dir.path());
let engine = karapace_core::Engine::new(store_dir.path());
let result = engine.build(&manifest).unwrap();
(store_dir, project_dir, manifest, engine, result)
},
|(_sd, _pd, manifest, engine, _result)| {
engine.build(&manifest).unwrap();
},
);
});
}
fn bench_commit(c: &mut Criterion) {
c.bench_function("engine_commit_100files", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let project_dir = tempfile::tempdir().unwrap();
let manifest = create_test_manifest(project_dir.path());
let engine = karapace_core::Engine::new(store_dir.path());
let result = engine.build(&manifest).unwrap();
let env_id = result.identity.env_id.to_string();
// Create 100 files in the upper directory to simulate drift
let upper = store_dir.path().join("env").join(&env_id).join("upper");
fs::create_dir_all(&upper).unwrap();
for i in 0..100 {
fs::write(
upper.join(format!("file_{i:03}.txt")),
format!("content {i}"),
)
.unwrap();
}
(store_dir, project_dir, engine, env_id)
},
|(_sd, _pd, engine, env_id)| {
engine.commit(&env_id).unwrap();
},
);
});
}
fn bench_restore(c: &mut Criterion) {
c.bench_function("engine_restore_snapshot", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let project_dir = tempfile::tempdir().unwrap();
let manifest = create_test_manifest(project_dir.path());
let engine = karapace_core::Engine::new(store_dir.path());
let result = engine.build(&manifest).unwrap();
let env_id = result.identity.env_id.to_string();
// Create files and commit a snapshot
let upper = store_dir.path().join("env").join(&env_id).join("upper");
fs::create_dir_all(&upper).unwrap();
for i in 0..50 {
fs::write(
upper.join(format!("file_{i:03}.txt")),
format!("content {i}"),
)
.unwrap();
}
let snapshot_hash = engine.commit(&env_id).unwrap();
(store_dir, project_dir, engine, env_id, snapshot_hash)
},
|(_sd, _pd, engine, env_id, snapshot_hash)| {
engine.restore(&env_id, &snapshot_hash).unwrap();
},
);
});
}
fn bench_gc(c: &mut Criterion) {
c.bench_function("gc_50envs", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let layout = karapace_store::StoreLayout::new(store_dir.path());
layout.initialize().unwrap();
let meta_store = karapace_store::MetadataStore::new(layout.clone());
let obj_store = karapace_store::ObjectStore::new(layout.clone());
// Create 50 environments: 25 live (ref_count=1), 25 dead (ref_count=0)
for i in 0..50 {
let obj_hash = obj_store.put(format!("obj-{i}").as_bytes()).unwrap();
let meta = karapace_store::EnvMetadata {
env_id: format!("env_{i:04}").into(),
short_id: format!("env_{i:04}").into(),
name: None,
state: karapace_store::EnvState::Built,
manifest_hash: obj_hash.into(),
base_layer: "".into(),
dependency_layers: vec![],
policy_layer: None,
created_at: "2026-01-01T00:00:00Z".to_owned(),
updated_at: "2026-01-01T00:00:00Z".to_owned(),
ref_count: u32::from(i < 25),
checksum: None,
};
meta_store.put(&meta).unwrap();
}
// Create 200 orphan objects
for i in 0..200 {
obj_store
.put(format!("orphan-object-{i}").as_bytes())
.unwrap();
}
(store_dir, layout)
},
|(_sd, layout)| {
let gc = karapace_store::GarbageCollector::new(layout);
gc.collect(false).unwrap();
},
);
});
}
fn bench_verify_store(c: &mut Criterion) {
c.bench_function("verify_store_200objects", |b| {
b.iter_with_setup(
|| {
let store_dir = tempfile::tempdir().unwrap();
let layout = karapace_store::StoreLayout::new(store_dir.path());
layout.initialize().unwrap();
let obj_store = karapace_store::ObjectStore::new(layout.clone());
// Create 200 objects
for i in 0..200 {
obj_store
.put(format!("verify-object-{i}").as_bytes())
.unwrap();
}
(store_dir, layout)
},
|(_sd, layout)| {
karapace_store::verify_store_integrity(&layout).unwrap();
},
);
});
}
criterion_group!(
benches,
bench_build,
bench_rebuild_unchanged,
bench_commit,
bench_restore,
bench_gc,
bench_verify_store,
);
criterion_main!(benches);