Skip to content

Commit b6e8ab1

Browse files
committed
Refactor test code and introduce TestSyncStore
.. which asserts that all `KVStore` implementations operatate synchronously, i.e., yield identical results given the same inputs.
1 parent 517fa08 commit b6e8ab1

File tree

6 files changed

+202
-136
lines changed

6 files changed

+202
-136
lines changed

src/io/sqlite_store/migrations.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub(super) fn migrate_schema(
3737
mod tests {
3838
use crate::io::sqlite_store::SqliteStore;
3939
use crate::io::test_utils::do_read_write_remove_list_persist;
40+
use crate::test::utils::random_storage_path;
4041

4142
use lightning::util::persist::KVStore;
4243

@@ -48,7 +49,7 @@ mod tests {
4849
fn rwrl_post_schema_1_migration() {
4950
let old_schema_version = 1;
5051

51-
let mut temp_path = std::env::temp_dir();
52+
let mut temp_path = random_storage_path();
5253
temp_path.push("rwrl_post_schema_1_migration");
5354

5455
let db_file_name = "test_db".to_string();

src/io/sqlite_store/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ impl KVStore for SqliteStore {
281281
mod tests {
282282
use super::*;
283283
use crate::io::test_utils::{do_read_write_remove_list_persist, do_test_store};
284+
use crate::test::utils::random_storage_path;
284285

285286
impl Drop for SqliteStore {
286287
fn drop(&mut self) {
@@ -293,7 +294,7 @@ mod tests {
293294

294295
#[test]
295296
fn read_write_remove_list_persist() {
296-
let mut temp_path = std::env::temp_dir();
297+
let mut temp_path = random_storage_path();
297298
temp_path.push("read_write_remove_list_persist");
298299
let store = SqliteStore::new(
299300
temp_path,
@@ -306,7 +307,7 @@ mod tests {
306307

307308
#[test]
308309
fn test_sqlite_store() {
309-
let mut temp_path = std::env::temp_dir();
310+
let mut temp_path = random_storage_path();
310311
temp_path.push("test_sqlite_store");
311312
let store_0 = SqliteStore::new(
312313
temp_path.clone(),

src/io/test_utils.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use lightning::{check_added_monitors, check_closed_broadcast, check_closed_event
1515

1616
use std::panic::RefUnwindSafe;
1717
use std::path::PathBuf;
18+
use std::sync::RwLock;
1819

1920
pub(crate) fn do_read_write_remove_list_persist<K: KVStore + RefUnwindSafe>(kv_store: &K) {
2021
let data = [42u8; 32];
@@ -171,3 +172,135 @@ pub(crate) fn do_test_store<K: KVStore>(store_0: &K, store_1: &K) {
171172
// Make sure everything is persisted as expected after close.
172173
check_persisted_data!(CLOSED_CHANNEL_UPDATE_ID);
173174
}
175+
176+
// A `KVStore` impl for testing purposes that wraps all our `KVStore`s and asserts their synchronicity.
177+
pub(crate) struct TestSyncStore {
178+
serializer: RwLock<()>,
179+
test_store: TestStore,
180+
fs_store: FilesystemStore,
181+
sqlite_store: SqliteStore,
182+
}
183+
184+
impl TestSyncStore {
185+
pub(crate) fn new(dest_dir: PathBuf) -> Self {
186+
let serializer = RwLock::new(());
187+
let mut fs_dir = dest_dir.clone();
188+
fs_dir.push("fs_store");
189+
let fs_store = FilesystemStore::new(fs_dir);
190+
let mut sql_dir = dest_dir.clone();
191+
sql_dir.push("sqlite_store");
192+
let sqlite_store = SqliteStore::new(
193+
sql_dir,
194+
Some("test_sync_db".to_string()),
195+
Some("test_sync_table".to_string()),
196+
)
197+
.unwrap();
198+
let test_store = TestStore::new();
199+
Self { serializer, fs_store, sqlite_store, test_store }
200+
}
201+
202+
fn do_list(&self, namespace: &str, sub_namespace: &str) -> std::io::Result<Vec<String>> {
203+
let fs_res = self.fs_store.list(namespace, sub_namespace);
204+
let sqlite_res = self.sqlite_store.list(namespace, sub_namespace);
205+
let test_res = self.test_store.list(namespace, sub_namespace);
206+
207+
match fs_res {
208+
Ok(mut list) => {
209+
list.sort();
210+
211+
let mut sqlite_list = sqlite_res.unwrap();
212+
sqlite_list.sort();
213+
assert_eq!(list, sqlite_list);
214+
215+
let mut test_list = test_res.unwrap();
216+
test_list.sort();
217+
assert_eq!(list, test_list);
218+
219+
Ok(list)
220+
}
221+
Err(e) => {
222+
assert!(sqlite_res.is_err());
223+
assert!(test_res.is_err());
224+
Err(e)
225+
}
226+
}
227+
}
228+
}
229+
230+
impl KVStore for TestSyncStore {
231+
fn read(&self, namespace: &str, sub_namespace: &str, key: &str) -> std::io::Result<Vec<u8>> {
232+
let _guard = self.serializer.read().unwrap();
233+
234+
let fs_res = self.fs_store.read(namespace, sub_namespace, key);
235+
let sqlite_res = self.sqlite_store.read(namespace, sub_namespace, key);
236+
let test_res = self.test_store.read(namespace, sub_namespace, key);
237+
238+
match fs_res {
239+
Ok(read) => {
240+
assert_eq!(read, sqlite_res.unwrap());
241+
assert_eq!(read, test_res.unwrap());
242+
Ok(read)
243+
}
244+
Err(e) => {
245+
assert!(sqlite_res.is_err());
246+
assert_eq!(e.kind(), unsafe { sqlite_res.unwrap_err_unchecked().kind() });
247+
assert!(test_res.is_err());
248+
assert_eq!(e.kind(), unsafe { test_res.unwrap_err_unchecked().kind() });
249+
Err(e)
250+
}
251+
}
252+
}
253+
254+
fn write(
255+
&self, namespace: &str, sub_namespace: &str, key: &str, buf: &[u8],
256+
) -> std::io::Result<()> {
257+
let _guard = self.serializer.write().unwrap();
258+
let fs_res = self.fs_store.write(namespace, sub_namespace, key, buf);
259+
let sqlite_res = self.sqlite_store.write(namespace, sub_namespace, key, buf);
260+
let test_res = self.test_store.write(namespace, sub_namespace, key, buf);
261+
262+
assert!(self.do_list(namespace, sub_namespace).unwrap().contains(&key.to_string()));
263+
264+
match fs_res {
265+
Ok(()) => {
266+
assert!(sqlite_res.is_ok());
267+
assert!(test_res.is_ok());
268+
Ok(())
269+
}
270+
Err(e) => {
271+
assert!(sqlite_res.is_err());
272+
assert!(test_res.is_err());
273+
Err(e)
274+
}
275+
}
276+
}
277+
278+
fn remove(
279+
&self, namespace: &str, sub_namespace: &str, key: &str, lazy: bool,
280+
) -> std::io::Result<()> {
281+
let _guard = self.serializer.write().unwrap();
282+
let fs_res = self.fs_store.remove(namespace, sub_namespace, key, lazy);
283+
let sqlite_res = self.sqlite_store.remove(namespace, sub_namespace, key, lazy);
284+
let test_res = self.test_store.remove(namespace, sub_namespace, key, lazy);
285+
286+
assert!(!self.do_list(namespace, sub_namespace).unwrap().contains(&key.to_string()));
287+
288+
match fs_res {
289+
Ok(()) => {
290+
assert!(sqlite_res.is_ok());
291+
assert!(test_res.is_ok());
292+
Ok(())
293+
}
294+
Err(e) => {
295+
assert!(sqlite_res.is_err());
296+
assert!(test_res.is_err());
297+
Err(e)
298+
}
299+
}
300+
}
301+
302+
fn list(&self, namespace: &str, sub_namespace: &str) -> std::io::Result<Vec<String>> {
303+
let _guard = self.serializer.read().unwrap();
304+
self.do_list(namespace, sub_namespace)
305+
}
306+
}

src/peer_store.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,11 @@ mod tests {
163163

164164
// Check we can read back what we persisted.
165165
let persisted_bytes = store
166-
.read(PEER_INFO_PERSISTENCE_NAMESPACE, PEER_INFO_PERSISTENCE_SUB_NAMESPACE, PEER_INFO_PERSISTENCE_KEY)
166+
.read(
167+
PEER_INFO_PERSISTENCE_NAMESPACE,
168+
PEER_INFO_PERSISTENCE_SUB_NAMESPACE,
169+
PEER_INFO_PERSISTENCE_KEY,
170+
)
167171
.unwrap();
168172
let deser_peer_store =
169173
PeerStore::read(&mut &persisted_bytes[..], (Arc::clone(&store), logger)).unwrap();

0 commit comments

Comments
 (0)