upstream: https://github.com/mirage/ocaml-mbr
0
fork

Configure Feed

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

test(gpt,mbr): expand test suites for partition table packages

+205 -1
+205 -1
test/test_mbr.ml
··· 142 142 ("Partition wire roundtrip", `Quick, test_partition_wire_roundtrip); 143 143 ] 144 144 145 - let suite = ("mbr", suite_partition_make @ suite_make @ suite_wire) 145 + (** {1 Well-known partition type codes (DOS/IBM PC specification)} *) 146 + 147 + let test_partition_type_fat12 () = 148 + let p = ok (Mbr.Partition.make ~partition_type:0x01 2048l 1024l) in 149 + Alcotest.(check int) "FAT12 type" 0x01 p.Mbr.Partition.ty 150 + 151 + let test_partition_type_fat16 () = 152 + let p = ok (Mbr.Partition.make ~partition_type:0x04 2048l 65535l) in 153 + Alcotest.(check int) "FAT16 (<32MB) type" 0x04 p.Mbr.Partition.ty 154 + 155 + let test_partition_type_fat32 () = 156 + let p = ok (Mbr.Partition.make ~partition_type:0x0B 2048l 204800l) in 157 + Alcotest.(check int) "FAT32 type" 0x0B p.Mbr.Partition.ty 158 + 159 + let test_partition_type_fat32_lba () = 160 + let p = ok (Mbr.Partition.make ~partition_type:0x0C 2048l 204800l) in 161 + Alcotest.(check int) "FAT32 LBA type" 0x0C p.Mbr.Partition.ty 162 + 163 + let test_partition_type_linux_swap () = 164 + let p = ok (Mbr.Partition.make ~partition_type:0x82 2048l 4194304l) in 165 + Alcotest.(check int) "Linux swap type" 0x82 p.Mbr.Partition.ty 166 + 167 + let test_partition_type_linux_fs () = 168 + let p = ok (Mbr.Partition.make ~partition_type:0x83 2048l 4194304l) in 169 + Alcotest.(check int) "Linux filesystem type" 0x83 p.Mbr.Partition.ty 170 + 171 + let test_partition_type_gpt_protective () = 172 + let p = ok (Mbr.Partition.make ~partition_type:0xEE 1l 0xFFFFFFFFl) in 173 + Alcotest.(check int) "GPT protective MBR type" 0xEE p.Mbr.Partition.ty 174 + 175 + let test_partition_type_wire_roundtrip () = 176 + (* Verify all well-known types survive wire encoding *) 177 + let types = 178 + [ 179 + (0x01, "FAT12"); 180 + (0x04, "FAT16"); 181 + (0x0B, "FAT32"); 182 + (0x0C, "FAT32 LBA"); 183 + (0x82, "Linux swap"); 184 + (0x83, "Linux filesystem"); 185 + (0xEE, "GPT protective"); 186 + ] 187 + in 188 + List.iter 189 + (fun (ty, label) -> 190 + let p = ok (Mbr.Partition.make ~partition_type:ty 2048l 1024l) in 191 + let buf = Bytes.create 16 in 192 + Wire.Codec.encode Mbr.Partition.codec p buf 0; 193 + let p' = Wire.Codec.decode Mbr.Partition.codec buf 0 in 194 + Alcotest.(check int) 195 + (Fmt.str "%s (0x%02X) survives roundtrip" label ty) 196 + ty p'.Mbr.Partition.ty) 197 + types 198 + 199 + let suite_partition_types = 200 + [ 201 + ("Partition type FAT12 (0x01)", `Quick, test_partition_type_fat12); 202 + ("Partition type FAT16 (0x04)", `Quick, test_partition_type_fat16); 203 + ("Partition type FAT32 (0x0B)", `Quick, test_partition_type_fat32); 204 + ("Partition type FAT32 LBA (0x0C)", `Quick, test_partition_type_fat32_lba); 205 + ("Partition type Linux swap (0x82)", `Quick, test_partition_type_linux_swap); 206 + ("Partition type Linux fs (0x83)", `Quick, test_partition_type_linux_fs); 207 + ( "Partition type GPT protective (0xEE)", 208 + `Quick, 209 + test_partition_type_gpt_protective ); 210 + ("Partition type wire roundtrip", `Quick, test_partition_type_wire_roundtrip); 211 + ] 212 + 213 + (** {1 Max LBA value (2TB limit)} *) 214 + 215 + let test_max_lba_value () = 216 + (* MBR uses 32-bit LBA: max = 2^32 - 1 = 0xFFFFFFFF sectors. 217 + At 512 bytes/sector this is the 2TB limit. *) 218 + let max_lba = 0xFFFFFFFFl in 219 + let p = ok (Mbr.Partition.make ~partition_type:0x83 1l max_lba) in 220 + Alcotest.(check int32) 221 + "max sectors = 0xFFFFFFFF" max_lba p.Mbr.Partition.sectors; 222 + (* Verify size_sectors returns the correct int64 *) 223 + Alcotest.(check int64) 224 + "size_sectors as int64" 0xFFFFFFFFL 225 + (Mbr.Partition.size_sectors p) 226 + 227 + let test_max_lba_wire_roundtrip () = 228 + let max_lba = 0xFFFFFFFFl in 229 + let p = ok (Mbr.Partition.make ~partition_type:0xEE 1l max_lba) in 230 + let buf = Bytes.create 16 in 231 + Wire.Codec.encode Mbr.Partition.codec p buf 0; 232 + let p' = Wire.Codec.decode Mbr.Partition.codec buf 0 in 233 + Alcotest.(check int32) 234 + "max sectors survives roundtrip" max_lba p'.Mbr.Partition.sectors; 235 + Alcotest.(check int32) 236 + "LBA start survives roundtrip" 1l p'.Mbr.Partition.first_absolute_sector_lba 237 + 238 + let test_max_lba_marshal_unmarshal () = 239 + (* Use the largest size that doesn't overflow with start=1: 240 + start + size must fit in uint32, so max size = 0xFFFFFFFF - 1 *) 241 + let max_size = 0xFFFFFFFEl in 242 + let p = ok (Mbr.Partition.make ~partition_type:0xEE 1l max_size) in 243 + let mbr = ok (Mbr.v [ p ]) in 244 + let s = Mbr.to_string mbr in 245 + let mbr' = ok (Mbr.of_string s) in 246 + let parts = Mbr.partitions mbr' in 247 + Alcotest.(check int) "one partition" 1 (List.length parts); 248 + Alcotest.(check int32) 249 + "near-max sectors after marshal" max_size 250 + (List.hd parts).Mbr.Partition.sectors; 251 + (* Verify that start=0 allows the true maximum size *) 252 + let p0 = ok (Mbr.Partition.make ~partition_type:0xEE 1l max_size) in 253 + Alcotest.(check int64) 254 + "size_sectors near 2TB" 0xFFFFFFFEL 255 + (Mbr.Partition.size_sectors p0) 256 + 257 + let suite_max_lba = 258 + [ 259 + ("max LBA value (2TB limit)", `Quick, test_max_lba_value); 260 + ("max LBA wire roundtrip", `Quick, test_max_lba_wire_roundtrip); 261 + ("max LBA marshal/unmarshal", `Quick, test_max_lba_marshal_unmarshal); 262 + ] 263 + 264 + (** {1 Multiple partitions (2, 3, 4 entries)} *) 265 + 266 + let test_two_partitions () = 267 + let p1 = ok (Mbr.Partition.make ~partition_type:0x83 2048l 204800l) in 268 + let p2 = ok (Mbr.Partition.make ~partition_type:0x82 206848l 1048576l) in 269 + let mbr = ok (Mbr.v [ p1; p2 ]) in 270 + let parts = Mbr.partitions mbr in 271 + Alcotest.(check int) "two partitions" 2 (List.length parts); 272 + (* Verify marshal roundtrip *) 273 + let s = Mbr.to_string mbr in 274 + let mbr' = ok (Mbr.of_string s) in 275 + Alcotest.(check int) 276 + "two partitions after roundtrip" 2 277 + (List.length (Mbr.partitions mbr')) 278 + 279 + let test_three_partitions () = 280 + let p1 = 281 + ok (Mbr.Partition.make ~active:true ~partition_type:0x83 2048l 204800l) 282 + in 283 + let p2 = ok (Mbr.Partition.make ~partition_type:0x82 206848l 1048576l) in 284 + let p3 = ok (Mbr.Partition.make ~partition_type:0x0B 1255424l 2097152l) in 285 + let mbr = ok (Mbr.v [ p1; p2; p3 ]) in 286 + let parts = Mbr.partitions mbr in 287 + Alcotest.(check int) "three partitions" 3 (List.length parts); 288 + (* Verify the active partition *) 289 + let active_parts = List.filter (fun p -> p.Mbr.Partition.active) parts in 290 + Alcotest.(check int) "one active partition" 1 (List.length active_parts); 291 + (* Verify marshal roundtrip *) 292 + let s = Mbr.to_string mbr in 293 + let mbr' = ok (Mbr.of_string s) in 294 + Alcotest.(check int) 295 + "three partitions after roundtrip" 3 296 + (List.length (Mbr.partitions mbr')) 297 + 298 + let test_four_partitions () = 299 + let p1 = 300 + ok (Mbr.Partition.make ~active:true ~partition_type:0x83 2048l 204800l) 301 + in 302 + let p2 = ok (Mbr.Partition.make ~partition_type:0x82 206848l 1048576l) in 303 + let p3 = ok (Mbr.Partition.make ~partition_type:0x0C 1255424l 2097152l) in 304 + let p4 = ok (Mbr.Partition.make ~partition_type:0x01 3352576l 2048l) in 305 + let mbr = ok (Mbr.v [ p1; p2; p3; p4 ]) in 306 + let parts = Mbr.partitions mbr in 307 + Alcotest.(check int) "four partitions" 4 (List.length parts); 308 + (* Verify all partition types are preserved *) 309 + let types = List.map (fun p -> p.Mbr.Partition.ty) parts in 310 + (* Partitions are sorted by start LBA *) 311 + Alcotest.(check (list int)) 312 + "partition types in order" [ 0x83; 0x82; 0x0C; 0x01 ] types; 313 + (* Verify marshal roundtrip *) 314 + let s = Mbr.to_string mbr in 315 + let mbr' = ok (Mbr.of_string s) in 316 + let parts' = Mbr.partitions mbr' in 317 + Alcotest.(check int) "four partitions after roundtrip" 4 (List.length parts'); 318 + let types' = List.map (fun p -> p.Mbr.Partition.ty) parts' in 319 + Alcotest.(check (list int)) 320 + "partition types preserved after roundtrip" [ 0x83; 0x82; 0x0C; 0x01 ] 321 + types' 322 + 323 + let test_four_partitions_mixed_types () = 324 + (* A realistic partition table: EFI System + Linux root + Linux swap + data *) 325 + let p1 = ok (Mbr.Partition.make ~partition_type:0xEE 1l 409599l) in 326 + let p2 = ok (Mbr.Partition.make ~partition_type:0x83 409600l 41943040l) in 327 + let p3 = ok (Mbr.Partition.make ~partition_type:0x82 42352640l 8388608l) in 328 + let p4 = ok (Mbr.Partition.make ~partition_type:0x0B 50741248l 20971520l) in 329 + let mbr = ok (Mbr.v [ p1; p2; p3; p4 ]) in 330 + let parts = Mbr.partitions mbr in 331 + Alcotest.(check int) "four mixed-type partitions" 4 (List.length parts); 332 + let s = Mbr.to_string mbr in 333 + Alcotest.(check int) "MBR is 512 bytes" Mbr.sizeof (String.length s); 334 + let mbr' = ok (Mbr.of_string s) in 335 + Alcotest.(check (list partition)) 336 + "mixed partitions roundtrip" (Mbr.partitions mbr) (Mbr.partitions mbr') 337 + 338 + let suite_multiple_partitions = 339 + [ 340 + ("two partitions", `Quick, test_two_partitions); 341 + ("three partitions", `Quick, test_three_partitions); 342 + ("four partitions", `Quick, test_four_partitions); 343 + ("four partitions mixed types", `Quick, test_four_partitions_mixed_types); 344 + ] 345 + 346 + let suite = 347 + ( "mbr", 348 + suite_partition_make @ suite_make @ suite_wire @ suite_partition_types 349 + @ suite_max_lba @ suite_multiple_partitions )