Skip to content

Commit 7686025

Browse files
committed
hex-simd: tests
1 parent e9cc0f2 commit 7686025

File tree

4 files changed

+178
-38
lines changed

4 files changed

+178
-38
lines changed

Cross.toml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build.env]
2+
passthrough = ["RUST_BACKTRACE", "RUST_LOG", "RUSTFLAGS"]

crates/hex-simd/src/lib.rs

+5-32
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@ mod encode;
2424

2525
pub mod multiversion;
2626

27+
#[cfg(test)]
28+
mod tests;
29+
2730
pub use simd_abstraction::ascii::AsciiCase;
28-
use simd_abstraction::item_group;
2931
pub use simd_abstraction::tools::OutBuf;
3032

3133
// -------------------------------------------------------------------------------------------------
3234

3335
use self::error::ERROR;
36+
37+
use simd_abstraction::item_group;
3438
use simd_abstraction::tools::slice_mut;
3539

3640
/// Checks whether `data` is a hex string.
@@ -181,34 +185,3 @@ pub fn decode_to_boxed_bytes(data: &[u8]) -> Result<Box<[u8]>, Error> {
181185
Ok(Box::from_raw(core::ptr::slice_from_raw_parts_mut(ptr, len)))
182186
}
183187
}
184-
185-
#[cfg(test)]
186-
mod tests {
187-
use super::*;
188-
189-
#[test]
190-
fn test_str() {
191-
use core::mem::MaybeUninit;
192-
let src = "hello";
193-
let mut dst = [MaybeUninit::uninit(); 10];
194-
let ans = {
195-
let src = src.as_bytes();
196-
let dst = OutBuf::uninit(&mut dst);
197-
let case = AsciiCase::Lower;
198-
encode_as_str(src, dst, case).unwrap()
199-
};
200-
assert_eq!(ans, "68656c6c6f");
201-
}
202-
203-
#[cfg(feature = "alloc")]
204-
#[test]
205-
fn test_alloc() {
206-
let src = "hello".as_bytes();
207-
208-
let ans = encode_to_boxed_str(src, AsciiCase::Lower);
209-
assert_eq!(&*ans, "68656c6c6f");
210-
211-
let ans = decode_to_boxed_bytes(ans.as_bytes()).unwrap();
212-
assert_eq!(&*ans, src);
213-
}
214-
}

crates/hex-simd/src/tests.rs

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
use crate::Error;
2+
3+
use simd_abstraction::ascii::AsciiCase;
4+
use simd_abstraction::tools::OutBuf;
5+
6+
#[test]
7+
fn test_str() {
8+
use core::mem::MaybeUninit;
9+
let src = "hello";
10+
let mut dst = [MaybeUninit::uninit(); 10];
11+
let ans = {
12+
let src = src.as_bytes();
13+
let dst = OutBuf::uninit(&mut dst);
14+
let case = AsciiCase::Lower;
15+
crate::encode_as_str(src, dst, case).unwrap()
16+
};
17+
assert_eq!(ans, "68656c6c6f");
18+
}
19+
20+
#[cfg(feature = "alloc")]
21+
#[test]
22+
fn test_alloc() {
23+
let src = "hello".as_bytes();
24+
25+
let ans = crate::encode_to_boxed_str(src, AsciiCase::Lower);
26+
assert_eq!(&*ans, "68656c6c6f");
27+
28+
let ans = crate::decode_to_boxed_bytes(ans.as_bytes()).unwrap();
29+
assert_eq!(&*ans, src);
30+
}
31+
32+
#[cfg(miri)]
33+
use std::io::Write as _;
34+
35+
macro_rules! dbgmsg {
36+
($($fmt:tt)*) => {
37+
println!($($fmt)*);
38+
#[cfg(miri)]
39+
std::io::stdout().flush().unwrap();
40+
};
41+
}
42+
43+
#[allow(clippy::type_complexity)]
44+
fn safety_unit_test(
45+
check: fn(&[u8]) -> bool,
46+
decode: for<'s, 'd> fn(&'s [u8], OutBuf<'d>) -> Result<&'d mut [u8], Error>,
47+
encode: for<'s, 'd> fn(&'s [u8], OutBuf<'d>, AsciiCase) -> Result<&'d mut [u8], Error>,
48+
decode_inplace: fn(&mut [u8]) -> Result<&mut [u8], Error>,
49+
) {
50+
println!();
51+
52+
let ok_cases: Vec<Vec<u8>> = {
53+
let mut ans = Vec::new();
54+
55+
for n in 0..256usize {
56+
dbgmsg!("generating ok case n = {}", n);
57+
58+
let iter = (0..16)
59+
.cycle()
60+
.take(n)
61+
.map(|x| char::from_digit(x, 16).unwrap() as u8);
62+
ans.push(iter.collect())
63+
}
64+
65+
ans
66+
};
67+
68+
let err_cases: Vec<Vec<u8>> = {
69+
vec![
70+
vec![0],
71+
vec![b'0', 0],
72+
vec![b'a', b'f', 0],
73+
vec![b'a', b'0', b'c', 0],
74+
vec![b'a', b'0', b'c', b'1', 0],
75+
]
76+
};
77+
78+
macro_rules! test_decode_encode {
79+
($src: expr, $case: expr) => {{
80+
let mut decode_buf = vec![0; $src.len() / 2];
81+
let mut encode_buf = vec![0; $src.len()];
82+
let decode_buf = OutBuf::new(&mut decode_buf);
83+
let encode_buf = OutBuf::new(&mut encode_buf);
84+
let decode_buf = decode($src, decode_buf).unwrap();
85+
let encode_buf = encode(decode_buf, encode_buf, $case).unwrap();
86+
assert_eq!(encode_buf, $src);
87+
}};
88+
}
89+
90+
macro_rules! test_decode_inplace_encode {
91+
($src: expr, $case: expr) => {{
92+
let mut decode_buf = $src.to_owned();
93+
let mut encode_buf = vec![0; $src.len()];
94+
let decode_buf = decode_inplace(&mut decode_buf).unwrap();
95+
let encode_buf = OutBuf::new(&mut encode_buf);
96+
let encode_buf = encode(decode_buf, encode_buf, $case).unwrap();
97+
assert_eq!(encode_buf, $src);
98+
}};
99+
}
100+
101+
macro_rules! test_encode_decode {
102+
($src: expr, $case: expr) => {{
103+
let mut encode_buf = vec![0; $src.len() * 2];
104+
let mut decode_buf = vec![0; $src.len()];
105+
let encode_buf = OutBuf::new(&mut encode_buf);
106+
let decode_buf = OutBuf::new(&mut decode_buf);
107+
let encode_buf = encode($src, encode_buf, $case).unwrap();
108+
let decode_buf = decode(encode_buf, decode_buf).unwrap();
109+
assert_eq!(decode_buf, $src);
110+
}};
111+
}
112+
113+
macro_rules! test_encode_decode_inplace {
114+
($src: expr, $case: expr) => {{
115+
let mut encode_buf = vec![0; $src.len() * 2];
116+
let encode_buf = OutBuf::new(&mut encode_buf);
117+
let encode_buf = encode($src, encode_buf, $case).unwrap();
118+
let decode_buf = decode_inplace(encode_buf).unwrap();
119+
assert_eq!(decode_buf, $src);
120+
}};
121+
}
122+
123+
for (i, src) in ok_cases.iter().enumerate() {
124+
dbgmsg!("ok case {}", i + 1);
125+
assert!(check(src));
126+
if src.len() % 2 == 0 {
127+
test_decode_encode!(src, AsciiCase::Lower);
128+
test_decode_inplace_encode!(src, AsciiCase::Lower);
129+
} else {
130+
test_encode_decode!(src, AsciiCase::Upper);
131+
test_encode_decode_inplace!(src, AsciiCase::Upper);
132+
}
133+
}
134+
135+
for (i, src) in err_cases.iter().enumerate() {
136+
dbgmsg!("err case {}", i + 1);
137+
assert!(!check(src));
138+
let mut buf = vec![0; src.len() / 2];
139+
let buf = OutBuf::new(&mut buf);
140+
assert!(decode(src, buf).is_err())
141+
}
142+
}
143+
144+
#[test]
145+
fn test_safety() {
146+
safety_unit_test(
147+
crate::check,
148+
crate::decode,
149+
crate::encode,
150+
crate::decode_inplace,
151+
);
152+
}

justfile

+19-6
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,29 @@ wasi-bench:
5050
x86-test *ARGS:
5151
#!/bin/bash -ex
5252
cd {{invocation_directory()}}
53-
export RUSTFLAGS="-C target-feature=+avx2 -C target-feature=+sse4.1 -Zsanitizer=address"
54-
cargo test --lib {{ARGS}}
55-
export RUSTFLAGS=""
56-
cargo test {{ARGS}}
53+
function x86test(){
54+
cargo test --no-default-features --features 'std,unstable' {{ARGS}}
55+
}
56+
export RUSTFLAGS="-Zsanitizer=address -C target-feature=+avx2"
57+
x86test
58+
export RUSTFLAGS="-Zsanitizer=address -C target-feature=+sse4.1"
59+
x86test
60+
export RUSTFLAGS="-Zsanitizer=address"
61+
x86test
5762

5863
arm-test *ARGS:
5964
#!/bin/bash -ex
65+
function armtest(){
66+
cross test --target armv7-unknown-linux-gnueabihf \
67+
--no-default-features --features 'std,unstable' {{ARGS}}
68+
cross test --target aarch64-unknown-linux-gnu \
69+
--no-default-features --features 'std,unstable' {{ARGS}}
70+
}
71+
6072
export RUSTFLAGS="-C target-feature=+neon"
61-
cross test --target armv7-unknown-linux-gnueabihf --features unstable {{ARGS}}
62-
cross test --target aarch64-unknown-linux-gnu --features unstable {{ARGS}}
73+
armtest
74+
export RUSTFLAGS=""
75+
armtest
6376

6477
wasm-test:
6578
#!/bin/bash -ex

0 commit comments

Comments
 (0)