diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 019bee124..2717cf9c2 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -6,7 +6,7 @@ branding: inputs: # Test Configuration auto_test: - description: 'Test type (general, osdk, boot, syscall, test)' + description: 'Test type (general, osdk, boot, syscall, test, xfstests)' required: true release: description: 'Whether to run in release mode' @@ -45,6 +45,9 @@ inputs: boot_protocol: description: 'Boot protocol (linux-efi-handover64/multiboot/multiboot2/linux-legacy32)' required: false + mem: + description: 'Guest memory size' + required: false runs: using: 'composite' @@ -91,6 +94,7 @@ runs: [[ -n "${{ inputs.syscall_test_suite }}" ]] && CMD+=" SYSCALL_TEST_SUITE=${{ inputs.syscall_test_suite }}" [[ -n "${{ inputs.syscall_test_workdir }}" ]] && CMD+=" SYSCALL_TEST_WORKDIR=${{ inputs.syscall_test_workdir }}" [[ -n "${{ inputs.boot_protocol }}" ]] && CMD+=" BOOT_PROTOCOL=${{ inputs.boot_protocol }}" + [[ -n "${{ inputs.mem }}" ]] && CMD+=" MEM=${{ inputs.mem }}" echo "Executing: $CMD" eval $CMD diff --git a/.github/workflows/test_x86.yml b/.github/workflows/test_x86.yml index 2481bcea0..515599cab 100644 --- a/.github/workflows/test_x86.yml +++ b/.github/workflows/test_x86.yml @@ -109,6 +109,7 @@ jobs: smp: ${{ matrix.smp }} netdev: ${{ matrix.netdev || 'tap' }} scheme: ${{ matrix.scheme }} + mem: ${{ matrix.mem }} extra_blocklists: ${{ matrix.extra_blocklists }} syscall_test_suite: 'ltp' syscall_test_workdir: ${{ matrix.syscall_test_workdir }} @@ -124,11 +125,27 @@ jobs: smp: ${{ matrix.smp }} netdev: ${{ matrix.netdev || 'tap' }} scheme: ${{ matrix.scheme }} + mem: ${{ matrix.mem }} extra_blocklists: ${{ matrix.extra_blocklists }} syscall_test_suite: 'gvisor' syscall_test_workdir: ${{ matrix.syscall_test_workdir }} boot_protocol: ${{ matrix.boot_protocol || 'linux-efi-handover64' }} + xfstests: + runs-on: ubuntu-4-cores-150GB-ssd + container: + image: asterinas/asterinas:0.17.0-20260114 + options: --device=/dev/kvm --privileged + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Run xfstests + uses: ./.github/actions/test + with: + auto_test: 'xfstests' + release: true + mem: '12G' + osdk-test: runs-on: ubuntu-latest strategy: diff --git a/Makefile b/Makefile index 7bac4db33..2eea0a453 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ NO_DEFAULT_FEATURES ?= 0 COVERAGE ?= 0 # Specify whether to build regression tests under `test/initramfs/src/apps`. ENABLE_BASIC_TEST ?= false +# Specify whether to build xfstests. +ENABLE_XFSTESTS ?= false # Specify the primary system console (supported: tty0, ttyS0, hvc0). # - tty0: The active virtual terminal (VT). # - ttyS0: The serial (UART) terminal. @@ -104,6 +106,9 @@ ENABLE_BASIC_TEST := true endif CARGO_OSDK_BUILD_ARGS += --kcmd-args="INTEL_TDX=$(INTEL_TDX)" CARGO_OSDK_BUILD_ARGS += --init-args="/test/run_general_test.sh" +else ifeq ($(AUTO_TEST), xfstests) +ENABLE_XFSTESTS := true +CARGO_OSDK_BUILD_ARGS += --init-args="/xfstests/run_xfstests.sh -R /xfstests/run.list" else ifeq ($(AUTO_TEST), boot) ENABLE_BASIC_TEST := true CARGO_OSDK_BUILD_ARGS += --init-args="/test/boot_hello.sh" @@ -315,6 +320,9 @@ ifeq ($(AUTO_TEST), syscall) else ifeq ($(AUTO_TEST), test) @tail --lines 100 qemu.log | grep -q "^All general tests passed." \ || (echo "General test failed" && exit 1) +else ifeq ($(AUTO_TEST), xfstests) + @tail --lines 100 qemu.log | grep -q "^All xfstests passed." \ + || (echo "Xfstests failed" && exit 1) else ifeq ($(AUTO_TEST), boot) @tail --lines 100 qemu.log | grep -q "^Successfully booted." \ || (echo "Boot test failed" && exit 1) diff --git a/test/initramfs/Makefile b/test/initramfs/Makefile index c6d195f63..988a465c3 100644 --- a/test/initramfs/Makefile +++ b/test/initramfs/Makefile @@ -10,6 +10,7 @@ ENABLE_BASIC_TEST ?= false # - asterinas: Define both `__asterinas__` and `__linux__`. Tests may fail in Linux. # - linux: Define only `__linux__`. Tests may fail in Asterinas. BASIC_TEST_PLATFORM ?= asterinas +ENABLE_XFSTESTS ?= false DNS_SERVER ?= none # Set Nix's cached tarballs to be live for a longer period of time (30 days) to avoid network traffics. # Nix's default value is rather small (1 hour or 3600 seconds). @@ -28,6 +29,8 @@ INITRAMFS_COMPRESSED := true endif EXT2_IMAGE := $(BUILD_DIR)/ext2.img EXFAT_IMAGE := $(BUILD_DIR)/exfat.img +XFSTESTS_TEST_IMAGE := $(BUILD_DIR)/xfstests_test.img +XFSTESTS_SCRATCH_IMAGE := $(BUILD_DIR)/xfstests_scratch.img # Include benchmark, if BENCHMARK is set. ifeq ($(BENCHMARK), none) @@ -56,6 +59,8 @@ ifeq ($(OSDK_TARGET_ARCH), loongarch64) build: $(EXT2_IMAGE) $(EXFAT_IMAGE) @echo "For loongarch, we generate a fake initramfs to successfully test or build." @touch $(INITRAMFS_IMAGE) +else ifeq ($(ENABLE_XFSTESTS), true) +build: $(INITRAMFS_IMAGE) $(EXT2_IMAGE) $(EXFAT_IMAGE) $(XFSTESTS_TEST_IMAGE) $(XFSTESTS_SCRATCH_IMAGE) else build: $(INITRAMFS_IMAGE) $(EXT2_IMAGE) $(EXFAT_IMAGE) endif @@ -69,6 +74,7 @@ $(INITRAMFS_IMAGE): $(INITRAMFS) --argstr basicTestPlatform $(BASIC_TEST_PLATFORM) \ --arg enableBenchmark $(ENABLE_BENCHMARK) \ --arg enableSyscallTest $(ENABLE_SYSCALL_TEST) \ + --arg enableXfstests $(ENABLE_XFSTESTS) \ --argstr syscallTestSuite $(SYSCALL_TEST_SUITE) \ --argstr syscallTestWorkDir $(SYSCALL_TEST_WORKDIR) \ --argstr dnsServer ${DNS_SERVER} \ @@ -86,6 +92,7 @@ $(INITRAMFS): --argstr basicTestPlatform $(BASIC_TEST_PLATFORM) \ --arg enableBenchmark $(ENABLE_BENCHMARK) \ --arg enableSyscallTest $(ENABLE_SYSCALL_TEST) \ + --arg enableXfstests $(ENABLE_XFSTESTS) \ --argstr syscallTestSuite $(SYSCALL_TEST_SUITE) \ --argstr syscallTestWorkDir $(SYSCALL_TEST_WORKDIR) \ --argstr dnsServer ${DNS_SERVER} \ @@ -176,6 +183,16 @@ $(EXFAT_IMAGE): @fallocate -l 64M $(EXFAT_IMAGE) @mkfs.exfat $(EXFAT_IMAGE) +$(XFSTESTS_TEST_IMAGE): + @mkdir -p $(BUILD_DIR) + @fallocate -l 12G $(XFSTESTS_TEST_IMAGE) + @mkfs.ext2 $(XFSTESTS_TEST_IMAGE) + +$(XFSTESTS_SCRATCH_IMAGE): + @mkdir -p $(BUILD_DIR) + @fallocate -l 12G $(XFSTESTS_SCRATCH_IMAGE) + @mkfs.ext2 $(XFSTESTS_SCRATCH_IMAGE) + .PHONY: format format: @$(MAKE) --no-print-directory -C src/apps format diff --git a/test/initramfs/nix/default.nix b/test/initramfs/nix/default.nix index 02c779e3a..8fe87d495 100644 --- a/test/initramfs/nix/default.nix +++ b/test/initramfs/nix/default.nix @@ -1,7 +1,7 @@ { target ? "x86_64", enableBasicTest ? false, basicTestPlatform ? "asterinas" , enableBenchmark ? false, enableSyscallTest ? false, syscallTestSuite ? "ltp" , syscallTestWorkDir ? "/tmp", dnsServer ? "none", smp ? 1 -, initramfsCompressed ? true, }: +, initramfsCompressed ? true, enableXfstests ? false, }: let crossSystem.config = if target == "x86_64" then "x86_64-unknown-linux-gnu" @@ -26,13 +26,16 @@ in rec { apps = pkgs.callPackage ./apps.nix { testPlatform = basicTestPlatform; }; busybox = pkgs.busybox; benchmark = pkgs.callPackage ./benchmark { }; + xfstests = pkgs.callPackage ./fs/xfstests.nix { }; syscall = pkgs.callPackage ./syscall { inherit smp; testSuite = syscallTestSuite; workDir = syscallTestWorkDir; }; + initramfs = pkgs.callPackage ./initramfs.nix { inherit busybox; + xfstests = if enableXfstests then xfstests else null; apps = if enableBasicTest then apps else null; benchmark = if enableBenchmark then benchmark else null; syscall = if enableSyscallTest then syscall else null; diff --git a/test/initramfs/nix/fs/xfstests.nix b/test/initramfs/nix/fs/xfstests.nix new file mode 100644 index 000000000..8e0684135 --- /dev/null +++ b/test/initramfs/nix/fs/xfstests.nix @@ -0,0 +1,87 @@ +{ lib, stdenvNoCC, pkgs }: + +stdenvNoCC.mkDerivation { + name = "xfstests-package"; + + buildCommand = '' + # Create output directory structure + mkdir -p $out/xfstests + + # Copy xfstests test suite from Nix package + cp -r ${pkgs.xfstests}/lib/xfstests/* $out/xfstests/ + + # Create wrapper script for running xfstests + cat > $out/xfstests/run_xfstests.sh << 'EOF' + #!/bin/sh + set -e + export PATH=\ + ${pkgs.perl}/bin:\ + ${pkgs.bash}/bin:\ + ${pkgs.gnugrep}/bin:\ + ${pkgs.gnused}/bin:\ + ${pkgs.gawk}/bin:\ + ${pkgs.coreutils}/bin:\ + ${pkgs.findutils}/bin:\ + ${pkgs.util-linux}/bin:\ + ${pkgs.util-linux}/sbin:\ + ${pkgs.bc}/bin:\ + ${pkgs.kmod}/bin:\ + ${pkgs.kmod}/sbin:\ + ${pkgs.xfsprogs}/bin:\ + ${pkgs.xfsprogs}/sbin:\ + ${pkgs.e2fsprogs}/bin:\ + ${pkgs.e2fsprogs}/sbin:\ + /bin:\ + /usr/bin:\ + /sbin:\ + /usr/sbin + cd /xfstests + RUNLIST_FILE="" + ARGS="" + while [ $# -gt 0 ]; do + case "$1" in + -R|--runlist) + RUNLIST_FILE="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + ARGS="$ARGS \"$1\"" + shift + ;; + esac + done + for arg in "$@"; do + ARGS="$ARGS \"$arg\"" + done + if [ -n "$RUNLIST_FILE" ]; then + if [ ! -f "$RUNLIST_FILE" ]; then + echo "Run list file not found: $RUNLIST_FILE" >&2 + exit 2 + fi + while IFS= read -r test; do + case "$test" in + ""|\#*) continue ;; + esac + ARGS="$ARGS \"$test\"" + done < "$RUNLIST_FILE" + fi + # shellcheck disable=SC2086 + eval ./check $ARGS + echo "All xfstests passed." + EOF + chmod +x $out/xfstests/run_xfstests.sh + + # Copy local.config from source directory + cp ${./../../src/fs/xfstests/local.config} $out/xfstests/local.config + + # Copy block.list into xfstests directory + cp ${./../../src/fs/xfstests/block.list} $out/xfstests/block.list + + # Copy run.list into xfstests directory + cp ${./../../src/fs/xfstests/run.list} $out/xfstests/run.list + ''; +} diff --git a/test/initramfs/nix/initramfs.nix b/test/initramfs/nix/initramfs.nix index a2a0c095a..71041a8d7 100644 --- a/test/initramfs/nix/initramfs.nix +++ b/test/initramfs/nix/initramfs.nix @@ -1,5 +1,5 @@ -{ lib, stdenvNoCC, fetchFromGitHub, hostPlatform, writeClosure, busybox, apps -, benchmark, syscall, dnsServer, pkgs }: +{ lib, stdenvNoCC, fetchFromGitHub, hostPlatform, writeClosure, busybox +, xfstests, apps, benchmark, syscall, dnsServer, pkgs }: let etc = lib.fileset.toSource { root = ./../src/etc; @@ -15,7 +15,9 @@ let resolv_conf = pkgs.callPackage ./resolv_conf.nix { dnsServer = dnsServer; }; # Whether the initramfs should include evtest, a common tool to debug input devices (`/dev/input/eventX`) is_evtest_included = false; + all_pkgs = [ busybox etc resolv_conf ] + ++ lib.optionals (xfstests != null) [ xfstests ] ++ lib.optionals (apps != null) [ apps.package ] ++ lib.optionals (benchmark != null) [ benchmark.package ] ++ lib.optionals (syscall != null) [ syscall.package ] @@ -24,7 +26,8 @@ in stdenvNoCC.mkDerivation { name = "initramfs"; buildCommand = '' mkdir -p $out/{dev,etc,root,usr,opt,tmp,var,proc,sys} - mkdir -p $out/{benchmark,test,ext2,exfat} + mkdir -p $out/{benchmark,test,xfstests,ext2,exfat} + mkdir -p $out/xfstests/{test,scratch} mkdir -p $out/usr/{bin,sbin,lib,lib64,local} ln -sfn usr/bin $out/bin ln -sfn usr/sbin $out/sbin @@ -61,6 +64,11 @@ in stdenvNoCC.mkDerivation { cp -L ${gvisor_libs}/libm.so.6 $out/lib/x86_64-linux-gnu/libm.so.6 ''} + ${lib.optionalString (xfstests != null) '' + # Copy xfstests package content + cp -r ${xfstests}/xfstests/* $out/xfstests/ + ''} + # Use `writeClosure` to retrieve all dependencies of the specified packages. # This will generate a text file containing the complete closure of the packages, # including the packages themselves. diff --git a/test/initramfs/src/etc/profile.d/init.sh b/test/initramfs/src/etc/profile.d/init.sh index b964c646d..b36094579 100644 --- a/test/initramfs/src/etc/profile.d/init.sh +++ b/test/initramfs/src/etc/profile.d/init.sh @@ -9,4 +9,12 @@ mount -t proc none /proc mount -t cgroup2 none /sys/fs/cgroup mount -t configfs none /sys/kernel/config mount -t ext2 /dev/vda /ext2 -mount -t exfat /dev/vdb /exfat \ No newline at end of file +mount -t exfat /dev/vdb /exfat + +# Mount xfstests images if they exist +if [ -b /dev/vdc ]; then + mount -t ext2 /dev/vdc /xfstests/test +fi +if [ -b /dev/vdd ]; then + mount -t ext2 /dev/vdd /xfstests/scratch +fi diff --git a/test/initramfs/src/fs/xfstests/block.list b/test/initramfs/src/fs/xfstests/block.list new file mode 100644 index 000000000..826f0a8ee --- /dev/null +++ b/test/initramfs/src/fs/xfstests/block.list @@ -0,0 +1,23 @@ +generic/015 +generic/027 +generic/084 +generic/204 +generic/226 +generic/247 +generic/251 +generic/274 +generic/275 +generic/315 +generic/344 +generic/391 +generic/426 +generic/446 +generic/464 +generic/466 +generic/467 +generic/477 +generic/524 +generic/558 +generic/590 +generic/591 +generic/604 diff --git a/test/initramfs/src/fs/xfstests/local.config b/test/initramfs/src/fs/xfstests/local.config new file mode 100644 index 000000000..33c70755e --- /dev/null +++ b/test/initramfs/src/fs/xfstests/local.config @@ -0,0 +1,15 @@ +export FSTYP=ext2 + +export TEST_DEV=/dev/vdc +export TEST_DIR=/xfstests/test + +export SCRATCH_DEV=/dev/vdd +export SCRATCH_MNT=/xfstests/scratch + +export MOUNT_OPTIONS="-o noload,noacl" +export EXT_MOUNT_OPTIONS="-o noload,noacl" + +export FSTYP_HAS_NON_DEFAULT_OPTS=0 +export SELINUX_MOUNT_OPTIONS=" " + +export MKFS_OPTIONS="-F" diff --git a/test/initramfs/src/fs/xfstests/run.list b/test/initramfs/src/fs/xfstests/run.list new file mode 100644 index 000000000..1fca4d4fd --- /dev/null +++ b/test/initramfs/src/fs/xfstests/run.list @@ -0,0 +1,54 @@ +generic/001 +generic/002 +generic/005 +generic/006 +generic/007 +generic/013 +generic/014 +generic/023 +generic/028 +generic/035 +generic/069 +generic/074 +generic/089 +generic/109 +generic/124 +generic/126 +generic/129 +generic/132 +generic/141 +generic/184 +generic/213 +generic/221 +generic/224 +generic/236 +generic/246 +generic/248 +generic/249 +generic/269 +generic/273 +generic/308 +generic/309 +generic/312 +generic/313 +generic/320 +generic/339 +generic/340 +generic/346 +generic/360 +generic/401 +generic/406 +generic/428 +generic/437 +generic/438 +generic/443 +generic/453 +generic/488 +generic/532 +generic/568 +generic/609 +generic/615 +generic/619 +generic/696 +generic/701 +generic/707 diff --git a/tools/qemu_args.sh b/tools/qemu_args.sh index 1be720403..2894dcf0d 100755 --- a/tools/qemu_args.sh +++ b/tools/qemu_args.sh @@ -14,12 +14,14 @@ # - CONSOLE: "hvc0" to enable virtio console; # - SMP: number of CPUs; # - MEM: amount of memory, e.g. "8G"; -# - VNC_PORT: VNC port, default is "42". +# - VNC_PORT: VNC port, default is "42"; +# - ENABLE_XFSTESTS: "true" or "false", whether to attach xfstests images. OVMF=${OVMF:-"on"} VHOST=${VHOST:-"off"} VSOCK=${VSOCK:-"off"} NETDEV=${NETDEV:-"user"} +ENABLE_XFSTESTS=${ENABLE_XFSTESTS:-"false"} CONSOLE=${CONSOLE:-"hvc0"} SSH_RAND_PORT=${SSH_PORT:-$(shuf -i 1024-65535 -n 1)} @@ -100,6 +102,14 @@ COMMON_QEMU_ARGS="\ -drive if=none,format=raw,id=x1,file=./test/initramfs/build/exfat.img \ " +# Add xfstests drives if enabled +if [ "$ENABLE_XFSTESTS" = "true" ]; then + COMMON_QEMU_ARGS="$COMMON_QEMU_ARGS \ + -drive if=none,format=raw,id=x2,file=./test/initramfs/build/xfstests_test.img \ + -drive if=none,format=raw,id=x3,file=./test/initramfs/build/xfstests_scratch.img \ +" +fi + if [ "$1" = "iommu" ]; then if [ "$OVMF" = "off" ]; then echo "Warning: OVMF is off, enabling it for IOMMU support." 1>&2 @@ -118,6 +128,17 @@ QEMU_ARGS="\ -machine q35,kernel-irqchip=split \ -device virtio-blk-pci,bus=pcie.0,addr=0x6,drive=x0,serial=vext2,disable-legacy=on,disable-modern=off,queue-size=64,num-queues=1,request-merging=off,backend_defaults=off,discard=off,write-zeroes=off,event_idx=off,indirect_desc=off,queue_reset=off$IOMMU_DEV_EXTRA \ -device virtio-blk-pci,bus=pcie.0,addr=0x7,drive=x1,serial=vexfat,disable-legacy=on,disable-modern=off,queue-size=64,num-queues=1,request-merging=off,backend_defaults=off,discard=off,write-zeroes=off,event_idx=off,indirect_desc=off,queue_reset=off$IOMMU_DEV_EXTRA \ +" + +# Add xfstests devices if enabled +if [ "$ENABLE_XFSTESTS" = "true" ]; then + QEMU_ARGS="$QEMU_ARGS \ + -device virtio-blk-pci,bus=pcie.0,addr=0x8,drive=x2,serial=vxfstest,disable-legacy=on,disable-modern=off,queue-size=64,num-queues=1,request-merging=off,backend_defaults=off,discard=off,write-zeroes=off,event_idx=off,indirect_desc=off,queue_reset=off$IOMMU_DEV_EXTRA \ + -device virtio-blk-pci,bus=pcie.0,addr=0x9,drive=x3,serial=vxfsscratch,disable-legacy=on,disable-modern=off,queue-size=64,num-queues=1,request-merging=off,backend_defaults=off,discard=off,write-zeroes=off,event_idx=off,indirect_desc=off,queue_reset=off$IOMMU_DEV_EXTRA \ +" +fi + +QEMU_ARGS="$QEMU_ARGS \ -device virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off$VIRTIO_NET_FEATURES$IOMMU_DEV_EXTRA \ -device virtio-serial-pci,disable-legacy=on,disable-modern=off$IOMMU_DEV_EXTRA \ $CONSOLE_ARGS \ @@ -131,6 +152,17 @@ MICROVM_QEMU_ARGS="\ -no-user-config \ -device virtio-blk-device,drive=x0,serial=vext2 \ -device virtio-blk-device,drive=x1,serial=vexfat \ +" + +# Add xfstests devices for microvm if enabled +if [ "$ENABLE_XFSTESTS" = "true" ]; then + MICROVM_QEMU_ARGS="$MICROVM_QEMU_ARGS \ + -device virtio-blk-device,drive=x2,serial=vxfstest \ + -device virtio-blk-device,drive=x3,serial=vxfsscratch \ +" +fi + +MICROVM_QEMU_ARGS="$MICROVM_QEMU_ARGS \ -device virtio-keyboard-device \ -device virtio-net-device,netdev=net01 \ -device virtio-serial-device \