Skip to content

Commit 4fd67cf

Browse files
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. Also updated the CI to run these tests, although that change should be obseleted by #283.
1 parent afbbb2e commit 4fd67cf

File tree

8 files changed

+149
-1
lines changed

8 files changed

+149
-1
lines changed

.github/workflows/rust.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
uses: actions-rs/cargo@v1
8282
with:
8383
command: test
84-
args: -Zbuild-std=std --target x86_64-unknown-linux-gnu --features=exts
84+
args: -Zbuild-std=std --target x86_64-unknown-linux-gnu --features=exts --package uefi --package uefi-macros
8585

8686
lints:
8787
name: Lints

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)