110 lines
3.9 KiB
Rust
110 lines
3.9 KiB
Rust
use std::path::Path;
|
|
|
|
use rpki::storage::{
|
|
PackTime, RawByHashEntry, RepositoryViewEntry, RepositoryViewState, RocksStore,
|
|
RrdpSourceRecord, RrdpSourceSyncState,
|
|
};
|
|
use sha2::Digest;
|
|
|
|
fn put_current_object(store: &RocksStore, rsync_uri: &str, bytes: &[u8], object_type: &str) {
|
|
let sha256_hex = hex::encode(sha2::Sha256::digest(bytes));
|
|
let mut raw = RawByHashEntry::from_bytes(sha256_hex.clone(), bytes.to_vec());
|
|
raw.origin_uris.push(rsync_uri.to_string());
|
|
raw.object_type = Some(object_type.to_string());
|
|
raw.encoding = Some("der".to_string());
|
|
store.put_raw_by_hash_entry(&raw).expect("put raw_by_hash");
|
|
store
|
|
.put_repository_view_entry(&RepositoryViewEntry {
|
|
rsync_uri: rsync_uri.to_string(),
|
|
current_hash: Some(sha256_hex),
|
|
repository_source: Some("https://example.invalid/notification.xml".to_string()),
|
|
object_type: Some(object_type.to_string()),
|
|
state: RepositoryViewState::Present,
|
|
})
|
|
.expect("put repository view");
|
|
}
|
|
|
|
#[test]
|
|
fn storage_opens_and_creates_column_families() {
|
|
let dir = tempfile::tempdir().expect("tempdir");
|
|
let _store = RocksStore::open(dir.path()).expect("open rocksdb");
|
|
}
|
|
|
|
#[test]
|
|
fn current_object_roundtrip_by_rsync_uri() {
|
|
let dir = tempfile::tempdir().expect("tempdir");
|
|
let store = RocksStore::open(dir.path()).expect("open rocksdb");
|
|
|
|
let key = "rsync://example.invalid/repo/a.cer";
|
|
let value = b"hello";
|
|
put_current_object(&store, key, value, "cer");
|
|
let got = store
|
|
.load_current_object_bytes_by_uri(key)
|
|
.expect("get current object");
|
|
assert_eq!(got.as_deref(), Some(value.as_slice()));
|
|
|
|
let current_hash = store
|
|
.get_repository_view_entry(key)
|
|
.expect("get repository view")
|
|
.expect("view exists")
|
|
.current_hash
|
|
.expect("current hash");
|
|
store
|
|
.delete_repository_view_entry(key)
|
|
.expect("delete repository view");
|
|
store
|
|
.delete_raw_by_hash_entry(¤t_hash)
|
|
.expect("delete raw_by_hash");
|
|
let got = store
|
|
.load_current_object_bytes_by_uri(key)
|
|
.expect("get current object after delete");
|
|
assert!(got.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn rrdp_source_roundtrip_by_notification_uri() {
|
|
let dir = tempfile::tempdir().expect("tempdir");
|
|
let store = RocksStore::open(dir.path()).expect("open rocksdb");
|
|
|
|
let notif = "https://example.invalid/rrdp/notification.xml";
|
|
let record = RrdpSourceRecord {
|
|
notify_uri: notif.to_string(),
|
|
last_session_id: Some("00000000-0000-0000-0000-000000000000".to_string()),
|
|
last_serial: Some(1),
|
|
first_seen_at: PackTime::from_utc_offset_datetime(time::OffsetDateTime::now_utc()),
|
|
last_seen_at: PackTime::from_utc_offset_datetime(time::OffsetDateTime::now_utc()),
|
|
last_sync_at: None,
|
|
sync_state: RrdpSourceSyncState::SnapshotOnly,
|
|
last_snapshot_uri: None,
|
|
last_snapshot_hash: None,
|
|
last_error: None,
|
|
};
|
|
store.put_rrdp_source_record(&record).expect("put rrdp_source");
|
|
|
|
let got = store
|
|
.get_rrdp_source_record(notif)
|
|
.expect("get rrdp_source")
|
|
.expect("rrdp_source present");
|
|
assert_eq!(got.last_serial, Some(1));
|
|
assert_eq!(
|
|
got.last_session_id.as_deref(),
|
|
Some("00000000-0000-0000-0000-000000000000")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn store_is_reopenable() {
|
|
let dir = tempfile::tempdir().expect("tempdir");
|
|
let path: &Path = dir.path();
|
|
|
|
let store = RocksStore::open(path).expect("open rocksdb");
|
|
put_current_object(&store, "rsync://example.invalid/repo/x", b"x", "bin");
|
|
drop(store);
|
|
|
|
let store = RocksStore::open(path).expect("reopen rocksdb");
|
|
let got = store
|
|
.load_current_object_bytes_by_uri("rsync://example.invalid/repo/x")
|
|
.expect("get after reopen");
|
|
assert_eq!(got.as_deref(), Some(b"x".as_slice()));
|
|
}
|