From 51b687b3943b208a1b08308ec4af167c32859384 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 8 Sep 2021 15:57:39 -0400 Subject: [PATCH] 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. --- uefi-macros/Cargo.toml | 4 +++ uefi-macros/tests/cargo_wrapper | 2 ++ uefi-macros/tests/compilation.rs | 20 ++++++++++++++ uefi-macros/tests/ui/entry.rs | 45 +++++++++++++++++++++++++++++++ uefi-macros/tests/ui/entry.stderr | 41 ++++++++++++++++++++++++++++ uefi-macros/tests/ui/guid.rs | 19 +++++++++++++ uefi-macros/tests/ui/guid.stderr | 17 ++++++++++++ 7 files changed, 148 insertions(+) create mode 100755 uefi-macros/tests/cargo_wrapper create mode 100644 uefi-macros/tests/compilation.rs create mode 100644 uefi-macros/tests/ui/entry.rs create mode 100644 uefi-macros/tests/ui/entry.stderr create mode 100644 uefi-macros/tests/ui/guid.rs create mode 100644 uefi-macros/tests/ui/guid.stderr diff --git a/uefi-macros/Cargo.toml b/uefi-macros/Cargo.toml index ea831ce03..fb9df1fe5 100644 --- a/uefi-macros/Cargo.toml +++ b/uefi-macros/Cargo.toml @@ -22,3 +22,7 @@ proc-macro = true proc-macro2 = "1.0.28" quote = "1.0.9" syn = { version = "1.0.75", features = ["full"] } + +[dev-dependencies] +trybuild = "1.0.45" +uefi = { version = "0.12.0", default-features = false } diff --git a/uefi-macros/tests/cargo_wrapper b/uefi-macros/tests/cargo_wrapper new file mode 100755 index 000000000..49db776c7 --- /dev/null +++ b/uefi-macros/tests/cargo_wrapper @@ -0,0 +1,2 @@ +#!/bin/sh +cargo -Zbuild-std=std "$@" diff --git a/uefi-macros/tests/compilation.rs b/uefi-macros/tests/compilation.rs new file mode 100644 index 000000000..1fec59ffd --- /dev/null +++ b/uefi-macros/tests/compilation.rs @@ -0,0 +1,20 @@ +use std::env; + +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + + // Due to the way trybuild compiles the input files, `no_std` + // doesn't work. So, since -Zbuild-std is enabled in the cargo + // config file in the root of the crate we need to also build the + // std crate for these tests. This wrapper script adds the necessary + // argument when trybuild invokes cargo. + let cargo_wrapper = env::current_exe() + .unwrap() + .parent() + .unwrap() + .join("../../../../uefi-macros/tests/cargo_wrapper"); + env::set_var("CARGO", cargo_wrapper); + + t.compile_fail("tests/ui/*.rs"); +} diff --git a/uefi-macros/tests/ui/entry.rs b/uefi-macros/tests/ui/entry.rs new file mode 100644 index 000000000..91dda4a52 --- /dev/null +++ b/uefi-macros/tests/ui/entry.rs @@ -0,0 +1,45 @@ +#![no_main] +#![feature(abi_efiapi)] + +use uefi::prelude::*; +use uefi_macros::entry; + +#[entry] +fn good_entry(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry(some_arg)] +fn bad_attr_arg(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry] +extern "C" fn bad_abi_modifier(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry] +async fn bad_async(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry] +fn bad_const(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry] +fn bad_generic(_handle: Handle, _st: SystemTable) -> Status { + Status::SUCCESS +} + +#[entry] +fn bad_args(_handle: Handle, _st: SystemTable, _x: usize) -> bool { + false +} + +#[entry] +fn bad_return_type(_handle: Handle, _st: SystemTable) -> bool { + false +} diff --git a/uefi-macros/tests/ui/entry.stderr b/uefi-macros/tests/ui/entry.stderr new file mode 100644 index 000000000..fb8dfc563 --- /dev/null +++ b/uefi-macros/tests/ui/entry.stderr @@ -0,0 +1,41 @@ +error: Entry attribute accepts no arguments + --> $DIR/entry.rs:12:9 + | +12 | #[entry(some_arg)] + | ^^^^^^^^ + +error: Entry method must have no ABI modifier + --> $DIR/entry.rs:18:1 + | +18 | extern "C" fn bad_abi_modifier(_handle: Handle, _st: SystemTable) -> Status { + | ^^^^^^^^^^ + +error: Entry method should not be async + --> $DIR/entry.rs:23:1 + | +23 | async fn bad_async(_handle: Handle, _st: SystemTable) -> Status { + | ^^^^^ + +error: Entry method should not be generic + --> $DIR/entry.rs:33:16 + | +33 | fn bad_generic(_handle: Handle, _st: SystemTable) -> Status { + | ^ + +error[E0308]: mismatched types + --> $DIR/entry.rs:38:4 + | +38 | fn bad_args(_handle: Handle, _st: SystemTable, _x: usize) -> bool { + | ^^^^^^^^ incorrect number of function parameters + | + = note: expected fn pointer `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable) -> uefi::Status` + found fn item `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable, usize) -> bool {bad_args}` + +error[E0308]: mismatched types + --> $DIR/entry.rs:43:4 + | +43 | fn bad_return_type(_handle: Handle, _st: SystemTable) -> bool { + | ^^^^^^^^^^^^^^^ expected struct `uefi::Status`, found `bool` + | + = note: expected fn pointer `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<_>) -> uefi::Status` + found fn item `extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable<_>) -> bool {bad_return_type}` diff --git a/uefi-macros/tests/ui/guid.rs b/uefi-macros/tests/ui/guid.rs new file mode 100644 index 000000000..4f18b21af --- /dev/null +++ b/uefi-macros/tests/ui/guid.rs @@ -0,0 +1,19 @@ +use uefi_macros::unsafe_guid; + +// The GUID here is OK. +#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")] +struct Good; + +// Fail because the length is wrong. +#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa")] +struct TooShort; + +// Error span should point to the second group. +#[unsafe_guid("aaaaaaaa-Gaaa-aaaa-aaaa-aaaaaaaaaaaa")] +struct BadHexGroup2; + +// Error span should point to the fifth group. +#[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaG")] +struct BadHexGroup5; + +fn main() {} diff --git a/uefi-macros/tests/ui/guid.stderr b/uefi-macros/tests/ui/guid.stderr new file mode 100644 index 000000000..8337be27e --- /dev/null +++ b/uefi-macros/tests/ui/guid.stderr @@ -0,0 +1,17 @@ +error: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa" is not a canonical GUID string (expected 36 bytes, found 35) + --> $DIR/guid.rs:8:15 + | +8 | #[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: GUID component "Gaaa" is not a hexadecimal number + --> $DIR/guid.rs:12:25 + | +12 | #[unsafe_guid("aaaaaaaa-Gaaa-aaaa-aaaa-aaaaaaaaaaaa")] + | ^^^^ + +error: GUID component "aaaaaaaaaaaG" is not a hexadecimal number + --> $DIR/guid.rs:16:40 + | +16 | #[unsafe_guid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaG")] + | ^^^^^^^^^^^^