Skip to content

Commit d37060f

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 rust-osdev#283.
1 parent afbbb2e commit d37060f

File tree

8 files changed

+190
-1
lines changed

8 files changed

+190
-1
lines changed

.github/workflows/rust.yml

Lines changed: 1 addition & 1 deletion
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

Lines changed: 4 additions & 0 deletions
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"
28+
uefi = { version = "0.12.0", default-features = false }

uefi-macros/tests/cargo_wrapper

Lines changed: 2 additions & 0 deletions
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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use std::env;
2+
3+
#[test]
4+
fn ui() {
5+
let t = trybuild::TestCases::new();
6+
7+
// This wrapper script adds the necessary `-Zbuild-std` argument
8+
// when trybuild invokes cargo.
9+
let cargo_wrapper = env::current_exe()
10+
.unwrap()
11+
.parent()
12+
.unwrap()
13+
.join("../../../../uefi-macros/tests/cargo_wrapper");
14+
env::set_var("CARGO", cargo_wrapper);
15+
16+
t.compile_fail("tests/ui/*.rs");
17+
}

uefi-macros/tests/ui/entry.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#![no_main]
2+
#![feature(abi_efiapi)]
3+
4+
use uefi::prelude::*;
5+
use uefi_macros::entry;
6+
7+
mod good_entry {
8+
use super::*;
9+
10+
#[entry]
11+
fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> Status {
12+
Status::SUCCESS
13+
}
14+
}
15+
16+
mod bad_attr_arg {
17+
use super::*;
18+
19+
#[entry(some_arg)]
20+
extern "C" fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> Status {
21+
Status::SUCCESS
22+
}
23+
}
24+
25+
mod bad_abi_modifier {
26+
use super::*;
27+
28+
#[entry]
29+
extern "C" fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> Status {
30+
Status::SUCCESS
31+
}
32+
}
33+
34+
mod bad_async {
35+
use super::*;
36+
37+
#[entry]
38+
async fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> Status {
39+
Status::SUCCESS
40+
}
41+
}
42+
43+
mod bad_const {
44+
use super::*;
45+
46+
#[entry]
47+
const fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> Status {
48+
Status::SUCCESS
49+
}
50+
}
51+
52+
mod bad_generic {
53+
use super::*;
54+
55+
#[entry]
56+
fn efi_main<T>(_handle: Handle, _st: SystemTable<Boot>) -> Status {
57+
Status::SUCCESS
58+
}
59+
}
60+
61+
mod bad_args {
62+
use super::*;
63+
64+
#[entry]
65+
fn efi_main(_handle: Handle, _st: SystemTable<Boot>, _x: usize) -> bool {
66+
false
67+
}
68+
}
69+
70+
mod bad_return_type {
71+
use super::*;
72+
73+
#[entry]
74+
fn efi_main(_handle: Handle, _st: SystemTable<Boot>) -> bool {
75+
false
76+
}
77+
}

uefi-macros/tests/ui/entry.stderr

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

uefi-macros/tests/ui/guid.rs

Lines changed: 19 additions & 0 deletions
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

Lines changed: 17 additions & 0 deletions
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)