mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 02:43:24 +00:00
Enable usermode unit test for specific crates
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
b8818bb740
commit
bb0560530f
4
.github/workflows/unit_test.yml
vendored
4
.github/workflows/unit_test.yml
vendored
@ -20,6 +20,8 @@ jobs:
|
|||||||
id: ktest_unit_test
|
id: ktest_unit_test
|
||||||
run: make run KTEST=all ENABLE_KVM=0 RELEASE_MODE=1
|
run: make run KTEST=all ENABLE_KVM=0 RELEASE_MODE=1
|
||||||
|
|
||||||
# TODO: include the unit tests for the crates that supports cargo test.
|
- name: Usermode Unit test
|
||||||
|
id: usermode_unit_test
|
||||||
|
run: make test
|
||||||
|
|
||||||
# TODO: add component check.
|
# TODO: add component check.
|
||||||
|
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -216,7 +216,7 @@ dependencies = [
|
|||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -368,7 +368,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -475,7 +475,7 @@ checksum = "ba330b70a5341d3bc730b8e205aaee97ddab5d9c448c4f51a7c2d924266fa8f9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -567,7 +567,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -839,7 +839,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rand",
|
"rand",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1290,9 +1290,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.38"
|
version = "2.0.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1332,7 +1332,7 @@ checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.38",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1405,6 +1405,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
"typeflags-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
61
Cargo.toml
61
Cargo.toml
@ -24,22 +24,65 @@ members = [
|
|||||||
"framework/jinux-frame",
|
"framework/jinux-frame",
|
||||||
"framework/jinux-frame/src/arch/x86/boot/linux_boot/setup",
|
"framework/jinux-frame/src/arch/x86/boot/linux_boot/setup",
|
||||||
"framework/libs/align_ext",
|
"framework/libs/align_ext",
|
||||||
"services/comps/virtio",
|
"framework/libs/ktest",
|
||||||
"services/comps/input",
|
"framework/libs/tdx-guest",
|
||||||
"services/comps/block",
|
"services/comps/block",
|
||||||
"services/comps/network",
|
|
||||||
"services/comps/framebuffer",
|
"services/comps/framebuffer",
|
||||||
|
"services/comps/input",
|
||||||
|
"services/comps/network",
|
||||||
"services/comps/time",
|
"services/comps/time",
|
||||||
"services/libs/jinux-std",
|
"services/comps/virtio",
|
||||||
"services/libs/jinux-rights-proc",
|
|
||||||
"services/libs/typeflags",
|
|
||||||
"services/libs/typeflags-util",
|
|
||||||
"services/libs/jinux-util",
|
|
||||||
"services/libs/cpio-decoder",
|
"services/libs/cpio-decoder",
|
||||||
"services/libs/int-to-c-enum",
|
"services/libs/int-to-c-enum",
|
||||||
|
"services/libs/int-to-c-enum/derive",
|
||||||
|
"services/libs/jinux-rights",
|
||||||
|
"services/libs/jinux-rights-proc",
|
||||||
|
"services/libs/jinux-std",
|
||||||
|
"services/libs/jinux-util",
|
||||||
|
"services/libs/keyable-arc",
|
||||||
|
"services/libs/typeflags",
|
||||||
|
"services/libs/typeflags-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude = ["services/libs/comp-sys/controlled", "services/libs/comp-sys/cargo-component"]
|
exclude = [
|
||||||
|
"services/libs/comp-sys/cargo-component",
|
||||||
|
"services/libs/comp-sys/component",
|
||||||
|
"services/libs/comp-sys/component-macro",
|
||||||
|
"services/libs/comp-sys/controlled",
|
||||||
|
]
|
||||||
|
|
||||||
|
[workspace.metadata]
|
||||||
|
|
||||||
|
usermode_testable = [
|
||||||
|
"runner",
|
||||||
|
"framework/libs/align_ext",
|
||||||
|
"framework/libs/ktest",
|
||||||
|
"services/libs/cpio-decoder",
|
||||||
|
"services/libs/int-to-c-enum",
|
||||||
|
"services/libs/int-to-c-enum/derive",
|
||||||
|
"services/libs/jinux-rights",
|
||||||
|
"services/libs/jinux-rights-proc",
|
||||||
|
"services/libs/keyable-arc",
|
||||||
|
"services/libs/typeflags",
|
||||||
|
"services/libs/typeflags-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
ktest_testable = [
|
||||||
|
"framework/jinux-frame",
|
||||||
|
"framework/libs/tdx-guest",
|
||||||
|
"services/comps/block",
|
||||||
|
"services/comps/framebuffer",
|
||||||
|
"services/comps/input",
|
||||||
|
"services/comps/network",
|
||||||
|
"services/comps/time",
|
||||||
|
"services/comps/virtio",
|
||||||
|
"services/libs/jinux-std",
|
||||||
|
"services/libs/jinux-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
untestable = [
|
||||||
|
"framework/jinux-frame/src/arch/x86/boot/linux_boot/setup",
|
||||||
|
]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
intel_tdx = ["jinux-frame/intel_tdx", "jinux-std/intel_tdx"]
|
intel_tdx = ["jinux-frame/intel_tdx", "jinux-std/intel_tdx"]
|
||||||
|
17
README.md
17
README.md
@ -58,7 +58,20 @@ make run
|
|||||||
|
|
||||||
### Unit Test
|
### Unit Test
|
||||||
|
|
||||||
We can run unit tests if building succeeds. This is powered by our [ktest](framework/libs/ktest) framework.
|
#### User mode unit test
|
||||||
|
|
||||||
|
Many of our crates does not require running on bare metal environment and can be tested through the standard Cargo testing framework. A specific list of which crates can be tested with `cargo test` is listed in the `[workspace.metadata.usermode_testable]` entry in the `Cargo.toml` file of the root workspace.
|
||||||
|
|
||||||
|
There is a tool `./tools/test/run_tests.py` to run all the user mode tests, and can be invoked through Make.
|
||||||
|
```bash
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
Nevertheless, you could enter the directory of a specific crate and invoke `cargo test` to perform user mode unit tests and doctests.
|
||||||
|
|
||||||
|
#### Kernel mode unit test
|
||||||
|
|
||||||
|
We can run unit tests in kernel mode for crates like `jinux-frame` or `jinux-std`. This is powered by our [ktest](framework/libs/ktest) framework.
|
||||||
```bash
|
```bash
|
||||||
make run KTEST=all
|
make run KTEST=all
|
||||||
```
|
```
|
||||||
@ -68,6 +81,8 @@ You could also specify tests in a crate or a subset of tests to run, as long as
|
|||||||
make run KTEST=jinux-frame,jinux-std
|
make run KTEST=jinux-frame,jinux-std
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Component check
|
||||||
|
|
||||||
If we want to check access control policy among components, install some standalone tools (e.g., `cargo-component`).
|
If we want to check access control policy among components, install some standalone tools (e.g., `cargo-component`).
|
||||||
``` bash
|
``` bash
|
||||||
make tools
|
make tools
|
||||||
|
@ -46,7 +46,7 @@ pub use self::error::Error;
|
|||||||
pub use self::prelude::Result;
|
pub use self::prelude::Result;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use arch::irq::{IrqCallbackHandle, IrqLine};
|
use arch::irq::{IrqCallbackHandle, IrqLine};
|
||||||
use core::mem;
|
use core::{mem, panic::PanicInfo};
|
||||||
#[cfg(feature = "intel_tdx")]
|
#[cfg(feature = "intel_tdx")]
|
||||||
use tdx_guest::init_tdx;
|
use tdx_guest::init_tdx;
|
||||||
use trapframe::TrapFrame;
|
use trapframe::TrapFrame;
|
||||||
@ -110,7 +110,22 @@ pub(crate) const fn zero<T>() -> T {
|
|||||||
unsafe { mem::MaybeUninit::zeroed().assume_init() }
|
unsafe { mem::MaybeUninit::zeroed().assume_init() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panic_handler() {
|
/// The panic handler provided by Jinux Frame.
|
||||||
|
///
|
||||||
|
/// The definition of the real panic handler is located at the kernel binary
|
||||||
|
/// crate with the `#[panic_handler]` attribute. This function provides a
|
||||||
|
/// default implementation of the panic handler, which can forwarded to by the
|
||||||
|
/// kernel binary crate.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// extern crate jinux_frame;
|
||||||
|
/// #[panic_handler]
|
||||||
|
/// fn panic(info: &PanicInfo) -> ! {
|
||||||
|
/// jinux_frame::panic_handler(info);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn panic_handler(info: &PanicInfo) -> ! {
|
||||||
|
println!("[panic]:{:#?}", info);
|
||||||
// let mut fp: usize;
|
// let mut fp: usize;
|
||||||
// let stop = unsafe{
|
// let stop = unsafe{
|
||||||
// Task::current().kstack.get_top()
|
// Task::current().kstack.get_top()
|
||||||
@ -130,6 +145,7 @@ pub fn panic_handler() {
|
|||||||
// }
|
// }
|
||||||
// println!("---END BACKTRACE---");
|
// println!("---END BACKTRACE---");
|
||||||
// }
|
// }
|
||||||
|
exit_qemu(QemuExitCode::Failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The exit code of x86 QEMU isa debug device. In `qemu-system-x86_64` the
|
/// The exit code of x86 QEMU isa debug device. In `qemu-system-x86_64` the
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![no_std]
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
/// An extension trait for Rust integer types, including `u8`, `u16`, `u32`,
|
/// An extension trait for Rust integer types, including `u8`, `u16`, `u32`,
|
||||||
/// `u64`, and `usize`, to provide methods to make integers aligned to a
|
/// `u64`, and `usize`, to provide methods to make integers aligned to a
|
||||||
@ -17,10 +17,11 @@ pub trait AlignExt {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// assert!(align_up(12, 2), 12);
|
/// use crate::align_ext::AlignExt;
|
||||||
/// assert!(align_up(12, 4), 12);
|
/// assert_eq!(12usize.align_up(2), 12);
|
||||||
/// assert!(align_up(12, 8), 16);
|
/// assert_eq!(12usize.align_up(4), 12);
|
||||||
/// assert!(align_up(12, 16), 16);
|
/// assert_eq!(12usize.align_up(8), 16);
|
||||||
|
/// assert_eq!(12usize.align_up(16), 16);
|
||||||
/// ```
|
/// ```
|
||||||
fn align_up(self, power_of_two: Self) -> Self;
|
fn align_up(self, power_of_two: Self) -> Self;
|
||||||
|
|
||||||
@ -34,10 +35,11 @@ pub trait AlignExt {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// assert!(align_down(12, 2), 12);
|
/// use crate::align_ext::AlignExt;
|
||||||
/// assert!(align_down(12, 4), 12);
|
/// assert_eq!(12usize.align_down(2), 12);
|
||||||
/// assert!(align_down(12, 8), 8);
|
/// assert_eq!(12usize.align_down(4), 12);
|
||||||
/// assert!(align_down(12, 16), 0);
|
/// assert_eq!(12usize.align_down(8), 8);
|
||||||
|
/// assert_eq!(12usize.align_down(16), 0);
|
||||||
/// ```
|
/// ```
|
||||||
fn align_down(self, power_of_two: Self) -> Self;
|
fn align_down(self, power_of_two: Self) -> Self;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
// The no_mangle macro need to remove the `forbid(unsafe_code)` macro. The bootloader needs the _start function
|
// The `no_mangle`` attribute for the `jinux_main` entrypoint requires the removal of safety check.
|
||||||
// to be no mangle so that it can jump into the entry point.
|
// Please be aware that the kernel is not allowed to introduce any other unsafe operations.
|
||||||
// #![forbid(unsafe_code)]
|
// #![forbid(unsafe_code)]
|
||||||
extern crate jinux_frame;
|
extern crate jinux_frame;
|
||||||
|
|
||||||
@ -19,9 +19,5 @@ pub fn jinux_main() -> ! {
|
|||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
use jinux_frame::{exit_qemu, QemuExitCode};
|
jinux_frame::panic_handler(info);
|
||||||
|
|
||||||
println!("[panic]:{:#?}", info);
|
|
||||||
jinux_frame::panic_handler();
|
|
||||||
exit_qemu(QemuExitCode::Failed);
|
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,13 @@ use lending_iterator::LendingIterator;
|
|||||||
fn test_decoder() {
|
fn test_decoder() {
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
let manifest_path = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
let manifest_path = std::path::Path::new(manifest_path.as_str());
|
||||||
|
|
||||||
// Prepare the cpio buffer
|
// Prepare the cpio buffer
|
||||||
let buffer = {
|
let buffer = {
|
||||||
let mut find_process = Command::new("find")
|
let mut find_process = Command::new("find")
|
||||||
.arg(".")
|
.arg(manifest_path.as_os_str())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("find command is not started");
|
.expect("find command is not started");
|
||||||
@ -26,38 +29,35 @@ fn test_decoder() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut decoder = CpioDecoder::new(buffer.as_slice());
|
let mut decoder = CpioDecoder::new(buffer.as_slice());
|
||||||
// 1st entry
|
// 1st entry must be the root entry
|
||||||
let entry = {
|
let entry = {
|
||||||
let entry_result = decoder.next().unwrap();
|
let entry_result = decoder.next().unwrap();
|
||||||
entry_result.unwrap()
|
entry_result.unwrap()
|
||||||
};
|
};
|
||||||
assert!(entry.name() == ".");
|
assert_eq!(entry.name(), manifest_path.as_os_str());
|
||||||
assert!(entry.metadata().file_type() == FileType::Dir);
|
|
||||||
assert!(entry.metadata().ino() > 0);
|
|
||||||
// 2nd entry
|
|
||||||
let entry = {
|
|
||||||
let entry_result = decoder.next().unwrap();
|
|
||||||
entry_result.unwrap()
|
|
||||||
};
|
|
||||||
assert!(entry.name() == "src");
|
|
||||||
assert!(entry.metadata().file_type() == FileType::Dir);
|
assert!(entry.metadata().file_type() == FileType::Dir);
|
||||||
assert!(entry.metadata().ino() > 0);
|
assert!(entry.metadata().ino() > 0);
|
||||||
|
|
||||||
// 3rd entry
|
// Other entries
|
||||||
let mut entry = {
|
while let Some(decode_result) = decoder.next() {
|
||||||
let entry_result = decoder.next().unwrap();
|
let mut entry = decode_result.unwrap();
|
||||||
entry_result.unwrap()
|
|
||||||
};
|
|
||||||
assert!(
|
|
||||||
entry.name() == "src/lib.rs"
|
|
||||||
|| entry.name() == "src/test.rs"
|
|
||||||
|| entry.name() == "src/error.rs"
|
|
||||||
);
|
|
||||||
assert!(entry.metadata().file_type() == FileType::File);
|
|
||||||
assert!(entry.metadata().ino() > 0);
|
assert!(entry.metadata().ino() > 0);
|
||||||
|
if entry.name() == manifest_path.join("src").as_os_str() {
|
||||||
|
assert!(entry.metadata().file_type() == FileType::Dir);
|
||||||
|
assert!(entry.metadata().ino() > 0);
|
||||||
|
} else if entry.name() == manifest_path.join("src").join("lib.rs").as_os_str()
|
||||||
|
|| entry.name() == manifest_path.join("src").join("test.rs").as_os_str()
|
||||||
|
|| entry.name() == manifest_path.join("src").join("error.rs").as_os_str()
|
||||||
|
|| entry.name() == manifest_path.join("Cargo.toml").as_os_str()
|
||||||
|
{
|
||||||
|
assert!(entry.metadata().file_type() == FileType::File);
|
||||||
assert!(entry.metadata().size() > 0);
|
assert!(entry.metadata().size() > 0);
|
||||||
let mut buffer: Vec<u8> = Vec::new();
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
assert!(entry.read_all(&mut buffer).is_ok());
|
assert!(entry.read_all(&mut buffer).is_ok());
|
||||||
|
} else {
|
||||||
|
panic!("unexpected entry: {:?}", entry.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#![no_std]
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
/// Error type for TryFromInt derive macro
|
/// Error type for TryFromInt derive macro
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -57,6 +57,8 @@ pub type WriteOp = TRights![Write];
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// use jinux_rights::{Rights, TRights, TRightSet};
|
||||||
|
///
|
||||||
/// pub struct Vmo<R=Rights>(R);
|
/// pub struct Vmo<R=Rights>(R);
|
||||||
///
|
///
|
||||||
/// impl<R:TRights> Vmo<TRightSet<R>>{
|
/// impl<R:TRights> Vmo<TRightSet<R>>{
|
||||||
|
@ -9,7 +9,8 @@ edition = "2021"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
itertools = "0.10.5"
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = {version = "1.0.90"}
|
syn = { version = "1.0.90" }
|
||||||
itertools = "0.10.5"
|
typeflags-util = { path = "../typeflags-util" }
|
||||||
|
@ -6,25 +6,24 @@
|
|||||||
//! typeflags is used to define another declarive macro to define type set.
|
//! typeflags is used to define another declarive macro to define type set.
|
||||||
//! It can be used as the following example.
|
//! It can be used as the following example.
|
||||||
//! ```rust
|
//! ```rust
|
||||||
|
//! use typeflags::typeflags;
|
||||||
//! typeflags! {
|
//! typeflags! {
|
||||||
//! pub trait RightSet: u32 {
|
//! pub trait RightSet: u32 {
|
||||||
//! struct Read = 1 << 1;
|
//! struct Read = 1 << 1;
|
||||||
//! struct Write = 1 << 2;
|
//! struct Write = 1 << 2;
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//!
|
||||||
//! The code will generate a macro with the name as RightSet, we can use this macro to define typesets with different types.
|
//! // The above code will generate a macro with the name as RightSet, we can use this macro to define typesets with different types.
|
||||||
//! Usage example:
|
//! // Usage example:
|
||||||
//! ```rust
|
|
||||||
//! type O = RightSet![]; // Nil
|
//! type O = RightSet![]; // Nil
|
||||||
//! type R = RightSet![Read]; // Cons<Read, Nil>
|
//! type R = RightSet![Read]; // Cons<Read, Nil>
|
||||||
//! type W = RightSet![Write]; // Cons<Write, Nil>
|
//! type W = RightSet![Write]; // Cons<Write, Nil>
|
||||||
//! type RW = RightSet![Read, Write]; // Cons<Write, Cons<Read, Nil>>
|
//! type RW = RightSet![Read, Write]; // Cons<Write, Cons<Read, Nil>>
|
||||||
//! type WR = RightSet![Write, Read]; // Cons<Write, Cons<Read, Nil>>
|
//! type WR = RightSet![Write, Read]; // Cons<Write, Cons<Read, Nil>>
|
||||||
//! ```
|
|
||||||
//!
|
//!
|
||||||
//! Test Example
|
//! // Test Example
|
||||||
//! ```rust
|
//! extern crate typeflags_util;
|
||||||
//! use typeflags_util::*;
|
//! use typeflags_util::*;
|
||||||
//! assert_eq!(O::BITS, 0);
|
//! assert_eq!(O::BITS, 0);
|
||||||
//! assert_eq!(R::BITS, 2);
|
//! assert_eq!(R::BITS, 2);
|
||||||
|
52
tools/test/run_tests.py
Normal file
52
tools/test/run_tests.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# Use cargo metadata to get the manifest in json format.
|
||||||
|
def get_manifest():
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
manifest = subprocess.check_output(
|
||||||
|
["cargo", "metadata", "--no-deps", "--format-version", "1"]
|
||||||
|
)
|
||||||
|
return json.loads(manifest)
|
||||||
|
|
||||||
|
# Run the user mode tests for the crates and exit if any test fails.
|
||||||
|
def run_usermode_tests(crates):
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
for crate in crates:
|
||||||
|
print("Running tests for", crate)
|
||||||
|
result = subprocess.check_call(["cargo", "test", "--manifest-path", crate + "/Cargo.toml"])
|
||||||
|
if result != 0:
|
||||||
|
print("Test failed for", crate)
|
||||||
|
os.exit(result)
|
||||||
|
|
||||||
|
# The member id returned by the cargo metadata command is
|
||||||
|
# `<package name> <package name> (path+file:///<absolute path to member>)`.
|
||||||
|
# We need a relative path as we specify them in `Cargo.toml`.
|
||||||
|
def member_id_to_crate_rel_path(member_id):
|
||||||
|
import os
|
||||||
|
annotation = member_id.split(" ")[2]
|
||||||
|
abs_path = annotation \
|
||||||
|
.replace("(", "") \
|
||||||
|
.replace(")", "") \
|
||||||
|
.replace("path+file://", "")
|
||||||
|
return os.path.relpath(abs_path, os.getcwd())
|
||||||
|
|
||||||
|
def main():
|
||||||
|
import os
|
||||||
|
manifest = get_manifest()
|
||||||
|
usermode_testables = manifest["metadata"]["usermode_testable"]
|
||||||
|
ktest_testables = manifest["metadata"]["ktest_testable"]
|
||||||
|
untestables = manifest["metadata"]["untestable"]
|
||||||
|
# A sanity check to make sure we have registered all crates.
|
||||||
|
all_members = sorted([member_id_to_crate_rel_path(p["id"]) for p in manifest["packages"]])
|
||||||
|
test_members = sorted(usermode_testables + ktest_testables + untestables + ["."])
|
||||||
|
if (all_members != test_members):
|
||||||
|
print("Test members does not match all the workspace members in Cargo.toml. "
|
||||||
|
"Please setup the testablity of all the crates in Cargo.toml correctly.")
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
run_usermode_tests(usermode_testables)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Reference in New Issue
Block a user