mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-11 04:42:16 +00:00
Merge pull request #8082 from dborquez/enable_fio_on_ctr
Enable fio test using containerd client
This commit is contained in:
commit
265f53e594
@ -147,7 +147,7 @@ done)
|
|||||||
EOF
|
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.
|
# If we have a JSON URL or host/socket pair set up, post the results there as well.
|
||||||
# Optionally compress into a single line.
|
# Optionally compress into a single line.
|
||||||
|
26
tests/metrics/storage/fio-dockerfile/Dockerfile
Normal file
26
tests/metrics/storage/fio-dockerfile/Dockerfile
Normal file
@ -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"]
|
129
tests/metrics/storage/fio-dockerfile/workload/fio_bench.sh
Executable file
129
tests/metrics/storage/fio-dockerfile/workload/fio_bench.sh
Executable file
@ -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 <count>
|
||||||
|
Description:
|
||||||
|
Runs FIO test using ctr to excercise IO in kata containers.
|
||||||
|
|
||||||
|
Params: <Operation> <io-engine>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
<Operation>: [Mandatory]
|
||||||
|
<io-engine> : [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 "$@"
|
1
tests/metrics/storage/fio-k8s/.gitignore
vendored
1
tests/metrics/storage/fio-k8s/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
./cmd/fiotest/fio-k8s
|
|
@ -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
|
|
@ -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
|
|
@ -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/
|
|
@ -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
|
|
||||||
)
|
|
@ -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=
|
|
@ -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...]", "<test-config-dir>", -1)
|
|
||||||
cli.ShowCommandHelp(c, "")
|
|
||||||
return errors.New("Missing <test-config-dir>")
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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]
|
|
@ -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]
|
|
@ -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]
|
|
@ -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
|
|
@ -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
|
|
@ -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" ]
|
|
@ -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" ]
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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]
|
|
@ -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
|
|
@ -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" ]
|
|
@ -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" ]
|
|
@ -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 "$@"
|
|
@ -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
|
|
38
tests/metrics/storage/fio-k8s/pkg/env/env.go
vendored
38
tests/metrics/storage/fio-k8s/pkg/env/env.go
vendored
@ -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
|
|
||||||
}
|
|
10
tests/metrics/storage/fio-k8s/pkg/env/go.mod
vendored
10
tests/metrics/storage/fio-k8s/pkg/env/go.mod
vendored
@ -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
|
|
2
tests/metrics/storage/fio-k8s/pkg/env/go.sum
vendored
2
tests/metrics/storage/fio-k8s/pkg/env/go.sum
vendored
@ -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=
|
|
@ -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()
|
|
||||||
}
|
|
@ -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
|
|
@ -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=
|
|
@ -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
|
|
@ -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)
|
|
||||||
}
|
|
@ -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
|
|
||||||
)
|
|
@ -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=
|
|
@ -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
|
|
||||||
}
|
|
@ -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"
|
|
@ -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.
|
|
@ -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 $*
|
|
@ -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
|
|
||||||
}
|
|
@ -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')
|
|
@ -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 <results_dir>"
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
@ -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 <results_dir>"
|
|
||||||
}
|
|
||||||
|
|
||||||
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=''
|
|
161
tests/metrics/storage/fio_test.sh
Executable file
161
tests/metrics/storage/fio_test.sh
Executable file
@ -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 "$@"
|
Loading…
Reference in New Issue
Block a user