xref: /cloud-hypervisor/scripts/test-util.sh (revision b686a5bb24f949e3b201308d69b01e85c14f1ad6)
1#!/usr/bin/env bash
2hypervisor="kvm"
3test_filter=""
4build_kernel=false
5
6# Checkout source code of a GIT repo with specified branch and commit
7# Args:
8#   $1: Target directory
9#   $2: GIT URL of the repo
10#   $3: Required branch
11#   $4: Required commit (optional)
12checkout_repo() {
13    SRC_DIR="$1"
14    GIT_URL="$2"
15    GIT_BRANCH="$3"
16    GIT_COMMIT="$4"
17
18    # Check whether the local HEAD commit same as the requested commit or not.
19    # If commit is not specified, compare local HEAD and remote HEAD.
20    # Remove the folder if there is difference.
21    if [ -d "$SRC_DIR" ]; then
22        pushd "$SRC_DIR" || exit
23        git fetch
24        SRC_LOCAL_COMMIT=$(git rev-parse HEAD)
25        if [ -z "$GIT_COMMIT" ]; then
26            GIT_COMMIT=$(git rev-parse remotes/origin/"$GIT_BRANCH")
27        fi
28        popd || exit
29        if [ "$SRC_LOCAL_COMMIT" != "$GIT_COMMIT" ]; then
30            rm -rf "$SRC_DIR"
31        fi
32    fi
33
34    # Checkout the specified branch and commit (if required)
35    if [ ! -d "$SRC_DIR" ]; then
36        git clone --depth 1 "$GIT_URL" -b "$GIT_BRANCH" "$SRC_DIR"
37        if [ "$GIT_COMMIT" ]; then
38            pushd "$SRC_DIR" || exit
39            git fetch --depth 1 origin "$GIT_COMMIT"
40            git reset --hard FETCH_HEAD
41            popd || exit
42        fi
43    fi
44}
45
46# Not actively used by CI
47build_custom_linux() {
48    ARCH=$(uname -m)
49    LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom"
50    LINUX_CUSTOM_BRANCH="ch-6.12.8"
51    LINUX_CUSTOM_URL="https://github.com/cloud-hypervisor/linux.git"
52
53    checkout_repo "$LINUX_CUSTOM_DIR" "$LINUX_CUSTOM_URL" "$LINUX_CUSTOM_BRANCH"
54
55    pushd "$LINUX_CUSTOM_DIR" || exit
56    make ch_defconfig
57    make -j "$(nproc)"
58    if [ "${ARCH}" == "x86_64" ]; then
59        cp vmlinux "$WORKLOADS_DIR/" || exit 1
60        cp arch/x86/boot/bzImage "$WORKLOADS_DIR/" || exit 1
61    elif [ "${ARCH}" == "aarch64" ]; then
62        cp arch/arm64/boot/Image "$WORKLOADS_DIR/" || exit 1
63        cp arch/arm64/boot/Image.gz "$WORKLOADS_DIR/" || exit 1
64    fi
65    popd || exit
66}
67
68cmd_help() {
69    echo ""
70    echo "Cloud Hypervisor $(basename "$0")"
71    echo "Usage: $(basename "$0") [<args>]"
72    echo ""
73    echo "Available arguments:"
74    echo ""
75    echo "    --hypervisor  Underlying hypervisor. Options kvm, mshv"
76    echo "    --test-filter Tests to run"
77    echo "    --build-guest-kernel Build guest kernel from source instead of downloading pre-built"
78    echo ""
79    echo "    --help        Display this help message."
80    echo ""
81}
82
83# shellcheck disable=SC2034
84process_common_args() {
85    while [ $# -gt 0 ]; do
86        case "$1" in
87        "-h" | "--help") {
88            cmd_help
89            exit 1
90        } ;;
91        "--hypervisor")
92            shift
93            hypervisor="$1"
94            ;;
95        "--test-filter")
96            shift
97            test_filter="$1"
98            ;;
99        "--build-guest-kernel")
100            build_kernel=true
101            ;;
102        "--") {
103            shift
104            break
105        } ;;
106        *)
107            echo "Unknown test scripts argument: $1. Please use '-- --help' for help."
108            exit
109            ;;
110        esac
111        shift
112    done
113    if [[ ! ("$hypervisor" = "kvm" || "$hypervisor" = "mshv") ]]; then
114        die "Hypervisor value must be kvm or mshv"
115    fi
116    # shellcheck disable=SC2034
117    test_binary_args=("$@")
118}
119
120download_hypervisor_fw() {
121    FW_TAG="0.5.0"
122    if [ -n "$AUTH_DOWNLOAD_TOKEN" ]; then
123        echo "Using authenticated download from GitHub"
124        FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/tags/${FW_TAG} \
125            --header "Authorization: Token $AUTH_DOWNLOAD_TOKEN" \
126            --header "X-GitHub-Api-Version: 2022-11-28" | grep "browser_download_url" |
127            grep -oP '"https://[^"]*hypervisor-fw"' | sed -e 's/^"//' -e 's/"$//')
128    else
129        echo "Using anonymous download from GitHub"
130        FW_URL=$(curl --silent https://api.github.com/repos/cloud-hypervisor/rust-hypervisor-firmware/releases/tags/${FW_TAG} |
131            grep "browser_download_url" | grep -oP '"https://[^"]*hypervisor-fw"' | sed -e 's/^"//' -e 's/"$//')
132    fi
133    FW="$WORKLOADS_DIR/hypervisor-fw"
134    pushd "$WORKLOADS_DIR" || exit
135    rm -f "$FW"
136    time wget --quiet "$FW_URL" || exit 1
137    popd || exit
138}
139
140download_linux() {
141    KERNEL_TAG="ch-release-v6.12.8-20250114"
142    if [ -n "$AUTH_DOWNLOAD_TOKEN" ]; then
143        echo "Using authenticated download from GitHub"
144        KERNEL_URLS=$(curl --silent https://api.github.com/repos/cloud-hypervisor/linux/releases/tags/${KERNEL_TAG} \
145            --header "Authorization: Token $AUTH_DOWNLOAD_TOKEN" \
146            --header "X-GitHub-Api-Version: 2022-11-28" | grep "browser_download_url" | grep -o 'https://.*[^ "]')
147    else
148        echo "Using anonymous download from GitHub"
149        KERNEL_URLS=$(curl --silent https://api.github.com/repos/cloud-hypervisor/linux/releases/tags/${KERNEL_TAG} | grep "browser_download_url" | grep -o 'https://.*[^ "]')
150    fi
151    pushd "$WORKLOADS_DIR" || exit
152    for url in $KERNEL_URLS; do
153        wget -N --quiet "$url" || exit 1
154    done
155
156    popd || exit
157}
158
159prepare_linux() {
160    if [ "$build_kernel" = true ]; then
161        echo "Building kernel from source"
162        build_custom_linux
163        echo "Using kernel built from source"
164    else
165        echo "Downloading pre-built kernel from GitHub"
166        download_linux
167        echo "Using kernel downloaded from GitHub"
168    fi
169}
170
171download_ovmf() {
172    OVMF_FW_TAG="ch-a54f262b09"
173    OVMF_FW_URL="https://github.com/cloud-hypervisor/edk2/releases/download/$OVMF_FW_TAG/CLOUDHV.fd"
174    OVMF_FW="$WORKLOADS_DIR/CLOUDHV.fd"
175    pushd "$WORKLOADS_DIR" || exit
176    rm -f "$OVMF_FW"
177    time wget --quiet $OVMF_FW_URL || exit 1
178    popd || exit
179}
180