use overgraph::{
DatabaseEngine, DbOptions, PrunePolicy, UpsertEdgeOptions, UpsertNodeOptions, WalSyncMode,
};
use std::process::Command;
use tempfile::TempDir;
fn inspect_binary() -> &'static str {
env!("CARGO_BIN_EXE_overgraph-inspect")
}
#[test]
fn test_inspect_empty_db() {
let dir = TempDir::new().unwrap();
let opts = DbOptions {
create_if_missing: true,
wal_sync_mode: WalSyncMode::Immediate,
..DbOptions::default()
};
let db = DatabaseEngine::open(dir.path(), &opts).unwrap();
db.close().unwrap();
let output = Command::new(inspect_binary())
.arg(dir.path().to_str().unwrap())
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
output.status.success(),
"inspect failed: {}",
String::from_utf8_lossy(&output.stderr)
);
assert!(stdout.contains("OverGraph Database:"));
assert!(stdout.contains("Version: 1"));
assert!(stdout.contains("Segments: 0"));
assert!(stdout.contains("WAL: 1 generation(s)"));
}
#[test]
fn test_inspect_with_data() {
let dir = TempDir::new().unwrap();
let opts = DbOptions {
create_if_missing: true,
wal_sync_mode: WalSyncMode::Immediate,
compact_after_n_flushes: 0,
..DbOptions::default()
};
let db = DatabaseEngine::open(dir.path(), &opts).unwrap();
for i in 0..10 {
db.upsert_node(1, &format!("node_{}", i), UpsertNodeOptions::default())
.unwrap();
}
let n1 = db
.upsert_node(2, "a", UpsertNodeOptions::default())
.unwrap();
let n2 = db
.upsert_node(2, "b", UpsertNodeOptions::default())
.unwrap();
db.upsert_edge(n1, n2, 1, UpsertEdgeOptions::default())
.unwrap();
db.flush().unwrap();
db.close().unwrap();
let output = Command::new(inspect_binary())
.arg(dir.path().to_str().unwrap())
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
output.status.success(),
"inspect failed: {}",
String::from_utf8_lossy(&output.stderr)
);
assert!(stdout.contains("Segments: 1"));
assert!(stdout.contains(" 12"));
assert!(stdout.contains("Segment Sizes"));
assert!(stdout.contains("seg_0001"));
assert!(stdout.contains("Next node ID: 13"));
assert!(stdout.contains("Next edge ID: 2"));
}
#[test]
fn test_inspect_multiple_segments() {
let dir = TempDir::new().unwrap();
let opts = DbOptions {
create_if_missing: true,
wal_sync_mode: WalSyncMode::Immediate,
compact_after_n_flushes: 0,
..DbOptions::default()
};
let db = DatabaseEngine::open(dir.path(), &opts).unwrap();
for i in 0..5 {
db.upsert_node(1, &format!("batch1_{}", i), UpsertNodeOptions::default())
.unwrap();
}
db.flush().unwrap();
for i in 0..3 {
db.upsert_node(1, &format!("batch2_{}", i), UpsertNodeOptions::default())
.unwrap();
}
db.flush().unwrap();
db.close().unwrap();
let output = Command::new(inspect_binary())
.arg(dir.path().to_str().unwrap())
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("Segments: 2"));
assert!(stdout.contains("seg_0001"));
assert!(stdout.contains("seg_0002"));
assert!(stdout.contains("Total"));
}
#[test]
fn test_inspect_with_prune_policies() {
let dir = TempDir::new().unwrap();
let opts = DbOptions {
create_if_missing: true,
wal_sync_mode: WalSyncMode::Immediate,
..DbOptions::default()
};
let db = DatabaseEngine::open(dir.path(), &opts).unwrap();
db.set_prune_policy(
"old_memories",
PrunePolicy {
max_age_ms: Some(86_400_000),
max_weight: Some(0.1),
type_id: Some(3),
},
)
.unwrap();
db.close().unwrap();
let output = Command::new(inspect_binary())
.arg(dir.path().to_str().unwrap())
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("Prune Policies: 1"));
assert!(stdout.contains("old_memories"));
assert!(stdout.contains("max_age=86400000ms"));
assert!(stdout.contains("max_weight=0.1"));
assert!(stdout.contains("type_id=3"));
}
#[test]
fn test_inspect_json_with_data() {
let dir = TempDir::new().unwrap();
let opts = DbOptions {
create_if_missing: true,
wal_sync_mode: WalSyncMode::Immediate,
compact_after_n_flushes: 0,
..DbOptions::default()
};
let db = DatabaseEngine::open(dir.path(), &opts).unwrap();
for i in 0..5 {
db.upsert_node(1, &format!("node_{}", i), UpsertNodeOptions::default())
.unwrap();
}
db.flush().unwrap();
db.close().unwrap();
let output = Command::new(inspect_binary())
.args(["--json", dir.path().to_str().unwrap()])
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
output.status.success(),
"inspect --json failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let parsed: serde_json::Value =
serde_json::from_str(&stdout).expect("output should be valid JSON");
assert_eq!(parsed["manifest_version"], 1);
assert_eq!(parsed["segment_count"], 1);
assert_eq!(parsed["total_nodes"], 5);
assert_eq!(parsed["total_edges"], 0);
assert_eq!(parsed["next_node_id"], 6);
assert_eq!(parsed["next_edge_id"], 1);
assert!(parsed["wal_bytes"].as_u64().unwrap() > 0);
assert_eq!(parsed["segments"].as_array().unwrap().len(), 1);
assert_eq!(parsed["segments"][0]["node_count"], 5);
assert!(parsed["segments"][0]["size_bytes"].as_u64().unwrap() > 0);
}
#[test]
fn test_inspect_json_uninitialized() {
let dir = TempDir::new().unwrap();
let output = Command::new(inspect_binary())
.args(["--json", dir.path().to_str().unwrap()])
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
let parsed: serde_json::Value =
serde_json::from_str(&stdout).expect("output should be valid JSON");
assert_eq!(parsed["initialized"], false);
assert!(parsed["wal_bytes"].is_null());
}
#[test]
fn test_inspect_nonexistent_path() {
let output = Command::new(inspect_binary())
.arg("/tmp/does_not_exist_overgraph_test")
.output()
.expect("failed to run overgraph-inspect");
assert!(!output.status.success());
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(stderr.contains("not a directory"));
}
#[test]
fn test_inspect_no_args() {
let output = Command::new(inspect_binary())
.output()
.expect("failed to run overgraph-inspect");
assert!(!output.status.success());
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(stderr.contains("Usage:"));
}
#[test]
fn test_inspect_uninitialized_dir() {
let dir = TempDir::new().unwrap();
let output = Command::new(inspect_binary())
.arg(dir.path().to_str().unwrap())
.output()
.expect("failed to run overgraph-inspect");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("No manifest found"));
assert!(stdout.contains("WAL: not present"));
}