@@ -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 ] ;
@@ -171,3 +172,135 @@ pub(crate) fn do_test_store<K: KVStore>(store_0: &K, store_1: &K) {
171
172
// Make sure everything is persisted as expected after close.
172
173
check_persisted_data ! ( CLOSED_CHANNEL_UPDATE_ID ) ;
173
174
}
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
+ }
0 commit comments