Skip to content

Commit fc67fab

Browse files
nicholasbishopGabrielMajeri
authored andcommitted
macros: add compilation tests
Use the [trybuild](https://github.com/dtolnay/trybuild) crate to test the `unsafe_guid` and `entry` macros. The compilation output is compared against expected output to check the various error cases in the macros, which allows detailed tests covering things like the specific error messages and the associated spans.
1 parent 750888c commit fc67fab

File tree

7 files changed

+148
-0
lines changed

7 files changed

+148
-0
lines changed

uefi-macros/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ proc-macro = true
2222
proc-macro2 = "1.0.28"
2323
quote = "1.0.9"
2424
syn = { version = "1.0.75", features = ["full"] }
25+
26+
[dev-dependencies]
27+
trybuild = "1.0.45"
28+
uefi = { version = "0.12.0", default-features = false }

uefi-macros/tests/cargo_wrapper

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
cargo -Zbuild-std=std "$@"

uefi-macros/tests/compilation.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::env;
2+
3+
#[test]
4+
fn ui() {
5+
let t = trybuild::TestCases::new();
6+
7+
// Due to the way trybuild compiles the input files, `no_std`
8+
// doesn't work. So, since -Zbuild-std is enabled in the cargo
9+
// config file in the root of the crate we need to also build the
10+
// std crate for these tests. This wrapper script adds the necessary
11+
// argument when trybuild invokes cargo.
12+
let cargo_wrapper = env::current_exe()
13+
.unwrap()
14+
.parent()
15+
.unwrap()
16+
.join("../../../../uefi-macros/tests/cargo_wrapper");
17+
env::set_var("CARGO", cargo_wrapper);
18+
19+
t.compile_fail("tests/ui/*.rs");
20+
}

uefi-macros/tests/ui/entry.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#![no_main]
2+
#![feature(abi_efiapi)]
3+
4+
use uefi::prelude::*;
5+
use uefi_macros::entry;
6+
7+
#[entry]
8+
fn good_entry(_handle: Handle, _st: SystemTable<Boot>) -> Status {
9+
Status::SUCCESS
10+
}
11+
12+
#[entry(some_arg)]
13+
fn bad_attr_arg(_handle: Handle, _st: SystemTable<Boot>) -> Status {
14+
Status::SUCCESS
15+
}
16+
17+
#[entry]
18+
extern "C" fn bad_abi_modifier(_handle: Handle, _st: SystemTable<Boot>) -> Status {
19+
Status::SUCCESS
20+
}
21+
22+
#[entry]
23+
async fn bad_async(_handle: Handle, _st: SystemTable<Boot>) -> Status {
24+
Status::SUCCESS
25+
}
26+
27+
#[entry]
28+
fn bad_const(_handle: Handle, _st: SystemTable<Boot>) -> Status {
29+
Status::SUCCESS
30+
}
31+
32+
#[entry]
33+
fn bad_generic<T>(_handle: Handle, _st: SystemTable<Boot>) -> Status {
34+
Status::SUCCESS
35+
}
36+
37+
#[entry]
38+
fn bad_args(_handle: Handle, _st: SystemTable<Boot>, _x: usize) -> bool {
39+
false
40+
}
41+
42+
#[entry]
43+
fn bad_return_type(_handle: Handle, _st: SystemTable<Boot>) -> bool {
44+
false
45+
}

uefi-macros/tests/ui/entry.stderr

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error: Entry attribute accepts no arguments
2+
--> $DIR/entry.rs:12:9
3+
|
4+
12 | #[entry(some_arg)]
5+
| ^^^^^^^^
6+
7+
error: Entry method must have no ABI modifier
8+
--> $DIR/entry.rs:18:1
9+
|
10+
18 | extern "C" fn bad_abi_modifier(_handle: Handle, _st: SystemTable<Boot>) -> Status {
11+
| ^^^^^^^^^^
12+
13+
error: Entry method should not be async
14+
--> $DIR/entry.rs:23:1
15+
|
16+
23 | async fn bad_async(_handle: Handle, _st: SystemTable<Boot>) -> Status {
17+
| ^^^^^
18+
19+
error: Entry method should not be generic
20+
--> $DIR/entry.rs:33:16
21+
|
22+
33 | fn bad_generic<T>(_handle: Handle, _st: SystemTable<Boot>) -> Status {
23+
| ^
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/entry.rs:38:4
27+
|
28+
38 | fn bad_args(_handle: Handle, _st: SystemTable<Boot>, _x: usize) -> bool {
29+
| ^^^^^^^^ incorrect number of function parameters
30+
|
31+
= note: expected fn pointer `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<uefi::table::Boot>) -> uefi::Status`
32+
found fn item `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<uefi::table::Boot>, usize) -> bool {bad_args}`
33+
34+
error[E0308]: mismatched types
35+
--> $DIR/entry.rs:43:4
36+
|
37+
43 | fn bad_return_type(_handle: Handle, _st: SystemTable<Boot>) -> bool {
38+
| ^^^^^^^^^^^^^^^ expected struct `uefi::Status`, found `bool`
39+
|
40+
= note: expected fn pointer `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<_>) -> uefi::Status`
41+
found fn item `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<_>) -> bool {bad_return_type}`

uefi-macros/tests/ui/guid.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use uefi_macros::unsafe_guid;
2+
3+
// The GUID here is OK.
4+
#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")]
5+
struct Good;
6+
7+
// Fail because the length is wrong.
8+
#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa")]
9+
struct TooShort;
10+
11+
// Error span should point to the second group.
12+
#[unsafe_guid("aaaaaaaa-Gaaa-aaaa-aaaa-aaaaaaaaaaaa")]
13+
struct BadHexGroup2;
14+
15+
// Error span should point to the fifth group.
16+
#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaG")]
17+
struct BadHexGroup5;
18+
19+
fn main() {}

uefi-macros/tests/ui/guid.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa" is not a canonical GUID string (expected 36 bytes, found 35)
2+
--> $DIR/guid.rs:8:15
3+
|
4+
8 | #[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: GUID component "Gaaa" is not a hexadecimal number
8+
--> $DIR/guid.rs:12:25
9+
|
10+
12 | #[unsafe_guid("aaaaaaaa-Gaaa-aaaa-aaaa-aaaaaaaaaaaa")]
11+
| ^^^^
12+
13+
error: GUID component "aaaaaaaaaaaG" is not a hexadecimal number
14+
--> $DIR/guid.rs:16:40
15+
|
16+
16 | #[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaG")]
17+
| ^^^^^^^^^^^^

0 commit comments

Comments
 (0)