diff --git a/tests/metrics/lib/json.bash b/tests/metrics/lib/json.bash index 017d6494a25e..1a308209507c 100755 --- a/tests/metrics/lib/json.bash +++ b/tests/metrics/lib/json.bash @@ -147,7 +147,7 @@ done) EOF )" - echo "$json" > $json_filename + echo "${json}" | jq . > "${json_filename}" # If we have a JSON URL or host/socket pair set up, post the results there as well. # Optionally compress into a single line. diff --git a/tests/metrics/storage/fio-dockerfile/Dockerfile b/tests/metrics/storage/fio-dockerfile/Dockerfile new file mode 100644 index 000000000000..62bba277278d --- /dev/null +++ b/tests/metrics/storage/fio-dockerfile/Dockerfile @@ -0,0 +1,26 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# Set up an Ubuntu image with 'fio io tester' installed + +FROM docker.io/library/ubuntu:22.04 + +# Version of the Dockerfile +LABEL DOCKERFILE_VERSION="1.0" + +# URL for the fio tester +ENV FIO_TOOLING_URL "https://github.com/axboe/fio" + +RUN apt-get update --quiet && \ + apt-get install --quiet --no-install-recommends -y \ + bash \ + util-linux \ + procps \ + fio && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/ + +COPY workload/fio_bench.sh / +WORKDIR / +CMD ["/bin/bash"] diff --git a/tests/metrics/storage/fio-dockerfile/workload/fio_bench.sh b/tests/metrics/storage/fio-dockerfile/workload/fio_bench.sh new file mode 100755 index 000000000000..43aed0136ef2 --- /dev/null +++ b/tests/metrics/storage/fio-dockerfile/workload/fio_bench.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# Description of the test: +# This test runs the 'fio benchmark' on kata containers +# https://fio.readthedocs.io/en/latest/ + +set -o pipefail + +# FIO variable settings + +# io-types supported: +# read, write, randread, randwrite, randrw, readwrite +io_type="read" +block_size="4k" +num_jobs="2" + +# FIO default settings +readonly ioengine="libaio" +readonly rate_process="linear" +readonly disable_buffered="1" +readonly iodepth="2" +readonly runtime="10s" +# ramp time +readonly rt="10s" +readonly fname="test.fio" +readonly workload_dir="/" +readonly workload_file="${workload_dir}${fname}" +readonly workload_size="10G" +readonly summary_file_local="/results.json" + +# Show help about this script +function help() { +cat << EOF +Usage: $0 + Description: + Runs FIO test using ctr to excercise IO in kata containers. + + Params: + + Operations are: + run-read-4k + run-write-4k + run-randread-4k + run-randwrite-4k + run-read-64k + run-write-64k + run-randread-64k + run-randwrite-64k + + : [Mandatory] + : [Optional] Any of the FIO supported ioengines, default: libaio. +EOF +} + +# Run from the host +function setup_workload() { + # create workload file: + if [ ! -f ${workload_file} ]; then + pushd "${workload_dir}" > /dev/null 2>&1 + dd if=/dev/urandom of="${workload_file}" bs=64M count=160 > /dev/null 2>&1 + fi +} + +# Run inside container +function launch_workload() { + # the parameters used in the test_name are accesible globally + local test_name="${io_type}_${block_size}_nj-${num_jobs}_${rate_process}_iodepth-${iodepth}_io-direct-${disable_buffered}" + + setup_workload + rm -f "${summary_file_local}" > /dev/null 2>&1 + fio \ + --name="${test_name}" \ + --output-format="json" \ + --filename="${workload_file}" \ + --size="${workload_size}" \ + --rate_process="${rate_process}" \ + --runtime="${runtime}" \ + --ioengine="${ioengine}" \ + --rw="${io_type}" \ + --direct="${disable_buffered}" \ + --numjobs="${num_jobs}" \ + --blocksize="${block_size}" \ + --ramp_time="${rt}" \ + --iodepth="${iodepth}" \ + --gtod_reduce="1" \ + --randrepeat="1" \ + | tee -a ${summary_file_local} > /dev/null 2>&1 +} + +function print_latest_results() { + [ ! -f "${summary_file_local}" ] && echo "Error: no results to display; you must run a test before requesting results display" && exit 1 + echo "$(cat ${summary_file_local})" +} + +function delete_workload() { + rm -f "${workload_file}" > /dev/null 2>&1 +} + +function main() { + local action="${1:-}" + num_jobs="${2:-1}" + + [[ ! ${num_jobs} =~ ^[0-9]+$ ]] && die "The number of jobs must be a positive integer" + + case "${action}" in + run-read-4k) launch_workload ;; + run-read-64k) block_size="64k" && launch_workload ;; + + run-write-4k) io_type="write" && launch_workload ;; + run-write-64k) block_size="64k" && io_type="write" && launch_workload ;; + + run-randread-4k) io_type="randread" && launch_workload ;; + run-randread-64k) block_size="64k" && io_type="randread" && launch_workload ;; + + run-randwrite-4k) io_type="randwrite" && launch_workload ;; + run-randwrite-64k) block_size="64k" && io_type="randwrite" && launch_workload ;; + + print-latest-results) print_latest_results ;; + delete-workload) delete_workload ;; + + *) >&2 echo "Invalid argument" ; help ; exit 1;; + esac +} + +main "$@" diff --git a/tests/metrics/storage/fio-k8s/.gitignore b/tests/metrics/storage/fio-k8s/.gitignore deleted file mode 100644 index 1caa97b15069..000000000000 --- a/tests/metrics/storage/fio-k8s/.gitignore +++ /dev/null @@ -1 +0,0 @@ -./cmd/fiotest/fio-k8s diff --git a/tests/metrics/storage/fio-k8s/Makefile b/tests/metrics/storage/fio-k8s/Makefile deleted file mode 100644 index 8bdcf91f6818..000000000000 --- a/tests/metrics/storage/fio-k8s/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2021-2022 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# - -MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -MKFILE_DIR := $(dir $(MKFILE_PATH)) - -build: - make -C $(MKFILE_DIR)/cmd/fiotest/ gomod - make -C $(MKFILE_DIR)/cmd/fiotest/ build - -test-report: - $(MKFILE_DIR)/scripts/dax-compare-test/report/gen-html-fio-report.sh $(MKFILE_DIR)/cmd/fiotest/test-results/ - -test-report-interactive: - $(MKFILE_DIR)/scripts/dax-compare-test/report/run-docker-jupyter-server.sh $(MKFILE_DIR)/cmd/fiotest/test-results/ - -test: build - make -C $(MKFILE_DIR)/cmd/fiotest/ run - make test-report - -run: build - make -C $(MKFILE_DIR)/scripts/dax-compare-test/ run - -test-qemu: build - make -C $(MKFILE_DIR)/cmd/fiotest/ run-qemu - -test-clh: build - make -C $(MKFILE_DIR)/cmd/fiotest/ run-clh diff --git a/tests/metrics/storage/fio-k8s/README.md b/tests/metrics/storage/fio-k8s/README.md deleted file mode 100644 index 96798849a62d..000000000000 --- a/tests/metrics/storage/fio-k8s/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# FIO test in Kubernetes - -This is an automation to run `fio` with Kubernetes. - -## Requirements: - -- Kubernetes cluster running. -- Kata configured as `runtimeclass`. - -## Test structure: - -- [fio-test]: Program wrapper to launch `fio` in a K8s pod. -- [pkg]: Library code that could be used for more `fio` automation. -- [configs]: Configuration files used by [fio-test]. -- [DAX-compare-test]: Script to run [fio-test] to generate `fio` data for Kata with/without `virtio-fs DAX` and K8s bare-metal runtime(`runc`). -- [report] Jupyter Notebook to create reports for data generated by [DAX-compare-test]. - -## Top-level Makefile targets - -- `build`: Build `fio` metrics. -- `test`: quick test, used to verify changes in [fio-test]. -- `run`: Run `fio` metrics and generate reports. -- `test-report-interactive`: Run python notebook in `localhost:8888`, useful to edit the report. -- `test-report`: Generate report from data generated by `make test`. - -[fio-test]:cmd/fiotest -[configs]:configs -[pkg]:pkg -[report]:scripts/dax-compare-test/report -[DAX-compare-test]:scripts/dax-compare-test/README.md diff --git a/tests/metrics/storage/fio-k8s/cmd/fiotest/Makefile b/tests/metrics/storage/fio-k8s/cmd/fiotest/Makefile deleted file mode 100644 index 48ea3c91f639..000000000000 --- a/tests/metrics/storage/fio-k8s/cmd/fiotest/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2021-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# - -MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -MKFILE_DIR := $(dir $(MKFILE_PATH)) - -build: - GO111MODULE=on go build - -run: build - $(MKFILE_DIR)/fio-k8s --debug --fio.size 10M --output-dir test-results --test-name kata $(MKFILE_DIR)/../../configs/example-config/ - $(MKFILE_DIR)/fio-k8s --debug --fio.size 10M --output-dir test-results --test-name runc --container-runtime runc $(MKFILE_DIR)/../../configs/example-config/ - -gomod: - go mod edit -replace=github.com/kata-containers/kata-containers/tests/metrics/k8s=../../pkg/k8s - go mod edit -replace=github.com/kata-containers/kata-containers/tests/metrics/exec=../../pkg/exec - go mod edit -replace=github.com/kata-containers/kata-containers/tests/metrics/env=../../pkg/env - go mod tidy - -run-qemu: build - $(MKFILE_DIR)/fio-k8s --debug --fio.size 10M --output-dir test-results --test-name kata --container-runtime kata-qemu $(MKFILE_DIR)/../../configs/example-config/ - -run-clh: build - $(MKFILE_DIR)/fio-k8s --debug --fio.size 10M --output-dir test-results --test-name kata --container-runtime kata-clh $(MKFILE_DIR)/../../configs/example-config/ diff --git a/tests/metrics/storage/fio-k8s/cmd/fiotest/go.mod b/tests/metrics/storage/fio-k8s/cmd/fiotest/go.mod deleted file mode 100644 index 4d6f8fb4552c..000000000000 --- a/tests/metrics/storage/fio-k8s/cmd/fiotest/go.mod +++ /dev/null @@ -1,24 +0,0 @@ -module github.com/kata-containers/kata-containers/tests/metrics/storage/fio-k8s - -go 1.19 - -replace github.com/kata-containers/kata-containers/tests/metrics/exec => ../../pkg/exec - -replace github.com/kata-containers/kata-containers/tests/metrics/k8s => ../../pkg/k8s - -replace github.com/kata-containers/kata-containers/tests/metrics/env => ../../pkg/env - -require ( - github.com/kata-containers/kata-containers/tests/metrics/env v0.0.0-00010101000000-000000000000 - github.com/kata-containers/kata-containers/tests/metrics/exec v0.0.0-00010101000000-000000000000 - github.com/kata-containers/kata-containers/tests/metrics/k8s v0.0.0-00010101000000-000000000000 - github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.9.3 - github.com/urfave/cli v1.22.14 -) - -require ( - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect -) diff --git a/tests/metrics/storage/fio-k8s/cmd/fiotest/go.sum b/tests/metrics/storage/fio-k8s/cmd/fiotest/go.sum deleted file mode 100644 index 45fbeb4a0954..000000000000 --- a/tests/metrics/storage/fio-k8s/cmd/fiotest/go.sum +++ /dev/null @@ -1,31 +0,0 @@ -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= -github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tests/metrics/storage/fio-k8s/cmd/fiotest/main.go b/tests/metrics/storage/fio-k8s/cmd/fiotest/main.go deleted file mode 100644 index de7e7b2ff043..000000000000 --- a/tests/metrics/storage/fio-k8s/cmd/fiotest/main.go +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright (c) 2021-2023 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -package main - -import ( - "encoding/csv" - "encoding/json" - "fmt" - "os" - "path" - "path/filepath" - "strings" - "time" - - env "github.com/kata-containers/kata-containers/tests/metrics/env" - exec "github.com/kata-containers/kata-containers/tests/metrics/exec" - "github.com/kata-containers/kata-containers/tests/metrics/k8s" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/urfave/cli" -) - -var log = logrus.New() - -var ( - optContainerRuntime = "container-runtime" - optDebug = "debug" - optOutputDir = "output-dir" - optTestName = "test-name" - // fio options - optFioBlockSize = "fio.block-size" - optFioDirect = "fio.direct" - optFioIoDepth = "fio.iodepth" - optFioSize = "fio.size" - optFioNumJobs = "fio.numjobs" -) - -type RwFioOp struct { - BandwidthKb int `json:"bw"` - IOPS float64 `json:"iops"` -} - -type fioResult struct { - GlobalOptions struct { - IOEngine string `json:"ioengine"` - RW string `json:"rw"` - } `json:"global options"` - Jobs []struct { - JobName string `json:"jobname"` - Read RwFioOp `json:"read"` - Write RwFioOp `json:"write"` - } `json:"jobs"` -} - -// Run fio in k8s metrics test in K8s -func (c fioTestConfig) run() (result fioResult, err error) { - log.Infof("Running fio config: %s", c.jobFile) - - pod := k8s.Pod{YamlPath: c.k8sYaml} - - log.Infof("Delete pod if already created") - err = pod.Delete() - if err != nil { - return result, err - } - - log.Infof("Create pod: %s", pod.YamlPath) - err = pod.Run() - if err != nil { - return result, err - } - - defer func() { - log.Info("Deleting pod") - delErr := pod.Delete() - if delErr != nil { - log.Error(delErr) - if err != nil { - err = errors.Wrapf(err, "Could not delete pod after: %s", delErr) - } - } - }() - - destDir := "/home/fio-jobs" - _, err = pod.Exec("mkdir " + destDir) - if err != nil { - return result, err - } - - dstJobFile := path.Join(destDir, "jobFile") - err = pod.CopyFromHost(c.jobFile, dstJobFile) - if err != nil { - return result, err - } - - _, err = pod.Exec("apt update") - if err != nil { - return result, err - } - _, err = pod.Exec("apt install -y fio") - if err != nil { - return result, err - } - - err = env.DropCaches() - if err != nil { - return result, err - } - - var directStr string - if c.direct { - directStr = "1" - } else { - directStr = "0" - } - - cmdFio := "fio" - cmdFio += " --append-terse " - cmdFio += " --blocksize=" + c.blocksize - cmdFio += " --direct=" + directStr - cmdFio += " --directory=" + c.directory - cmdFio += " --iodepth=" + c.iodepth - cmdFio += " --numjobs=" + c.numjobs - cmdFio += " --runtime=" + c.runtime - cmdFio += " --size=" + c.size - cmdFio += " --output-format=json" - cmdFio += " " + dstJobFile - - log.Infof("Exec fio") - output, err := pod.Exec(cmdFio, k8s.ExecOptShowStdOut()) - if err != nil { - return result, err - } - err = json.Unmarshal([]byte(output), &result) - if err != nil { - return result, errors.Wrapf(err, "failed to unmarshall output : %s", output) - } - - log.Infof("ioengine:%s", result.GlobalOptions.IOEngine) - log.Infof("rw:%s", result.GlobalOptions.RW) - if len(result.Jobs) == 0 { - return result, errors.New("No jobs found after parsing fio results") - } - - testDir := path.Join(c.outputDir, filepath.Base(c.jobFile)) - err = os.MkdirAll(testDir, 0775) - if err != nil { - return result, errors.Wrapf(err, "failed to create test directory for :%s", c.jobFile) - } - outputFile := path.Join(testDir, "output.json") - log.Infof("Store results output in : %s", outputFile) - - err = os.WriteFile(outputFile, []byte(output), 0644) - if err != nil { - return result, err - } - - return result, nil -} - -type fioTestConfig struct { - //test options - k8sYaml string - containerRuntime string - outputDir string - - //fio options - blocksize string - directory string - iodepth string - numjobs string - jobFile string - loops string - runtime string - size string - - direct bool -} - -func runFioJobs(testDirPath string, cfg fioTestConfig) (results []fioResult, err error) { - fioJobsDir, err := filepath.Abs(path.Join(testDirPath, "fio-jobs")) - if err != nil { - return results, err - } - - files, err := os.ReadDir(fioJobsDir) - if err != nil { - log.Fatal(err) - return results, err - } - - if cfg.containerRuntime == "" { - return results, errors.New("containerRuntime is empty") - } - - podYAMLName := cfg.containerRuntime + ".yaml" - cfg.k8sYaml = path.Join(testDirPath, podYAMLName) - - if len(files) == 0 { - return results, errors.New("No fio configs found") - } - - for _, file := range files { - cfg.jobFile = path.Join(fioJobsDir, file.Name()) - r, err := cfg.run() - if err != nil { - return results, err - } - results = append(results, r) - - log.Infof("workload:%s", r.Jobs[0].JobName) - log.Infof("bw_r:%d", r.Jobs[0].Read.BandwidthKb) - log.Infof("IOPS_r:%f", r.Jobs[0].Read.IOPS) - log.Infof("bw_w:%d", r.Jobs[0].Write.BandwidthKb) - log.Infof("IOPS_w:%f", r.Jobs[0].Write.IOPS) - - waitTime := 5 - log.Debugf("Sleep %d seconds(if not wait sometimes create another pod timesout)", waitTime) - time.Sleep(time.Duration(waitTime) * time.Second) - } - return results, err - -} - -func generateResultsView(testName string, results []fioResult, outputDir string) error { - outputFile := path.Join(outputDir, "results.csv") - f, err := os.Create(outputFile) - if err != nil { - return err - } - defer f.Close() - - log.Infof("Creating results output in %s", outputFile) - - w := csv.NewWriter(f) - - headers := []string{"NAME", "WORKLOAD", "bw_r", "bw_w", "IOPS_r", "IOPS_w"} - err = w.Write(headers) - if err != nil { - return err - } - - for _, r := range results { - if len(r.Jobs) == 0 { - return errors.Errorf("fio result has no jobs: %v", r) - } - row := []string{testName} - row = append(row, r.Jobs[0].JobName) - row = append(row, fmt.Sprintf("%d", r.Jobs[0].Read.BandwidthKb)) - row = append(row, fmt.Sprintf("%d", r.Jobs[0].Write.BandwidthKb)) - row = append(row, fmt.Sprintf("%f", r.Jobs[0].Read.IOPS)) - row = append(row, fmt.Sprintf("%f", r.Jobs[0].Write.IOPS)) - if err := w.Write(row); err != nil { - return err - } - } - - w.Flush() - - return w.Error() -} - -func main() { - - app := &cli.App{ - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: optDebug, - Usage: "Logs in debug level", - }, - &cli.StringFlag{ - Name: optTestName, - Value: "kata-fio-test", - Usage: "Change the fio test name for reports", - }, - &cli.StringFlag{ - Name: optOutputDir, - Value: ".", - Usage: "Use a file to store results", - }, - &cli.StringFlag{ - Name: optContainerRuntime, - Value: "kata", - Usage: "Choose the runtime to use", - }, - //fio options - &cli.StringFlag{ - Name: optFioSize, - Value: "200M", - Usage: "File size to use for tests", - }, - &cli.StringFlag{ - Name: optFioBlockSize, - Value: "4K", - Usage: "Block size for fio tests", - }, - &cli.BoolFlag{ - Name: optFioDirect, - Usage: "Use direct io", - }, - &cli.StringFlag{ - Name: optFioIoDepth, - Value: "16", - Usage: "Number of I/O units to keep in flight against the file", - }, - &cli.StringFlag{ - Name: optFioNumJobs, - Value: "1", - Usage: "Number of clones (processes/threads performing the same workload) of this job", - }, - }, - Action: func(c *cli.Context) error { - jobsDir := c.Args().First() - - if jobsDir == "" { - cli.SubcommandHelpTemplate = strings.Replace(cli.SubcommandHelpTemplate, "[arguments...]", "", -1) - cli.ShowCommandHelp(c, "") - return errors.New("Missing ") - } - - if c.Bool(optDebug) { - log.SetLevel(logrus.DebugLevel) - k8s.Debug = true - env.Debug = true - } - - exec.SetLogger(log) - k8s.SetLogger(log) - env.SetLogger(log) - - testName := c.String(optTestName) - - outputDir, err := filepath.Abs(path.Join(c.String(optOutputDir), testName)) - if err != nil { - return err - } - - cfg := fioTestConfig{ - blocksize: c.String(optFioBlockSize), - direct: c.Bool(optFioDirect), - directory: ".", - iodepth: c.String(optFioIoDepth), - loops: "3", - numjobs: c.String(optFioNumJobs), - runtime: "20", - size: c.String(optFioSize), - containerRuntime: c.String(optContainerRuntime), - outputDir: outputDir, - } - - log.Infof("Results will be created in %s", cfg.outputDir) - - err = os.MkdirAll(cfg.outputDir, 0775) - if err != nil { - return err - } - - results, err := runFioJobs(jobsDir, cfg) - if err != nil { - return err - } - - return generateResultsView(c.String(optTestName), results, outputDir) - }, - } - - err := app.Run(os.Args) - if err != nil { - log.Fatal(err) - } - -} diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-async.job b/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-async.job deleted file mode 100644 index 9e0edb96c2a9..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-async.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2022 Intel Corporation -[global] -name=io_uring -filename=fio-file -rw=randrw -rwmixread=75 -ioengine=io_uring - -[randrw-io_uring] diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-libaio.job b/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-libaio.job deleted file mode 100644 index 327852e442cb..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-libaio.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randrw-libaio -filename=fio-file -rw=randrw -rwmixread=75 -ioengine=libaio - -[randrw-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-sync.job b/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-sync.job deleted file mode 100644 index 3f7f2b6ed867..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/fio-jobs/randrw-sync.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2022 Intel Corporation -[global] -name=sync -filename=fio-file -rw=randrw -rwmixread=75 -ioengine=sync - -[randrw-sync] diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/kata-clh.yaml b/tests/metrics/storage/fio-k8s/configs/example-config/kata-clh.yaml deleted file mode 100644 index 0744fe0133ff..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/kata-clh.yaml +++ /dev/null @@ -1,17 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - runtimeClassName: kata-clh - containers: - - args: - - sleep - - infinity - image: ubuntu:latest - name: iometrics - imagePullPolicy: Always diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/kata-qemu.yaml b/tests/metrics/storage/fio-k8s/configs/example-config/kata-qemu.yaml deleted file mode 100644 index 8d7cb33195d6..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/kata-qemu.yaml +++ /dev/null @@ -1,17 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - runtimeClassName: kata-qemu - containers: - - args: - - sleep - - infinity - image: ubuntu:latest - name: iometrics - imagePullPolicy: Always diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/kata.yaml b/tests/metrics/storage/fio-k8s/configs/example-config/kata.yaml deleted file mode 100644 index 08f397deae29..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/kata.yaml +++ /dev/null @@ -1,16 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - runtimeClassName: kata - containers: - - name: iometrics - image: ubuntu:latest - # Just spin & wait forever - command: [ "/bin/bash", "-c", "--" ] - args: [ "sleep infinity" ] diff --git a/tests/metrics/storage/fio-k8s/configs/example-config/runc.yaml b/tests/metrics/storage/fio-k8s/configs/example-config/runc.yaml deleted file mode 100644 index 4fd96d3c1e90..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/example-config/runc.yaml +++ /dev/null @@ -1,15 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - containers: - - name: iometrics - image: ubuntu:latest - # Just spin & wait forever - command: [ "/bin/bash", "-c", "--" ] - args: [ "sleep infinity" ] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-libaio.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-libaio.job deleted file mode 100644 index 5ab22606109d..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-libaio.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randread-libaio -filename=fio-file -rw=randread -ioengine=libaio - -[randread-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-mmpap.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-mmpap.job deleted file mode 100644 index cd79854f2687..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randread-mmpap.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randread-mmap -rw=randread -ioengine=mmap - -[randread-mmap] -filename=fio-file diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-libaio.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-libaio.job deleted file mode 100644 index 327852e442cb..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-libaio.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randrw-libaio -filename=fio-file -rw=randrw -rwmixread=75 -ioengine=libaio - -[randrw-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-mmap.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-mmap.job deleted file mode 100644 index cf0c1288a997..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randrw-mmap.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randrw-mmap -rw=randrw -rwmixread=75 -ioengine=mmap - -[randrw-mmap] -filename=fio-file diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-libaio.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-libaio.job deleted file mode 100644 index ef3bfc5a5666..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-libaio.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randwrite-libaio -filename=fio-file -rw=randwrite -ioengine=libaio - -[randwrite-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-mmap.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-mmap.job deleted file mode 100644 index 0d4f6ef73ad8..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/randwrite-mmap.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=randwrite-mmap -rw=randwrite -ioengine=mmap - -[randwrite-mmap] -filename=fio-file diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-libaio.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-libaio.job deleted file mode 100644 index 6f8a16a3fa26..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-libaio.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=seqread-libaio -filename=fio-file -rw=read -ioengine=libaio - -[seqread-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-mmap.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-mmap.job deleted file mode 100644 index 9829726d3a34..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-mmap.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=seqread-mmap -rw=read -ioengine=mmap - -[seqread-mmap] -filename=fio-file diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-psync.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-psync.job deleted file mode 100644 index a1f54ca7c098..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqread-psync.job +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=seqread-psync -filename=fio-file -rw=read - -[seqread-psync] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-libaio.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-libaio.job deleted file mode 100644 index 9927e05c98d5..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-libaio.job +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=seqwrite-libaio -filename=fio-file -rw=write -ioengine=libaio - -[seqwrite-libaio] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-mmap.job b/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-mmap.job deleted file mode 100644 index e3485db4f667..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/fio-jobs/seqwrite-mmap.job +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2021 Intel Corporation -[global] -name=seqwrite-mmap -filename=fio-file -rw=write -ioengine=mmap - -[seqwrite-mmap] -filename=fio-file diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/kata.yaml b/tests/metrics/storage/fio-k8s/configs/test-config/kata.yaml deleted file mode 100644 index 08f397deae29..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/kata.yaml +++ /dev/null @@ -1,16 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - runtimeClassName: kata - containers: - - name: iometrics - image: ubuntu:latest - # Just spin & wait forever - command: [ "/bin/bash", "-c", "--" ] - args: [ "sleep infinity" ] diff --git a/tests/metrics/storage/fio-k8s/configs/test-config/runc.yaml b/tests/metrics/storage/fio-k8s/configs/test-config/runc.yaml deleted file mode 100644 index 4fd96d3c1e90..000000000000 --- a/tests/metrics/storage/fio-k8s/configs/test-config/runc.yaml +++ /dev/null @@ -1,15 +0,0 @@ -## Copyright (c) 2021 Intel Corporation -# -## SPDX-License-Identifier: Apache-2.0 -# -apiVersion: v1 -kind: Pod -metadata: - name: iometrics -spec: - containers: - - name: iometrics - image: ubuntu:latest - # Just spin & wait forever - command: [ "/bin/bash", "-c", "--" ] - args: [ "sleep infinity" ] diff --git a/tests/metrics/storage/fio-k8s/fio-test-ci.sh b/tests/metrics/storage/fio-k8s/fio-test-ci.sh deleted file mode 100755 index 9933bffdb2f1..000000000000 --- a/tests/metrics/storage/fio-k8s/fio-test-ci.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2022-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -set -e - -# General env -SCRIPT_PATH=$(dirname "$(readlink -f "$0")") -source "${SCRIPT_PATH}/../../lib/common.bash" -FIO_PATH="${GOPATH}/tests/metrics/storage/fio-k8s" -TEST_NAME="${TEST_NAME:-fio}" - -function main() { - cmds=("bc" "jq") - check_cmds "${cmds[@]}" - init_env - check_processes - - pushd "${FIO_PATH}" - [ -z "${KATA_HYPERVISOR}" ] && die "Hypervisor ID is missing." - [ "${KATA_HYPERVISOR}" != "qemu" ] && [ "${KATA_HYPERVISOR}" != "clh" ] && die "Hypervisor not recognized: ${KATA_HYPERVISOR}" - - echo "INFO: Running K8S FIO test using ${KATA_HYPERVISOR} hypervisor" - make "test-${KATA_HYPERVISOR}" - popd - - test_result_file="${FIO_PATH}/cmd/fiotest/test-results/kata/randrw-sync.job/output.json" - - metrics_json_init - local read_io=$(cat $test_result_file | grep io_bytes | head -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local read_bw=$(cat $test_result_file | grep bw_bytes | head -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local read_90_percentile=$(cat $test_result_file | grep 90.000000 | head -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local read_95_percentile=$(cat $test_result_file | grep 95.000000 | head -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local write_io=$(cat $test_result_file | grep io_bytes | head -2 | tail -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local write_bw=$(cat $test_result_file | grep bw_bytes | head -2 | tail -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local write_90_percentile=$(cat $test_result_file | grep 90.000000 | head -2 | tail -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - local write_95_percentile=$(cat $test_result_file | grep 95.000000 | head -2 | tail -1 | sed 's/[[:blank:]]//g' | cut -f2 -d ':' | cut -f1 -d ',') - - metrics_json_start_array - local json="$(cat << EOF - { - "readio": { - "Result" : $read_io, - "Units" : "bytes" - }, - "readbw": { - "Result" : $read_bw, - "Units" : "bytes/sec" - }, - "read90percentile": { - "Result" : $read_90_percentile, - "Units" : "ns" - }, - "read95percentile": { - "Result" : $read_95_percentile, - "Units" : "ns" - }, - "writeio": { - "Result" : $write_io, - "Units" : "bytes" - }, - "writebw": { - "Result" : $write_bw, - "Units" : "bytes/sec" - }, - "write90percentile": { - "Result" : $write_90_percentile, - "Units" : "ns" - }, - "write95percentile": { - "Result" : $write_95_percentile, - "Units" : "ns" - } - } -EOF -)" - metrics_json_add_array_element "$json" - metrics_json_end_array "Results" - metrics_json_save - - check_processes -} - -main "$@" diff --git a/tests/metrics/storage/fio-k8s/pkg/env/Makefile b/tests/metrics/storage/fio-k8s/pkg/env/Makefile deleted file mode 100644 index a1c0a7779c7f..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/env/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2021-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# - -gomod: - GO111MODULE=on go mod edit -replace=github.com/kata-containers/kata-containers/tests/metrics/exec=../exec - GO111MODULE=on go mod tidy diff --git a/tests/metrics/storage/fio-k8s/pkg/env/env.go b/tests/metrics/storage/fio-k8s/pkg/env/env.go deleted file mode 100644 index 034127f96239..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/env/env.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2021-2023 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -package env - -import ( - exec "github.com/kata-containers/kata-containers/tests/metrics/exec" -) - -// logger interface for pkg -var log logger -var Debug bool = false - -type logger interface { - Infof(string, ...interface{}) - Debugf(string, ...interface{}) - Errorf(string, ...interface{}) -} - -func SetLogger(l logger) { - log = l -} - -var sysDropCachesPath = "/proc/sys/vm/drop_caches" - -func DropCaches() (err error) { - log.Infof("drop caches") - _, err = exec.ExecCmd("sync", Debug) - if err != nil { - return err - } - - _, err = exec.ExecCmd("echo 3 | sudo tee "+sysDropCachesPath, Debug) - if err != nil { - return err - } - return nil -} diff --git a/tests/metrics/storage/fio-k8s/pkg/env/go.mod b/tests/metrics/storage/fio-k8s/pkg/env/go.mod deleted file mode 100644 index 4e59e60d9675..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/env/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/kata-containers/kata-containers/tests/metrics/storage/fio-k8s/exec - -go 1.19 - -require ( - github.com/kata-containers/kata-containers/tests/metrics/exec v0.0.0-00010101000000-000000000000 // indirect - github.com/pkg/errors v0.9.1 // indirect -) - -replace github.com/kata-containers/kata-containers/tests/metrics/exec => ../exec diff --git a/tests/metrics/storage/fio-k8s/pkg/env/go.sum b/tests/metrics/storage/fio-k8s/pkg/env/go.sum deleted file mode 100644 index 7c401c3f58b8..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/env/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/tests/metrics/storage/fio-k8s/pkg/exec/Exec.go b/tests/metrics/storage/fio-k8s/pkg/exec/Exec.go deleted file mode 100644 index 6e409f427a9f..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/exec/Exec.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2021-2023 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -package exec - -import ( - "bytes" - "io" - "os" - "os/exec" - - "github.com/pkg/errors" -) - -// logger interface for pkg -var log logger - -type logger interface { - Infof(string, ...interface{}) - Debugf(string, ...interface{}) - Errorf(string, ...interface{}) -} - -func SetLogger(l logger) { - log = l -} - -// Exec a command -// err != nil if command fails to execute -// output is a string with a combined stdout and stderr -func ExecCmd(c string, showInStdout bool) (stdout string, err error) { - if c == "" { - return "", errors.New("command is empty") - } - - log.Debugf("Exec: %s", c) - cmd := exec.Command("bash", "-o", "pipefail", "-c", c) - var stdBuffer bytes.Buffer - var writers []io.Writer - writers = append(writers, &stdBuffer) - if showInStdout { - writers = append(writers, os.Stdout) - } - mw := io.MultiWriter(writers...) - - cmd.Stdout = mw - cmd.Stderr = mw - - err = cmd.Run() - output := stdBuffer.String() - - return stdBuffer.String(), errors.Wrap(err, output) -} - -// Exec a command -// Send output to Stdout and Stderr -func ExecStdout(c string) error { - if c == "" { - return errors.New("command is empty") - } - - log.Debugf("Exec: %s", c) - cmd := exec.Command("bash", "-o", "pipefail", "-c", c) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} diff --git a/tests/metrics/storage/fio-k8s/pkg/exec/go.mod b/tests/metrics/storage/fio-k8s/pkg/exec/go.mod deleted file mode 100644 index c74fcbeb83d1..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/exec/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/kata-containers/kata-containers/tests/metrics/storage/fio-k8s/exec - -go 1.19 - -require github.com/pkg/errors v0.9.1 diff --git a/tests/metrics/storage/fio-k8s/pkg/exec/go.sum b/tests/metrics/storage/fio-k8s/pkg/exec/go.sum deleted file mode 100644 index 7c401c3f58b8..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/exec/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/tests/metrics/storage/fio-k8s/pkg/k8s/Makefile b/tests/metrics/storage/fio-k8s/pkg/k8s/Makefile deleted file mode 100644 index f5bee6d16fb6..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/k8s/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2021-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# -gomod: - GO111MODULE=on go mod edit -replace=github.com/kata-containers/kata-containers/tests/metrics/exec=../exec - GO111MODULE=on go mod tidy diff --git a/tests/metrics/storage/fio-k8s/pkg/k8s/exec.go b/tests/metrics/storage/fio-k8s/pkg/k8s/exec.go deleted file mode 100644 index 9be25f618413..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/k8s/exec.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2021-2023 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -package k8s - -import ( - "fmt" - - exec "github.com/kata-containers/kata-containers/tests/metrics/exec" -) - -type execOpt struct { - showInStdOut bool -} - -type ExecOption func(e *execOpt) - -func ExecOptShowStdOut() ExecOption { - return func(e *execOpt) { - e.showInStdOut = true - } - -} - -func (p *Pod) Exec(cmd string, opts ...ExecOption) (output string, err error) { - log.Debugf("Exec %q in %s", cmd, p.YamlPath) - o := &execOpt{showInStdOut: false} - for _, opt := range opts { - opt(o) - - } - execCmd := fmt.Sprintf("kubectl exec -f %s -- /bin/bash -c %q", p.YamlPath, cmd) - return exec.ExecCmd(execCmd, Debug || o.showInStdOut) -} diff --git a/tests/metrics/storage/fio-k8s/pkg/k8s/go.mod b/tests/metrics/storage/fio-k8s/pkg/k8s/go.mod deleted file mode 100644 index 6a349002a210..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/k8s/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/kata-containers/kata-containers/tests/metrics/k8s - -go 1.19 - -replace github.com/kata-containers/kata-containers/tests/metrics/exec => ../exec - -require ( - github.com/kata-containers/kata-containers/tests/metrics/exec v0.0.0-00010101000000-000000000000 // indirect - github.com/pkg/errors v0.9.1 // indirect -) diff --git a/tests/metrics/storage/fio-k8s/pkg/k8s/go.sum b/tests/metrics/storage/fio-k8s/pkg/k8s/go.sum deleted file mode 100644 index 7c401c3f58b8..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/k8s/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/tests/metrics/storage/fio-k8s/pkg/k8s/k8s.go b/tests/metrics/storage/fio-k8s/pkg/k8s/k8s.go deleted file mode 100644 index 2fef788cc121..000000000000 --- a/tests/metrics/storage/fio-k8s/pkg/k8s/k8s.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2021-2023 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -package k8s - -import ( - "fmt" - - exec "github.com/kata-containers/kata-containers/tests/metrics/exec" - "github.com/pkg/errors" -) - -// logger interface for pkg -var log logger -var Debug bool = false - -type logger interface { - Infof(string, ...interface{}) - Debugf(string, ...interface{}) - Errorf(string, ...interface{}) -} - -func SetLogger(l logger) { - log = l -} - -type Pod struct { - YamlPath string -} - -func (p *Pod) waitForReady() (err error) { - log.Debugf("Wait for pod %s", p.YamlPath) - _, err = exec.ExecCmd("kubectl wait --for=condition=ready -f "+p.YamlPath, Debug) - return err -} - -func (p *Pod) Run() (err error) { - - log.Debugf("Creating K8s Pod %s", p.YamlPath) - _, err = exec.ExecCmd("kubectl apply -f "+p.YamlPath, Debug) - if err != nil { - return errors.Wrapf(err, "Failed to run pod %s", p.YamlPath) - } - - err = p.waitForReady() - if err != nil { - return errors.Wrapf(err, "Failed to wait for pod %s", p.YamlPath) - } - return err -} - -func (p *Pod) Delete() (err error) { - log.Debugf("Delete pod %s", p.YamlPath) - _, err = exec.ExecCmd("kubectl delete --ignore-not-found -f "+p.YamlPath, Debug) - return errors.Wrapf(err, "Failed to delete pod %s", p.YamlPath) -} - -func (p *Pod) CopyFromHost(src, dst string) (err error) { - podName, err := exec.ExecCmd("kubectl get -f "+p.YamlPath+" -o jsonpath={.metadata.name}", Debug) - if err != nil { - return nil - } - - log.Debugf("Copy from host %q->%q in pod %s", src, dst, p.YamlPath) - execCmd := fmt.Sprintf("kubectl cp %s %s:%s", src, podName, dst) - _, err = exec.ExecCmd(execCmd, Debug) - return err -} diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/Makefile b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/Makefile deleted file mode 100644 index a33a5015c0d1..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2021-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# -MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -MKFILE_DIR := $(dir $(MKFILE_PATH)) -run: - $(MKFILE_DIR)/compare-virtiofsd-dax.sh - "$(MKFILE_DIR)/report/gen-html-fio-report.sh" "./results" diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/README.md b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/README.md deleted file mode 100644 index c8b00f0f98f3..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# FIO in Kubernetes - -This test runs `fio` jobs to measure how Kata Containers work using virtio-fs DAX. The test works using Kubernetes. -The test has to run in a single node cluster, it is needed as the test modifies Kata configuration file. - -The `virtio-fs` options that this test will use are: - -* `cache mode` Only `auto`, this is the most compatible mode for most of the Kata use cases. Today this is default in Kata. -* `thread pool size` Restrict the number of worker threads per request queue, zero means no thread pool. -* `DAX` -``` -File contents can be mapped into a memory window on the host, allowing the guest to directly access data from the host page cache. This has several advantages: The guest page cache is bypassed, reducing the memory footprint. No communication is necessary -to access file contents, improving I/O performance. Shared file access is coherent between virtual machines on the same host even with mmap. -``` - -This test by default iterates over different `virtio-fs` configurations. - -| test name | DAX | thread pool size | cache mode | -|---------------------------|-----|------------------|------------| -| pool_0_cache_auto_no_DAX | no | 0 | auto | -| pool_0_cache_auto_DAX | yes | 0 | auto | - -The `fio` options used are: - -`ioengine`: How the IO requests are issued to the kernel. -* `libaio`: Supports async IO for both direct and buffered IO. -* `mmap`: File is memory mapped with mmap(2) and data copied to/from using memcpy(3). - -`rw type`: Type of I/O pattern. -* `randread`: Random reads. -* `randrw`: Random mixed reads and writes. -* `randwrite`: Random writes. -* `read`: Sequential reads. -* `write`: Sequential writes. - -Additional notes: Some jobs contain a `multi` prefix. This means that the same job runs more than once at the same time using its own file. - -### Static `fio` values: - -Some `fio` values are not modified over all the jobs. - -* `runtime`: Tell `fio` to terminate processing after the specified period of time(seconds). -* `loops`: Run the specified number of iterations of this job. Used to repeat the same workload a given number of times. -* `iodepth`: Number of I/O units to keep in flight against the file. Note that increasing `iodepth` beyond 1 will not affect synchronous `ioengine`. -* `size`: The total size of file I/O for each thread of this job. -* `direct`: If value is true, use non-buffered I/O. This is usually O_`DIRECT`. -* `blocksize`: The block size in bytes used for I/O units. diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/compare-virtiofsd-dax.sh b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/compare-virtiofsd-dax.sh deleted file mode 100755 index 248e37776279..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/compare-virtiofsd-dax.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash -#Copyright (c) 2021-2023 Intel Corporation -# -#SPDX-License-Identifier: Apache-2.0 -# - -set -o errexit -set -o nounset -set -o pipefail -set -o errtrace - -script_dir=$(dirname "$(readlink -f "$0")") - -runtime_path="/opt/kata/bin/kata-runtime" -kata_config_path="/opt/kata/share/defaults/kata-containers/configuration.toml" - -results_dir="$(realpath ./)/results" - -KATA_RUNTIME="${KATA_RUNTIME_CLASS:-kata}" -BAREMETAL_RUNTIME="runc" -RUNTIME_CLASS="" - -FIO_SIZE="${FIO_SIZE:-500M}" -FIO_BLOCKSIZE="${FIO_BLOCKSIZE:-4K}" -VIRTIOFS_DAX_SIZE=${VIRTIOFS_DAX_SIZE:-600M} - -# set the base case for virtiofsd -set_base_virtiofs_config() { - # Running kata-qemu-virtiofs - # Defaults for virtiofs - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache '"auto"' - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache_size ${VIRTIOFS_DAX_SIZE} -} - -## helper function: get name of current bash function -fn_name() { - echo "${FUNCNAME[1]}" -} - -# directory where results are stored -get_results_dir() { - local test_name - local test_result_dir - test_name="${1}" - test_result_dir="${results_dir}/${test_name}" - mkdir -p "${test_result_dir}" - echo "${test_result_dir}" -} - -# Collect kata env -# save kata config toml -# save output from kata-env -kata_env() { - local suffix=${1} - local config_path - local kata_env_bk - local kata_config_bk - kata_env_bk="$(get_results_dir "${suffix}")/kata-env.toml" - kata_config_bk="$(get_results_dir "${suffix}")/kata-config.toml" - - ${runtime_path} kata-env >"${kata_env_bk}" - config_path="$(${runtime_path} kata-env --json | jq .Runtime.Config.Path -r)" - cp "${config_path}" "${kata_config_bk}" -} - -# Collect the command used by virtiofsd -collect_qemu_virtiofs_cmd() { - local rdir - local test_name - test_name="${1}" - - rdir=$(get_results_dir "${test_name}") - # TODO -} - -# Run metrics runner -run_workload() { - local test_name - local test_result_file - local test_result_dir - - test_name="${1}" - - test_result_dir="$(get_results_dir "${test_name}")" - test_result_file="${test_result_dir}/test-out.txt" - - echo "Running for kata config: ${test_name}" - collect_qemu_virtiofs_cmd "$test_name" - - fio_runner_dir="${script_dir}/../../cmd/fiotest/" - fio_jobs="${script_dir}/../../configs/test-config/" - make -C "${fio_runner_dir}" build - pwd - set -x - "${fio_runner_dir}fio-k8s" \ - --debug \ - --fio.size "${FIO_SIZE}" \ - --fio.block-size "${FIO_BLOCKSIZE}" \ - --container-runtime "${RUNTIME_CLASS}" \ - --test-name "${test_name}" \ - --output-dir "$(dirname ${test_result_dir})" \ - "${fio_jobs}" | - tee \ - "${test_result_file}" - set +x -} - -pool_0_cache_auto_dax() { - local suffix="$(fn_name)" - - set_base_virtiofs_config - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_extra_args '["--thread-pool-size=0","-o","no_posix_lock","-o","xattr"]' - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache '"auto"' - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache_size 1024 - kata_env "${suffix}" - RUNTIME_CLASS="${KATA_RUNTIME}" - run_workload "${suffix}" -} - -pool_0_cache_auto_no_dax() { - local suffix="$(fn_name)" - - set_base_virtiofs_config - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_extra_args '["--thread-pool-size=0","-o","no_posix_lock","-o","xattr"]' - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache '"auto"' - sudo crudini --set --existing "$kata_config_path" hypervisor.qemu virtio_fs_cache_size 0 - - kata_env "${suffix}" - - RUNTIME_CLASS="${KATA_RUNTIME}" - run_workload "${suffix}" - echo "done" -} - -k8s_baremetal() { - local suffix="$(fn_name)" - - RUNTIME_CLASS="${BAREMETAL_RUNTIME}" - run_workload "${suffix}" -} - -main() { - - mkdir -p "${results_dir}" - - k8s_baremetal - pool_0_cache_auto_dax - pool_0_cache_auto_no_dax -} - -main $* diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.ipynb b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.ipynb deleted file mode 100644 index d2e8da202315..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.ipynb +++ /dev/null @@ -1,51 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "tWacOPbMYPtc" - }, - "source": [ - "# FIO comparision" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "jXtTs6yldl_y" - }, - "outputs": [], - "source": [ - "import fio\n", - "fio.generate_report()" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "fio.ipynb", - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.py b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.py deleted file mode 100644 index 313f63313061..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/fio.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) 2021-2023 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -import pandas as pd -import os -import re -import io -import glob -from IPython.display import display, Markdown -import matplotlib.pyplot as plt - -#Compare the tests results group by fio job. -#Input: -# df: dataset from `import_data()` -# metric: string of metrics provided in `df` -def compare_tests_group_by_fio_job(df, metric): - test_names, metric_df = group_metrics_group_by_testname(df, metric) - show_df(metric_df) - plot_df(metric_df,test_names) - -# Given a metric return results per test group by fio job. -# input: -# df: dataset from `import_data()` -# metric: string with the name of the metric to filter. -# output: -# dataset with fomat: -# 'workload' , 'name[0]' , ... , 'name[n]' -# -def group_metrics_group_by_testname(df, metric): - #name of each tests from results - names = set() - # Rows of new data set - rows = [] - # map: - # keys: name of fio job - # value: dict[k]:v where k: name of a test, v: value of test for metric` - workload = {} - - for k, row in df.iterrows(): - # name of a fio job - w = row['WORKLOAD'] - # name of tests - tname = row['NAME'] - names.add(tname) - # given a fio job name get dict of values - # if not previous values init empty dict - dict_values = workload.get(w, {}) - # For a given metric, add it into as value of dict_values[testname]=val - #e.g - # dict_values["test-name"] = row["IOPS"] - dict_values[tname] = row[metric] - workload[w] = dict_values - - names = list(names) - cols = ['WORKLOAD'] + list(names) - rdf = pd.DataFrame(workload,columns = cols) - - for k in workload: - d = workload[k] - - if not d[names[0]] == 0: - d["WORKLOAD"] = k; - rdf = rdf.append(d,ignore_index=True) - rdf = rdf.dropna() - return names, rdf - -def plot_df(df, names,sort_key=""): - if sort_key != "": - df.sort_values(sort_key, ascending=False) - df.plot(kind='bar',x="WORKLOAD",y=names, figsize=(30, 10)) - plt.show() - - -def import_data(): - frames = [] - for f in glob.glob('./results/*/results.csv'): - print("reading:" + f) - df = pd.read_csv(f) - frames.append(df) - return pd.concat(frames) - -def show_df(df): - pd.set_option('display.max_rows', df.shape[0]+1) - print(df) - -def print_md(s): - display(Markdown(s)) - -#notebook entrypoint -def generate_report(): - #Load the all test results in a single dataset - df_results = import_data() - print_md("Show all data from results") - show_df(df_results) - print_md("### Compare the tests results group by fio job. The metric used to compare is write bandwidth") - compare_tests_group_by_fio_job(df_results, 'bw_w') - print_md("### Compare the tests results group by fio job. The metric used to compare is read bandwidth") - compare_tests_group_by_fio_job(df_results, 'bw_r') - print_md("### Compare the tests results group by fio job. The metric used to compare is write IOPS(Input/Output Operations Per Second)") - compare_tests_group_by_fio_job(df_results, 'IOPS_w') - print_md("### Compare the tests results group by fio job. The metric used to compare is read IOPS(Input/Output Operations Per Second)") - compare_tests_group_by_fio_job(df_results, 'IOPS_r') diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/gen-html-fio-report.sh b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/gen-html-fio-report.sh deleted file mode 100644 index 8061c059d015..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/gen-html-fio-report.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -#Copyright (c) 2021-2023 Intel Corporation -# -#SPDX-License-Identifier: Apache-2.0 -# - -set -o errexit -set -o nounset -set -o pipefail -set -o errtrace - -script_dir=$(dirname "$(readlink -f "$0")") - -results_dir=${1:-} - -usage(){ - echo "$0 " -} - -if [ "${results_dir}" == "" ];then - echo "missing results directory" - usage - exit 1 -fi - -if [ ! -d "${results_dir}" ];then - echo "${results_dir} is not a directory" - usage - exit 1 -fi - -results_dir=$(realpath "${results_dir}") - -generate_report(){ - sudo chown "${USER}:${USER}" -R ${results_dir} - sudo docker run --rm -e JUPYTER_ENABLE_LAB=yes \ - -v "${script_dir}:/home/jovyan" \ - -v "${results_dir}:/home/jovyan/results" \ - --user $(id -u):$(id -g) \ - jupyter/scipy-notebook:399cbb986c6b \ - bash -e -c ' - cd results; - jupyter nbconvert --execute /home/jovyan/fio.ipynb --to html; - cp /home/jovyan/fio.html /home/jovyan/results; - ' -} - -generate_report diff --git a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/run-docker-jupyter-server.sh b/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/run-docker-jupyter-server.sh deleted file mode 100644 index f386da4e2298..000000000000 --- a/tests/metrics/storage/fio-k8s/scripts/dax-compare-test/report/run-docker-jupyter-server.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -#Copyright (c) 2021-2023 Intel Corporation -# -#SPDX-License-Identifier: Apache-2.0 -# - -set -o errexit -set -o nounset -set -o pipefail -set -o errtrace - -script_dir=$(dirname "$(readlink -f "$0")") -NOTEBOOK_PORT="8888" - -results_dir=${1:-} - -usage(){ - echo "$0 " -} - -if [ "${results_dir}" == "" ];then - echo "missing results directory" - usage - exit 1 -fi - -if [ ! -d "${results_dir}" ];then - echo "${results_dir} is not a directory" - usage - exit 1 -fi - -results_dir=$(realpath "${results_dir}") - -sudo -E docker run --rm -p "${NOTEBOOK_PORT}:${NOTEBOOK_PORT}" -e JUPYTER_ENABLE_LAB=yes \ - -v "${script_dir}:/home/jovyan" \ - -v "${results_dir}:/home/jovyan/results" \ - jupyter/scipy-notebook:399cbb986c6b \ - start.sh jupyter lab --LabApp.token='' diff --git a/tests/metrics/storage/fio_test.sh b/tests/metrics/storage/fio_test.sh new file mode 100755 index 000000000000..7ea7deb8e91e --- /dev/null +++ b/tests/metrics/storage/fio_test.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# Description of the test: +# This test runs the 'fio benchmark' on kata containers +# https://fio.readthedocs.io/en/latest/ + +set -o pipefail + +SCRIPT_PATH=$(dirname "$(readlink -f "$0")") +source "${SCRIPT_PATH}/../lib/common.bash" + +CONTAINER_ID="fio_bench_${RANDOM}" +IMAGE="docker.io/library/fio-bench:latest" +DOCKERFILE="${SCRIPT_PATH}/fio-dockerfile/Dockerfile" +PAYLOAD_ARGS="${PAYLOAD_ARGS:-tail -f /dev/null}" +TEST_NAME="fio" + +# Fio default number of jobs +nj=4 + +function release_resources() { + sudo -E "${CTR_EXE}" t exec --exec-id "$(random_name)" ${CONTAINER_ID} sh -c "./fio_bench.sh delete-workload" + sleep 0.5 + clean_env_ctr + info "fio test end" +} + +trap release_resources EXIT + +function setup() { + info "setup fio test" + clean_env_ctr + check_cmds "${cmds[@]}" + check_ctr_images "$IMAGE" "$DOCKERFILE" + init_env + + # drop caches + sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches' + + # launch container + sudo -E "${CTR_EXE}" run -d --runtime "${CTR_RUNTIME}" "${IMAGE}" "${CONTAINER_ID}" sh -c "${PAYLOAD_ARGS}" +} + +function parse_results() { + local data="${1}" + local bw=0 + local bw_stddev=0 + local iops=0 + local iops_stddev=0 + + [ -z "${data}" ] && die "Data results are missing when trying to parsing them." + + local io_type="$(echo "${data}" | jq -r '.jobs[0]."job options".rw')" + + if [ "${io_type}" = "read" ] || [ "${io_type}" = "randread" ]; then + # Bandwidth + bw="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .read.bw] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + bw_stddev="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .read.bw_dev] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + # IOPS + iops="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .read.iops] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + iops_stddev="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .read.iops_stddev] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + elif [ "${io_type}" = "write" ] || [ "${io_type}" = "randwrite" ]; then + # Bandwidth + bw="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .write.bw] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + bw_stddev="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .write.bw_dev] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + # IOPS + iops="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .write.iops] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + iops_stddev="$(echo "${data}" | num_jobs="$nj" jq '[.jobs[] | .write.iops_stddev] | add/(env.num_jobs|tonumber) | .*1000|round/1000')" + else + die "io type ${io_type} is not valid when parsing results" + fi + + convert_results_to_json "${io_type}" "${bw}" "${bw_stddev}" "${iops}" "${iops_stddev}" +} + +function extract_test_params() { + local data="${1}" + [ -z "${data}" ] && die "Missing fio parameters when trying to convert to json format." + + local json_params="$(echo "${data}" | jq -r '.jobs[0]."job options" | del(.name) | del(.rw) | del(.filename)')" + local json="$(cat << EOF + { + "Parameters" : ${json_params} + } +EOF +)" + metrics_json_add_array_element "${json}" +} + +function convert_results_to_json() { + local io_type="${1}" + local bw="${2}" + local bw_stddev="${3}" + local iops="${4}" + local iops_stddev="${5}" + + [ -z "${io_type}" ] || [ -z "${bw}" ] || [ -z "${bw_stddev}" ] || [ -z "${iops}" ] || [ -z "${iops_stddev}" ] && die "Results are missing when trying to convert to json format." + + local json="$(cat << EOF + { + "${io_type}" : { + "bw" : "${bw}", + "bw_stddev" : "${bw_stddev}", + "iops" : "${iops}", + "iops_stddev" : "${iops_stddev}", + "units" : "Kb" + } + } +EOF +)" + metrics_json_add_array_element "${json}" +} + +function store_results() { + local data_r="${1}" + local data_w="${2}" + local title="${3}" + + [ -z "${data_r}" ] || [ -z "${data_w}" ] || [ -z "${title}" ] && die "Missing data and/or title when trying storing results." + + metrics_json_start_array + extract_test_params "${data_r}" + parse_results "${data_r}" + parse_results "${data_w}" + metrics_json_end_array "${title}" +} + +function main() { + setup + + # Collect bs=4K, num_jobs=4, io-direct, io-depth=2 + info "Processing sequential type workload" + sudo -E "${CTR_EXE}" t exec --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh run-read-4k ${nj}" >/dev/null 2>&1 + local results_read_4K="$(sudo -E "${CTR_EXE}" t exec -t --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh print-latest-results")" + + sleep 0.5 + sudo -E "${CTR_EXE}" t exec --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh run-write-4k ${nj}" >/dev/null 2>&1 + local results_write_4K="$(sudo -E "${CTR_EXE}" t exec -t --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh print-latest-results")" + + # Collect bs=64K, num_jobs=4, io-direct, io-depth=2 + info "Processing random type workload" + sleep 0.5 + sudo -E "${CTR_EXE}" t exec --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh run-randread-64k ${nj}" >/dev/null 2>&1 + local results_rand_read_64K="$(sudo -E "${CTR_EXE}" t exec -t --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh print-latest-results")" + + sleep 0.5 + sudo -E "${CTR_EXE}" t exec --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh run-randwrite-64k ${nj}" >/dev/null 2>&1 + local results_rand_write_64K="$(sudo -E "${CTR_EXE}" t exec -t --exec-id "${RANDOM}" ${CONTAINER_ID} sh -c "./fio_bench.sh print-latest-results")" + + # parse results + metrics_json_init + store_results "${results_read_4K}" "${results_write_4K}" "Results sequential" + store_results "${results_rand_read_64K}" "${results_rand_write_64K}" "Results random" + metrics_json_save +} + +main "$@"