ci: lint all targets, run interop suites for real, compile benches
- clippy --all-targets plus a clawhdf5-format feature matrix (parallel, lz4, zstd, pcodec, fast-checksum); fix the accumulated lint backlog in test, bench and feature-gated code (no behaviour changes). - Install python3 + h5py/numpy/netCDF4/xarray in the CI container and set CLAWHDF5_REQUIRE_INTEROP=1, which makes a missing interop dependency a test failure. Every h5py/netCDF4 interop test used to skip silently in CI. Run the #[ignore]d writer_h5py_tests suite explicitly. - cargo bench --no-run so benches can't rot; fix bench.rs and memory_bench.rs, which no longer compiled against the current strategy/consolidation APIs. - Optional fuzz smoke run via CLAWHDF5_FUZZ_SECONDS. - CHANGELOG and docs/known-issues.md updated. Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
706189c3ef
commit
bbe1baa208
@@ -343,7 +343,11 @@ fn attrs_h5_dataset_scale() {
|
||||
let scale_attr = find_attribute(&attrs, "scale").expect("scale attr not found");
|
||||
let vals = scale_attr.read_as_f64().unwrap();
|
||||
assert_eq!(vals.len(), 1);
|
||||
assert!((vals[0] - 3.14).abs() < 1e-10);
|
||||
// 3.14 here is the literal value baked into the binary fixture (fixtures/attrs.h5),
|
||||
// not an arbitrary sample value, so it cannot be swapped for another constant.
|
||||
#[allow(clippy::approx_constant)]
|
||||
let expected = 3.14;
|
||||
assert!((vals[0] - expected).abs() < 1e-10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -556,8 +560,8 @@ fn chunked_deflate_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "data");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 100);
|
||||
for i in 0..100 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,8 +571,8 @@ fn chunked_shuffle_deflate_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "data");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 100);
|
||||
for i in 0..100 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,8 +582,8 @@ fn chunked_fletcher32_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "data");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 100);
|
||||
for i in 0..100 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,11 +593,10 @@ fn chunked_2d_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "matrix");
|
||||
let values = read_as_f32(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 60);
|
||||
for i in 0..60 {
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert!(
|
||||
(values[i] - i as f32).abs() < 1e-6,
|
||||
"mismatch at index {i}: got {}",
|
||||
values[i]
|
||||
(v - i as f32).abs() < 1e-6,
|
||||
"mismatch at index {i}: got {v}"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -604,8 +607,8 @@ fn chunked_large_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "big");
|
||||
let values = read_as_i32(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 1000);
|
||||
for i in 0..1000 {
|
||||
assert_eq!(values[i], i as i32, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as i32, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,8 +618,8 @@ fn chunked_nofilter_read_values() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "raw");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 50);
|
||||
for i in 0..50 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,8 +649,8 @@ fn v4_implicit_read() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "data");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 100);
|
||||
for i in 0..100 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,8 +660,8 @@ fn v4_fixed_array_read() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "data");
|
||||
let values = read_as_f64(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 100);
|
||||
for i in 0..100 {
|
||||
assert_eq!(values[i], i as f64, "mismatch at index {i}");
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert_eq!(v, i as f64, "mismatch at index {i}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,11 +874,10 @@ fn v4_2d_fixed_array_read() {
|
||||
let (raw, datatype, _) = read_chunked_dataset(file_data, "matrix");
|
||||
let values = read_as_f32(&raw, &datatype).unwrap();
|
||||
assert_eq!(values.len(), 60);
|
||||
for i in 0..60 {
|
||||
for (i, &v) in values.iter().enumerate() {
|
||||
assert!(
|
||||
(values[i] - i as f32).abs() < 1e-6,
|
||||
"mismatch at index {i}: got {}",
|
||||
values[i]
|
||||
(v - i as f32).abs() < 1e-6,
|
||||
"mismatch at index {i}: got {v}"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1272,7 +1274,7 @@ fn write_roundtrip_scalar_f64_attr() {
|
||||
let mut fw = FileWriter::new();
|
||||
fw.create_dataset("data")
|
||||
.with_f64_data(&[1.0])
|
||||
.set_attr("scale", AttrValue::F64(3.14));
|
||||
.set_attr("scale", AttrValue::F64(3.25));
|
||||
let bytes = fw.finish().unwrap();
|
||||
|
||||
let sig = find_signature(&bytes).unwrap();
|
||||
@@ -1283,7 +1285,7 @@ fn write_roundtrip_scalar_f64_attr() {
|
||||
let scale = find_attribute(&attrs, "scale").expect("scale attr not found");
|
||||
let vals = scale.read_as_f64().unwrap();
|
||||
assert_eq!(vals.len(), 1);
|
||||
assert!((vals[0] - 3.14).abs() < 1e-10);
|
||||
assert!((vals[0] - 3.25).abs() < 1e-10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -180,15 +180,20 @@ print('ok')
|
||||
let output = match output {
|
||||
Ok(o) if o.status.success() => o,
|
||||
_ => {
|
||||
// CI sets CLAWHDF5_REQUIRE_INTEROP=1 so this can't silently skip.
|
||||
assert!(
|
||||
!std::env::var("CLAWHDF5_REQUIRE_INTEROP").is_ok_and(|v| v == "1"),
|
||||
"CLAWHDF5_REQUIRE_INTEROP=1 but python3 with h5py is not available"
|
||||
);
|
||||
eprintln!("skipping h5py_object_reference_roundtrip: python3+h5py not available");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||
if !stdout.trim().contains("ok") {
|
||||
eprintln!("skipping h5py_object_reference_roundtrip: h5py script failed");
|
||||
return;
|
||||
}
|
||||
assert!(
|
||||
stdout.trim().contains("ok"),
|
||||
"h5py reference-file generator did not report ok: {stdout}"
|
||||
);
|
||||
|
||||
// Read the file and parse object references
|
||||
let file_data = std::fs::read(&path).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user