mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 20:46:35 +00:00
Refactor CI and OSDK tests, add OSDK publish workflow
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
eb42383532
commit
6694f08eac
@ -1,4 +1,4 @@
|
||||
name: Integration test
|
||||
name: Asterinas CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@ -7,7 +7,43 @@ on:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test:
|
||||
aster-lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
container: asterinas/asterinas:0.3.0
|
||||
steps:
|
||||
- run: echo "Running in asterinas/asterinas:0.3.0"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: make install_osdk
|
||||
|
||||
- name: Check
|
||||
id: check
|
||||
run: make check
|
||||
|
||||
aster-unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
container: asterinas/asterinas:0.3.0
|
||||
steps:
|
||||
- run: echo "Running in asterinas/asterinas:0.3.0"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: make install_osdk
|
||||
|
||||
- name: Usermode Unit test
|
||||
id: usermode_unit_test
|
||||
run: make test
|
||||
|
||||
- name: Ktest Unit Test
|
||||
id: ktest_unit_test
|
||||
run: make update_initramfs && make ktest
|
||||
|
||||
# TODO: add component check.
|
||||
|
||||
aster-integration-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
container: asterinas/asterinas:0.3.1
|
||||
@ -49,4 +85,3 @@ jobs:
|
||||
- name: Regression Test (MicroVM)
|
||||
id: regression_test_linux
|
||||
run: make run AUTO_TEST=regression ENABLE_KVM=0 QEMU_MACHINE=microvm RELEASE_MODE=1
|
||||
|
2
.github/workflows/docker_build.yml
vendored
2
.github/workflows/docker_build.yml
vendored
@ -6,7 +6,7 @@ on:
|
||||
paths:
|
||||
- VERSION
|
||||
branches:
|
||||
- 'main'
|
||||
- main
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
|
8
.github/workflows/osdk_ci.yml
vendored
8
.github/workflows/osdk_ci.yml
vendored
@ -2,6 +2,8 @@ name: OSDK CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- osdk/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@ -16,9 +18,9 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Format check
|
||||
id: fmt_check
|
||||
run: cd osdk && cargo check && cargo clippy
|
||||
- name: Lint
|
||||
id: lint
|
||||
run: cd osdk && cargo clippy -- -D warnings
|
||||
|
||||
- name: Unit test
|
||||
id: unit_test
|
||||
|
23
.github/workflows/osdk_publish.yml
vendored
Normal file
23
.github/workflows/osdk_publish.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
name: OSDK Publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- osdk/Cargo.toml
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
osdk-publish:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
container: asterinas/asterinas:0.3.0
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: katyo/publish-crates@v2
|
||||
with:
|
||||
path: './osdk'
|
||||
args: --no-verify
|
||||
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
ignore-unpublished-changes: true
|
@ -3,6 +3,8 @@
|
||||
A secure, fast, and general-purpose OS kernel written in Rust and compatible with Linux
|
||||
</p>
|
||||
|
||||
[](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml)
|
||||
|
||||
English | [中文版](README_CN.md)
|
||||
|
||||
## Introducing Asterinas
|
||||
|
@ -3,6 +3,8 @@
|
||||
一个安全、快速、通用的操作系统内核,使用Rust编写,并与Linux兼容
|
||||
</p>
|
||||
|
||||
[](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml)
|
||||
|
||||
[English](README.md) | 中文版
|
||||
|
||||
## 初见星绽
|
||||
|
3
osdk/.gitignore
vendored
3
osdk/.gitignore
vendored
@ -8,6 +8,3 @@ target/
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# Integration test generated files
|
||||
workspace_*
|
6
osdk/Cargo.lock
generated
6
osdk/Cargo.lock
generated
@ -88,9 +88,9 @@ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.9.0"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc"
|
||||
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
@ -119,7 +119,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-osdk"
|
||||
version = "0.1.5"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"assert_cmd",
|
||||
"clap",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cargo-osdk"
|
||||
version = "0.1.5"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
description = "Accelerate OS development with Asterinas OSDK"
|
||||
license = "MPL-2.0"
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Accelerate OS development with Asterinas OSDK
|
||||
|
||||
[](https://crates.io/crates/cargo-osdk)
|
||||
[](https://github.com/asterinas/asterinas/actions/workflows/osdk_ci.yml)
|
||||
|
||||
### What is it?
|
||||
|
||||
|
@ -1,3 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2023-12-01"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
channel = "stable"
|
4
osdk/src/base_crate/Cargo.toml.template
Normal file
4
osdk/src/base_crate/Cargo.toml.template
Normal file
@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "#NAME#"
|
||||
version = "#VERSION#"
|
||||
edition = "2021"
|
@ -4,9 +4,7 @@
|
||||
//! It will depend on the kernel crate.
|
||||
//!
|
||||
|
||||
use std::{fs, path::Path, process, process::Command, str::FromStr};
|
||||
|
||||
use crate::{error::Errno, error_msg};
|
||||
use std::{fs, path::Path, str::FromStr};
|
||||
|
||||
pub fn new_base_crate(
|
||||
base_crate_path: impl AsRef<Path>,
|
||||
@ -17,17 +15,32 @@ pub fn new_base_crate(
|
||||
std::fs::remove_dir_all(&base_crate_path).unwrap();
|
||||
}
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("new").arg("--bin").arg(base_crate_path.as_ref());
|
||||
cmd.arg("--vcs").arg("none");
|
||||
let dep_crate_version = {
|
||||
let cargo_toml = dep_crate_path.as_ref().join("Cargo.toml");
|
||||
let cargo_toml = fs::read_to_string(cargo_toml).unwrap();
|
||||
let cargo_toml: toml::Value = toml::from_str(&cargo_toml).unwrap();
|
||||
let dep_version = cargo_toml
|
||||
.get("package")
|
||||
.unwrap()
|
||||
.as_table()
|
||||
.unwrap()
|
||||
.get("version")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap();
|
||||
dep_version.to_string()
|
||||
};
|
||||
|
||||
if !cmd.status().unwrap().success() {
|
||||
error_msg!(
|
||||
"Failed to create base crate at: {:#?}",
|
||||
base_crate_path.as_ref()
|
||||
);
|
||||
process::exit(Errno::CreateBaseCrate as _);
|
||||
}
|
||||
// Create the directory
|
||||
fs::create_dir_all(&base_crate_path).unwrap();
|
||||
// Create the src directory
|
||||
fs::create_dir_all(base_crate_path.as_ref().join("src")).unwrap();
|
||||
|
||||
// Write Cargo.toml
|
||||
let cargo_toml = include_str!("Cargo.toml.template");
|
||||
let cargo_toml = cargo_toml.replace("#NAME#", &(dep_crate_name.to_string() + "-osdk-bin"));
|
||||
let cargo_toml = cargo_toml.replace("#VERSION#", &dep_crate_version);
|
||||
fs::write(base_crate_path.as_ref().join("Cargo.toml"), cargo_toml).unwrap();
|
||||
|
||||
// Set the current directory to the target osdk directory
|
||||
let original_dir = std::env::current_dir().unwrap();
|
||||
@ -44,7 +57,7 @@ pub fn new_base_crate(
|
||||
// Overrite the main.rs file
|
||||
let main_rs = include_str!("main.rs.template");
|
||||
// Replace all occurence of `#TARGET_NAME#` with the `dep_crate_name`
|
||||
let main_rs = main_rs.replace("#TARGET_NAME#", &dep_crate_name.replace("-", "_"));
|
||||
let main_rs = main_rs.replace("#TARGET_NAME#", &dep_crate_name.replace('-', "_"));
|
||||
fs::write("src/main.rs", main_rs).unwrap();
|
||||
|
||||
// Add dependencies to the Cargo.toml
|
||||
@ -54,7 +67,7 @@ pub fn new_base_crate(
|
||||
copy_manifest_configurations(base_crate_path);
|
||||
|
||||
// Get back to the original directory
|
||||
std::env::set_current_dir(&original_dir).unwrap();
|
||||
std::env::set_current_dir(original_dir).unwrap();
|
||||
}
|
||||
|
||||
fn add_manifest_dependency(crate_name: &str, crate_path: impl AsRef<Path>) {
|
||||
@ -65,6 +78,14 @@ fn add_manifest_dependency(crate_name: &str, crate_path: impl AsRef<Path>) {
|
||||
toml::from_str(&content).unwrap()
|
||||
};
|
||||
|
||||
// Check if "dependencies" key exists, create it if it doesn't
|
||||
if !manifest.contains_key("dependencies") {
|
||||
manifest.insert(
|
||||
"dependencies".to_string(),
|
||||
toml::Value::Table(toml::Table::new()),
|
||||
);
|
||||
}
|
||||
|
||||
let dependencies = manifest.get_mut("dependencies").unwrap();
|
||||
|
||||
let dep = toml::Table::from_str(&format!(
|
||||
|
@ -44,7 +44,7 @@ impl Bundle {
|
||||
#[allow(dead_code)]
|
||||
pub fn load(path: impl AsRef<Path>) -> Self {
|
||||
let manifest_file_path = path.as_ref().join("bundle.toml");
|
||||
let manifest_file_content = std::fs::read_to_string(&manifest_file_path).unwrap();
|
||||
let manifest_file_content = std::fs::read_to_string(manifest_file_path).unwrap();
|
||||
let manifest: BundleManifest = toml::from_str(&manifest_file_content).unwrap();
|
||||
// TODO: check integrity of the loaded bundle.
|
||||
Self {
|
||||
@ -142,7 +142,7 @@ impl Bundle {
|
||||
}
|
||||
let file_name = vm_image.path.file_name().unwrap();
|
||||
let copied_path = self.path.join(file_name);
|
||||
std::fs::copy(&vm_image.path, &copied_path).unwrap();
|
||||
std::fs::copy(&vm_image.path, copied_path).unwrap();
|
||||
self.manifest.vm_image = Some(AsterVmImage {
|
||||
path: file_name.into(),
|
||||
typ: vm_image.typ.clone(),
|
||||
@ -158,13 +158,13 @@ impl Bundle {
|
||||
}
|
||||
let file_name = aster_bin.path.file_name().unwrap();
|
||||
let copied_path = self.path.join(file_name);
|
||||
std::fs::copy(&aster_bin.path, &copied_path).unwrap();
|
||||
std::fs::copy(&aster_bin.path, copied_path).unwrap();
|
||||
self.manifest.aster_bin = Some(AsterBin {
|
||||
path: file_name.into(),
|
||||
typ: aster_bin.typ.clone(),
|
||||
version: aster_bin.version.clone(),
|
||||
sha256sum: aster_bin.sha256sum.clone(),
|
||||
stripped: aster_bin.stripped.clone(),
|
||||
stripped: aster_bin.stripped,
|
||||
});
|
||||
self.write_manifest_content();
|
||||
}
|
||||
@ -172,7 +172,7 @@ impl Bundle {
|
||||
fn write_manifest_content(&self) {
|
||||
let manifest_file_content = toml::to_string(&self.manifest).unwrap();
|
||||
let manifest_file_path = self.path.join("bundle.toml");
|
||||
std::fs::write(&manifest_file_path, manifest_file_content).unwrap();
|
||||
std::fs::write(manifest_file_path, manifest_file_content).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ pub struct TestArgs {
|
||||
pub struct CargoArgs {
|
||||
#[arg(
|
||||
long,
|
||||
help = "The Cargo build profile (built-in candidates are 'debug', 'release' and 'dev')",
|
||||
help = "The Cargo build profile (built-in candidates are 'debug', 'release', 'dev' and 'bench')",
|
||||
default_value = "dev"
|
||||
)]
|
||||
pub profile: String,
|
||||
|
@ -49,7 +49,7 @@ pub fn make_install_bzimage(
|
||||
setup_install_dir.join("bin").join("linux-bzimage-setup")
|
||||
};
|
||||
// Make the `bzImage`-compatible kernel image and place it in the boot directory.
|
||||
let install_path = install_dir.as_ref().join(&target_name);
|
||||
let install_path = install_dir.as_ref().join(target_name);
|
||||
info!("Building bzImage");
|
||||
println!("install_path: {:?}", install_path);
|
||||
make_bzimage(&install_path, image_type, &aster_elf.path, &setup_bin);
|
||||
|
@ -25,7 +25,7 @@ pub fn create_bootdev_image(
|
||||
|
||||
// Clear or make the iso dir.
|
||||
if iso_root.exists() {
|
||||
fs::remove_dir_all(&iso_root).unwrap();
|
||||
fs::remove_dir_all(iso_root).unwrap();
|
||||
}
|
||||
fs::create_dir_all(iso_root.join("boot").join("grub")).unwrap();
|
||||
|
||||
@ -41,12 +41,12 @@ pub fn create_bootdev_image(
|
||||
// Make the kernel image and place it in the boot directory.
|
||||
match protocol {
|
||||
BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => {
|
||||
make_install_bzimage(&iso_root.join("boot"), &target_dir, aster_bin, protocol);
|
||||
make_install_bzimage(iso_root.join("boot"), &target_dir, aster_bin, protocol);
|
||||
}
|
||||
BootProtocol::Multiboot | BootProtocol::Multiboot2 => {
|
||||
// Copy the kernel image to the boot directory.
|
||||
let target_path = iso_root.join("boot").join(&target_name);
|
||||
fs::copy(&aster_bin.path, &target_path).unwrap();
|
||||
fs::copy(&aster_bin.path, target_path).unwrap();
|
||||
}
|
||||
};
|
||||
|
||||
@ -63,7 +63,7 @@ pub fn create_bootdev_image(
|
||||
protocol,
|
||||
);
|
||||
let grub_cfg_path = iso_root.join("boot").join("grub").join("grub.cfg");
|
||||
fs::write(&grub_cfg_path, grub_cfg).unwrap();
|
||||
fs::write(grub_cfg_path, grub_cfg).unwrap();
|
||||
|
||||
// Make the boot device CDROM image using `grub-mkrescue`.
|
||||
let iso_path = &target_dir.as_ref().join(target_name.to_string() + ".iso");
|
||||
@ -109,11 +109,11 @@ fn generate_grub_cfg(
|
||||
let grub_cfg = grub_cfg.replace("#KERNEL_COMMAND_LINE#", kcmdline);
|
||||
// Replace the grub commands according to the protocol selected.
|
||||
let aster_bin_path_on_device = PathBuf::from("/boot")
|
||||
.join(&target_name)
|
||||
.join(target_name)
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap();
|
||||
let grub_cfg = match protocol {
|
||||
match protocol {
|
||||
BootProtocol::Multiboot => grub_cfg
|
||||
.replace("#GRUB_CMD_KERNEL#", "multiboot")
|
||||
.replace("#KERNEL#", &aster_bin_path_on_device)
|
||||
@ -147,9 +147,7 @@ fn generate_grub_cfg(
|
||||
"".to_owned()
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
grub_cfg
|
||||
}
|
||||
}
|
||||
|
||||
fn get_grub_mkrescue_version(grub_mkrescue: &PathBuf) -> String {
|
||||
|
@ -29,9 +29,9 @@ pub fn execute_build_command(config: &BuildConfig) {
|
||||
std::fs::create_dir_all(&osdk_target_directory).unwrap();
|
||||
}
|
||||
let target_info = get_current_crate_info();
|
||||
let bundle_path = osdk_target_directory.join(&target_info.name);
|
||||
let bundle_path = osdk_target_directory.join(target_info.name);
|
||||
|
||||
let _bundle = create_base_and_build(&bundle_path, &osdk_target_directory, &config);
|
||||
let _bundle = create_base_and_build(bundle_path, &osdk_target_directory, config);
|
||||
}
|
||||
|
||||
pub fn create_base_and_build(
|
||||
@ -43,12 +43,12 @@ pub fn create_base_and_build(
|
||||
new_base_crate(
|
||||
&base_crate_path,
|
||||
&get_current_crate_info().name,
|
||||
&get_current_crate_info().path,
|
||||
get_current_crate_info().path,
|
||||
);
|
||||
let original_dir = std::env::current_dir().unwrap();
|
||||
std::env::set_current_dir(&base_crate_path).unwrap();
|
||||
let bundle = do_build(&bundle_path, &osdk_target_directory, &config);
|
||||
std::env::set_current_dir(&original_dir).unwrap();
|
||||
let bundle = do_build(&bundle_path, &osdk_target_directory, config);
|
||||
std::env::set_current_dir(original_dir).unwrap();
|
||||
bundle
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ pub fn do_build(
|
||||
&osdk_target_directory,
|
||||
&aster_elf,
|
||||
config.manifest.initramfs.as_ref(),
|
||||
&config,
|
||||
config,
|
||||
);
|
||||
bundle.add_vm_image(&bootdev_image);
|
||||
}
|
||||
@ -105,6 +105,7 @@ fn build_kernel_elf(args: &CargoArgs) -> AsterBin {
|
||||
let target_json_path = PathBuf::from_str("x86_64-custom.json").unwrap();
|
||||
|
||||
let mut command = cargo();
|
||||
command.env_remove("RUSTUP_TOOLCHAIN");
|
||||
command.arg("build").arg("--target").arg(&target_json_path);
|
||||
command.args(COMMON_CARGO_ARGS);
|
||||
command.arg("--profile=".to_string() + &args.profile);
|
||||
@ -114,8 +115,8 @@ fn build_kernel_elf(args: &CargoArgs) -> AsterBin {
|
||||
process::exit(Errno::ExecuteCommand as _);
|
||||
}
|
||||
|
||||
let aster_bin_path = PathBuf::from(target_directory)
|
||||
.join(target_json_path.file_stem().unwrap().to_str().unwrap());
|
||||
let aster_bin_path =
|
||||
target_directory.join(target_json_path.file_stem().unwrap().to_str().unwrap());
|
||||
let aster_bin_path = if args.profile == "dev" {
|
||||
aster_bin_path.join("debug")
|
||||
} else {
|
||||
|
@ -77,7 +77,7 @@ fn create_osdk_manifest(cargo_metadata: &serde_json::Value) {
|
||||
// The apt OVMF repo installs to `/usr/share/OVMF`
|
||||
fs::write(
|
||||
osdk_manifest_path,
|
||||
r#"
|
||||
r#"\
|
||||
[boot]
|
||||
ovmf = "/usr/share/OVMF"
|
||||
[qemu]
|
||||
|
@ -18,10 +18,10 @@ pub fn execute_run_command(config: &RunConfig) {
|
||||
|
||||
// TODO: Check if the bundle is already built and compatible with the run configuration.
|
||||
let bundle = create_base_and_build(
|
||||
&default_bundle_directory,
|
||||
default_bundle_directory,
|
||||
&osdk_target_directory,
|
||||
&required_build_config,
|
||||
);
|
||||
|
||||
bundle.run(&config);
|
||||
bundle.run(config);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub fn execute_test_command(config: &TestConfig) {
|
||||
|
||||
let ktest_test_whitelist = match &config.test_name {
|
||||
Some(name) => format!(r#"Some(&["{}"])"#, name),
|
||||
None => format!(r#"None"#),
|
||||
None => r#"None"#.to_string(),
|
||||
};
|
||||
|
||||
let mut ktest_crate_whitelist = vec![current_crate.name];
|
||||
@ -54,12 +54,12 @@ pub static KTEST_CRATE_WHITELIST: Option<&[&str]> = Some(&{:#?});
|
||||
// Add `--cfg ktest` to RUSTFLAGS
|
||||
std::env::set_var("RUSTFLAGS", "--cfg ktest");
|
||||
let bundle = do_build(
|
||||
&default_bundle_directory,
|
||||
default_bundle_directory,
|
||||
&osdk_target_directory,
|
||||
&required_build_config,
|
||||
);
|
||||
std::env::remove_var("RUSTFLAGS");
|
||||
std::env::set_current_dir(&original_dir).unwrap();
|
||||
std::env::set_current_dir(original_dir).unwrap();
|
||||
|
||||
let required_run_config = RunConfig {
|
||||
manifest: required_build_config.manifest.clone(),
|
||||
|
@ -158,3 +158,16 @@ fn check_cfg(cfg: &str) {
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref SELECT_REGEX: Regex = Regex::new(r#"cfg\(select="(?P<select>\w+)"\)"#).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn extract_selection() {
|
||||
let text = "cfg(select=\"abc123_\")";
|
||||
let captures = SELECT_REGEX.captures(text).unwrap();
|
||||
let selection = captures.name("select").unwrap().as_str();
|
||||
assert_eq!(selection, "abc123_");
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ pub mod boot;
|
||||
pub mod manifest;
|
||||
pub mod qemu;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
use std::{fs, path::PathBuf, process};
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
@ -336,39 +339,3 @@ fn split_kcmd_args(kcmd_args: &mut Vec<String>) -> Vec<String> {
|
||||
init_args.remove(0);
|
||||
init_args
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_kcmd_args_test() {
|
||||
let mut kcmd_args = ["init=/bin/sh", "--", "sh", "-l"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<_> = ["sh", "-l"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
|
||||
let mut kcmd_args = ["init=/bin/sh", "--"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<String> = Vec::new();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
|
||||
let mut kcmd_args = ["init=/bin/sh", "shell=/bin/sh"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh", "shell=/bin/sh"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<String> = Vec::new();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
}
|
||||
|
152
osdk/src/config_manager/test/mod.rs
Normal file
152
osdk/src/config_manager/test/mod.rs
Normal file
@ -0,0 +1,152 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn split_kcmd_args_test() {
|
||||
let mut kcmd_args = ["init=/bin/sh", "--", "sh", "-l"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<_> = ["sh", "-l"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
|
||||
let mut kcmd_args = ["init=/bin/sh", "--"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh"].iter().map(ToString::to_string).collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<String> = Vec::new();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
|
||||
let mut kcmd_args = ["init=/bin/sh", "shell=/bin/sh"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
let init_args = split_kcmd_args(&mut kcmd_args);
|
||||
let expected_kcmd_args: Vec<_> = ["init=/bin/sh", "shell=/bin/sh"]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
assert_eq!(kcmd_args, expected_kcmd_args);
|
||||
let expecetd_init_args: Vec<String> = Vec::new();
|
||||
assert_eq!(init_args, expecetd_init_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_key_test() {
|
||||
let string1 = "init=/bin/init";
|
||||
let key = get_key(string1, "=").unwrap();
|
||||
assert_eq!(key.as_str(), "init");
|
||||
|
||||
let string2 = "-m 2G";
|
||||
let key = get_key(string2, " ").unwrap();
|
||||
assert_eq!(key.as_str(), "-m");
|
||||
|
||||
let string3 = "-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off";
|
||||
let key = get_key(string3, " ").unwrap();
|
||||
assert_eq!(key.as_str(), "-device");
|
||||
|
||||
let string4 = "-device";
|
||||
assert!(get_key(string4, " ").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_kv_array_test() {
|
||||
let qemu_args = &[
|
||||
"-enable-kvm",
|
||||
"-m 2G",
|
||||
"-device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||
];
|
||||
|
||||
let args = &["-m 100G", "-device ioh3420,id=pcie.0,chassis=1"];
|
||||
|
||||
let expected = &[
|
||||
"-enable-kvm",
|
||||
"-m 100G",
|
||||
"-device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||
"-device ioh3420,id=pcie.0,chassis=1",
|
||||
];
|
||||
|
||||
let mut array = qemu_args.iter().map(ToString::to_string).collect();
|
||||
let args = args.iter().map(ToString::to_string).collect();
|
||||
apply_kv_array(&mut array, &args, " ", &["-device"]);
|
||||
|
||||
let expected: Vec<_> = expected.iter().map(ToString::to_string).collect();
|
||||
assert_eq!(expected, array);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_osdk_manifest() {
|
||||
let content = include_str!("OSDK.toml.empty");
|
||||
let osdk_manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
assert!(osdk_manifest == TomlManifest::default());
|
||||
|
||||
let content = include_str!("OSDK.toml.full");
|
||||
let osdk_manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
assert!(osdk_manifest.boot.grub_mkrescue.unwrap() == PathBuf::from("/usr/bin/grub-mkrescue"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_osdk_manifest() {
|
||||
let manifest = TomlManifest::default();
|
||||
let contents = toml::to_string(&manifest).unwrap();
|
||||
fs::write("OSDK.toml", contents).unwrap();
|
||||
fs::remove_file("OSDK.toml").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_conditional_osdk_manifest() {
|
||||
let content = include_str!("OSDK.toml.conditional");
|
||||
let manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
println!("manifest = {:?}", manifest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conditional_manifest() {
|
||||
let toml_manifest: TomlManifest = {
|
||||
let content = include_str!("OSDK.toml.conditional");
|
||||
toml::from_str(content).unwrap()
|
||||
};
|
||||
|
||||
assert!(toml_manifest.qemu.cfg.is_some());
|
||||
assert!(toml_manifest
|
||||
.qemu
|
||||
.cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains_key(&String::from("cfg(select=\"intel_tdx\")")));
|
||||
assert!(toml_manifest
|
||||
.qemu
|
||||
.cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains_key(&String::from("cfg(select=\"iommu\")")));
|
||||
|
||||
// Default selection
|
||||
let selection: Option<&str> = None;
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest.qemu.args.contains(&String::from(
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off"
|
||||
)));
|
||||
|
||||
// Iommu
|
||||
let selection: Option<&str> = Some("iommu");
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest
|
||||
.qemu
|
||||
.args
|
||||
.contains(&String::from("-device ioh3420,id=pcie.0,chassis=1")));
|
||||
|
||||
// Tdx
|
||||
let selection: Option<&str> = Some("intel_tdx");
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest.qemu.args.is_empty());
|
||||
}
|
@ -10,7 +10,6 @@ pub enum Errno {
|
||||
ExecuteCommand = 5,
|
||||
BuildCrate = 6,
|
||||
RunBundle = 7,
|
||||
CreateBaseCrate = 8,
|
||||
}
|
||||
|
||||
/// Print error message to console
|
||||
|
@ -14,8 +14,6 @@ mod cli;
|
||||
mod commands;
|
||||
mod config_manager;
|
||||
mod error;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
mod utils;
|
||||
mod vm_image;
|
||||
|
||||
|
@ -1,153 +0,0 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
cli::CargoArgs,
|
||||
config_manager::{
|
||||
get_feature_strings,
|
||||
manifest::{OsdkManifest, TomlManifest, SELECT_REGEX},
|
||||
},
|
||||
test::utils::{assert_success, cargo_osdk, create_workspace},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn deserialize_osdk_manifest() {
|
||||
let content = include_str!("OSDK.toml.empty");
|
||||
let osdk_manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
assert!(osdk_manifest == TomlManifest::default());
|
||||
|
||||
let content = include_str!("OSDK.toml.full");
|
||||
let osdk_manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
assert!(osdk_manifest.boot.grub_mkrescue.unwrap() == PathBuf::from("/usr/bin/grub-mkrescue"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_osdk_manifest() {
|
||||
let manifest = TomlManifest::default();
|
||||
let contents = toml::to_string(&manifest).unwrap();
|
||||
fs::write("OSDK.toml", contents).unwrap();
|
||||
fs::remove_file("OSDK.toml").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_conditional_osdk_manifest() {
|
||||
let content = include_str!("OSDK.toml.conditional");
|
||||
let manifest: TomlManifest = toml::from_str(content).unwrap();
|
||||
println!("manifest = {:?}", manifest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_manifest() {
|
||||
let workspace = "workspace_foo";
|
||||
let kernel_name: &str = "foo_os";
|
||||
create_workspace(workspace, &[kernel_name]);
|
||||
create_osdk_kernel(kernel_name, workspace);
|
||||
let cargo_args = CargoArgs::default();
|
||||
cargo_osdk_build(PathBuf::from(workspace).join(kernel_name), &cargo_args);
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_manifest_conditional() {
|
||||
let workspace = "workspace_bar";
|
||||
let kernel_name: &str = "bar_os";
|
||||
create_workspace(workspace, &[kernel_name]);
|
||||
create_osdk_kernel_with_features(kernel_name, &["intel_tdx", "iommu"], workspace);
|
||||
let contents = include_str!("OSDK.toml.conditional");
|
||||
let path = PathBuf::from(workspace).join("OSDK.toml");
|
||||
fs::write(path, contents).unwrap();
|
||||
|
||||
let cargo_args = CargoArgs {
|
||||
profile: "release".to_string(),
|
||||
features: vec![String::from("iommu")],
|
||||
};
|
||||
cargo_osdk_build(PathBuf::from(workspace).join(kernel_name), &cargo_args);
|
||||
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
fn create_osdk_kernel(name: &str, current_dir: &str) {
|
||||
let output = cargo_osdk(&["new", "--kernel", name])
|
||||
.current_dir(current_dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_success(&output);
|
||||
}
|
||||
|
||||
fn create_osdk_kernel_with_features(name: &str, features: &[&str], current_dir: &str) {
|
||||
create_osdk_kernel(name, current_dir);
|
||||
let manifest_path = PathBuf::from(current_dir).join(name).join("Cargo.toml");
|
||||
let contents = fs::read_to_string(&manifest_path).unwrap();
|
||||
let mut manifest: toml::Table = toml::from_str(&contents).unwrap();
|
||||
|
||||
let mut features_table = toml::Table::new();
|
||||
for feature in features {
|
||||
features_table.insert(feature.to_string(), toml::Value::Array(Vec::new()));
|
||||
}
|
||||
manifest.insert("features".to_string(), toml::Value::Table(features_table));
|
||||
|
||||
fs::write(&manifest_path, manifest.to_string()).unwrap();
|
||||
}
|
||||
|
||||
fn cargo_osdk_build<P: AsRef<Path>>(current_dir: P, cargo_args: &CargoArgs) {
|
||||
let args = get_feature_strings(cargo_args);
|
||||
let mut command = cargo_osdk(&["build"]);
|
||||
command.args(args);
|
||||
command.current_dir(current_dir);
|
||||
let output = command.output().unwrap();
|
||||
assert_success(&output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conditional_manifest() {
|
||||
let toml_manifest: TomlManifest = {
|
||||
let content = include_str!("OSDK.toml.conditional");
|
||||
toml::from_str(content).unwrap()
|
||||
};
|
||||
|
||||
assert!(toml_manifest.qemu.cfg.is_some());
|
||||
assert!(toml_manifest
|
||||
.qemu
|
||||
.cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains_key(&String::from("cfg(select=\"intel_tdx\")")));
|
||||
assert!(toml_manifest
|
||||
.qemu
|
||||
.cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains_key(&String::from("cfg(select=\"iommu\")")));
|
||||
|
||||
// Default selection
|
||||
let selection: Option<&str> = None;
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest.qemu.args.contains(&String::from(
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off"
|
||||
)));
|
||||
|
||||
// Iommu
|
||||
let selection: Option<&str> = Some("iommu");
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest
|
||||
.qemu
|
||||
.args
|
||||
.contains(&String::from("-device ioh3420,id=pcie.0,chassis=1")));
|
||||
|
||||
// Tdx
|
||||
let selection: Option<&str> = Some("intel_tdx");
|
||||
let manifest = OsdkManifest::from_toml_manifest(toml_manifest.clone(), selection);
|
||||
assert!(manifest.qemu.args.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_selection() {
|
||||
let text = "cfg(select=\"abc123_\")";
|
||||
let captures = SELECT_REGEX.captures(text).unwrap();
|
||||
let selection = captures.name("select").unwrap().as_str();
|
||||
assert_eq!(selection, "abc123_");
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use crate::config_manager::{apply_kv_array, get_key};
|
||||
mod manifest;
|
||||
|
||||
#[test]
|
||||
fn get_key_test() {
|
||||
let string1 = "init=/bin/init";
|
||||
let key = get_key(string1, "=").unwrap();
|
||||
assert_eq!(key.as_str(), "init");
|
||||
|
||||
let string2 = "-m 2G";
|
||||
let key = get_key(string2, " ").unwrap();
|
||||
assert_eq!(key.as_str(), "-m");
|
||||
|
||||
let string3 = "-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off";
|
||||
let key = get_key(string3, " ").unwrap();
|
||||
assert_eq!(key.as_str(), "-device");
|
||||
|
||||
let string4 = "-device";
|
||||
assert!(get_key(string4, " ").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_kv_array_test() {
|
||||
let qemu_args = &[
|
||||
"-enable-kvm",
|
||||
"-m 2G",
|
||||
"-device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||
];
|
||||
|
||||
let args = &["-m 100G", "-device ioh3420,id=pcie.0,chassis=1"];
|
||||
|
||||
let expected = &[
|
||||
"-enable-kvm",
|
||||
"-m 100G",
|
||||
"-device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||
"-device ioh3420,id=pcie.0,chassis=1",
|
||||
];
|
||||
|
||||
let mut array = qemu_args.iter().map(ToString::to_string).collect();
|
||||
let args = args.iter().map(ToString::to_string).collect();
|
||||
apply_kv_array(&mut array, &args, " ", &["-device"]);
|
||||
|
||||
let expected: Vec<_> = expected.iter().map(ToString::to_string).collect();
|
||||
assert_eq!(expected, array);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! The crate unit test module
|
||||
|
||||
mod cli;
|
||||
mod commands;
|
||||
mod config_manager;
|
||||
mod utils;
|
@ -83,13 +83,13 @@ pub fn get_current_crate_info() -> CrateInfo {
|
||||
let default_member = default_members[0]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.split(" ")
|
||||
.split(' ')
|
||||
.collect::<Vec<&str>>();
|
||||
let name = default_member[0].to_string();
|
||||
let version = default_member[1].to_string();
|
||||
let path = default_member[2]
|
||||
.trim_start_matches("(path+file://")
|
||||
.trim_end_matches(")")
|
||||
.trim_end_matches(')')
|
||||
.to_string();
|
||||
CrateInfo {
|
||||
name,
|
||||
|
10
osdk/tests/bin.rs
Normal file
10
osdk/tests/bin.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! This module contains tests that invokes the `osdk` binary and checks the output.
|
||||
//! Please be sure the the `osdk` binary is built and available in the `target/debug`
|
||||
//! directory before running these tests.
|
||||
|
||||
mod cli;
|
||||
mod commands;
|
||||
mod integration;
|
||||
mod util;
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use super::utils::*;
|
||||
use crate::util::*;
|
||||
|
||||
#[test]
|
||||
fn cli_help_message() {
|
@ -1,15 +1,18 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::fs::remove_dir_all;
|
||||
use std::{fs::remove_dir_all, path::Path};
|
||||
|
||||
use crate::test::utils::*;
|
||||
use crate::util::*;
|
||||
|
||||
const KERNEL_NAME: &str = "myos";
|
||||
const LIB_NAME: &str = "my_module";
|
||||
|
||||
#[test]
|
||||
fn create_kernel_in_workspace() {
|
||||
const WORKSPACE_NAME: &str = "kernel_workspace";
|
||||
const WORKSPACE_NAME: &str = "/tmp/kernel_workspace";
|
||||
if Path::new(WORKSPACE_NAME).exists() {
|
||||
remove_dir_all(WORKSPACE_NAME).unwrap();
|
||||
}
|
||||
create_workspace(WORKSPACE_NAME, &[KERNEL_NAME]);
|
||||
let mut cargo_osdk = cargo_osdk(["new", "--kernel", KERNEL_NAME]);
|
||||
cargo_osdk.current_dir(WORKSPACE_NAME);
|
||||
@ -20,7 +23,10 @@ fn create_kernel_in_workspace() {
|
||||
|
||||
#[test]
|
||||
fn create_lib_in_workspace() {
|
||||
const WORKSPACE_NAME: &str = "lib_workspace";
|
||||
const WORKSPACE_NAME: &str = "/tmp/lib_workspace";
|
||||
if Path::new(WORKSPACE_NAME).exists() {
|
||||
remove_dir_all(WORKSPACE_NAME).unwrap();
|
||||
}
|
||||
create_workspace(WORKSPACE_NAME, &[LIB_NAME]);
|
||||
let mut cargo_osdk = cargo_osdk(["new", LIB_NAME]);
|
||||
cargo_osdk.current_dir(WORKSPACE_NAME);
|
||||
@ -31,7 +37,11 @@ fn create_lib_in_workspace() {
|
||||
|
||||
#[test]
|
||||
fn create_two_crates_in_workspace() {
|
||||
const WORKSPACE_NAME: &str = "my_workspace";
|
||||
const WORKSPACE_NAME: &str = "/tmp/my_workspace";
|
||||
if Path::new(WORKSPACE_NAME).exists() {
|
||||
remove_dir_all(WORKSPACE_NAME).unwrap();
|
||||
}
|
||||
|
||||
create_workspace(WORKSPACE_NAME, &[LIB_NAME]);
|
||||
// Create lib crate
|
||||
let mut command = cargo_osdk(["new", LIB_NAME]);
|
16
osdk/tests/integration/OSDK.toml.conditional
Normal file
16
osdk/tests/integration/OSDK.toml.conditional
Normal file
@ -0,0 +1,16 @@
|
||||
[qemu]
|
||||
args = [
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off",
|
||||
"-device virtio-serial-pci,disable-legacy=on,disable-modern=off"
|
||||
]
|
||||
|
||||
[qemu.'cfg(select="intel_tdx")']
|
||||
|
||||
[qemu.'cfg(select="iommu")']
|
||||
args = [
|
||||
"-device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
|
||||
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
|
||||
"-device intel-iommu,intremap=on,device-iotlb=on",
|
||||
"-device ioh3420,id=pcie.0,chassis=1",
|
||||
]
|
76
osdk/tests/integration/mod.rs
Normal file
76
osdk/tests/integration/mod.rs
Normal file
@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::util::{assert_success, cargo_osdk, create_workspace};
|
||||
|
||||
#[test]
|
||||
fn build_with_default_manifest() {
|
||||
let workspace = "/tmp/workspace_foo";
|
||||
if Path::new(workspace).exists() {
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
let kernel_name: &str = "foo_os";
|
||||
create_workspace(workspace, &[kernel_name]);
|
||||
create_osdk_kernel(kernel_name, workspace);
|
||||
cargo_osdk_build(PathBuf::from(workspace).join(kernel_name), &[]);
|
||||
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_with_conditional_manifest() {
|
||||
let workspace = "/tmp/workspace_bar";
|
||||
if Path::new(workspace).exists() {
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
let kernel_name: &str = "bar_os";
|
||||
create_workspace(workspace, &[kernel_name]);
|
||||
create_osdk_kernel_with_features(kernel_name, &["intel_tdx", "iommu"], workspace);
|
||||
let contents = include_str!("OSDK.toml.conditional");
|
||||
let path = PathBuf::from(workspace).join("OSDK.toml");
|
||||
fs::write(path, contents).unwrap();
|
||||
|
||||
cargo_osdk_build(
|
||||
PathBuf::from(workspace).join(kernel_name),
|
||||
&["--profile", "release", "--features", "iommu"],
|
||||
);
|
||||
|
||||
fs::remove_dir_all(workspace).unwrap();
|
||||
}
|
||||
|
||||
fn create_osdk_kernel(name: &str, current_dir: &str) {
|
||||
let output = cargo_osdk(&["new", "--kernel", name])
|
||||
.current_dir(current_dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_success(&output);
|
||||
}
|
||||
|
||||
fn create_osdk_kernel_with_features(name: &str, features: &[&str], current_dir: &str) {
|
||||
create_osdk_kernel(name, current_dir);
|
||||
let manifest_path = PathBuf::from(current_dir).join(name).join("Cargo.toml");
|
||||
let contents = fs::read_to_string(&manifest_path).unwrap();
|
||||
let mut manifest: toml::Table = toml::from_str(&contents).unwrap();
|
||||
|
||||
let mut features_table = toml::Table::new();
|
||||
for feature in features {
|
||||
features_table.insert(feature.to_string(), toml::Value::Array(Vec::new()));
|
||||
}
|
||||
manifest.insert("features".to_string(), toml::Value::Table(features_table));
|
||||
|
||||
fs::write(&manifest_path, manifest.to_string()).unwrap();
|
||||
}
|
||||
|
||||
fn cargo_osdk_build<P: AsRef<Path>>(current_dir: P, args: &[&str]) {
|
||||
let mut command = cargo_osdk(&["build"]);
|
||||
command.args(args);
|
||||
command.current_dir(current_dir);
|
||||
let output = command.output().unwrap();
|
||||
assert_success(&output);
|
||||
}
|
@ -33,6 +33,7 @@ pub fn assert_stdout_contains_msg(output: &Output, msg: &str) {
|
||||
}
|
||||
|
||||
pub fn create_workspace(workspace_name: &str, members: &[&str]) {
|
||||
// Create Cargo.toml
|
||||
let mut table = toml::Table::new();
|
||||
let workspace_table = {
|
||||
let mut table = toml::Table::new();
|
||||
@ -58,8 +59,14 @@ pub fn create_workspace(workspace_name: &str, members: &[&str]) {
|
||||
let content = table.to_string();
|
||||
fs::write(manefest_path, content).unwrap();
|
||||
|
||||
// Create OSDK.toml
|
||||
let osdk_manifest_path = PathBuf::from(workspace_name).join("OSDK.toml");
|
||||
fs::write(osdk_manifest_path, "").unwrap();
|
||||
|
||||
// Create rust-toolchain.toml which is synced with the Asterinas' toolchain
|
||||
let rust_toolchain_path = PathBuf::from(workspace_name).join("rust-toolchain.toml");
|
||||
let content = include_str!("../../../rust-toolchain.toml");
|
||||
fs::write(rust_toolchain_path, content).unwrap();
|
||||
}
|
||||
|
||||
pub fn add_member_to_workspace(workspace: impl AsRef<Path>, new_member: &str) {
|
Reference in New Issue
Block a user