lmdb: migration test, clean data after allocate test

This commit is contained in:
ardocrat
2026-05-18 13:22:24 +03:00
parent 2dd726f17b
commit 7a387d434b
+115 -2
View File
@@ -16,9 +16,17 @@ use grin_core as core;
use grin_store as store;
use grin_util as util;
use crate::core::global;
use crate::core::ser::{self, Readable, Reader, Writeable, Writer};
use core::global;
use core::ser::{self, Readable, Reader, Writeable, Writer};
use store::{
needs_resize, to_key, to_key_u64, Store, ALLOC_CHUNK_SIZE_DEFAULT_TEST, DEFAULT_ENV_NAME,
};
use byteorder::WriteBytesExt;
use heed::types::Bytes;
use heed::{Database, Env, EnvOpenOptions, WithoutTls};
use std::fs;
use std::path::Path;
const WRITE_CHUNK_SIZE: usize = 20;
const TEST_ALLOC_SIZE: usize = store::lmdb::ALLOC_CHUNK_SIZE_DEFAULT / 8 / WRITE_CHUNK_SIZE;
@@ -168,5 +176,110 @@ fn lmdb_allocate() -> Result<(), store::Error> {
}
}
clean_output_dir(test_dir);
Ok(())
}
fn create_old_db(
test_dir: &str,
) -> Result<(Database<Bytes, Bytes>, Env<WithoutTls>), store::Error> {
let env_name = DEFAULT_ENV_NAME;
let alloc_chunk_size = ALLOC_CHUNK_SIZE_DEFAULT_TEST;
let full_path = Path::new(test_dir)
.join(env_name)
.to_str()
.unwrap()
.to_string();
let _ = fs::create_dir_all(&full_path);
let env = unsafe {
let mut options = EnvOpenOptions::new().read_txn_without_tls();
let env_options = options.map_size(alloc_chunk_size).max_dbs(1);
env_options.open(&full_path)?
};
let (resize, new_size) = needs_resize(&env, alloc_chunk_size);
if resize {
unsafe {
env.resize(new_size)?;
};
}
let mut write = env.write_txn()?;
let db: Database<Bytes, Bytes> = env.create_database(&mut write, Some(env_name))?;
write.commit()?;
Ok((db, env))
}
#[test]
fn test_migration() -> Result<(), store::Error> {
let test_dir = "target/test_migration";
setup(test_dir);
let test_prefix_1 = b'H';
let test_key_1 = [0, 1, 2, 4];
let test_data_1 = [1, 2, 3, 4];
let test_prefix_2 = b'G';
let test_key_2 = [3, 4, 5, 6];
let test_key_64_2 = 65480464;
let test_data_2 = [4, 5, 6, 7];
let test_key_3 = [6, 7, 8, 9];
let test_data_3 = [7, 8, 9, 10];
// Create old db and fill the data.
{
let (old_db, old_env) = create_old_db(test_dir)?;
let mut w = old_env.write_txn()?;
// Create old format key value.
let key_1 = to_key(test_prefix_1, test_key_1);
old_db.put(&mut w, key_1.as_slice(), test_data_1.as_slice())?;
// Create old format 64 key value.
let key_2 = to_key_u64(test_prefix_2, test_key_2, test_key_64_2);
old_db.put(&mut w, key_2.as_slice(), test_data_2.as_slice())?;
// Create key value without prefix.
old_db.put(&mut w, test_key_3.as_slice(), test_data_3.as_slice())?;
w.commit()?;
}
// Create new store to migrate data.
let store = Store::new(
test_dir,
None,
Some(DEFAULT_ENV_NAME),
vec![test_prefix_1, test_prefix_2],
None,
)?;
// Check we can see key value.
{
assert!(store.exists(Some(test_prefix_1), &test_key_1)?);
let data = store.get_ser::<Vec<u8>>(Some(test_prefix_1), &test_key_1, None)?;
assert_eq!(data, Some(test_data_1.to_vec()));
}
// Check we can see key 64 value.
{
let mut key = test_key_2.to_vec();
key.write_u64::<byteorder::BigEndian>(test_key_64_2)
.unwrap();
assert!(store.exists(Some(test_prefix_2), &key)?);
let data = store.get_ser::<Vec<u8>>(Some(test_prefix_2), &key, None)?;
assert_eq!(data, Some(test_data_2.to_vec()));
}
// Check we can see key value without prefix.
{
assert!(store.exists(None, &test_key_3)?);
let data = store.get_ser::<Vec<u8>>(None, &test_key_3, None)?;
assert_eq!(data, Some(test_data_3.to_vec()));
}
clean_output_dir(test_dir);
Ok(())
}