mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 16:33: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
|
id: unit_test
|
||||||
run: cd osdk && cargo build && RUSTUP_HOME=/root/.rustup cargo 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.
|
# Test OSDK in the same environment
|
||||||
osdk_doc_env_test:
|
# as described in the OSDK User Guide in the Asterinas Book.
|
||||||
|
osdk-doc-env-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
container: asterinas/osdk:0.4.0
|
container: asterinas/osdk:0.4.0
|
||||||
@ -44,6 +45,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Unit test
|
- name: Unit test
|
||||||
id: 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
|
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
|
@cargo clean
|
||||||
@cd docs && mdbook clean
|
@cd docs && mdbook clean
|
||||||
@make --no-print-directory -C regression 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`:
|
Then, add the following content to `Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/Cargo.toml}}
|
||||||
[workspace]
|
|
||||||
members = []
|
|
||||||
resolver = "2"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Creating a kernel project and a library project
|
## 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
|
This function will calculate the available memory
|
||||||
after booting:
|
after booting:
|
||||||
|
|
||||||
```rust
|
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/mymodule/src/lib.rs}}
|
||||||
pub fn available_memory() -> usize {
|
|
||||||
let regions = aster_frame::boot::memory_regions();
|
|
||||||
regions.iter().map(|region| region.len()).sum()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, add a dependency on `mymodule` to `myos/Cargo.toml`:
|
Then, add a dependency on `mymodule` to `myos/Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/myos/Cargo.toml}}
|
||||||
[dependencies]
|
|
||||||
mymodule = { path = "../mymodule" }
|
|
||||||
```
|
|
||||||
|
|
||||||
In `myos/src/lib.rs`,
|
In `myos/src/lib.rs`,
|
||||||
modify the main function as follows.
|
modify the file content as follows.
|
||||||
This function will call the function from `mymodule`:
|
This main function will call the function from `mymodule`:
|
||||||
|
|
||||||
```rust
|
{{#include ../../../../osdk/tests/examples_in_book/work_in_workspace_templates/myos/src/lib.rs}}
|
||||||
#[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);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building and Running the kernel
|
## Building and Running the kernel
|
||||||
|
|
||||||
|
2
osdk/Cargo.lock
generated
2
osdk/Cargo.lock
generated
@ -128,7 +128,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo-osdk"
|
name = "cargo-osdk"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -6,5 +6,6 @@
|
|||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod examples_in_book;
|
||||||
mod integration;
|
mod integration;
|
||||||
mod util;
|
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.
|
# This image is for the OSDK GitHub CI.
|
||||||
# The environment is consistent with the one
|
# The environment is consistent with the one
|
||||||
# described in the OSDK User Guide section of the Asterinas Book.
|
# 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
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user