1#!/usr/bin/env bash 2# shellcheck disable=SC2048,SC2086 3set -x 4 5# shellcheck source=/dev/null 6source "$HOME"/.cargo/env 7source "$(dirname "$0")"/test-util.sh 8source "$(dirname "$0")"/common-aarch64.sh 9 10WORKLOADS_LOCK="$WORKLOADS_DIR/integration_test.lock" 11 12build_virtiofsd() { 13 VIRTIOFSD_DIR="$WORKLOADS_DIR/virtiofsd_build" 14 VIRTIOFSD_REPO="https://gitlab.com/virtio-fs/virtiofsd.git" 15 16 checkout_repo "$VIRTIOFSD_DIR" "$VIRTIOFSD_REPO" v1.8.0 "97ea7908fe7f9bc59916671a771bdcfaf4044b45" 17 18 if [ ! -f "$VIRTIOFSD_DIR/.built" ]; then 19 pushd "$VIRTIOFSD_DIR" || exit 20 rm -rf target/ 21 time RUSTFLAGS="" TARGET_CC="" cargo build --release 22 cp target/release/virtiofsd "$WORKLOADS_DIR/" || exit 1 23 touch .built 24 popd || exit 25 fi 26} 27 28update_workloads() { 29 cp scripts/sha1sums-aarch64 "$WORKLOADS_DIR" 30 31 FOCAL_OS_RAW_IMAGE_NAME="focal-server-cloudimg-arm64-custom-20210929-0.raw" 32 FOCAL_OS_RAW_IMAGE_DOWNLOAD_URL="https://ch-images.azureedge.net/$FOCAL_OS_RAW_IMAGE_NAME" 33 FOCAL_OS_RAW_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME" 34 if [ ! -f "$FOCAL_OS_RAW_IMAGE" ]; then 35 pushd "$WORKLOADS_DIR" || exit 36 time wget --quiet $FOCAL_OS_RAW_IMAGE_DOWNLOAD_URL || exit 1 37 popd || exit 38 fi 39 40 FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="focal-server-cloudimg-arm64-custom-20210929-0.qcow2" 41 FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL="https://ch-images.azureedge.net/$FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME" 42 FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME" 43 if [ ! -f "$FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then 44 pushd "$WORKLOADS_DIR" || exit 45 time wget --quiet $FOCAL_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL || exit 1 46 popd || exit 47 fi 48 49 FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME="focal-server-cloudimg-arm64-custom-20210929-0-backing.qcow2" 50 FOCAL_OS_QCOW2_BACKING_FILE_IMAGE="$WORKLOADS_DIR/$FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME" 51 if [ ! -f "$FOCAL_OS_QCOW2_BACKING_FILE_IMAGE" ]; then 52 pushd "$WORKLOADS_DIR" || exit 53 time qemu-img create -f qcow2 -b "$FOCAL_OS_QCOW2_UNCOMPRESSED_IMAGE" -F qcow2 $FOCAL_OS_QCOW2_IMAGE_BACKING_FILE_NAME 54 popd || exit 55 fi 56 57 JAMMY_OS_RAW_IMAGE_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.raw" 58 JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL="https://ch-images.azureedge.net/$JAMMY_OS_RAW_IMAGE_NAME" 59 JAMMY_OS_RAW_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_RAW_IMAGE_NAME" 60 if [ ! -f "$JAMMY_OS_RAW_IMAGE" ]; then 61 pushd "$WORKLOADS_DIR" || exit 62 time wget --quiet $JAMMY_OS_RAW_IMAGE_DOWNLOAD_URL || exit 1 63 popd || exit 64 fi 65 66 JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME="jammy-server-cloudimg-arm64-custom-20220329-0.qcow2" 67 JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL="https://ch-images.azureedge.net/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME" 68 JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE="$WORKLOADS_DIR/$JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_NAME" 69 if [ ! -f "$JAMMY_OS_QCOW2_UNCOMPRESSED_IMAGE" ]; then 70 pushd "$WORKLOADS_DIR" || exit 71 time wget --quiet $JAMMY_OS_QCOW2_IMAGE_UNCOMPRESSED_DOWNLOAD_URL || exit 1 72 popd || exit 73 fi 74 75 ALPINE_MINIROOTFS_URL="http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/aarch64/alpine-minirootfs-3.11.3-aarch64.tar.gz" 76 ALPINE_MINIROOTFS_TARBALL="$WORKLOADS_DIR/alpine-minirootfs-aarch64.tar.gz" 77 if [ ! -f "$ALPINE_MINIROOTFS_TARBALL" ]; then 78 pushd "$WORKLOADS_DIR" || exit 79 time wget --quiet $ALPINE_MINIROOTFS_URL -O "$ALPINE_MINIROOTFS_TARBALL" || exit 1 80 popd || exit 81 fi 82 83 ALPINE_INITRAMFS_IMAGE="$WORKLOADS_DIR/alpine_initramfs.img" 84 if [ ! -f "$ALPINE_INITRAMFS_IMAGE" ]; then 85 pushd "$WORKLOADS_DIR" || exit 86 mkdir alpine-minirootfs 87 tar xf "$ALPINE_MINIROOTFS_TARBALL" -C alpine-minirootfs 88 cat >alpine-minirootfs/init <<-EOF 89 #! /bin/sh 90 mount -t devtmpfs dev /dev 91 echo \$TEST_STRING > /dev/console 92 poweroff -f 93 EOF 94 chmod +x alpine-minirootfs/init 95 cd alpine-minirootfs || exit 96 find . -print0 | 97 cpio --null --create --verbose --owner root:root --format=newc >"$ALPINE_INITRAMFS_IMAGE" 98 popd || exit 99 fi 100 101 pushd "$WORKLOADS_DIR" || exit 102 103 if ! sha1sum sha1sums-aarch64 --check; then 104 echo "sha1sum validation of images failed, remove invalid images to fix the issue." 105 exit 1 106 fi 107 popd || exit 108 109 # Download Cloud Hypervisor binary from its last stable release 110 LAST_RELEASE_VERSION="v39.0" 111 CH_RELEASE_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$LAST_RELEASE_VERSION/cloud-hypervisor-static-aarch64" 112 CH_RELEASE_NAME="cloud-hypervisor-static-aarch64" 113 pushd "$WORKLOADS_DIR" || exit 114 # Repeat a few times to workaround a random wget failure 115 WGET_RETRY_MAX=10 116 wget_retry=0 117 118 until [ "$wget_retry" -ge "$WGET_RETRY_MAX" ]; do 119 time wget $CH_RELEASE_URL -O "$CH_RELEASE_NAME" && break 120 wget_retry=$((wget_retry + 1)) 121 done 122 123 if [ $wget_retry -ge "$WGET_RETRY_MAX" ]; then 124 exit 1 125 else 126 chmod +x $CH_RELEASE_NAME 127 fi 128 popd || exit 129 130 # Prepare linux image (build from source or download pre-built) 131 prepare_linux 132 133 # Update the kernel in the cloud image for some tests that requires recent kernel version 134 FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_NAME="focal-server-cloudimg-arm64-custom-20210929-0-update-kernel.raw" 135 cp "$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_NAME" "$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_NAME" 136 FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR="$WORKLOADS_DIR/focal-server-cloudimg-root" 137 mkdir -p "$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR" 138 # Mount the 'raw' image, replace the compressed kernel file and umount the working folder 139 guestmount -a "$WORKLOADS_DIR/$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_NAME" -m /dev/sda1 "$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR" || exit 1 140 cp "$WORKLOADS_DIR"/Image-arm64.gz "$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR"/boot/vmlinuz 141 guestunmount "$FOCAL_OS_RAW_IMAGE_UPDATE_KERNEL_ROOT_DIR" 142 143 # Build virtiofsd 144 build_virtiofsd 145 146 BLK_IMAGE="$WORKLOADS_DIR/blk.img" 147 MNT_DIR="mount_image" 148 if [ ! -f "$BLK_IMAGE" ]; then 149 pushd "$WORKLOADS_DIR" || exit 150 fallocate -l 16M "$BLK_IMAGE" 151 mkfs.ext4 -j "$BLK_IMAGE" 152 mkdir $MNT_DIR 153 sudo mount -t ext4 "$BLK_IMAGE" $MNT_DIR 154 sudo bash -c "echo bar > $MNT_DIR/foo" || exit 1 155 sudo umount "$BLK_IMAGE" 156 rm -r $MNT_DIR 157 popd || exit 158 fi 159 160 SHARED_DIR="$WORKLOADS_DIR/shared_dir" 161 if [ ! -d "$SHARED_DIR" ]; then 162 mkdir -p "$SHARED_DIR" 163 echo "foo" >"$SHARED_DIR/file1" 164 echo "bar" >"$SHARED_DIR/file3" || exit 1 165 fi 166 167 # Checkout and build EDK2 168 build_edk2 169} 170 171process_common_args "$@" 172 173# aarch64 not supported for MSHV 174if [[ "$hypervisor" = "mshv" ]]; then 175 echo "AArch64 is not supported in Microsoft Hypervisor" 176 exit 1 177fi 178 179# lock the workloads folder to avoid parallel updating by different containers 180( 181 echo "try to lock $WORKLOADS_DIR folder and update" 182 flock -x 12 && update_workloads 183) 12>"$WORKLOADS_LOCK" 184 185# Check if there is any error in the execution of `update_workloads`. 186# If there is any error, then kill the shell. Otherwise the script will continue 187# running even if the `update_workloads` function was failed. 188RES=$? 189if [ $RES -ne 0 ]; then 190 exit 1 191fi 192 193export RUST_BACKTRACE=1 194 195cargo build --all --release --target "$BUILD_TARGET" 196 197# Enable KSM with some reasonable parameters so that it won't take too long 198# for the memory to be merged between two processes. 199sudo bash -c "echo 1000000 > /sys/kernel/mm/ksm/pages_to_scan" 200sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs" 201sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run" 202 203# Both test_vfio and ovs-dpdk rely on hugepages 204HUGEPAGESIZE=$(grep Hugepagesize /proc/meminfo | awk '{print $2}') 205PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE)) 206echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages 207sudo chmod a+rwX /dev/hugepages 208 209# Run all direct kernel boot (Device Tree) test cases in mod `parallel` 210time cargo test "common_parallel::$test_filter" --target "$BUILD_TARGET" -- --test-threads=$(($(nproc) / 8)) ${test_binary_args[*]} 211RES=$? 212 213# Run some tests in sequence since the result could be affected by other tests 214# running in parallel. 215if [ $RES -eq 0 ]; then 216 time cargo test "common_sequential::$test_filter" --target "$BUILD_TARGET" -- --test-threads=1 ${test_binary_args[*]} 217 RES=$? 218else 219 exit $RES 220fi 221 222# Run all ACPI test cases 223if [ $RES -eq 0 ]; then 224 time cargo test "aarch64_acpi::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]} 225 RES=$? 226else 227 exit $RES 228fi 229 230# Run all test cases related to live migration 231if [ $RES -eq 0 ]; then 232 time cargo test "live_migration_parallel::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]} 233 RES=$? 234else 235 exit $RES 236fi 237 238if [ $RES -eq 0 ]; then 239 time cargo test "live_migration_sequential::$test_filter" --target "$BUILD_TARGET" -- --test-threads=1 ${test_binary_args[*]} 240 RES=$? 241else 242 exit $RES 243fi 244 245# Run tests on dbus_api 246if [ $RES -eq 0 ]; then 247 cargo build --features "dbus_api" --all --release --target "$BUILD_TARGET" 248 export RUST_BACKTRACE=1 249 time cargo test "dbus_api::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]} 250 RES=$? 251fi 252 253exit $RES 254