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