From 3107de6a073591f039838a94c698676fd446a1ff Mon Sep 17 00:00:00 2001 From: Hongyu Ning Date: Thu, 28 Sep 2023 14:23:40 +0800 Subject: [PATCH] [New][guest-test]: code style improve based on github code check code style improvement based on github code check, plus minor json contents change and qemu_get_config.py print context change Signed-off-by: Hongyu Ning --- guest-test/guest.qemu_runner.sh | 4 +- guest-test/guest.test_executor.sh | 10 +-- guest-test/guest.test_launcher.sh | 105 +++++++++++++------------ guest-test/qemu.config.json | 8 +- guest-test/qemu_get_config.py | 54 ++++++------- guest-test/tdx/tdx_guest_boot_check.sh | 8 +- 6 files changed, 93 insertions(+), 96 deletions(-) diff --git a/guest-test/guest.qemu_runner.sh b/guest-test/guest.qemu_runner.sh index a218acb8..b0bfd854 100755 --- a/guest-test/guest.qemu_runner.sh +++ b/guest-test/guest.qemu_runner.sh @@ -76,7 +76,7 @@ cd "$(dirname "$0")" 2>/dev/null || exit 1 source ../.env # get test scenario config for qemu_runner -source $SCRIPT_DIR/test_params.py +source "$SCRIPT_DIR"/test_params.py # do basic pre-check for TDX/TDXIO VM launching if [[ $VM_TYPE == "tdx" ]] || [[ $VM_TYPE == "tdxio" ]]; then @@ -85,4 +85,4 @@ fi # launch VM by qemu via qemu_runner.py test_print_trc "qemu_runner start to launch $VM_TYPE VM" -python3 $SCRIPT_DIR/qemu_runner.py \ No newline at end of file +python3 "$SCRIPT_DIR"/qemu_runner.py \ No newline at end of file diff --git a/guest-test/guest.test_executor.sh b/guest-test/guest.test_executor.sh index 13369ad9..5627ec2d 100755 --- a/guest-test/guest.test_executor.sh +++ b/guest-test/guest.test_executor.sh @@ -24,14 +24,14 @@ guest_test_prepare() { rm -rf $GUEST_TEST_DIR mkdir $GUEST_TEST_DIR EOF - sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no common.sh root@localhost:$GUEST_TEST_DIR - sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no $1 root@localhost:$GUEST_TEST_DIR + sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no common.sh root@localhost:"$GUEST_TEST_DIR" + sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no "$1" root@localhost:"$GUEST_TEST_DIR" test_print_trc "Guest VM test script prepare complete" } # function based on sshpass to scp $1 source_code_dir and compile $2 test_binary in Guest VM guest_test_source_code() { - sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no -r $1 root@localhost:$GUEST_TEST_DIR + sshpass -e scp -P "$PORT" -o StrictHostKeyChecking=no -r "$1" root@localhost:"$GUEST_TEST_DIR" sshpass -e ssh -p "$PORT" -o StrictHostKeyChecking=no root@localhost << EOF source $GUEST_TEST_DIR/common.sh cd $GUEST_TEST_DIR/$1 @@ -78,9 +78,9 @@ cd "$(dirname "$0")" 2>/dev/null || exit 1 source ../.env # get test scenario config for test_executor -source $SCRIPT_DIR/test_params.py +source "$SCRIPT_DIR"/test_params.py -cd $SCRIPT_DIR +cd "$SCRIPT_DIR" || die "fail to switch to $SCRIPT_DIR" # select test_functions by $TEST_SCENARIO case "$TESTCASE" in TD_BOOT) diff --git a/guest-test/guest.test_launcher.sh b/guest-test/guest.test_launcher.sh index ebdda31d..1ab31dbd 100755 --- a/guest-test/guest.test_launcher.sh +++ b/guest-test/guest.test_launcher.sh @@ -25,7 +25,7 @@ echo "$SCRIPT_DIR" GCOV="off" # timeout control in case of TD VM booting hang SECONDS=0 -TIMEOUT=60 +TIMEOUT=300 # EXEC_FLAG=0 shows test_executor being called EXEC_FLAG=1 @@ -67,13 +67,25 @@ NOTE!! args passed here will override params in qemu.confg.json EOF } +guest_kernel_check() { + sshpass -e ssh -p "$PORT" -o StrictHostKeyChecking=no root@localhost << EOF + echo "$VM_TYPE VM guest kernel under test:" + uname -r +EOF +} + +guest_kernel_reboot() { + sshpass -e ssh -p "$PORT" -o StrictHostKeyChecking=no root@localhost << EOF + systemctl reboot --reboot-argument=now +EOF +} + ###################### Do Works ###################### cd "$(dirname "$0")" 2>/dev/null || exit 1 source ../.env ## PART 0: prepare test prerequisites ## -which sshpass > /dev/null -if [ $? -ne 0 ]; then +if [ ! "$(which sshpass)" ]; then dnf install -y sshpass > /dev/null apt install -y sshpass > /dev/null else @@ -85,7 +97,7 @@ fi # generate a unified random port number in one test cycle PORT=$(shuf -i 10010-10900 -n 1) # generate test_params.py based on script args -echo PORT=$PORT > $SCRIPT_DIR/test_params.py +echo PORT="$PORT" > "$SCRIPT_DIR"/test_params.py # 1.1 get test scenario config related params from script args # append following params in above fresh new test_params.py @@ -96,39 +108,42 @@ while getopts :v:s:m:d:t:x:c:p:g:h arg; do case $arg in v) VCPU=$OPTARG - echo VCPU=$VCPU >> $SCRIPT_DIR/test_params.py + echo VCPU="$VCPU" >> "$SCRIPT_DIR"/test_params.py ;; s) SOCKETS=$OPTARG - echo SOCKETS=$SOCKETS >> $SCRIPT_DIR/test_params.py + echo SOCKETS="$SOCKETS" >> "$SCRIPT_DIR"/test_params.py ;; m) MEM=$OPTARG - echo MEM=$MEM >> $SCRIPT_DIR/test_params.py + echo MEM="$MEM" >> "$SCRIPT_DIR"/test_params.py ;; d) DEBUG=$OPTARG - echo DEBUG=\"$DEBUG\" >> $SCRIPT_DIR/test_params.py + echo DEBUG="\"$DEBUG\"" >> "$SCRIPT_DIR"/test_params.py ;; t) VM_TYPE=$OPTARG - echo VM_TYPE=\"$VM_TYPE\" >> $SCRIPT_DIR/test_params.py + echo VM_TYPE="\"$VM_TYPE\"" >> "$SCRIPT_DIR"/test_params.py ;; x) TESTCASE=$OPTARG - echo TESTCASE=\"$TESTCASE\" >> $SCRIPT_DIR/test_params.py + echo TESTCASE="\"$TESTCASE\"" >> "$SCRIPT_DIR"/test_params.py ;; c) CMDLINE=$OPTARG - echo CMDLINE=\"$CMDLINE\" >> $SCRIPT_DIR/test_params.py + echo CMDLINE="\"$CMDLINE\"" >> "$SCRIPT_DIR"/test_params.py ;; p) PMU=$OPTARG - echo PMU=\"$PMU\" >> $SCRIPT_DIR/test_params.py + echo PMU="\"$PMU\"" >> "$SCRIPT_DIR"/test_params.py ;; g) GCOV=$OPTARG - echo GCOV=\"$GCOV\" >> $SCRIPT_DIR/test_params.py + echo GCOV="\"$GCOV\"" >> "$SCRIPT_DIR"/test_params.py + ;; + h) + usage && exit 0 ;; :) test_print_err "Must supply an argument to -$OPTARG." @@ -148,15 +163,15 @@ done # $GUEST_IMG_FORMAT $BOOT_PATTERN $SSHPASS $PORT #global_variable -output=$(python3 $SCRIPT_DIR/qemu_get_config.py) -KERNEL_IMG=$(echo $output | awk '{print $1}') -INITRD_IMG=$(echo $output | awk '{print $2}') -BIOS_IMG=$(echo $output | awk '{print $3}') -QEMU_IMG=$(echo $output | awk '{print $4}') -GUEST_IMG=$(echo $output | awk '{print $5}') -GUEST_IMG_FORMAT=$(echo $output | awk '{print $6}') -BOOT_PATTERN=$(echo $output | awk '{print $7}') -SSHPASS=$(echo $output | awk '{print $8}') +output=$(python3 "$SCRIPT_DIR"/qemu_get_config.py) +KERNEL_IMG=$(echo "$output" | awk '{print $1; exit}') +INITRD_IMG=$(echo "$output" | awk '{print $2; exit}') +BIOS_IMG=$(echo "$output" | awk '{print $3; exit}') +QEMU_IMG=$(echo "$output" | awk '{print $4; exit}') +GUEST_IMG=$(echo "$output" | awk '{print $5; exit}') +GUEST_IMG_FORMAT=$(echo "$output" | awk '{print $6; exit}') +BOOT_PATTERN=$(echo "$output" | awk '{print $7; exit}') +SSHPASS=$(echo "$output" | awk '{print $8; exit}') test_print_trc "KERNEL_IMG $KERNEL_IMG" test_print_trc "INITRD_IMG $INITRD_IMG" @@ -187,7 +202,7 @@ export GCOV # 2.3 check TD VM boot $ERR_STRs, then run corresponding err_handler ($ERR_FLAGs) # 2.4 break while loop if reach $TIMEOUT seconds (in case of TD VM boot hang) -cd $SCRIPT_DIR +cd "$SCRIPT_DIR" || die "fail to switch to $SCRIPT_DIR" rm -rf /root/.ssh/known_hosts while read -r line; do echo "[${VM_TYPE}_vm]: $line" @@ -196,10 +211,7 @@ while read -r line; do if [[ $line == $BOOT_PATTERN ]]; then test_print_trc "VM_TYPE: $VM_TYPE, VCPU: $VCPU, SOCKETS: $SOCKETS, MEM: $MEM, DEBUG: $DEBUG, PMU: $PMU, CMDLINE: $CMDLINE, TESTCASE: $TESTCASE, SECONDS: $SECONDS" EXEC_FLAG=0 - ./guest.test_executor.sh - if [ $? -ne 0 ]; then # break while read loop in case of TD VM test failure - break - fi + ./guest.test_executor.sh || break # break while read loop in case of TD VM test failure # err_handlers string matching elif [[ $line == $ERR_STR1 ]]; then test_print_err "There is $ERR_STR1, test is not fully PASS" @@ -221,7 +233,7 @@ while read -r line; do elif [[ $SECONDS -ge $TIMEOUT ]]; then # break while read loop in case of TD VM boot timeout (no $BOOT_PATTERN found) break fi -done < <(if [ $GCOV == "off" ]; then timeout $TIMEOUT ./guest.qemu_runner.sh; else ./guest.qemu_runner.sh; fi) +done < <(if [ "$GCOV" == "off" ]; then timeout "$TIMEOUT" ./guest.qemu_runner.sh; else ./guest.qemu_runner.sh; fi) ## PART 3: err_handlers error management # unexpected error/bug/warning/call trace handling @@ -251,15 +263,10 @@ fi sleep 3 # VM life-cycles management step 1 -# check if TDVM is still up, non-zero return value indicates TDVM is not accessible +# check if TDVM is still up via guest_kernel_check function, non-zero return value indicates TDVM is not accessible # TDVM not acccessible cases: # a. TDVM is already closed after test # b. TDVM boot up stuck at some point -sshpass -e ssh -p "$PORT" -o StrictHostKeyChecking=no root@localhost << EOF - echo "$VM_TYPE VM guest kernel under test:" - uname -r -EOF - # VM life-cycles management step 2 # non-zero return value of TD VM not accessible handling # time count between 3 and $TIMEOUT is expected case a @@ -268,24 +275,19 @@ EOF # - handling: kill the tdvm_$PORT process since it's stuck # time count less or qual than 3 is case b # - handling: nothing to do, die for TDVM boot early failure, likely qemu config issue -if [ $? -ne 0 ]; then - if [ $SECONDS -gt 3 ] && [ $SECONDS -lt $TIMEOUT ] && [ $EXEC_FLAG -eq 0 ]; then +if ! guest_kernel_check; then + if [ "$SECONDS" -gt 3 ] && [ "$SECONDS" -lt "$TIMEOUT" ] && [ "$EXEC_FLAG" -eq 0 ]; then test_print_trc "$VM_TYPE VM test complete..." - elif [ $SECONDS -ge $TIMEOUT ] && [ $GCOV == "on" ]; then + elif [ "$SECONDS" -ge "$TIMEOUT" ] && [ "$GCOV" == "on" ]; then pkill "${VM_TYPE}vm_$PORT" die "TEST TIMEOUT!!!!!!!!!!!!" - elif [ $GCOV == "off" ]; then + elif [ "$GCOV" == "off" ] && [ "$EXEC_FLAG" -eq 1 ]; then die "$VM_TYPE VM test seems fail at beginning, please check test log" fi -# zero return value shows TDVM is still accessible handling -# handing: no matter why it's still accessible, close it by ssh login -elif [ $GCOV == "off" ]; then - sshpass -e ssh -p "$PORT" -o StrictHostKeyChecking=no root@localhost << EOF - echo "$VM_TYPE VM guest kernel under test:" - uname -r - systemctl reboot --reboot-argument=now -EOF - if [ $? -eq 0 ]; then +# guest_kernel_kernel function zero return value shows TDVM is still accessible handling +# handling: no matter why it's still accessible, close it by guest_kernel_reboot function +elif [ "$GCOV" == "off" ]; then + if ! guest_kernel_reboot; then test_print_trc "$VM_TYPE VM is still up" test_print_trc "time: $SECONDS" test_print_trc "SSHPASS: $SSHPASS" @@ -295,7 +297,7 @@ EOF # else it's due to test die before reaching final close point td_test_close function die "$VM_TYPE VM test fail, please check test log" fi -else # [ $GCOV == "on" ] || [ $? -eq 0 ] +else # [ $GCOV == "on" ] || [ guest_kernel_check return 0 ] test_print_trc "${VM_TYPE}vm_$PORT keep alive for gcov data collection" test_print_trc "'ssh -p $PORT root@localhost' with PASSWORD '$SSHPASS' to login and get data" fi @@ -303,13 +305,12 @@ fi ## PART 5: clean up at test execution ends, kill tdvm_$PORT process if it's still up ## # VM life-cycles management step 3 # Kill the tdvm_$PORT process in case above ssh command close not accessible due to network or other issues -if [ $GCOV == "off" ]; then - pgrep "${VM_TYPE}vm_$PORT" - if [ $? -ne 0 ]; then +if [ "$GCOV" == "off" ]; then + if [ ! "$(pgrep "${VM_TYPE}vm_$PORT")" ]; then test_print_trc "$VM_TYPE VM test complete all correctly..." else pkill "${VM_TYPE}vm_$PORT" test_print_wrg "${VM_TYPE}vm_$PORT process is still up, kill it since test expected to end here" die "$VM_TYPE VM test fail, please check test log" fi -fi +fi \ No newline at end of file diff --git a/guest-test/qemu.config.json b/guest-test/qemu.config.json index 63fafcaa..49243370 100644 --- a/guest-test/qemu.config.json +++ b/guest-test/qemu.config.json @@ -1,10 +1,10 @@ { "common": { - "kernel_img": "/tdx/home/sdp/tdx/guest_kernel_github/tdx/arch/x86/boot/bzImage.guest-next.0105", + "kernel_img": "/boot/vmlinuz-xxx-yyy", "initrd_img": "/boot/initramfs-xxx-yyy", - "bios_img": "/tdx/home/sdp/tdx/hongyu/OVMF.edk2-stable202211.fd", - "qemu_img": "/tdx/home/sdp/tdx/host_qemu_github/qemu-tdx/build/qemu-system-x86_64.tdx-qemu-2023-3-13-v7.2-kvm-upstream-2023.03.10-v6.2-wa", - "guest_img": "/tdx/home/sdp/tdx/hongyu/emr-bkc-centos-stream-9-coreserver-host-6.2-13.3-43.image", + "bios_img": "/path/to/EDKII/OVMF.fd or other virtual BIOS", + "qemu_img": "/path/to/qemu-kvm with proper capabilty of VM test", + "guest_img": "/path/to/prepared/guest_os_image, in qcow2 or raw image format", "guest_img_format": "raw", "boot_pattern": "*Kernel*on*x86_64*", "guest_root_passwd": "123456", diff --git a/guest-test/qemu_get_config.py b/guest-test/qemu_get_config.py index 2179ad3a..17adcf03 100755 --- a/guest-test/qemu_get_config.py +++ b/guest-test/qemu_get_config.py @@ -44,15 +44,7 @@ # print above G-list variables to test_launcher.sh to export for global shell scripts access # NOTICE!! DON'T interrupt before any of the following print to avoid mis-behaviors -print(kernel_img) # shell awk $1 -print(initrd_img) # shell awk $2 -print(bios_img) # shell awk $3 -print(qemu_img) # shell awk $4 -print(guest_img) # shell awk $5 -print(guest_img_format) # shell awk $6 -print(boot_pattern) # shell awk $7 -print(guest_root_passwd) # shell awk $8 -#print(port) # shell awk $9 +print(kernel_img, initrd_img, bios_img, qemu_img, guest_img, guest_img_format, boot_pattern, guest_root_passwd) # shell awk $1-$8 # NOTICE!! DON'T interrupt before any of the above print to avoid mis-behaviors # end of G-list variables handling @@ -61,37 +53,37 @@ # test_params.py is generated by test_launcher.sh for both qemu_runner.py and test_executor.sh # O-list variables default value from qemu.config.json vm_type = qemu_config["common"]["vm_type"] -if PMU != None: +if PMU is not None: pmu = PMU else: pmu = qemu_config["common"]["pmu"] -if VCPU != None: +if VCPU is not None: cpus = VCPU else: cpus = qemu_config["common"]["cpus"] -if SOCKETS != None: +if SOCKETS is not None: sockets = SOCKETS else: sockets = qemu_config["common"]["sockets"] -if MEM != None: +if MEM is not None: mem = MEM else: mem = qemu_config["common"]["mem"] -if CMDLINE != None: +if CMDLINE is not None: cmdline = CMDLINE else: cmdline = qemu_config["common"]["cmdline"] -if DEBUG != None: +if DEBUG is not None: debug = DEBUG else: debug = qemu_config["common"]["debug"] -if TESTCASE != None: +if TESTCASE is not None: testcase = TESTCASE else: print("No TESTCASE info found, can't run any test!") @@ -118,21 +110,21 @@ args = params_o_list.parse_args() # NOTICE!! O-list veriables' value will be override if passed through above args option -if args.vmtype != None: +if args.vmtype is not None: vm_type = args.vmtype -if args.pmu != None: +if args.pmu is not None: pmu = args.pmu -if args.cpus != None: +if args.cpus is not None: cpus = args.cpus -if args.sockets != None: +if args.sockets is not None: sockets = args.sockets -if args.mem != None: +if args.mem is not None: mem = args.mem -if args.cmdline != None: +if args.cmdline is not None: cmdline = args.cmdline -if args.debug != None: +if args.debug is not None: debug = args.debug -if args.testcase != None: +if args.testcase is not None: testcase = args.testcase # end of O-list variables handling @@ -202,7 +194,7 @@ def get_sub_cfgs(l, key, result=""): if vm_type == "legacy": vm_cfg = get_sub_cfgs(vm_keys, "vm") print("HERE're all the vm configs to launch legacy vm:") - print("qemu config option, part 1:") + print("#### qemu config option, part 1 ####") print(vm_cfg) #print_sub_keys(tdx_keys, "tdx") @@ -210,9 +202,9 @@ def get_sub_cfgs(l, key, result=""): vm_cfg = get_sub_cfgs(vm_keys, "vm") tdx_cfg = get_sub_cfgs(tdx_keys, "tdx") print("HERE're all the tdx configs to launch tdx vm:") - print("qemu config option, part 1:") + print("#### qemu config option, part 1 ####") print(vm_cfg) - print("qemu config option, part 2:") + print("#### qemu config option, part 2 ####") print(tdx_cfg) #print_sub_keys(tdxio_keys, "tdxio") @@ -221,9 +213,9 @@ def get_sub_cfgs(l, key, result=""): tdx_cfg = get_sub_cfgs(tdx_keys, "tdx") tdxio_cfg = get_sub_cfgs(tdxio_keys, "tdxio") print("HERE're all the tdx configs to launch tdxio vm:") - print("qemu config option, part 1:") + print("#### qemu config option, part 1 ####") print(vm_cfg) - print("qemu config option, part 2:") + print("#### qemu config option, part 2 ####") print(tdx_cfg) - print("qemu config option, part 3:") - print(tdxio_cfg) + print("#### qemu config option, part 3 ####") + print(tdxio_cfg) \ No newline at end of file diff --git a/guest-test/tdx/tdx_guest_boot_check.sh b/guest-test/tdx/tdx_guest_boot_check.sh index 36e4382d..5830db9b 100755 --- a/guest-test/tdx/tdx_guest_boot_check.sh +++ b/guest-test/tdx/tdx_guest_boot_check.sh @@ -25,6 +25,10 @@ while getopts :v:s:m: arg; do m) MEM=$OPTARG ;; + *) + test_print_err "Must supply an argument to -$OPTARG." + exit 1 + ;; esac done @@ -49,12 +53,12 @@ test_print_trc "mem_td: $mem_td" # $MEM less than or equal to 4GB need special memory size check if [[ $MEM -le 4 ]]; then - if [[ $(( $MEM / $mem_td )) -lt 1 ]] || [[ $(( $MEM / $mem_td )) -gt 2 ]]; then + if [[ $(( MEM / mem_td )) -lt 1 ]] || [[ $(( MEM / mem_td )) -gt 2 ]]; then die "Guest TD VM boot with memory: $mem_td GB (expected $MEM GB)" fi # $MEM more than 4GB use general memory size check else - if [[ $(( $MEM / $mem_td )) -ne 1 ]]; then + if [[ $(( MEM / mem_td )) -ne 1 ]]; then die "Guest TD VM boot with memory: $mem_td GB (expected $MEM GB)" fi fi