mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-15 00:06:47 +00:00
171 lines
5.3 KiB
Rust
171 lines
5.3 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
//! Test the `run` command
|
|
|
|
use crate::util::is_tdx_enabled;
|
|
|
|
const WORKSPACE: &str = "/tmp/kernel_test_workspace/run_command";
|
|
|
|
mod workspace {
|
|
use crate::util::*;
|
|
use std::{
|
|
fs::{create_dir_all, remove_dir_all},
|
|
path::Path,
|
|
};
|
|
|
|
fn create_kernel_in_workspace(workspace: &str, kernel_name: &str) {
|
|
let os_dir = Path::new(workspace).join(kernel_name);
|
|
if os_dir.exists() {
|
|
remove_dir_all(&os_dir).unwrap();
|
|
}
|
|
let mut cargo_osdk_new = cargo_osdk(["new", "--kernel", kernel_name]);
|
|
cargo_osdk_new.current_dir(workspace);
|
|
cargo_osdk_new
|
|
.ok()
|
|
.expect("Failed to create kernel project");
|
|
let manifest_path = os_dir.join("Cargo.toml");
|
|
depends_on_local_ostd(manifest_path);
|
|
}
|
|
|
|
fn prepare_workspace(workspace: &str) {
|
|
if !Path::new(workspace).exists() {
|
|
create_dir_all(workspace).unwrap();
|
|
}
|
|
}
|
|
#[derive(Debug)]
|
|
pub struct WorkSpace {
|
|
pub workspace: String,
|
|
pub kernel_name: String,
|
|
}
|
|
impl WorkSpace {
|
|
pub fn new(workspace: &str, kernel_name: &str) -> Self {
|
|
prepare_workspace(workspace);
|
|
create_kernel_in_workspace(workspace, kernel_name);
|
|
Self {
|
|
workspace: workspace.to_string(),
|
|
kernel_name: kernel_name.to_string(),
|
|
}
|
|
}
|
|
|
|
pub fn os_dir(&self) -> String {
|
|
Path::new(&self.workspace)
|
|
.join(self.kernel_name.clone())
|
|
.to_string_lossy()
|
|
.to_string()
|
|
}
|
|
}
|
|
impl Drop for WorkSpace {
|
|
fn drop(&mut self) {
|
|
remove_dir_all(&self.os_dir()).unwrap();
|
|
}
|
|
}
|
|
}
|
|
|
|
mod qemu_gdb_feature {
|
|
use super::*;
|
|
use crate::util::cargo_osdk;
|
|
use assert_cmd::Command;
|
|
use std::{path::Path, thread::sleep};
|
|
|
|
#[test]
|
|
fn basic_debug() {
|
|
// Test skipped because TDX is enabled.
|
|
if is_tdx_enabled() {
|
|
return;
|
|
}
|
|
let workspace = workspace::WorkSpace::new(WORKSPACE, "basic_debug");
|
|
let unix_socket = {
|
|
let path = Path::new(&workspace.os_dir()).join("qemu-gdb-sock");
|
|
path.to_string_lossy().to_string()
|
|
};
|
|
|
|
let mut instance = cargo_osdk([
|
|
"run",
|
|
"--gdb-server",
|
|
format!("addr={},wait-client", unix_socket.as_str()).as_str(),
|
|
]);
|
|
instance.current_dir(&workspace.os_dir());
|
|
|
|
let sock = unix_socket.clone();
|
|
let _gdb = std::thread::spawn(move || {
|
|
gdb_continue_via_unix_sock(&sock);
|
|
});
|
|
|
|
let output = instance
|
|
.output()
|
|
.expect("Failed to wait for QEMU GDB instance");
|
|
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
|
assert!(stdout.contains("Hello world from guest kernel!"));
|
|
}
|
|
|
|
fn gdb_continue_via_unix_sock(socket: &str) {
|
|
let sock_file = Path::new(&socket);
|
|
while !sock_file.exists() {
|
|
sleep(std::time::Duration::from_secs(1));
|
|
}
|
|
gdb_continue_via(socket);
|
|
}
|
|
|
|
fn gdb_continue_via(addr: &str) {
|
|
let mut gdb = Command::new("gdb");
|
|
gdb.args(["-ex", format!("target remote {}", addr).as_str()]);
|
|
gdb.write_stdin("\n")
|
|
.write_stdin("quit\n")
|
|
.write_stdin("y\n");
|
|
gdb.assert().success();
|
|
}
|
|
mod vsc {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn vsc_launch_file() {
|
|
// Test skipped because TDX is enabled.
|
|
if is_tdx_enabled() {
|
|
return;
|
|
}
|
|
let kernel_name = "vsc_launch_file";
|
|
let workspace = workspace::WorkSpace::new(WORKSPACE, kernel_name);
|
|
let addr = ":50001";
|
|
|
|
let mut instance = cargo_osdk([
|
|
"run",
|
|
"--gdb-server",
|
|
format!("wait-client,vscode,addr={}", addr).as_str(),
|
|
]);
|
|
instance.current_dir(&workspace.os_dir());
|
|
|
|
let dir = workspace.os_dir();
|
|
let bin_file_path = Path::new(&workspace.os_dir())
|
|
.join("target")
|
|
.join("osdk")
|
|
.join(kernel_name)
|
|
.join(format!("{}-osdk-bin", kernel_name));
|
|
let _gdb = std::thread::spawn(move || {
|
|
while !bin_file_path.exists() {
|
|
sleep(std::time::Duration::from_secs(1));
|
|
}
|
|
assert!(
|
|
check_launch_file_existence(&dir),
|
|
"VSCode launch config file is not found during debugging session"
|
|
);
|
|
gdb_continue_via(&addr);
|
|
});
|
|
|
|
let output = instance
|
|
.output()
|
|
.expect("Failed to wait for QEMU GDB instance");
|
|
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
|
assert!(stdout.contains("Hello world from guest kernel!"));
|
|
assert!(
|
|
!check_launch_file_existence(&workspace.workspace),
|
|
"VSCode launch config file should be removed after debugging session"
|
|
);
|
|
}
|
|
|
|
fn check_launch_file_existence(workspace: &str) -> bool {
|
|
let launch_file = Path::new(workspace).join(".vscode/launch.json");
|
|
launch_file.exists()
|
|
}
|
|
}
|
|
}
|