Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
- name: Unit Test
run: make test

# this job is for compilation test, it will make sure all aaarch64, riscv64, loongarch64 can be compiled successfully
# this job is for compilation test, it will make sure all aarch64, riscv64, loongarch64 can be compiled successfully
# there is no actual running in this job
build:
name: build
Expand Down Expand Up @@ -143,6 +143,45 @@ jobs:
run: make

# this job is for booting root and nonroot inside qemu for system test
# curently waiting for another person to add his system test here
# systemtest:
# ...
systemtest:
name: systemtest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# aarch64
- arch: aarch64
rustc_target: aarch64-unknown-none
features: "platform_qemu,gicv3"
board: "qemu"
# currently supports only "platform_qemu,gicv3"
# Because other features need to be customized scripts
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.rustc_target }}
components: rust-src
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y qemu-system-aarch64 qemu-system-riscv64 gdb-multiarch llvm-dev libclang-dev wget expect device-tree-compiler p7zip-full
cargo install --version 0.3.0 cargo-binutils
cargo install cargo-xbuild
- name: Set up environment variables
run: |
echo "ARCH=${{ matrix.arch }}" >> $GITHUB_ENV
echo "FEATURES=${{ matrix.features }}" >> $GITHUB_ENV
echo "BOARD=${{ matrix.board }}" >> $GITHUB_ENV
- name: Compile DTB
run: |
./test/tcompiledtb.sh
- name: Download rootfs and image
run: |
./test/tdownload_all.sh
- name: Run Tests
run: |
./test/tstart.sh
13 changes: 12 additions & 1 deletion scripts/qemu-aarch64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,15 @@ $(hvisor_bin): elf
$(OBJCOPY) $(hvisor_elf) --strip-all -O binary $(hvisor_bin).tmp && \
mkimage -n hvisor_img -A arm64 -O linux -C none -T kernel -a 0x40400000 \
-e 0x40400000 -d $(hvisor_bin).tmp $(hvisor_bin) && \
rm -rf $(hvisor_bin).tmp
rm -rf $(hvisor_bin).tmp

QEMU_ARGS += -netdev type=user,id=net1
QEMU_ARGS += -device virtio-net-pci,netdev=net1,disable-legacy=on,disable-modern=off,iommu_platform=on

# QEMU_ARGS += -device pci-testdev

QEMU_ARGS += -netdev type=user,id=net2
QEMU_ARGS += -device virtio-net-pci,netdev=net2,disable-legacy=on,disable-modern=off,iommu_platform=on

QEMU_ARGS += -netdev type=user,id=net3
QEMU_ARGS += -device virtio-net-pci,netdev=net3,disable-legacy=on,disable-modern=off,iommu_platform=on
9 changes: 9 additions & 0 deletions test/tcompiledtb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
set -e # Exit immediately if any command fails

# Compile device tree in a subshell to maintain working directory
(
cd images/aarch64/devicetree &&
make all
)
# Subshell automatically returns to original directory after execution
160 changes: 160 additions & 0 deletions test/tdownload_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/bin/bash

# Split archive + independent image download/merge/unzip script
# Usage: ./download_all.sh

# Configuration parameters
RELEASE_NAME="v2025.03.01"
BASE_URL="https://github.com/CHonghaohao/hvisor_env_img/releases/download/$RELEASE_NAME"

# Split archive configuration (must be in order)
ZIP_PARTS=(
"rootfs1.zip.001"
"rootfs1.zip.002"
"rootfs1.zip.003"
)
ZIP_OUTPUT="rootfs1.zip"
UNZIP_DIR="images/aarch64/virtdisk" # Extraction directory

# Independent image configuration
TARGET_DIR="images/aarch64/kernel" # Target directory path
IMAGE_FILE="${TARGET_DIR}/Image" # Full image file path
IMAGE_URL="$BASE_URL/Image"

# Download control parameters
MAX_RETRIES=3 # Max retries per file
PARALLEL_DOWNLOADS=1 # Parallel downloads (improves speed for large files)
TIMEOUT=3600 # Timeout per file (seconds)

# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'

# Check dependencies
check_dependencies() {
local missing=()
command -v unzip >/dev/null 2>&1 || missing+=("unzip")
command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || missing+=("curl/wget")

if [ ${#missing[@]} -gt 0 ]; then
echo -e "${RED}Error: Missing dependencies - ${missing[*]}${NC}"
exit 1
fi
}

# Download function with progress display
download_file() {
local url="$1"
local output="$2"
local retries=0

while [ $retries -lt $MAX_RETRIES ]; do
if [ -f "$output" ]; then
local current_size=$(stat -c%s "$output" 2>/dev/null || echo 0)
if command -v curl >/dev/null 2>&1; then
curl -C - -# -L --retry 2 --max-time $TIMEOUT -o "$output" "$url" && return 0
elif command -v wget >/dev/null 2>&1; then
wget -c -q --show-progress --tries=2 --timeout=$TIMEOUT -O "$output" "$url" && return 0
fi
else
if command -v curl >/dev/null 2>&1; then
curl -# -L --retry 2 --max-time $TIMEOUT -o "$output" "$url" && return 0
elif command -v wget >/dev/null 2>&1; then
wget -q --show-progress --tries=2 --timeout=$TIMEOUT -O "$output" "$url" && return 0
fi
fi

((retries++))
echo -e "${YELLOW}Retry ($retries/$MAX_RETRIES): $output${NC}"
sleep 2
done

echo -e "${RED}Download failed: $url${NC}"
return 1
}

# Main process
main() {
check_dependencies

# Check if final files exist
if [ -d "$UNZIP_DIR" ] && [ -f "$IMAGE_FILE" ]; then
echo -e "${GREEN}All files already exist:\n- Image file: $IMAGE_FILE\n- Extracted directory: $UNZIP_DIR${NC}"
exit 0
fi

# Parallel download split files
echo -e "${YELLOW}Starting split file downloads (parallel: $PARALLEL_DOWNLOADS)...${NC}"
for part in "${ZIP_PARTS[@]}"; do
local url="$BASE_URL/$part"
local output="$part"

if [ -f "$output" ]; then
echo -e "${GREEN}Part already exists: $output${NC}"
continue
fi

((i=i%PARALLEL_DOWNLOADS)); ((i++==0)) && wait
(
if download_file "$url" "$output"; then
echo -e "${GREEN}Download completed: $output${NC}"
else
exit 1
fi
) &
done
wait

# Verify split file integrity
for part in "${ZIP_PARTS[@]}"; do
if [ ! -f "$part" ]; then
echo -e "${RED}Missing part: $part${NC}"
exit 1
fi
done

# Merge split files
if [ ! -f "$ZIP_OUTPUT" ]; then
echo -e "${YELLOW}Merging split files -> $ZIP_OUTPUT ...${NC}"
cat "${ZIP_PARTS[@]}" > "$ZIP_OUTPUT" || {
echo -e "${RED}Merge failed!${NC}"
exit 1
}
else
echo -e "${GREEN}Using existing merged file: $ZIP_OUTPUT${NC}"
fi

# Unzip files
if [ ! -d "$UNZIP_DIR" ]; then
echo -e "${YELLOW}Extracting to directory: $UNZIP_DIR ...${NC}"
unzip -q "$ZIP_OUTPUT" -d "$UNZIP_DIR" || {
echo -e "${RED}Extraction failed! Possible reasons:\n1. Password protected\n2. Corrupted file${NC}"
exit 1
}
fi

# Download independent image
echo -e "${YELLOW}Downloading image file: $IMAGE_FILE ...${NC}"
mkdir -p "$TARGET_DIR" || {
echo -e "${RED}Failed to create directory: $TARGET_DIR${NC}"
exit 1
}

if [ -f "$IMAGE_FILE" ]; then
echo -e "${GREEN}Image already exists: $IMAGE_FILE${NC}"
else
download_file "$IMAGE_URL" "$IMAGE_FILE" || {
echo -e "${RED}Download failed: $IMAGE_FILE${NC}"
exit 1
}
fi

# Final verification
echo -e "\n${GREEN}All components ready: "
echo -e " - Image file: $(ls -lh $IMAGE_FILE)"
echo -e " - Extracted directory: $(du -sh $UNZIP_DIR)${NC}"
}

main
2 changes: 2 additions & 0 deletions test/testcase/tc_insmod.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hvisor: loading out-of-tree module taints kernel.
hvisor init done!!!
35 changes: 35 additions & 0 deletions test/testcase/tc_ls.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
1.c
2
2.c
Image
a.out
byte-unixbench-5.1.3
hvisor
hvisor.ko
linux2.dtb
linux2.json
linux2.sh
linux2_back.dtb
linux3.dtb
linux3.json
linux3.sh
lmbench-3.0-a9
log.txt
ltp
main.ko
msi_engine.ko
nohup.out
pci
pciutils-3.13.0
rootfs2.ext4
screen_linux2.sh
setup.sh
sysbench-1.0.20
test
test.zip
test_nohup1.txt
virtio.json
virtio_cfg.json
virtio_cfg2.json
virtio_cfg3.json
å
1 change: 1 addition & 0 deletions test/testcase/tc_pwd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/home/arm64
1 change: 1 addition & 0 deletions test/testcase/tc_zone1_ls.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
zone1.txt
2 changes: 2 additions & 0 deletions test/testcase/tc_zone1_start.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
non root region mmap succeed!
hvisor: calling hypercall to start zone
2 changes: 2 additions & 0 deletions test/testcase/tc_zone_list1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| zone_id | cpus | name |
| 0 | 0, 1 | root-linux |
3 changes: 3 additions & 0 deletions test/testcase/tc_zone_list2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| zone_id | cpus | name |
| 0 | 0, 1 | root-linux |
| 1 | 2, 3 | linux2 |
53 changes: 53 additions & 0 deletions test/textract_dmesg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash

# Define a function to process dmesg output
extract_dmesg() {
local output_file="$1" # The first parameter is output file path

# Capture dmesg output
local dmesg_output=$(dmesg)

# Process output with awk
echo "$dmesg_output" | awk '
BEGIN {
RS="\n"; # Set record separator to newline
}
{
# Remove leading [] timestamps
sub(/^\[[^]]*\] /, "")
# Store processed lines in array
lines[NR] = $0
}
END {
# Initialize counters and output arrays
count = 0
output_lines[1] = ""
output_lines[2] = ""
# Traverse from last line backwards
for (i = NR; i > 0; i--) {
if (lines[i] !~ /random: fast init done/) {
# If line does not contain - random: fast init done -
if (count < 2) {
# Store line in output array
output_lines[2-count] = lines[i]
count++
}
}
# Break loop when count reaches 2
if (count >= 2) {
break
}
}
# Output lines in correct order
if (output_lines[1] != "") {
printf "%s\n", output_lines[1]
}
if (output_lines[2] != "") {
printf "%s\n", output_lines[2]
}
}
' > "$output_file"
}

# Call function with output file path
extract_dmesg "$1"
Loading