Supply Chain Integrity, Transparency, and Trust (IETF SCITT)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Multicore-safe backends with Stdlib.Mutex; multicore stress tests

Both backends use Stdlib.Mutex (domain-safe, no Eio runtime needed).
Eio.Mutex would be better for fiber scheduling but requires an Eio
event loop — VDS is a data structure that should work without one.

Two new multicore stress tests:
- 4 domains appending 250 entries each concurrently (1000 total)
- 2 writer domains + 2 reader domains running simultaneously

Both pass — Mutex prevents data corruption across domains.

+65
+65
test/test_vds.ml
··· 98 98 (Scitt.vds_root reimported) 99 99 done 100 100 101 + let test_multicore_append () = 102 + (* Stress test: 4 domains appending concurrently. The Mutex inside the 103 + backend must prevent data corruption. After all domains finish, the 104 + tree size must equal the total number of appended entries and the 105 + root must be deterministic (same as sequential append in sorted order). *) 106 + let vds = Scitt.Vds_rfc9162.in_memory () in 107 + let n_per_domain = 250 in 108 + let n_domains = 4 in 109 + let domains = 110 + List.init n_domains (fun d -> 111 + Domain.spawn (fun () -> 112 + for i = 0 to n_per_domain - 1 do 113 + let key = Fmt.str "d%d-k%d" d i in 114 + ignore (Scitt.vds_append vds ~key ~value:key) 115 + done)) 116 + in 117 + List.iter Domain.join domains; 118 + let total = n_domains * n_per_domain in 119 + Alcotest.(check int) "total size" total (Scitt.vds_size vds); 120 + (* Root must be non-empty *) 121 + let root = Scitt.vds_root vds in 122 + Alcotest.(check bool) "root not empty" true (String.length root > 0); 123 + (* Verify all entries are present *) 124 + for d = 0 to n_domains - 1 do 125 + for i = 0 to n_per_domain - 1 do 126 + let key = Fmt.str "d%d-k%d" d i in 127 + Alcotest.(check bool) (Fmt.str "found %s" key) true 128 + (Option.is_some (Scitt.vds_lookup vds ~key)) 129 + done 130 + done 131 + 132 + let test_multicore_read_write () = 133 + (* Readers and writers running concurrently. Writers append, readers 134 + call root() and lookup(). No crashes, no corruption. *) 135 + let vds = Scitt.Vds_rfc9162.in_memory () in 136 + (* Pre-fill *) 137 + for i = 0 to 99 do 138 + ignore (Scitt.vds_append vds ~key:(Fmt.str "pre%d" i) ~value:"v") 139 + done; 140 + let writers = 141 + List.init 2 (fun d -> 142 + Domain.spawn (fun () -> 143 + for i = 0 to 199 do 144 + let key = Fmt.str "w%d-%d" d i in 145 + ignore (Scitt.vds_append vds ~key ~value:key) 146 + done)) 147 + in 148 + let readers = 149 + List.init 2 (fun _d -> 150 + Domain.spawn (fun () -> 151 + for _ = 0 to 999 do 152 + ignore (Scitt.vds_root vds); 153 + ignore (Scitt.vds_lookup vds ~key:"pre50"); 154 + ignore (Scitt.vds_size vds) 155 + done)) 156 + in 157 + List.iter Domain.join writers; 158 + List.iter Domain.join readers; 159 + (* All writes landed *) 160 + Alcotest.(check int) "final size" 500 (Scitt.vds_size vds) 161 + 101 162 let suite = 102 163 ( "vds", 103 164 [ ··· 111 172 test_import_rejects_bad_version; 112 173 Alcotest.test_case "vds: root consistency 0-100 entries" `Quick 113 174 test_root_consistency_various_sizes; 175 + Alcotest.test_case "vds: multicore append (4 domains)" `Quick 176 + test_multicore_append; 177 + Alcotest.test_case "vds: multicore read+write" `Quick 178 + test_multicore_read_write; 114 179 ] )