blob: 8b8d14e9af301a4b931d6a077166bbda877bfac3 [file] [log] [blame]
Naveen Joy7ea7ab52021-05-11 10:31:18 -07001#!/usr/bin/env bash
2# Run VPP in a QEMU VM
3# set -o xtrace
4set -o nounset
5
6# Arguments:
7# $1:- Test Filter
8# $2:- Kernel Image
9# $3:- Test Data Directory
10# $4:- CPU Mask String (e.g. "5,6,7,8")
11# $5:- Guest MEM in Gibibytes (e.g. 2G)
12
13if [[ -z "${1:-}" ]]; then
14 echo "ERROR: A non-empty test selection is required to run
15 tests in a QEMU VM"
16 exit 1
17fi
18TEST=${1:-}
19TEST_JOBS=${TEST_JOBS:-1}
20
21# Init RAM disk image to boot the QEMU VM
22INITRD=${INITRD:-}
23
24# Ensure test dir
25TEST_DATA_DIR=${3:-"/tmp/vpp-vm-tests"}
26if [[ ! -d ${TEST_DATA_DIR} ]]; then
27 mkdir -p ${TEST_DATA_DIR}
28fi
29
30# CPU Affinity for taskset
31CPU_MASK=${4:-"5,6,7,8"}
32IFS=',' read -r -a CPU_MASK_ARRAY <<< ${CPU_MASK}
33CPUS=${#CPU_MASK_ARRAY[@]}
34
35# Guest MEM (Default 2G)
36MEM=${5:-"2G"}
37
38# Set the QEMU executable for the OS pkg.
39os_VENDOR=$(lsb_release -i -s)
40if [[ $os_VENDOR =~ (Debian|Ubuntu) ]]; then
41 os_PACKAGE="deb"
42 QEMU=${QEMU:-"qemu-system-x86_64"}
43else
44 os_PACKAGE="rpm"
45 QEMU=${QEMU:-"qemu-kvm"}
46fi
47
48# Exit if the ${QEMU} executable is not available
49if ! command -v ${QEMU} &> /dev/null; then
50 echo "Error: ${QEMU} is required, but could not be found."
51 exit 1
52fi
53
54# Download the Generic Linux Kernel, if needed
55if [[ -z "${2:-}" ]] || [[ ! -f "${2:-}" ]]; then
56 if [[ $os_PACKAGE == "deb" ]]; then
57 PWD=$(pwd)
58 cd ${TEST_DATA_DIR}
59 PKG="linux-image-$(uname -r)"
60 echo "Getting the Linux Kernel image..${PKG}"
61 apt-get download ${PKG}
62 dpkg --fsys-tarfile ${PKG}_*.deb | tar xvf - ./boot
63 KERNEL_BIN=$(ls ${TEST_DATA_DIR}/boot/vmlinuz-*-generic)
64 cd ${PWD}
65 else
66 echo "ERROR: Kernel Image selection is required for RPM pkgs."
67 exit 1
68 fi
69else
70 KERNEL_BIN=${2:-}
71fi
72
73## Create initrd with 9p drivers, if ${INITRD} is null
74DRIVERS_9P=""
75if [[ -z "${INITRD}" ]] && [[ ! -d "/etc/initramfs-tools" ]]; then
76 echo "To boot the QEMU VM, an initial RAM disk with 9p drivers is needed"
77 echo "Install the initramfs-tools package or set env var INITRD to the RAM disk path"
78 exit 1
79elif [[ -z "${INITRD}" ]]; then
80 if [[ -f "/etc/initramfs-tools/modules" ]]; then
81 DRIVERS_9P=$(grep 9p /etc/initramfs-tools/modules | awk '{print $1}' | cut -d$'\n' -f1)
82 fi
83 if [[ -z "${DRIVERS_9P}" ]]; then
84 echo "You'll need to update the file /etc/initramfs-tools/modules with the below 9p drivers"
85 echo "9p >> /etc/initramfs-tools/modules"
86 echo "9pnet >> /etc/initramfs-tools/modules"
87 echo "9pnet_virtio >> /etc/initramfs-tools/modules"
88 exit 1
89 fi
90 # Generate the initramfs image, if the we haven't generated one yet
91 if ! ls ${TEST_DATA_DIR}/boot/initrd.img-*-generic &> /dev/null; then
92 echo "Generating a bootable initramfs image in ${TEST_DATA_DIR}/boot/"
93 update-initramfs -c -k $(uname -r) -b ${TEST_DATA_DIR}/boot >/dev/null 2>&1
94 echo "Generated the INITRD image"
95 fi
96 INITRD=$(ls ${TEST_DATA_DIR}/boot/initrd.img-*-generic)
97fi
98echo "Using INITRD=${TEST_DATA_DIR}/boot/${INITRD} for booting the QEMU VM"
99
100
101## Install iperf into ${TEST_DATA_DIR}
102IPERF=${TEST_DATA_DIR}/usr/bin/iperf
103if [[ ! -x ${IPERF} ]] && [[ $os_PACKAGE == "deb" ]]; then
104 echo "Installing iperf: ${IPERF}"
105 PWD=$(pwd)
106 cd ${TEST_DATA_DIR}
107 IPRF_PKG="iperf_2.0.5+dfsg1-2_amd64.deb"
108 wget https://iperf.fr/download/ubuntu/${IPRF_PKG}
109 dpkg --fsys-tarfile ${IPRF_PKG} | tar xvf -
110 if [[ -x ${IPERF} ]]; then
111 echo "${IPERF} installed successfully"
112 else
113 echo "ERROR: iperf executable ${IPERF} installation failed"
114 exit 1
115 fi
116 cd ${PWD}
117elif [[ ! -x ${IPERF} ]] && [[ $os_PACKAGE != "deb" ]]; then
118 echo "ERROR: install iperf: ${IPERF} before running QEMU tests"
119 exit 1
120fi
121
122FAILED_DIR=${FAILED_DIR:-"/tmp/vpp-failed-unittests/"}
123if [[ ! -d ${FAILED_DIR} ]]; then
124 mkdir -p ${FAILED_DIR}
125fi
126
127HUGEPAGES=${HUGEPAGES:-256}
128
129# Ensure all required Env vars are bound to non-zero values
130EnvVarArray=("WS_ROOT=${WS_ROOT:-}"
131 "RND_SEED=${RND_SEED:-}"
132 "BR=${BR:-}"
133 "VENV_PATH=${VENV_PATH:-}"
134 "VPP_BUILD_DIR=${VPP_BUILD_DIR:-}"
135 "VPP_BIN=${VPP_BIN:-}"
136 "VPP_PLUGIN_PATH=${VPP_PLUGIN_PATH:-}"
137 "VPP_TEST_PLUGIN_PATH=${VPP_TEST_PLUGIN_PATH:-}"
138 "VPP_INSTALL_PATH=${VPP_INSTALL_PATH:-}"
139 "LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-}")
140
141for envVar in ${EnvVarArray[*]}; do
142 var_name=$(echo $envVar | cut -d= -f1)
143 var_val=$(echo $envVar | cut -d= -f2)
144 if [[ -z "$var_val" ]]; then
145 echo "ERROR: Env var: $var_name is not set"
146 exit 1
147 fi
148done
149
150# Boot QEMU VM and run the test
151function run_in_vm {
152 INIT=$(mktemp -p ${TEST_DATA_DIR})
153 cat > ${INIT} << _EOF_
154#!/bin/bash
155mkdir -p /dev/shm
156mount -t tmpfs -o rw,nosuid,nodev tmpfs /dev/shm
157mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
158mount -t tmpfs -o "noexec,nosuid,size=10%,mode=0755" tmpfs /run
159mount -t 9p /dev/vpp9p ${WS_ROOT}
160mount -t 9p tmp9p /tmp
161modprobe -a vhost_net
162env SOCKET=1 SANITY=no \
163FAILED_DIR=${FAILED_DIR} RND_SEED=${RND_SEED} BR=${BR} \
164VENV_PATH=${VENV_PATH} TEST=${TEST} TEST_JOBS=${TEST_JOBS} \
165VPP_BUILD_DIR=${VPP_BUILD_DIR} VPP_BIN=${VPP_BIN} VPP_PLUGIN_PATH=${VPP_PLUGIN_PATH} \
166VPP_TEST_PLUGIN_PATH=${VPP_TEST_PLUGIN_PATH} VPP_INSTALL_PATH=${VPP_INSTALL_PATH} \
167LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TEST_DATA_DIR=${TEST_DATA_DIR} INITRD=${INITRD} \
168bash -c "${WS_ROOT}/test/scripts/run.sh --filter=${TEST} --jobs=${TEST_JOBS} --failed-dir=${FAILED_DIR} \
169--venv-dir=${VENV_PATH} --vpp-ws-dir=${WS_ROOT} --extended"
170poweroff -f
171_EOF_
172
173 chmod +x ${INIT}
174
175 sudo taskset -c ${CPU_MASK} ${QEMU} \
176 -nodefaults \
177 -name test_$(basename $INIT) \
178 -chardev stdio,mux=on,id=char0 \
179 -mon chardev=char0,mode=readline,pretty=on \
180 -serial chardev:char0 \
181 -machine pc,accel=kvm,usb=off,mem-merge=off \
182 -cpu host \
183 -smp ${CPUS},sockets=1,cores=${CPUS},threads=1 \
184 -m ${MEM} \
185 -no-user-config \
186 -kernel ${KERNEL_BIN} \
187 -initrd ${INITRD} \
188 -fsdev local,id=root9p,path=/,security_model=none,multidevs=remap \
189 -device virtio-9p-pci,fsdev=root9p,mount_tag=fsRoot \
190 -virtfs local,path=${WS_ROOT},mount_tag=/dev/vpp9p,security_model=none,id=vpp9p,multidevs=remap \
191 -virtfs local,path=/tmp,mount_tag=tmp9p,security_model=passthrough,id=tmp9p,multidevs=remap \
192 -netdev tap,id=net0,vhost=on \
193 -device virtio-net-pci,netdev=net0,mac=52:54:00:de:64:01 \
194 -nographic \
195 -append "ro root=fsRoot rootfstype=9p rootflags=trans=virtio,cache=mmap console=ttyS0 hugepages=${HUGEPAGES} init=${INIT}"
196 }
197
198run_in_vm