xref: /cloud-hypervisor/scripts/run_integration_tests_aarch64.sh (revision ea4693a09123234951ae1516f112c5cfce5032ca)
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.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