mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 00:43:24 +00:00
Add OSDK demos in Asterinas Book in OSDK integration test
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
11ff0521e7
commit
63499c675c
11
.github/workflows/osdk_test.yml
vendored
11
.github/workflows/osdk_test.yml
vendored
@ -32,8 +32,9 @@ jobs:
|
||||
id: unit_test
|
||||
run: cd osdk && cargo build && RUSTUP_HOME=/root/.rustup cargo test
|
||||
|
||||
# Test OSDK in the same environment as described in the OSDK User Guide in the Asterinas Book.
|
||||
osdk_doc_env_test:
|
||||
# Test OSDK in the same environment
|
||||
# as described in the OSDK User Guide in the Asterinas Book.
|
||||
osdk-doc-env-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
container: asterinas/osdk:0.4.0
|
||||
@ -44,6 +45,10 @@ jobs:
|
||||
|
||||
- name: Unit test
|
||||
id: unit_test
|
||||
# Github's actions/checkout@v4 will result in a new user (not root)
|
||||
# and thus not using the Rust environment we set up in the container.
|
||||
# So the RUSTUP_HOME needs to be set here.
|
||||
# This only breaks when we invoke Cargo in the integration test of OSDK
|
||||
# since the OSDK toolchain is not nightly.
|
||||
run: cd osdk && cargo build && RUSTUP_HOME=/root/.rustup cargo test
|
||||
|
||||
# TODO: test the demos in Asterinas Book
|
||||
|
1
Makefile
1
Makefile
@ -186,3 +186,4 @@ clean:
|
||||
@cargo clean
|
||||
@cd docs && mdbook clean
|
||||
@make --no-print-directory -C regression clean
|
||||
@rm -f $(CARGO_OSDK)
|
||||
|
@ -17,11 +17,7 @@ touch Cargo.toml
|
||||
|
||||
Then, add the following content to `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[workspace]
|
||||
members = []
|
||||
resolver = "2"
|
||||
```
|
||||
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/Cargo.toml}}
|
||||
|
||||
## Creating a kernel project and a library project
|
||||
|
||||
@ -60,31 +56,17 @@ Next, add the following function to `mymodule/src/lib.rs`.
|
||||
This function will calculate the available memory
|
||||
after booting:
|
||||
|
||||
```rust
|
||||
pub fn available_memory() -> usize {
|
||||
let regions = aster_frame::boot::memory_regions();
|
||||
regions.iter().map(|region| region.len()).sum()
|
||||
}
|
||||
```
|
||||
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/mymodule/src/lib.rs}}
|
||||
|
||||
Then, add a dependency on `mymodule` to `myos/Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
mymodule = { path = "../mymodule" }
|
||||
```
|
||||
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/myos/Cargo.toml}}
|
||||
|
||||
In `myos/src/lib.rs`,
|
||||
modify the main function as follows.
|
||||
This function will call the function from `mymodule`:
|
||||
modify the file content as follows.
|
||||
This main function will call the function from `mymodule`:
|
||||
|
||||
```rust
|
||||
#[aster_main]
|
||||
fn kernel_main() {
|
||||
let avail_mem_as_mb = mymodule::available_memory() / 1_000_000;
|
||||
println!("The available memory is {} MB", avail_mem_as_mb);
|
||||
}
|
||||
```
|
||||
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/myos/src/lib.rs}}
|
||||
|
||||
## Building and Running the kernel
|
||||
|
||||
|
2
osdk/Cargo.lock
generated
2
osdk/Cargo.lock
generated
@ -128,7 +128,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-osdk"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"assert_cmd",
|
||||
"clap",
|
||||
|
@ -6,5 +6,6 @@
|
||||
|
||||
mod cli;
|
||||
mod commands;
|
||||
mod examples_in_book;
|
||||
mod integration;
|
||||
mod util;
|
||||
|
46
osdk/tests/examples_in_book/create_os_projects.rs
Normal file
46
osdk/tests/examples_in_book/create_os_projects.rs
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::util::cargo_osdk;
|
||||
|
||||
#[test]
|
||||
fn create_a_kernel_project() {
|
||||
let workdir = "/tmp";
|
||||
let kernel = "my_foo_os";
|
||||
|
||||
let kernel_path = PathBuf::from(workdir).join(kernel);
|
||||
|
||||
if kernel_path.exists() {
|
||||
fs::remove_dir_all(&kernel_path).unwrap();
|
||||
}
|
||||
|
||||
cargo_osdk(&["new", "--kernel", kernel])
|
||||
.current_dir(workdir)
|
||||
.unwrap();
|
||||
|
||||
assert!(kernel_path.is_dir());
|
||||
assert!(kernel_path.join("Cargo.toml").is_file());
|
||||
assert!(kernel_path.join("rust-toolchain.toml").is_file());
|
||||
|
||||
fs::remove_dir_all(&kernel_path).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_a_library_project() {
|
||||
let workdir = "/tmp";
|
||||
let module = "my_foo_module";
|
||||
|
||||
let module_path = PathBuf::from(workdir).join(module);
|
||||
if module_path.exists() {
|
||||
fs::remove_dir_all(&module_path).unwrap();
|
||||
}
|
||||
|
||||
cargo_osdk(&["new", module]).current_dir(workdir).unwrap();
|
||||
|
||||
assert!(module_path.is_dir());
|
||||
assert!(module_path.join("Cargo.toml").is_file());
|
||||
assert!(module_path.join("rust-toolchain.toml").is_file());
|
||||
|
||||
fs::remove_dir_all(&module_path).unwrap();
|
||||
}
|
7
osdk/tests/examples_in_book/mod.rs
Normal file
7
osdk/tests/examples_in_book/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! This module contains the demos in OSDK section in the Asterinas Book.
|
||||
|
||||
mod create_os_projects;
|
||||
mod test_and_run_projects;
|
||||
mod work_in_workspace;
|
56
osdk/tests/examples_in_book/test_and_run_projects.rs
Normal file
56
osdk/tests/examples_in_book/test_and_run_projects.rs
Normal file
@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::util::cargo_osdk;
|
||||
|
||||
#[test]
|
||||
fn create_and_run_kernel() {
|
||||
let work_dir = "/tmp";
|
||||
let os_name = "myos";
|
||||
|
||||
let os_dir = PathBuf::from(work_dir).join(os_name);
|
||||
|
||||
if os_dir.exists() {
|
||||
fs::remove_dir_all(&os_dir).unwrap();
|
||||
}
|
||||
|
||||
let mut command = cargo_osdk(&["new", "--kernel", os_name]);
|
||||
command.current_dir(work_dir);
|
||||
command.ok().unwrap();
|
||||
|
||||
let mut command = cargo_osdk(&["build"]);
|
||||
command.current_dir(&os_dir);
|
||||
command.ok().unwrap();
|
||||
|
||||
let mut command = cargo_osdk(&["run"]);
|
||||
command.current_dir(&os_dir);
|
||||
let output = command.output().unwrap();
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
assert!(stdout.contains("Hello world from guest kernel!"));
|
||||
|
||||
fs::remove_dir_all(&os_dir).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_and_test_library() {
|
||||
let work_dir = "/tmp";
|
||||
let module_name = "mymodule";
|
||||
|
||||
let module_dir = PathBuf::from(work_dir).join(module_name);
|
||||
|
||||
if module_dir.exists() {
|
||||
fs::remove_dir_all(&module_dir).unwrap();
|
||||
}
|
||||
|
||||
let mut command = cargo_osdk(&["new", module_name]);
|
||||
command.current_dir(work_dir);
|
||||
command.ok().unwrap();
|
||||
|
||||
let mut command = cargo_osdk(&["test"]);
|
||||
command.current_dir(&module_dir);
|
||||
command.output().unwrap();
|
||||
|
||||
fs::remove_dir_all(&module_dir).unwrap();
|
||||
}
|
75
osdk/tests/examples_in_book/work_in_workspace.rs
Normal file
75
osdk/tests/examples_in_book/work_in_workspace.rs
Normal file
@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, OpenOptions},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use crate::util::cargo_osdk;
|
||||
|
||||
#[test]
|
||||
fn work_in_workspace() {
|
||||
let workdir = "/tmp";
|
||||
let workspace_name = "myworkspace";
|
||||
|
||||
// Create workspace and its manifest
|
||||
let workspace_dir = PathBuf::from(workdir).join(workspace_name);
|
||||
if workspace_dir.is_dir() {
|
||||
fs::remove_dir_all(&workspace_dir).unwrap();
|
||||
}
|
||||
|
||||
fs::create_dir_all(&workspace_dir).unwrap();
|
||||
env::set_current_dir(&workspace_dir).unwrap();
|
||||
|
||||
let workspace_toml = include_str!("work_in_workspace_templates/Cargo.toml");
|
||||
fs::write(workspace_dir.join("Cargo.toml"), workspace_toml).unwrap();
|
||||
|
||||
// Create a kernel project and a library project
|
||||
let kernel = "myos";
|
||||
let module = "mymodule";
|
||||
cargo_osdk(&["new", "--kernel", kernel]).ok().unwrap();
|
||||
cargo_osdk(&["new", module]).ok().unwrap();
|
||||
|
||||
// Add a test function to mymodule/src/lib.rs
|
||||
let module_src_path = workspace_dir.join(module).join("src").join("lib.rs");
|
||||
assert!(module_src_path.is_file());
|
||||
let mut module_src_file = OpenOptions::new()
|
||||
.append(true)
|
||||
.open(&module_src_path)
|
||||
.unwrap();
|
||||
module_src_file
|
||||
.write_all(include_bytes!("work_in_workspace_templates/mymodule/src/lib.rs"))
|
||||
.unwrap();
|
||||
module_src_file.flush().unwrap();
|
||||
|
||||
// Add dependency to myos/Cargo.toml
|
||||
let kernel_manifest_path = workspace_dir.join(kernel).join("Cargo.toml");
|
||||
assert!(kernel_manifest_path.is_file());
|
||||
let mut kernel_manifest_file = OpenOptions::new()
|
||||
.append(true)
|
||||
.open(&kernel_manifest_path)
|
||||
.unwrap();
|
||||
kernel_manifest_file
|
||||
.write_all(include_bytes!("work_in_workspace_templates/myos/Cargo.toml"))
|
||||
.unwrap();
|
||||
kernel_manifest_file.flush().unwrap();
|
||||
|
||||
// Add the content to myos/src/lib.rs
|
||||
let kernel_src_path = workspace_dir.join(kernel).join("src").join("lib.rs");
|
||||
assert!(kernel_src_path.is_file());
|
||||
fs::write(&kernel_src_path, include_str!("work_in_workspace_templates/myos/src/lib.rs")).unwrap();
|
||||
|
||||
// Run subcommand build & run
|
||||
cargo_osdk(&["build"]).ok().unwrap();
|
||||
let output = cargo_osdk(&["run"]).output().unwrap();
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
assert!(stdout.contains("The available memory is"));
|
||||
|
||||
// Run subcommand test
|
||||
cargo_osdk(&["test"]).output().unwrap();
|
||||
|
||||
// Remove the directory
|
||||
fs::remove_dir_all(&workspace_dir).unwrap();
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
[workspace]
|
||||
members = []
|
||||
resolver = "2"
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
pub fn available_memory() -> usize {
|
||||
let regions = aster_frame::boot::memory_regions();
|
||||
regions.iter().map(|region| region.len()).sum()
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[dependencies]
|
||||
mymodule = { path = "../mymodule" }
|
@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use aster_frame::prelude::*;
|
||||
|
||||
#[aster_main]
|
||||
fn kernel_main() {
|
||||
let avail_mem_as_mb = mymodule::available_memory() / 1_000_000;
|
||||
println!("The available memory is {} MB", avail_mem_as_mb);
|
||||
}
|
@ -3,6 +3,15 @@
|
||||
# This image is for the OSDK GitHub CI.
|
||||
# The environment is consistent with the one
|
||||
# described in the OSDK User Guide section of the Asterinas Book.
|
||||
#
|
||||
# TODO: We should build the Asterinas image based on the OSDK image
|
||||
# since Asterinas is managed by OSDK itself.
|
||||
# However, currently, these two images have different contents.
|
||||
# The main distinction is that
|
||||
# QEMU, grub, and OVMF in the OSDK image are installed via apt,
|
||||
# while these tools in the Asterinas image are built from source.
|
||||
# Some boot methods in Asterinas only function properly
|
||||
# when using the tools that are built from source.
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
|
Reference in New Issue
Block a user