Skip to content

Commit b248789

Browse files
committed
Add TestSyncStore
We add a `KVStore` implementation that wraps all three of our `KVStore` implementation and uses them in lock step while asserting they behave identical. This will be useful for (upcoming) integration tests.
1 parent d1c49d1 commit b248789

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

lightning-persister/src/test_utils.rs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
use crate::fs_store::FilesystemStore;
2+
use crate::sqlite_store::SqliteStore;
3+
14
use lightning::util::persist::{KVStore, KVSTORE_NAMESPACE_KEY_MAX_LEN, read_channel_monitors};
25
use lightning::ln::functional_test_utils::{connect_block, create_announced_chan_between_nodes,
36
create_chanmon_cfgs, create_dummy_block, create_network, create_node_cfgs, create_node_chanmgrs,
47
send_payment};
8+
59
use lightning::chain::channelmonitor::CLOSED_CHANNEL_UPDATE_ID;
6-
use lightning::util::test_utils;
10+
use lightning::util::test_utils::{self, TestStore};
711
use lightning::{check_closed_broadcast, check_closed_event, check_added_monitors};
812
use lightning::events::ClosureReason;
913

1014
use std::panic::RefUnwindSafe;
15+
use std::path::PathBuf;
1116

1217
pub(crate) fn do_read_write_remove_list_persist<K: KVStore + RefUnwindSafe>(kv_store: &K) {
1318
let data = [42u8; 32];
@@ -119,3 +124,111 @@ pub(crate) fn do_test_store<K: KVStore>(store_0: &K, store_1: &K) {
119124
// Make sure everything is persisted as expected after close.
120125
check_persisted_data!(CLOSED_CHANNEL_UPDATE_ID);
121126
}
127+
128+
// A `KVStore` impl for testing purposes that wraps all our `KVStore`s and asserts their synchronicity.
129+
pub(crate) struct TestSyncStore {
130+
test_store: TestStore,
131+
fs_store: FilesystemStore,
132+
sqlite_store: SqliteStore,
133+
}
134+
135+
impl TestSyncStore {
136+
pub(crate) fn new(dest_dir: PathBuf) -> Self {
137+
let fs_store = FilesystemStore::new(dest_dir.clone());
138+
let sqlite_store = SqliteStore::new(dest_dir, Some("test_sync_db".to_string()), Some("test_sync_table".to_string()));
139+
let test_store = TestStore::new(false);
140+
Self { fs_store, sqlite_store, test_store }
141+
}
142+
}
143+
144+
impl KVStore for TestSyncStore {
145+
fn read(&self, namespace: &str, key: &str) -> std::io::Result<Vec<u8>> {
146+
let fs_res = self.fs_store.read(namespace, key);
147+
let sqlite_res = self.sqlite_store.read(namespace, key);
148+
let test_res = self.test_store.read(namespace, key);
149+
150+
match fs_res {
151+
Ok(read) => {
152+
assert_eq!(read, sqlite_res.unwrap());
153+
assert_eq!(read, test_res.unwrap());
154+
Ok(read)
155+
}
156+
Err(e) => {
157+
assert!(sqlite_res.is_err());
158+
assert_eq!(e.kind(), unsafe { sqlite_res.unwrap_err_unchecked().kind() });
159+
assert!(test_res.is_err());
160+
assert_eq!(e.kind(), unsafe { test_res.unwrap_err_unchecked().kind() });
161+
Err(e)
162+
}
163+
}
164+
}
165+
166+
fn write(&self, namespace: &str, key: &str, buf: &[u8]) -> std::io::Result<()> {
167+
let fs_res = self.fs_store.write(namespace, key, buf);
168+
let sqlite_res = self.sqlite_store.write(namespace, key, buf);
169+
let test_res = self.test_store.write(namespace, key, buf);
170+
171+
assert!(self.list(namespace).unwrap().contains(&key.to_string()));
172+
173+
match fs_res {
174+
Ok(()) => {
175+
assert!(sqlite_res.is_ok());
176+
assert!(test_res.is_ok());
177+
Ok(())
178+
}
179+
Err(e) => {
180+
assert!(sqlite_res.is_err());
181+
assert!(test_res.is_err());
182+
Err(e)
183+
}
184+
}
185+
}
186+
187+
fn remove(&self, namespace: &str, key: &str) -> std::io::Result<()> {
188+
let fs_res = self.fs_store.remove(namespace, key);
189+
let sqlite_res = self.sqlite_store.remove(namespace, key);
190+
let test_res = self.test_store.remove(namespace, key);
191+
192+
assert!(!self.list(namespace).unwrap().contains(&key.to_string()));
193+
194+
match fs_res {
195+
Ok(()) => {
196+
assert!(sqlite_res.is_ok());
197+
assert!(test_res.is_ok());
198+
Ok(())
199+
}
200+
Err(e) => {
201+
assert!(sqlite_res.is_err());
202+
assert!(test_res.is_err());
203+
Err(e)
204+
}
205+
}
206+
}
207+
208+
fn list(&self, namespace: &str) -> std::io::Result<Vec<String>> {
209+
let fs_res = self.fs_store.list(namespace);
210+
let sqlite_res = self.sqlite_store.list(namespace);
211+
let test_res = self.test_store.list(namespace);
212+
213+
match fs_res {
214+
Ok(mut list) => {
215+
list.sort();
216+
217+
let mut sqlite_list = sqlite_res.unwrap();
218+
sqlite_list.sort();
219+
assert_eq!(list, sqlite_list);
220+
221+
let mut test_list = test_res.unwrap();
222+
test_list.sort();
223+
assert_eq!(list, test_list);
224+
225+
Ok(list)
226+
}
227+
Err(e) => {
228+
assert!(sqlite_res.is_err());
229+
assert!(test_res.is_err());
230+
Err(e)
231+
}
232+
}
233+
}
234+
}

lightning/src/util/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ impl<Signer: sign::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> fo
426426
}
427427
}
428428

429-
pub(crate) struct TestStore {
429+
pub struct TestStore {
430430
persisted_bytes: Mutex<HashMap<String, HashMap<String, Vec<u8>>>>,
431431
read_only: bool,
432432
}

0 commit comments

Comments
 (0)