1
+ use core:: hash:: { BuildHasher , Hasher } ;
1
2
use lightning:: util:: persist:: { KVStore , KVStoreSync } ;
2
3
use lightning_persister:: fs_store:: FilesystemStore ;
3
4
use std:: fs;
4
5
use tokio:: runtime:: Runtime ;
5
- use uuid:: Uuid ;
6
6
7
7
use crate :: utils:: test_logger;
8
8
@@ -20,7 +20,8 @@ impl TempFilesystemStore {
20
20
std:: env:: temp_dir ( )
21
21
} ;
22
22
23
- let random_folder_name = format ! ( "fs_store_fuzz_{}" , Uuid :: new_v4( ) ) ;
23
+ let random_number = std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) ;
24
+ let random_folder_name = format ! ( "fs_store_fuzz_{:016x}" , random_number) ;
24
25
temp_path. push ( random_folder_name) ;
25
26
26
27
let inner = FilesystemStore :: new ( temp_path. clone ( ) ) ;
@@ -46,10 +47,11 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
46
47
( $len: expr) => { {
47
48
let slice_len = $len as usize ;
48
49
if data. len( ) < read_pos + slice_len {
49
- return ;
50
+ None
51
+ } else {
52
+ read_pos += slice_len;
53
+ Some ( & data[ read_pos - slice_len..read_pos] )
50
54
}
51
- read_pos += slice_len;
52
- & data[ read_pos - slice_len..read_pos]
53
55
} } ;
54
56
}
55
57
@@ -72,7 +74,10 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
72
74
73
75
let mut handles = Vec :: new ( ) ;
74
76
loop {
75
- let v = get_slice ! ( 1 ) [ 0 ] ;
77
+ let v = match get_slice ! ( 1 ) {
78
+ Some ( b) => b[ 0 ] ,
79
+ None => break ,
80
+ } ;
76
81
match v % 13 {
77
82
// Sync write
78
83
0 => {
@@ -104,7 +109,7 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
104
109
3 => {
105
110
_ = KVStoreSync :: read ( fs_store, primary_namespace, secondary_namespace, key) ;
106
111
} ,
107
- // Async write
112
+ // Async write. Bias writes a bit.
108
113
4 ..=9 => {
109
114
let data_value = get_next_data_value ( ) ;
110
115
@@ -127,8 +132,9 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
127
132
} ,
128
133
// Async remove
129
134
10 | 11 => {
135
+ let lazy = v == 10 ;
130
136
let fut =
131
- KVStore :: remove ( fs_store, primary_namespace, secondary_namespace, key, v == 10 ) ;
137
+ KVStore :: remove ( fs_store, primary_namespace, secondary_namespace, key, lazy ) ;
132
138
133
139
// Already set the current_data, even though writing hasn't finished yet. This supports the call-time
134
140
// ordering semantics.
@@ -143,9 +149,7 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
143
149
let _ = handle. await . unwrap ( ) ;
144
150
}
145
151
} ,
146
- _ => {
147
- return ;
148
- } ,
152
+ _ => unreachable ! ( ) ,
149
153
}
150
154
151
155
// If no more writes are pending, we can reliably see if the data is consistent.
@@ -160,6 +164,12 @@ async fn do_test_internal<Out: test_logger::Output>(data: &[u8], _out: Out) {
160
164
assert_eq ! ( 0 , fs_store. state_size( ) ) ;
161
165
}
162
166
}
167
+
168
+ // Always make sure that all async tasks are completed before returning. Otherwise the temporary storage dir could
169
+ // be removed, and then again recreated by unfinished tasks.
170
+ for handle in handles. drain ( ..) {
171
+ let _ = handle. await . unwrap ( ) ;
172
+ }
163
173
}
164
174
165
175
/// Method that needs to be added manually, {name}_test
0 commit comments