From ee5cd35814e4ee8d998b788d94d0ebe1c1e4af5b Mon Sep 17 00:00:00 2001 From: Hongyu Ning Date: Fri, 24 Nov 2023 15:38:13 +0800 Subject: [PATCH 1/2] [guest-test] New Test: add tdx guest mem ebizzy func testcase add new testcase based on tdx_ebizzy_test_suite [Test Components] tdx [Test Types] func [Supported Devices] spr,emr,gnr,srf Signed-off-by: Hongyu Ning --- guest-test/guest.test_executor.sh | 10 + .../tdx/tdx_ebizzy_test_suite/.gitignore | 1 + guest-test/tdx/tdx_ebizzy_test_suite/Makefile | 22 + guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.c | 520 ++++++++++++++++++ guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.h | 34 ++ guest-test/tdx/tdx_mem_test.sh | 59 ++ guest-test/tdx/tests | 4 +- 7 files changed, 649 insertions(+), 1 deletion(-) create mode 100644 guest-test/tdx/tdx_ebizzy_test_suite/.gitignore create mode 100644 guest-test/tdx/tdx_ebizzy_test_suite/Makefile create mode 100644 guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.c create mode 100644 guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.h create mode 100755 guest-test/tdx/tdx_mem_test.sh diff --git a/guest-test/guest.test_executor.sh b/guest-test/guest.test_executor.sh index e0dda3c..a7e1bfd 100755 --- a/guest-test/guest.test_executor.sh +++ b/guest-test/guest.test_executor.sh @@ -191,6 +191,16 @@ case "$TESTCASE" in guest_tsm_attest "tsm.get_quote.negative" || \ die "Failed on $TESTCASE" ;; + TD_MEM_EBIZZY_FUNC) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_source_code tdx/tdx_ebizzy_test_suite ebizzy || \ + { die "Failed to prepare guest test source code of tdx_ebizzy_test_suite"; return 1; } + guest_test_entry tdx_mem_test.sh "-t EBIZZY_FUNC" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t EBIZZY_FUNC"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; :) test_print_err "Must specify the test scenario option by [-t]" usage && exit 1 diff --git a/guest-test/tdx/tdx_ebizzy_test_suite/.gitignore b/guest-test/tdx/tdx_ebizzy_test_suite/.gitignore new file mode 100644 index 0000000..18696d0 --- /dev/null +++ b/guest-test/tdx/tdx_ebizzy_test_suite/.gitignore @@ -0,0 +1 @@ +ebizzy \ No newline at end of file diff --git a/guest-test/tdx/tdx_ebizzy_test_suite/Makefile b/guest-test/tdx/tdx_ebizzy_test_suite/Makefile new file mode 100644 index 0000000..162f988 --- /dev/null +++ b/guest-test/tdx/tdx_ebizzy_test_suite/Makefile @@ -0,0 +1,22 @@ +# MakeFile function :: MakeFile for tdx_ebizzy_test_suite + +CC := gcc + +VAR_CFLAGS := $(shell pkg-config --cflags libtracefs 2>/dev/null) +VAR_LDLIBS := $(shell pkg-config --libs libtracefs 2>/dev/null) + +CFLAGS += -static -Wall -Wextra -g -O2 $(VAR_CFLAGS) +LDFLAGS += -lpthread $(VAR_LDLIBS) +INCLUDES = -I include + +#List of source files- Update this on adding a new C file +SOURCES := \ + ebizzy.c \ + +MAKE_TARGETS := ebizzy + +tdx_guest_test: + $(CC) $(CFLAGS) $(LDFLAGS) -o ${MAKE_TARGETS} ${INCLUDES} ${SOURCES} + +clean: + rm -rf ${MAKE_TARGETS} diff --git a/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.c b/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.c new file mode 100644 index 0000000..934d951 --- /dev/null +++ b/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.c @@ -0,0 +1,520 @@ +/* + * Ebizzy - replicate a large ebusiness type of workload. + * + * Written by Valerie Henson + * + * Copyright 2006 - 2007 Intel Corporation + * Copyright 2007 Valerie Henson + * + * Rodrigo Rubira Branco - HP/BSD/Solaris port and some + * new features + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +/* + * This program is designed to replicate a common web search app + * workload. A lot of search applications have the basic pattern: Get + * a request to find a certain record, index into the chunk of memory + * that contains it, copy it into another chunk, then look it up via + * binary search. The interesting parts of this workload are: + * + * Large working set + * Data alloc/copy/free cycle + * Unpredictable data access patterns + * + * Fiddle with the command line options until you get something + * resembling the kind of workload you want to investigate. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ebizzy.h" + +/* + * Command line options + */ + +static unsigned int always_mmap; +static unsigned int never_mmap; +static unsigned int chunks; +static unsigned int use_permissions; +static unsigned int use_holes; +static unsigned int random_size; +static unsigned int chunk_size; +static unsigned int seconds; +static unsigned int threads; +static unsigned int verbose; +static unsigned int linear; +static unsigned int touch_pages; +static unsigned int no_lib_memcpy; + +/* + * Other global variables + */ + +typedef size_t record_t; +static unsigned int record_size = sizeof(record_t); +static char *cmd; +static record_t **mem; +static char **hole_mem; +static unsigned int page_size; +static time_t start_time; +static volatile int threads_go; +static unsigned int records_read; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s [options]\n" + "-T\t\t Just 'touch' the allocated pages\n" + "-l\t\t Don't use library memcpy\n" + "-m\t\t Always use mmap instead of malloc\n" + "-M\t\t Never use mmap\n" + "-n \t Number of memory chunks to allocate\n" + "-p \t\t Prevent mmap coalescing using permissions\n" + "-P \t\t Prevent mmap coalescing using holes\n" + "-R\t\t Randomize size of memory to copy and search\n" + "-s \t Size of memory chunks, in bytes\n" + "-S \t Number of seconds to run\n" + "-t \t Number of threads (2 * number cpus by default)\n" + "-v[v[v]]\t Be verbose (more v's for more verbose)\n" + "-z\t\t Linear search instead of binary search\n", cmd); + exit(1); +} + +/* + * Read options, check them, and set some defaults. + */ + +static void read_options(int argc, char *argv[]) +{ + int c; + + page_size = getpagesize(); + + /* + * Set some defaults. These are currently tuned to run in a + * reasonable amount of time on my laptop. + * + * We could set the static defaults in the declarations, but + * then the defaults would be split between here and the top + * of the file, which is annoying. + */ + threads = 2 * sysconf(_SC_NPROCESSORS_ONLN); + chunks = 10; + chunk_size = record_size * 64 * 1024; + seconds = 10; + + /* On to option processing */ + + cmd = argv[0]; + opterr = 1; + + while ((c = getopt(argc, argv, "lmMn:pPRs:S:t:vzT")) != -1) { + switch (c) { + case 'l': + no_lib_memcpy = 1; + break; + case 'm': + always_mmap = 1; + break; + case 'M': + never_mmap = 1; + break; + case 'n': + chunks = atoi(optarg); + if (chunks == 0) + usage(); + break; + case 'p': + use_permissions = 1; + break; + case 'P': + use_holes = 1; + break; + case 'R': + random_size = 1; + break; + case 's': + chunk_size = atoi(optarg); + if (chunk_size == 0) + usage(); + break; + case 'S': + seconds = atoi(optarg); + if (seconds == 0) + usage(); + break; + case 't': + threads = atoi(optarg); + if (threads == 0) + usage(); + break; + case 'T': + touch_pages = 1; + break; + case 'v': + verbose++; + break; + case 'z': + linear = 1; + break; + default: + usage(); + } + } + + if (verbose) + printf("ebizzy 0.2\n" + "(C) 2006-7 Intel Corporation\n" + "(C) 2007 Valerie Henson \n"); + + if (verbose) { + printf("always_mmap %u\n", always_mmap); + printf("never_mmap %u\n", never_mmap); + printf("chunks %u\n", chunks); + printf("prevent coalescing using permissions %u\n", + use_permissions); + printf("prevent coalescing using holes %u\n", use_holes); + printf("random_size %u\n", random_size); + printf("chunk_size %u\n", chunk_size); + printf("seconds %d\n", seconds); + printf("threads %u\n", threads); + printf("verbose %u\n", verbose); + printf("linear %u\n", linear); + printf("touch_pages %u\n", touch_pages); + printf("page size %d\n", page_size); + } + + /* Check for incompatible options */ + + if (always_mmap && never_mmap) { + fprintf(stderr, "Both -m \"always mmap\" and -M " + "\"never mmap\" option specified\n"); + usage(); + } +#ifdef __GLIBC__ + if (never_mmap) + mallopt(M_MMAP_MAX, 0); +#endif + if (chunk_size < record_size) { + fprintf(stderr, "Chunk size %u smaller than record size %u\n", + chunk_size, record_size); + usage(); + } +} + +static void touch_mem(char *dest, size_t size) +{ + int i; + if (touch_pages) { + for (i = 0; i < size; i += page_size) + *(dest + i) = 0xff; + } +} + +static void *alloc_mem(size_t size) +{ + char *p; + int err = 0; + + if (always_mmap) { + p = mmap(NULL, size, (PROT_READ | PROT_WRITE), + (MAP_PRIVATE | MAP_ANONYMOUS), -1, 0); + if (p == MAP_FAILED) + err = 1; + } else { + p = malloc(size); + if (p == NULL) + err = 1; + } + + if (err) { + fprintf(stderr, "Couldn't allocate %zu bytes, try smaller " + "chunks or size options\n" + "Using -n %u chunks and -s %u size\n", + size, chunks, chunk_size); + exit(1); + } + + return (p); +} + +static void free_mem(void *p, size_t size) +{ + if (always_mmap) + munmap(p, size); + else + free(p); +} + +/* + * Factor out differences in memcpy implementation by optionally using + * our own simple memcpy implementation. + */ + +static void my_memcpy(void *dest, void *src, size_t len) +{ + char *d = (char *)dest; + char *s = (char *)src; + int i; + + for (i = 0; i < len; i++) + d[i] = s[i]; + return; +} + +static void allocate(void) +{ + int i; + + mem = alloc_mem(chunks * sizeof(record_t *)); + + if (use_holes) + hole_mem = alloc_mem(chunks * sizeof(record_t *)); + + for (i = 0; i < chunks; i++) { + mem[i] = (record_t *) alloc_mem(chunk_size); + /* Prevent coalescing using holes */ + if (use_holes) + hole_mem[i] = alloc_mem(page_size); + } + + /* Free hole memory */ + if (use_holes) + for (i = 0; i < chunks; i++) + free_mem(hole_mem[i], page_size); + + if (verbose) + printf("Allocated memory\n"); +} + +static void write_pattern(void) +{ + int i, j; + + for (i = 0; i < chunks; i++) { + for (j = 0; j < chunk_size / record_size; j++) + mem[i][j] = (record_t) j; + /* Prevent coalescing by alternating permissions */ + if (use_permissions && (i % 2) == 0) + mprotect((void *)mem[i], chunk_size, PROT_READ); + } + if (verbose) + printf("Wrote memory\n"); +} + +static void *linear_search(record_t key, record_t * base, size_t size) +{ + record_t *p; + record_t *end = base + (size / record_size); + + for (p = base; p < end; p++) + if (*p == key) + return p; + return NULL; +} + +static int compare(const void *p1, const void *p2) +{ + return (*(record_t *) p1 - *(record_t *) p2); +} + +/* + * Stupid ranged random number function. We don't care about quality. + * + * Inline because it's starting to be a scaling issue. + */ + +static inline unsigned int rand_num(unsigned int max, unsigned int *state) +{ + *state *= 1103515245 + 12345; + return ((*state / 65536) % max); +} + +/* + * This function is the meat of the program; the rest is just support. + * + * In this function, we randomly select a memory chunk, copy it into a + * newly allocated buffer, randomly select a search key, look it up, + * then free the memory. An option tells us to allocate and copy a + * randomly sized chunk of the memory instead of the whole thing. + * + * Linear search provided for sanity checking. + * + */ + +static unsigned int search_mem(void) +{ + record_t key, *found; + record_t *src, *copy; + unsigned int chunk; + size_t copy_size = chunk_size; + unsigned int i; + unsigned int state = 0; + + for (i = 0; threads_go == 1; i++) { + chunk = rand_num(chunks, &state); + src = mem[chunk]; + /* + * If we're doing random sizes, we need a non-zero + * multiple of record size. + */ + if (random_size) + copy_size = (rand_num(chunk_size / record_size, &state) + + 1) * record_size; + copy = alloc_mem(copy_size); + + if (touch_pages) { + touch_mem((char *)copy, copy_size); + } else { + + if (no_lib_memcpy) + my_memcpy(copy, src, copy_size); + else + memcpy(copy, src, copy_size); + + key = rand_num(copy_size / record_size, &state); + + if (verbose > 2) + printf("Search key %zu, copy size %zu\n", key, + copy_size); + if (linear) + found = linear_search(key, copy, copy_size); + else + found = + bsearch(&key, copy, copy_size / record_size, + record_size, compare); + + /* Below check is mainly for memory corruption or other bug */ + if (found == NULL) { + fprintf(stderr, "Couldn't find key %zd\n", key); + exit(1); + } + } /* end if ! touch_pages */ + + free_mem(copy, copy_size); + } + + return (i); +} + +static void *thread_run(void *arg) +{ + + if (verbose > 1) + printf("Thread started\n"); + + /* Wait for the start signal */ + + while (threads_go == 0) ; + + records_read += search_mem(); + + if (verbose > 1) + printf("Thread finished, %f seconds\n", + difftime(time(NULL), start_time)); + + return NULL; +} + +static struct timeval difftimeval(struct timeval *end, struct timeval *start) +{ + struct timeval diff; + diff.tv_sec = end->tv_sec - start->tv_sec; + diff.tv_usec = end->tv_usec - start->tv_usec; + return diff; +} + +static void start_threads(void) +{ + pthread_t thread_array[threads]; + double elapsed; + unsigned int i; + struct rusage start_ru, end_ru; + struct timeval usr_time, sys_time; + int err; + + if (verbose) + printf("Threads starting\n"); + + for (i = 0; i < threads; i++) { + err = pthread_create(&thread_array[i], NULL, thread_run, NULL); + if (err) { + fprintf(stderr, "Error creating thread %d\n", i); + exit(1); + } + } + + /* + * Begin accounting - this is when we actually do the things + * we want to measure. */ + + getrusage(RUSAGE_SELF, &start_ru); + start_time = time(NULL); + threads_go = 1; + sleep(seconds); + threads_go = 0; + elapsed = difftime(time(NULL), start_time); + getrusage(RUSAGE_SELF, &end_ru); + + /* + * The rest is just clean up. + */ + + for (i = 0; i < threads; i++) { + err = pthread_join(thread_array[i], NULL); + if (err) { + fprintf(stderr, "Error joining thread %d\n", i); + exit(1); + } + } + + if (verbose) + printf("Threads finished\n"); + + printf("%u records/s\n", + (unsigned int)(((double)records_read) / elapsed)); + + usr_time = difftimeval(&end_ru.ru_utime, &start_ru.ru_utime); + sys_time = difftimeval(&end_ru.ru_stime, &start_ru.ru_stime); + + printf("real %5.2f s\n", elapsed); + printf("user %5.2f s\n", usr_time.tv_sec + usr_time.tv_usec / 1e6); + printf("sys %5.2f s\n", sys_time.tv_sec + sys_time.tv_usec / 1e6); +} + +int main(int argc, char *argv[]) +{ + read_options(argc, argv); + + allocate(); + + write_pattern(); + + start_threads(); + + return 0; +} diff --git a/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.h b/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.h new file mode 100644 index 0000000..afc18b5 --- /dev/null +++ b/guest-test/tdx/tdx_ebizzy_test_suite/ebizzy.h @@ -0,0 +1,34 @@ +/* Portability stuff */ + +#ifndef EBIZZY_H +#define EBIZZY_H + +#ifndef _freebsd +#include +#endif + +/* + * Solaris and FreeBSD compatibility stuff + */ +#if defined(_solaris) || defined(_freebsd) +#define MAP_ANONYMOUS MAP_ANON +#define M_MMAP_MAX (-4) +#endif + +/* + * FreeBSD compatibility stuff + */ +#if defined(_freebsd) || defined(__UCLIBC__) +#define mallopt(arg1, arg2) do { } while (0); +#endif + +/* + * HP-UX compatibility stuff + */ +#ifdef _HPUX_SOURCE +#define _SC_NPROCESSORS_ONLN pthread_num_processors_np() +#endif + + + +#endif /* EBIZZY_H */ diff --git a/guest-test/tdx/tdx_mem_test.sh b/guest-test/tdx/tdx_mem_test.sh new file mode 100755 index 0000000..1c7aa3b --- /dev/null +++ b/guest-test/tdx/tdx_mem_test.sh @@ -0,0 +1,59 @@ +#!/usr/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2023 Intel Corporation + +# Author: Hongyu Ning +# +# History: 23, Nov., 2023 - Hongyu Ning - creation + + +# @desc This script do basic memory test in TDX Guest VM + +###################### Variables ###################### +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" +echo "$SCRIPT_DIR" +source common.sh + +while getopts :t: arg; do + case $arg in + t) + MEM_CASE=$OPTARG + ;; + *) + test_print_err "Must supply an argument to -$OPTARG." + exit 1 + ;; + esac +done + +###################### Functions ###################### +ebizzy_func() { + test_print_trc "Start TDX guest ebizzy test 10s with malloc" + ebizzy -M + ebizzy_malloc=$? + test_print_trc "Start TDX guest ebizzy test 10s with mmap" + ebizzy -m + ebizzy_mmap=$? + if [[ $ebizzy_malloc == 0 && $ebizzy_mmap == 0 ]]; then + test_print_trc "TDX guest ebizzy test PASS" + return 0 + else + die "TDX guest ebizzy test FAIL" + return 1 + fi +} + +###################### Do Works ###################### +case "$MEM_CASE" in + EBIZZY_FUNC) + ebizzy_func + ;; + :) + test_print_err "Must specify the memory case option by [-t]" + exit 1 + ;; + \?) + test_print_err "Input test case option $MEM_CASE is not supported" + exit 1 + ;; +esac \ No newline at end of file diff --git a/guest-test/tdx/tests b/guest-test/tdx/tests index 414c6ea..5e2ec05 100644 --- a/guest-test/tdx/tests +++ b/guest-test/tdx/tests @@ -17,4 +17,6 @@ guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_TSM_ATTEST_QUOTE_PRECHE guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_TSM_ATTEST_QUOTE -c "accept_memory=lazy" -p off guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_TSM_ATTEST_QUOTE_NEG -c "accept_memory=lazy" -p off # case implemented by tdx_speed_test.sh -guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_NET_SPEED -c "accept_memory=lazy" -p off \ No newline at end of file +guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_NET_SPEED -c "accept_memory=lazy" -p off +# case implemented by tdx_mem_test.sh +guest.test_launcher.sh -v 1 -s 1 -m 16 -d on -t tdx -x TD_MEM_EBIZZY_FUNC -c "accept_memory=lazy" -p off \ No newline at end of file From c23c554b7ac4e20f09ce5d8a9d3d0638a8a4e13d Mon Sep 17 00:00:00 2001 From: Hongyu Ning Date: Mon, 27 Nov 2023 16:19:36 +0800 Subject: [PATCH 2/2] [guest-next] New Test: add unaccepted memory full accept time test Add 5 TCs to cover TDVM kernel remained unaccepted memory fully accepted time calculation and check [Test Components] tdx [Test Types] func [Supported Devices] spr,emr,gnr,srf Signed-off-by: Hongyu Ning --- guest-test/guest.test_executor.sh | 40 ++++++++++++++++++++++ guest-test/tdx/tdx_mem_test.sh | 56 +++++++++++++++++++++++++++++++ guest-test/tdx/tests | 7 +++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/guest-test/guest.test_executor.sh b/guest-test/guest.test_executor.sh index a7e1bfd..6dbf5c4 100755 --- a/guest-test/guest.test_executor.sh +++ b/guest-test/guest.test_executor.sh @@ -201,6 +201,46 @@ case "$TESTCASE" in guest_test_close fi ;; + TD_MEM_ACCEPT_TIME_4G) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_entry tdx_mem_test.sh "-t MEM_ACCEPT_TIME_4G" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t MEM_ACCEPT_TIME_4G"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; + TD_MEM_ACCEPT_TIME_16G) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_entry tdx_mem_test.sh "-t MEM_ACCEPT_TIME_16G" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t MEM_ACCEPT_TIME_16G"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; + TD_MEM_ACCEPT_TIME_32G) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_entry tdx_mem_test.sh "-t MEM_ACCEPT_TIME_32G" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t MEM_ACCEPT_TIME_32G"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; + TD_MEM_ACCEPT_TIME_64G) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_entry tdx_mem_test.sh "-t MEM_ACCEPT_TIME_64G" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t MEM_ACCEPT_TIME_64G"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; + TD_MEM_ACCEPT_TIME_96G) + guest_test_prepare tdx/tdx_mem_test.sh + guest_test_entry tdx_mem_test.sh "-t MEM_ACCEPT_TIME_96G" || \ + { die "Failed on $TESTCASE tdx_mem_test.sh -t MEM_ACCEPT_TIME_96G"; return 1; } + if [[ $GCOV == "off" ]]; then + guest_test_close + fi + ;; :) test_print_err "Must specify the test scenario option by [-t]" usage && exit 1 diff --git a/guest-test/tdx/tdx_mem_test.sh b/guest-test/tdx/tdx_mem_test.sh index 1c7aa3b..53ea46c 100755 --- a/guest-test/tdx/tdx_mem_test.sh +++ b/guest-test/tdx/tdx_mem_test.sh @@ -43,11 +43,67 @@ ebizzy_func() { fi } +# function based on stress-ng calculate total remained mem accepted time +mem_accepted_time() { +# common expected time consumed in seconds +expected_time=$1 +# prepare for prerequisites + if [ ! "$(which stress-ng)" ]; then + dnf install -y stress-ng > /dev/null + apt install -y stress-ng > /dev/null + else + test_print_trc "stress-ng prerequisites is ready for use" + test_print_trc "unaccepted memory drained time calculation is starting now..." + fi +# calculate memory accepted fully completed time +SECONDS=0 +stress-ng --vm 1 --vm-bytes 100% & +while (true); do + if [[ $(grep "nr_unaccepted" /proc/vmstat | awk '{print $2}') -eq 0 ]]; then + actual_time=$SECONDS; + pkill stress-ng; + break; + fi +done +# check if memory accept time far exceed expected (passed in value) +compare_result=$(echo "scale=2; ($actual_time/$expected_time)" | bc) +baseline_result=1.1 +result=$(awk -v n1="$compare_result" -v n2="$baseline_result" 'BEGIN {if (n1>n2) print 1; else print 0}') +if [ "$result" -eq 0 ]; then + test_print_trc "Memory accepted full time consumed: $actual_time" + return 0 +else + die "Memory accepted full time consumed: $actual_time seconds" + die "It's over expectation $expected_time seconds 10% more!!!" + return 1 +fi +} + ###################### Do Works ###################### case "$MEM_CASE" in EBIZZY_FUNC) ebizzy_func ;; + MEM_ACCEPT_TIME_4G) + # expected 4 secs + mem_accepted_time 4 + ;; + MEM_ACCEPT_TIME_16G) + # expected 1 min 4 secs + mem_accepted_time 64 + ;; + MEM_ACCEPT_TIME_32G) + # expected 2 mins 18 secs + mem_accepted_time 138 + ;; + MEM_ACCEPT_TIME_64G) + # expected 4 mins 46 secs + mem_accepted_time 286 + ;; + MEM_ACCEPT_TIME_96G) + # expected 5 mins 59 secs + mem_accepted_time 359 + ;; :) test_print_err "Must specify the memory case option by [-t]" exit 1 diff --git a/guest-test/tdx/tests b/guest-test/tdx/tests index 5e2ec05..ae4952d 100644 --- a/guest-test/tdx/tests +++ b/guest-test/tdx/tests @@ -19,4 +19,9 @@ guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_TSM_ATTEST_QUOTE_NEG -c # case implemented by tdx_speed_test.sh guest.test_launcher.sh -v 1 -s 1 -m 1 -d on -t tdx -x TD_NET_SPEED -c "accept_memory=lazy" -p off # case implemented by tdx_mem_test.sh -guest.test_launcher.sh -v 1 -s 1 -m 16 -d on -t tdx -x TD_MEM_EBIZZY_FUNC -c "accept_memory=lazy" -p off \ No newline at end of file +guest.test_launcher.sh -v 1 -s 1 -m 16 -d on -t tdx -x TD_MEM_EBIZZY_FUNC -c "accept_memory=lazy" -p off +guest.test_launcher.sh -v 4 -s 1 -m 4 -d on -t tdx -x TD_MEM_ACCEPT_TIME_4G -c "accept_memory=lazy" -p off +guest.test_launcher.sh -v 16 -s 1 -m 4 -d on -t tdx -x TD_MEM_ACCEPT_TIME_16G -c "accept_memory=lazy" -p off +guest.test_launcher.sh -v 16 -s 1 -m 4 -d on -t tdx -x TD_MEM_ACCEPT_TIME_32G -c "accept_memory=lazy" -p off +guest.test_launcher.sh -v 16 -s 1 -m 4 -d on -t tdx -x TD_MEM_ACCEPT_TIME_64G -c "accept_memory=lazy" -p off +guest.test_launcher.sh -v 16 -s 1 -m 4 -d on -t tdx -x TD_MEM_ACCEPT_TIME_96G -c "accept_memory=lazy" -p off \ No newline at end of file