Skip to content

Commit 82fdb62

Browse files
committed
test: Use automatic test detection
Move from `test/` to `tests/`, which is the directory for autodetection. This means that we can drop `[[test]]` entries in `libc-test/Cargo.toml` that don't require nondefault configuration like `harness = false`. As part of this, `style` and its selftests are moved to the `libc-test` source directory.
1 parent 503ece7 commit 82fdb62

20 files changed

+274
-49
lines changed

libc-test/Cargo.toml

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ license = "MIT OR Apache-2.0"
99
repository = "https://github.com/rust-lang/libc"
1010

1111
[dependencies]
12+
annotate-snippets = { version = "0.11.5", features = ["testing-colors"] }
1213
cfg-if = "1.0.1"
1314
libc = { path = "..", version = "1.0.0-alpha.1", default-features = false }
15+
proc-macro2 = { version = "1.0.95", features = ["span-locations"] }
16+
syn = { version = "2.0.104", features = ["full", "visit"] }
1417

1518
[dev-dependencies]
16-
syn = { version = "2.0.104", features = ["full", "visit"] }
17-
proc-macro2 = { version = "1.0.95", features = ["span-locations"] }
1819
glob = "0.3.2"
19-
annotate-snippets = { version = "0.11.5", features = ["testing-colors"] }
2020

2121
[build-dependencies]
2222
cc = "1.2.29"
@@ -30,79 +30,44 @@ extra_traits = ["libc/extra_traits"]
3030

3131
[[test]]
3232
name = "main"
33-
path = "test/main.rs"
33+
path = "tests/main.rs"
3434
harness = false
3535

3636
[[test]]
3737
name = "linux-fcntl"
38-
path = "test/linux_fcntl.rs"
38+
path = "tests/linux_fcntl.rs"
3939
harness = false
4040

4141
[[test]]
4242
name = "linux-if-arp"
43-
path = "test/linux_if_arp.rs"
43+
path = "tests/linux_if_arp.rs"
4444
harness = false
4545

4646
[[test]]
4747
name = "linux-ipv6"
48-
path = "test/linux_ipv6.rs"
48+
path = "tests/linux_ipv6.rs"
4949
harness = false
5050

5151
[[test]]
5252
name = "linux-elf"
53-
path = "test/linux_elf.rs"
53+
path = "tests/linux_elf.rs"
5454
harness = false
5555

5656
[[test]]
5757
name = "linux-strerror_r"
58-
path = "test/linux_strerror_r.rs"
58+
path = "tests/linux_strerror_r.rs"
5959
harness = false
6060

6161
[[test]]
6262
name = "linux-termios"
63-
path = "test/linux_termios.rs"
63+
path = "tests/linux_termios.rs"
6464
harness = false
6565

66-
[[test]]
67-
name = "cmsg"
68-
path = "test/cmsg.rs"
69-
harness = true
70-
71-
[[test]]
72-
name = "makedev"
73-
path = "test/makedev.rs"
74-
harness = true
75-
76-
[[test]]
77-
name = "errqueue"
78-
path = "test/errqueue.rs"
79-
harness = true
80-
81-
[[test]]
82-
name = "sigrt"
83-
path = "test/sigrt.rs"
84-
harness = true
85-
8666
[[test]]
8767
name = "semver"
88-
path = "test/semver.rs"
68+
path = "tests/semver.rs"
8969
harness = false
9070

91-
[[test]]
92-
name = "primitive_types"
93-
path = "test/primitive_types.rs"
94-
harness = true
95-
96-
[[test]]
97-
name = "style"
98-
path = "test/check_style.rs"
99-
harness = true
100-
101-
[[test]]
102-
name = "style_tests"
103-
path = "test/style_tests.rs"
104-
harness = true
105-
10671
# FIXME(msrv): These should be moved to the root Cargo.toml as `[workspace.lints.*]`
10772
# once MSRV is above 1.64 and replaced with `[lints] workspace=true`
10873

libc-test/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod style;

libc-test/test/style/mod.rs renamed to libc-test/src/style.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ use syn::spanned::Spanned;
3737
use syn::visit::{self, Visit};
3838
use syn::Token;
3939

40+
#[cfg(test)]
41+
mod tests;
42+
4043
const ALLOWED_REPEATED_MACROS: &[&str] = &["s", "s_no_extra_traits", "s_paren"];
4144

4245
pub type Error = Box<dyn std::error::Error>;

libc-test/src/style/tests.rs

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
//! Verifies the implementation of the style checker in [style].
2+
3+
use super::StyleChecker;
4+
5+
#[test]
6+
fn check_style_accept_correct_module_layout() {
7+
let contents = r#"
8+
use core::mem::size_of;
9+
pub type foo_t = u32;
10+
struct Foo {}
11+
pub const FOO: u32 = 0x20000;
12+
f! {}
13+
extern "C" {}
14+
mod foolib;
15+
pub use self::foolib::*;
16+
"#
17+
.to_string();
18+
19+
let mut checker = StyleChecker::new();
20+
checker.check_string(contents).unwrap();
21+
checker.finalize().unwrap();
22+
}
23+
24+
#[test]
25+
fn check_style_reject_incorrect_module_layout() {
26+
let contents = r#"
27+
use core::mem::size_of;
28+
pub type foo_t = u32;
29+
struct Foo {}
30+
pub const FOO: u32 = 0x20000;
31+
extern "C" {}
32+
f! {}
33+
mod foolib;
34+
pub use self::foolib::*;
35+
"#
36+
.to_string();
37+
38+
let mut checker = StyleChecker::new();
39+
checker.check_string(contents).unwrap();
40+
assert!(checker.finalize().is_err());
41+
}
42+
43+
#[test]
44+
fn check_style_reject_incorrect_cfg_if_layout() {
45+
let contents = r#"
46+
cfg_if! {
47+
if #[cfg(foo)] {
48+
pub type foo_t = u32;
49+
use core::mem::size_of;
50+
}
51+
}
52+
"#
53+
.to_string();
54+
55+
let mut checker = StyleChecker::new();
56+
checker.check_string(contents).unwrap();
57+
assert!(checker.finalize().is_err());
58+
}
59+
60+
#[test]
61+
fn check_style_accept_cfg_if_branch_resets_state() {
62+
let contents = r#"
63+
cfg_if! {
64+
if #[cfg(foo)] {
65+
use core::mem::size_of;
66+
pub type foo_t = u32;
67+
} else {
68+
use core::mem::align_of;
69+
}
70+
}
71+
"#
72+
.to_string();
73+
74+
let mut checker = StyleChecker::new();
75+
checker.check_string(contents).unwrap();
76+
checker.finalize().unwrap();
77+
}
78+
79+
#[test]
80+
fn check_style_reject_multiple_f_macros() {
81+
let contents = r#"
82+
f! {}
83+
f! {}
84+
"#
85+
.to_string();
86+
87+
let mut checker = StyleChecker::new();
88+
checker.check_string(contents).unwrap();
89+
assert!(checker.finalize().is_err());
90+
}
91+
92+
#[test]
93+
fn check_style_accept_cfg_ignore_target_endian_nested() {
94+
let contents = r#"
95+
pub struct Foo {
96+
#[cfg(target_endian = "little")]
97+
pub id: __u16,
98+
}
99+
"#
100+
.to_string();
101+
102+
let mut checker = StyleChecker::new();
103+
checker.check_string(contents).unwrap();
104+
checker.finalize().unwrap();
105+
}
106+
107+
#[test]
108+
fn check_style_reject_manual_copy() {
109+
let contents = r#"
110+
#[derive(Copy)]
111+
pub struct Foo {}
112+
"#
113+
.to_string();
114+
115+
let mut checker = StyleChecker::new();
116+
checker.check_string(contents).unwrap();
117+
assert!(checker.finalize().is_err());
118+
}
119+
120+
#[test]
121+
fn check_style_reject_manual_clone() {
122+
let contents = r#"
123+
#[derive(Clone)]
124+
pub struct Foo {}
125+
"#
126+
.to_string();
127+
128+
let mut checker = StyleChecker::new();
129+
checker.check_string(contents).unwrap();
130+
assert!(checker.finalize().is_err());
131+
}
132+
133+
#[test]
134+
fn check_style_accept_multiple_s_macros_with_disjoint_cfg() {
135+
let contents = r#"
136+
// Main `s!`
137+
s! {}
138+
139+
// These are not supported on a single arch. It doesn't make sense to
140+
// duplicate `foo` into every single file except one, so allow this here.
141+
#[cfg(not(target_arch = "foo"))]
142+
s! { pub struct foo { /* ... */ } }
143+
144+
// Similar to the above, no problems here
145+
#[cfg(not(target_os = "illumos"))]
146+
s! { pub struct bar { /* ... */ } }
147+
"#
148+
.to_string();
149+
150+
let mut checker = StyleChecker::new();
151+
checker.check_string(contents).unwrap();
152+
checker.finalize().unwrap();
153+
}
154+
155+
#[test]
156+
fn check_style_reject_duplicated_s_macro() {
157+
let contents = r#"
158+
s! {}
159+
s! {}
160+
"#
161+
.to_string();
162+
163+
let mut checker = StyleChecker::new();
164+
checker.check_string(contents).unwrap();
165+
assert!(checker.finalize().is_err());
166+
}
167+
168+
#[test]
169+
fn check_style_reject_duplicated_s_macro_cfg() {
170+
let contents = r#"
171+
#[cfg(not(target_arch = "foo"))]
172+
s! {}
173+
174+
#[cfg(not(target_arch = "foo"))]
175+
s! {}
176+
"#
177+
.to_string();
178+
179+
let mut checker = StyleChecker::new();
180+
checker.check_string(contents).unwrap();
181+
assert!(checker.finalize().is_err());
182+
}
183+
184+
#[test]
185+
fn check_style_reject_single_positive_s_macro_cfg() {
186+
let contents = r#"
187+
// A positive (no `not`) config: reject because this should go into
188+
// the relevant file.
189+
#[cfg(target_arch = "foo")]
190+
s! { pub struct foo { /* ... */ } }
191+
"#
192+
.to_string();
193+
194+
let mut checker = StyleChecker::new();
195+
checker.check_string(contents).unwrap();
196+
assert!(checker.finalize().is_err());
197+
}
198+
199+
#[test]
200+
fn check_style_reject_single_positive_s_macro_cfg_target_os() {
201+
let contents = r#"
202+
// A positive (no `not`) config: reject because this should go into
203+
// the relevant file.
204+
#[cfg(target_os = "foo")]
205+
s! { pub struct foo { /* ... */ } }
206+
"#
207+
.to_string();
208+
209+
let mut checker = StyleChecker::new();
210+
checker.check_string(contents).unwrap();
211+
assert!(checker.finalize().is_err());
212+
}
213+
214+
#[test]
215+
fn check_style_accept_positive_s_macro_any() {
216+
let contents = r#"
217+
// It's nicer to accept this so that we don't have to duplicate the same struct 3 times.
218+
#[cfg(any(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
219+
s! { pub struct foo { /* ... */ } }
220+
"#
221+
.to_string();
222+
223+
let mut checker = StyleChecker::new();
224+
checker.check_string(contents).unwrap();
225+
checker.finalize().unwrap();
226+
}
227+
228+
#[test]
229+
fn check_style_accept_positive_s_macro_all() {
230+
let contents = r#"
231+
#[cfg(all(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
232+
s! { pub struct foo { /* ... */ } }
233+
"#
234+
.to_string();
235+
236+
let mut checker = StyleChecker::new();
237+
checker.check_string(contents).unwrap();
238+
checker.finalize().unwrap();
239+
}
240+
241+
#[test]
242+
fn check_style_reject_duplicated_cfg_and_cfg_if() {
243+
let contents = r#"
244+
#[cfg(not(target_arch = "foo"))]
245+
s! { pub struct foo { /* ... */ } }
246+
247+
cfg_if! {
248+
if #[cfg(not(target_arch = "foo"))] {
249+
s!{ pub struct bar {} }
250+
}
251+
}
252+
"#
253+
.to_string();
254+
255+
let mut checker = StyleChecker::new();
256+
checker.check_string(contents).unwrap();
257+
assert!(checker.finalize().is_err());
258+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)