Skip to content

Commit 7e7688a

Browse files
committed
Improve tests
1 parent 18c436d commit 7e7688a

File tree

3 files changed

+99
-162
lines changed

3 files changed

+99
-162
lines changed

src/arch/mod.rs

Lines changed: 26 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ mod tests {
158158
use crate::crc64::consts::CRC64_NVME;
159159
use crate::test::consts::{TEST_256_BYTES_STRING, TEST_ALL_CONFIGS, TEST_CHECK_STRING};
160160
use crate::test::create_aligned_data;
161+
use crate::test::enums::AnyCrcTestConfig;
161162
use rand::{rng, Rng};
162163

163164
#[test]
@@ -327,100 +328,56 @@ mod tests {
327328

328329
#[test]
329330
fn test_small_lengths_all() {
330-
let mut rng = rng();
331-
332331
// Test each CRC-64 variant
333332
for config in TEST_ALL_CONFIGS {
334333
// Test each length from 0 to 255
335334
for len in 0..=255 {
336-
// Generate random data for this length
337-
let mut data = vec![0u8; len];
338-
rng.fill(&mut data[..]);
339-
340-
// Calculate expected CRC using the reference implementation
341-
let expected = config.checksum_with_reference(&data);
342-
343-
// direct update() call, which needs XOROUT applied
344-
let actual = unsafe {
345-
update(config.get_init(), &data, *config.get_params()) ^ config.get_xorout()
346-
};
347-
348-
assert_eq!(
349-
actual,
350-
expected,
351-
"\nFailed for {} with length {}\nGot: {:016x}\nExpected: {:016x}",
352-
config.get_name(),
353-
len,
354-
actual,
355-
expected
356-
);
335+
test_length(len, config);
357336
}
358337
}
359338
}
360339

361340
#[test]
362341
fn test_medium_lengths() {
363-
let mut rng = rng();
364-
365342
// Test each CRC-64 variant
366343
for config in TEST_ALL_CONFIGS {
367344
// Test each length from 256 to 1024, which should fold and include handling remainders
368345
for len in 256..=1024 {
369-
// Generate random data for this length
370-
let mut data = vec![0u8; len];
371-
rng.fill(&mut data[..]);
372-
373-
// Calculate expected CRC using the reference implementation
374-
let expected = config.checksum_with_reference(&data);
375-
376-
// direct update() call, which needs XOROUT applied
377-
let actual = unsafe {
378-
update(config.get_init(), &data, *config.get_params()) ^ config.get_xorout()
379-
};
380-
381-
assert_eq!(
382-
actual,
383-
expected,
384-
"\nFailed for {} with length {}\nGot: {:016x}\nExpected: {:016x}",
385-
config.get_name(),
386-
len,
387-
actual,
388-
expected
389-
);
346+
test_length(len, config);
390347
}
391348
}
392349
}
393350

394351
#[test]
395352
fn test_large_lengths() {
396-
let mut rng = rng();
397-
398353
// Test each CRC-64 variant
399354
for config in TEST_ALL_CONFIGS {
400355
// Test ~1 MiB just before, at, and just after the folding boundaries
401356
for len in 1048575..=1048577 {
402-
// Generate random data for this length
403-
let mut data = vec![0u8; len];
404-
rng.fill(&mut data[..]);
405-
406-
// Calculate expected CRC using the reference implementation
407-
let expected = config.checksum_with_reference(&data);
408-
409-
// direct update() call, which needs XOROUT applied
410-
let actual = unsafe {
411-
update(config.get_init(), &data, *config.get_params()) ^ config.get_xorout()
412-
};
413-
414-
assert_eq!(
415-
actual,
416-
expected,
417-
"\nFailed for {} with length {}\nGot: {:016x}\nExpected: {:016x}",
418-
config.get_name(),
419-
len,
420-
actual,
421-
expected
422-
);
357+
test_length(len, config);
423358
}
424359
}
425360
}
361+
362+
fn test_length(length: usize, config: &AnyCrcTestConfig) {
363+
let mut data = vec![0u8; length];
364+
rng().fill(&mut data[..]);
365+
366+
// Calculate expected CRC using the reference implementation
367+
let expected = config.checksum_with_reference(&data);
368+
369+
// direct update() call, which needs XOROUT applied
370+
let actual =
371+
unsafe { update(config.get_init(), &data, *config.get_params()) ^ config.get_xorout() };
372+
373+
assert_eq!(
374+
actual,
375+
expected,
376+
"\nFailed for {} with length {}\nGot: {:016x}\nExpected: {:016x}",
377+
config.get_name(),
378+
length,
379+
actual,
380+
expected
381+
);
382+
}
426383
}

src/lib.rs

Lines changed: 71 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ pub fn checksum(algorithm: CrcAlgorithm, buf: &[u8]) -> u64 {
373373
/// use crc_fast::{checksum_file, CrcAlgorithm::Crc32IsoHdlc};
374374
///
375375
/// // for example/test purposes only, use your own file path
376-
/// let binding = env::current_dir().expect("missing working dir").join("crc-check.txt");
377-
/// let file_on_disk = binding.to_str().unwrap();
376+
/// let file_path = env::current_dir().expect("missing working dir").join("crc-check.txt");
377+
/// let file_on_disk = file_path.to_str().unwrap();
378378
///
379379
/// let checksum = checksum_file(Crc32IsoHdlc, file_on_disk, None);
380380
///
@@ -547,68 +547,52 @@ mod lib {
547547

548548
#[test]
549549
fn test_small_all_lengths() {
550-
let mut rng = rng();
551-
552-
// Test each CRC-64 variant
553550
for config in TEST_ALL_CONFIGS {
554551
// Test each length from 1 to 255
555552
for len in 1..=255 {
556-
// Generate random data for this length
557-
let mut data = vec![0u8; len];
558-
rng.fill(&mut data[..]);
559-
560-
// Calculate expected CRC using the reference implementation
561-
let expected = config.checksum_with_reference(&data);
562-
563-
let result = checksum(config.get_algorithm(), &data);
564-
565-
assert_eq!(result, expected);
553+
test_length(len, config);
566554
}
567555
}
568556
}
569557

570558
#[test]
571559
fn test_medium_lengths() {
572-
let mut rng = rng();
573-
574-
// Test each CRC-64 variant
575560
for config in TEST_ALL_CONFIGS {
576561
// Test each length from 256 to 1024, which should fold and include handling remainders
577562
for len in 256..=1024 {
578-
// Generate random data for this length
579-
let mut data = vec![0u8; len];
580-
rng.fill(&mut data[..]);
581-
582-
// Calculate expected CRC using the reference implementation
583-
let expected = config.checksum_with_reference(&data);
584-
585-
let result = checksum(config.get_algorithm(), &data);
586-
587-
assert_eq!(result, expected);
563+
test_length(len, config);
588564
}
589565
}
590566
}
591567

592568
#[test]
593569
fn test_large_lengths() {
594-
let mut rng = rng();
595-
596-
// Test each CRC-64 variant
597570
for config in TEST_ALL_CONFIGS {
598571
// Test 1 MiB just before, at, and just after the folding boundaries
599572
for len in 1048575..1048577 {
600-
// Generate random data for this length
601-
let mut data = vec![0u8; len];
602-
rng.fill(&mut data[..]);
573+
test_length(len, config);
574+
}
575+
}
576+
}
603577

604-
// Calculate expected CRC using the reference implementation
605-
let expected = config.checksum_with_reference(&data);
578+
fn test_length(length: usize, config: &AnyCrcTestConfig) {
579+
let mut data = vec![0u8; length];
580+
rng().fill(&mut data[..]);
606581

607-
let result = checksum(config.get_algorithm(), &data);
582+
// Calculate expected CRC using the reference implementation
583+
let expected = config.checksum_with_reference(&data);
608584

609-
assert_eq!(result, expected);
610-
}
611-
}
585+
let result = checksum(config.get_algorithm(), &data);
586+
587+
assert_eq!(
588+
result,
589+
expected,
590+
"Failed for algorithm: {:?}, length: {}, expected: {:#x}, got: {:#x}",
591+
config.get_algorithm(),
592+
length,
593+
expected,
594+
result
595+
);
612596
}
613597

614598
#[test]
@@ -759,57 +743,53 @@ mod lib {
759743
return Ok(());
760744
}
761745

762-
#[cfg(not(target_os = "windows"))]
763-
{
764-
const HEADER: &str = "libcrc_fast.h";
765-
766-
let crate_dir =
767-
std::env::var("CARGO_MANIFEST_DIR").map_err(|error| error.to_string())?;
768-
769-
let mut expected = Vec::new();
770-
cbindgen::Builder::new()
771-
.with_crate(crate_dir)
772-
.with_include_guard("CRC_FAST_H")
773-
.with_header("/* crc_fast library C/C++ API - Copyright 2025 Don MacAskill */\n/* This header is auto-generated. Do not edit directly. */\n")
774-
// exclude internal implementation functions
775-
.exclude_item("crc32_iscsi_impl")
776-
.exclude_item("crc32_iso_hdlc_impl")
777-
.exclude_item("get_iscsi_target")
778-
.exclude_item("get_iso_hdlc_target")
779-
.exclude_item("ISO_HDLC_TARGET")
780-
.exclude_item("ISCSI_TARGET")
781-
.exclude_item("CrcParams")
782-
.rename_item("Digest", "CrcFastDigest")
783-
.with_style(Both)
784-
// generate C header
785-
.with_language(C)
786-
// with C++ compatibility
787-
.with_cpp_compat(true)
788-
.generate()
789-
.map_err(|error| error.to_string())?
790-
.write(&mut expected);
791-
792-
// Convert the expected bytes to string for pattern replacement, since cbindgen
793-
// generates an annoying amount of empty contiguous newlines
794-
let header_content = String::from_utf8(expected).map_err(|error| error.to_string())?;
795-
796-
// Replace excessive newlines (3 or more consecutive newlines) with 2 newlines
797-
let regex = regex::Regex::new(r"\n{3,}").map_err(|error| error.to_string())?;
798-
let cleaned_content = regex.replace_all(&header_content, "\n\n").to_string();
799-
800-
// Convert back to bytes
801-
expected = cleaned_content.into_bytes();
802-
803-
let actual = read(HEADER).map_err(|error| error.to_string())?;
804-
805-
if expected != actual {
806-
write(HEADER, expected).map_err(|error| error.to_string())?;
807-
return Err(format!(
808-
"{HEADER} is not up-to-date, commit the generated file and try again"
809-
));
810-
}
811-
812-
Ok(())
746+
const HEADER: &str = "libcrc_fast.h";
747+
748+
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").map_err(|error| error.to_string())?;
749+
750+
let mut expected = Vec::new();
751+
cbindgen::Builder::new()
752+
.with_crate(crate_dir)
753+
.with_include_guard("CRC_FAST_H")
754+
.with_header("/* crc_fast library C/C++ API - Copyright 2025 Don MacAskill */\n/* This header is auto-generated. Do not edit directly. */\n")
755+
// exclude internal implementation functions
756+
.exclude_item("crc32_iscsi_impl")
757+
.exclude_item("crc32_iso_hdlc_impl")
758+
.exclude_item("get_iscsi_target")
759+
.exclude_item("get_iso_hdlc_target")
760+
.exclude_item("ISO_HDLC_TARGET")
761+
.exclude_item("ISCSI_TARGET")
762+
.exclude_item("CrcParams")
763+
.rename_item("Digest", "CrcFastDigest")
764+
.with_style(Both)
765+
// generate C header
766+
.with_language(C)
767+
// with C++ compatibility
768+
.with_cpp_compat(true)
769+
.generate()
770+
.map_err(|error| error.to_string())?
771+
.write(&mut expected);
772+
773+
// Convert the expected bytes to string for pattern replacement, since cbindgen
774+
// generates an annoying amount of empty contiguous newlines
775+
let header_content = String::from_utf8(expected).map_err(|error| error.to_string())?;
776+
777+
// Replace excessive newlines (3 or more consecutive newlines) with 2 newlines
778+
let regex = regex::Regex::new(r"\n{3,}").map_err(|error| error.to_string())?;
779+
let cleaned_content = regex.replace_all(&header_content, "\n\n").to_string();
780+
781+
// Convert back to bytes
782+
expected = cleaned_content.into_bytes();
783+
784+
let actual = read(HEADER).map_err(|error| error.to_string())?;
785+
786+
if expected != actual {
787+
write(HEADER, expected).map_err(|error| error.to_string())?;
788+
return Err(format!(
789+
"{HEADER} is not up-to-date, commit the generated file and try again"
790+
));
813791
}
792+
793+
Ok(())
814794
}
815795
}

src/test/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#![cfg(test)]
66
#![allow(dead_code)]
77

8-
pub mod consts;
9-
mod enums;
8+
pub(crate) mod consts;
9+
pub(crate) mod enums;
1010
mod structs;
1111

1212
/// Creates a new aligned data vector from the input slice for testing.

0 commit comments

Comments
 (0)