github.com/kata-containers/tests@v0.0.0-20240307153542-772105b56064/metrics/storage/webtooling.sh (about)

     1  #!/bin/bash
     2  #
     3  # Copyright (c) 2020-2021 Intel Corporation
     4  #
     5  # SPDX-License-Identifier: Apache-2.0
     6  
     7  # Description of the test:
     8  # This test runs the 'web tooling benchmark'
     9  # https://github.com/v8/web-tooling-benchmark
    10  
    11  set -o pipefail
    12  
    13  # General env
    14  SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
    15  source "${SCRIPT_PATH}/../lib/common.bash"
    16  NUM_CONTAINERS="$1"
    17  
    18  TEST_NAME="web-tooling"
    19  IMAGE="docker.io/library/local-web-tooling:latest"
    20  DOCKERFILE="${SCRIPT_PATH}/web-tooling-dockerfile/Dockerfile"
    21  CI_JOB="${CI_JOB:-""}"
    22  configuration_file="/opt/kata/share/defaults/kata-containers/configuration.toml"
    23  
    24  # Directory to run the test inside of the container
    25  TESTDIR="${TESTDIR:-/testdir}"
    26  file_path="/web-tooling-benchmark"
    27  file_name="output"
    28  
    29  # Directory where the webtooling results are stored
    30  TMP_DIR=$(mktemp --tmpdir -d webtool.XXXXXXXXXX)
    31  
    32  # Options to control the start of the workload using a trigger-file
    33  dst_dir="/host"
    34  src_dir=$(mktemp --tmpdir -d webtool.XXXXXXXXXX)
    35  trigger_file="$RANDOM.txt"
    36  guest_trigger_file="$dst_dir/$trigger_file"
    37  host_trigger_file="$src_dir/$trigger_file"
    38  start_script="webtooling_start.sh"
    39  
    40  # CMD points to the script that starts the workload
    41  CMD="$dst_dir/$start_script"
    42  MOUNT_OPTIONS="type=bind,src=$src_dir,dst=$dst_dir,options=rbind:ro"
    43  PAYLOAD_ARGS="${PAYLOAD_ARGS:-tail -f /dev/null}"
    44  
    45  # This timeout is related with the amount of time that
    46  # webtool benchmark needs to run inside the container
    47  timeout=600
    48  INITIAL_NUM_PIDS=1
    49  
    50  cpu_period="100000"
    51  cpu_quota="200000"
    52  
    53  remove_tmp_dir() {
    54  	rm -rf "$TMP_DIR"
    55  	rm -rf "$src_dir"
    56  }
    57  
    58  trap remove_tmp_dir EXIT
    59  
    60  # Show help about this script
    61  help(){
    62  cat << EOF
    63  Usage: $0 <count>
    64     Description:
    65         <count> : Number of containers to run.
    66  EOF
    67  }
    68  
    69  # script used to launch the workload
    70  create_start_script() {
    71  	local script="$src_dir/$start_script"
    72  	rm -rf "$script"
    73  
    74  cat <<EOF >>"$script"
    75  #!/bin/bash
    76  mkdir -p ${TESTDIR}
    77  
    78  until [ -f $guest_trigger_file ]; do
    79  	sleep 1
    80  done
    81  pushd $file_path
    82  node dist/cli.js > $file_name
    83  EOF
    84  	chmod +x "$script"
    85  }
    86  
    87  verify_task_is_completed_on_all_containers() {
    88  	local containers=( $(sudo -E "${CTR_EXE}" c list -q) )
    89  	local sleep_secs=10
    90  	local max=$(bc <<<"$timeout / $sleep_secs")
    91  	local wip_list=()
    92  	local count=1
    93  	local sum=0
    94  	local i=""
    95  
    96  	while (( $sum < $NUM_CONTAINERS )); do
    97  
    98  	    for i in "${containers[@]}"; do
    99  		# Only check containers that have not completed the workload at this step
   100  		num_pids=$(sudo -E "${CTR_EXE}" t metrics "$i" | grep pids.current | grep pids.current | xargs | cut -d ' ' -f 2)
   101  
   102  	        if [ "$num_pids" -lt "$INITIAL_NUM_PIDS" ]; then
   103                      ((sum++))
   104                  else
   105                      wip_list+=("$i")
   106                  fi
   107              done
   108  
   109              # hold the list of containers that are still running the workload
   110              containers=(${wip_list[*]})
   111              wip_list=()
   112  
   113              info "loop $count of $max: sleeping for $sleep_secs seconds"
   114              sleep $sleep_secs
   115              ((count++))
   116  	done
   117  }
   118  
   119  check_containers_are_up() {
   120  	info "Verify that the containers are running"
   121  	local containers_launched=0
   122  	while (( $containers_launched < $NUM_CONTAINERS )); do
   123  		containers_launched="$(sudo -E ${CTR_EXE} t list | grep -c "RUNNING")"
   124  		sleep 1
   125  	done
   126  }
   127  
   128  save_config(){
   129  	metrics_json_start_array
   130  
   131  	local json="$(cat << EOF
   132  	{
   133  		"containers": "$NUM_CONTAINERS",
   134  		"image": "$IMAGE",
   135  		"units": "runs/s"
   136  	}
   137  EOF
   138  )"
   139  	metrics_json_add_array_element "$json"
   140  	metrics_json_end_array "Config"
   141  }
   142  
   143  function main() {
   144  	# Verify enough arguments
   145  	if [ $# != 1 ]; then
   146  		echo >&2 "error: Not enough arguments [$@]"
   147  		help
   148  		exit 1
   149  	fi
   150  
   151  	local i=0
   152  	local containers=()
   153  	local cmds=("docker")
   154  	local not_started_count=$NUM_CONTAINERS
   155  
   156  	restart_containerd_service
   157  	# Check tools/commands dependencies
   158  	init_env
   159  	check_cmds "${cmds[@]}"
   160  	check_ctr_images "$IMAGE" "$DOCKERFILE"
   161  	metrics_json_init
   162  	save_config
   163  	create_start_script
   164  	rm -rf $host_trigger_file
   165  
   166  	info "Creating $NUM_CONTAINERS containers"
   167  
   168  	for ((i=1; i<= "$NUM_CONTAINERS"; i++)); do
   169  		containers+=($(random_name))
   170  		# Web tool benchmark needs 2 cpus to run completely in its cpu utilization
   171  		sudo -E "${CTR_EXE}" run -d --runtime "${CTR_RUNTIME}" --cpu-quota "${cpu_quota}" --cpu-period "${cpu_period}" --mount="$MOUNT_OPTIONS" "$IMAGE" "${containers[-1]}" sh -c "$PAYLOAD_ARGS"
   172  		((not_started_count--))
   173  		info "$not_started_count remaining containers"
   174  	done
   175  
   176  	# Check that the requested number of containers are running
   177  	local timeout_launch="10"
   178  	check_containers_are_up & pid=$!
   179  	(sleep "$timeout_launch" && kill -HUP $pid) 2>/dev/null & pid_tout=$!
   180  
   181  	if wait $pid 2>/dev/null; then
   182  		pkill -HUP -P $pid_tout
   183  		wait $pid_tout
   184  	else
   185  		warn "Time out exceeded"
   186  		return 1
   187  	fi
   188  
   189  	# Get the initial number of pids in a single container before the workload starts
   190          INITIAL_NUM_PIDS=$(sudo -E "${CTR_EXE}" t metrics "${containers[-1]}" | grep pids.current | grep pids.current | xargs | cut -d ' ' -f 2)
   191  	((INITIAL_NUM_PIDS++))
   192  
   193  	# Launch webtooling benchmark
   194  	local pids=()
   195  	local j=0
   196  	for i in "${containers[@]}"; do
   197  		$(sudo -E "${CTR_EXE}" t exec -d --exec-id "$(random_name)" "$i" sh -c "$CMD") &
   198  		pids[${j}]=$!
   199  		((j++))
   200  	done
   201  
   202  	# wait for all pids
   203  	for pid in ${pids[*]}; do
   204  	    wait $pid
   205  	done
   206  
   207  	touch $host_trigger_file
   208  	info "All containers are running the workload..."
   209  
   210  	# Verify that all containers have completed the assigned task
   211  	verify_task_is_completed_on_all_containers & pid=$!
   212  	(sleep "$timeout" && kill -HUP $pid) 2>/dev/null & pid_tout=$!
   213  	if wait $pid 2>/dev/null; then
   214  		pkill -HUP -P $pid_tout
   215  		wait $pid_tout
   216  	else
   217  		warn "Time out exceeded"
   218  		return 1
   219  	fi
   220  
   221  	RESULTS_CMD="cat $file_path/$file_name"
   222  	for i in "${containers[@]}"; do
   223  		sudo -E "${CTR_EXE}" t exec --exec-id "$RANDOM" "$i" sh -c "$RESULTS_CMD" >> "$TMP_DIR/results"
   224  	done
   225  
   226  	# Save configuration
   227  	metrics_json_start_array
   228  
   229  	local output=$(cat "$TMP_DIR/results")
   230  	local cut_results="cut -d':' -f2 | sed -e 's/^[ \t]*//'| cut -d ' ' -f1 | tr '\n' ',' | sed 's/.$//'"
   231  
   232  	local acorn=$(echo "$output" | grep -w "acorn" | eval "${cut_results}")
   233  	local babel=$(echo "$output" | grep -w "babel" | sed '/babel-minify/d' | eval "${cut_results}")
   234  	local babel_minify=$(echo "$output" | grep -w "babel-minify" | eval "${cut_results}")
   235  	local babylon=$(echo "$output" | grep -w "babylon" | eval "${cut_results}")
   236  	local buble=$(echo "$output" | grep -w "buble" | eval "${cut_results}")
   237  	local chai=$(echo "$output" | grep -w "chai" | eval "${cut_results}")
   238  	local coffeescript=$(echo "$output" | grep -w "coffeescript" | eval "${cut_results}")
   239  	local espree=$(echo "$output" | grep -w "espree" | eval "${cut_results}")
   240  	local esprima=$(echo "$output" | grep -w "esprima" | eval "${cut_results}")
   241  	local jshint=$(echo "$output" | grep -w "jshint" | eval "${cut_results}")
   242  	local lebab=$(echo "$output" | grep -w "lebab" | eval "${cut_results}")
   243  	local postcss=$(echo "$output" | grep -w "postcss" | eval "${cut_results}")
   244  	local prepack=$(echo "$output" | grep -w "prepack" | eval "${cut_results}")
   245  	local prettier=$(echo "$output" | grep -w "prettier" | eval "${cut_results}")
   246  	local source_map=$(echo "$output" | grep -w "source-map" | eval "${cut_results}")
   247  	local terser=$(echo "$output" | grep -w "terser" | eval "${cut_results}")
   248  	local typescript=$(echo "$output" | grep -w "typescript" | eval "${cut_results}")
   249  	local uglify_js=$(echo "$output" | grep -w "uglify-js" | eval "${cut_results}")
   250  	local geometric_mean=$(echo "$output" | grep -w "Geometric" | eval "${cut_results}")
   251  	local average_tps=$(echo "$geometric_mean" | sed "s/,/+/g;s/.*/(&)\/$NUM_CONTAINERS/g" | bc -l)
   252  	local tps=$(echo "$average_tps*$NUM_CONTAINERS" | bc -l)
   253  
   254  	local json="$(cat << EOF
   255  	{
   256  		"Acorn" : "$acorn",
   257  		"Babel" : "$babel",
   258  		"Babel minify" : "$babel_minify",
   259  		"Babylon" : "$babylon",
   260  		"Buble" : "$buble",
   261  		"Chai" : "$chai",
   262  		"Coffeescript" : "$coffeescript",
   263  		"Espree" : "$espree",
   264  		"Esprima" : "$esprima",
   265  		"Jshint" : "$jshint",
   266  		"Lebab" : "$lebab",
   267  		"Postcss" : "$postcss",
   268  		"Prepack" : "$prepack",
   269  		"Prettier" : "$prettier",
   270  		"Source map" : "$source_map",
   271  		"Terser" : "$terser",
   272  		"Typescript" : "$typescript",
   273  		"Uglify js" : "$uglify_js",
   274  		"Geometric mean" : "$geometric_mean",
   275  		"Average TPS" : "$average_tps",
   276  		"TPS" : "$tps"
   277  	}
   278  EOF
   279  )"
   280  	metrics_json_add_array_element "$json"
   281  	metrics_json_end_array "Results"
   282  	metrics_json_save
   283  	clean_env_ctr
   284  }
   285  
   286  main "$@"