From 05864b7a382bd8edccce7d9cbe983187fbd02f11 Mon Sep 17 00:00:00 2001 From: Qianyong Xu <13038089398@163.com> Date: Fri, 25 Oct 2024 13:43:21 +0800 Subject: [PATCH] Github runner add benchmark (#1599) --- .github/workflows/benchmark.yaml | 118 +++++++++++ .github/workflows/static-check.yaml | 1 + Makefile | 11 +- docs/cn/developer-guide/test/benchmark.md | 59 ++++++ licenses/LICENSE_OF_ILOGTAIL_DEPENDENCIES.md | 22 +- .../LICENSE_OF_TESTENGINE_DEPENDENCIES.md | 3 +- scripts/benchmark_collect_result.sh | 49 +++++ test/benchmark/benchmark_docker_test.go | 38 ++++ .../case.feature | 12 ++ .../docker-compose.yaml | 10 + .../filebeat.yml | 20 ++ .../case.feature | 12 ++ .../docker-compose.yaml | 14 ++ .../main.conf | 17 ++ .../parsers.conf | 4 + .../case.feature | 12 ++ .../docker-compose.yaml | 26 +++ .../ilogtail.yaml | 32 +++ .../case.feature | 12 ++ .../docker-compose.yaml | 26 +++ .../ilogtail.yaml | 17 ++ .../case.feature | 12 ++ .../docker-compose.yaml | 8 + .../vector.yaml | 28 +++ test/engine/cleanup/helper.go | 1 + .../setup/controller/docker_compose_boot.go | 4 +- test/engine/setup/docker_compose.go | 16 +- test/engine/setup/dockercompose/common.go | 18 +- .../setup/dockercompose/compose_benchmark.go | 189 ++++++++++++++++++ test/engine/setup/monitor/monitor.go | 147 ++++++++++++++ test/engine/setup/monitor/statistic.go | 156 +++++++++++++++ test/engine/steps.go | 5 + test/engine/trigger/file.go | 114 +++++++++++ test/go.mod | 33 +-- test/go.sum | 53 +++-- 35 files changed, 1243 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/benchmark.yaml create mode 100644 docs/cn/developer-guide/test/benchmark.md create mode 100755 scripts/benchmark_collect_result.sh create mode 100644 test/benchmark/benchmark_docker_test.go create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_filebeat/case.feature create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_filebeat/docker-compose.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_filebeat/filebeat.yml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/case.feature create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/docker-compose.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/main.conf create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/parsers.conf create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/case.feature create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/docker-compose.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/ilogtail.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/case.feature create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/docker-compose.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/ilogtail.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_vector/case.feature create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_vector/docker-compose.yaml create mode 100644 test/benchmark/test_cases/performance_file_to_blackhole_vector/vector.yaml create mode 100644 test/engine/setup/dockercompose/compose_benchmark.go create mode 100644 test/engine/setup/monitor/monitor.go create mode 100644 test/engine/setup/monitor/statistic.go create mode 100644 test/engine/trigger/file.go diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml new file mode 100644 index 0000000000..5cc0ff4411 --- /dev/null +++ b/.github/workflows/benchmark.yaml @@ -0,0 +1,118 @@ +# Copyright 2021 iLogtail Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Benchmark + +on: + pull_request: + branches: + - main + paths-ignore: + - 'docs/**' + - 'example_config/**' + - 'docker/**' + - 'k8s_template/**' + - 'changes/**' + - 'licenses/**' + - 'CHANGELOG.md' + types: + - closed + +jobs: + CI: + if: github.event.pull_request.merged == true + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + matrix: + go-version: [ 1.19.10 ] + runner: [ ubuntu-latest ] + fail-fast: true + permissions: + contents: write + steps: + # Clean up space to prevent action from running out of disk space. + - name: clean + if: matrix.runner == 'ubuntu-latest' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo -E apt-get -qq autoremove --purge + sudo -E apt-get -qq clean + + - name: Check disk space + run: | + df -hT $PWD + + - name: Set up Go ${{ matrix.go-version }} + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + + - name: Check out code + uses: actions/checkout@v2 + with: + submodules: true + + - name: Update Docker-compose to v2 + run: | + sudo curl -SL https://github.com/docker/compose/releases/download/v2.7.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + + - name: System environment + run: | + uname -r + docker --version + go version + + - name: Run benchmark + env: + BUILD_LOGTAIL_UT: OFF + WITHOUTGDB: ON + run: | + make benchmark + git stash + + - name: Store benchmark result iLogtail + uses: benchmark-action/github-action-benchmark@v1 + with: + name: benchmark + tool: "customSmallerIsBetter" + output-file-path: "test/benchmark/report/ilogtail_statistic_all.json" + auto-push: false + summary-always: true + + - name: Store benchmark result other agents + run: | + git checkout gh-pages + mv test/benchmark/report/records_all.json dev/bench/records_all.js + sed -i '1s/^\[/window.BENCHMARK_RECORDS = [/' dev/bench/records_all.js + git add dev/bench/records_all.js + last_commit_message=$(git log -1 --pretty=%B) + git -c user.name=github-action-benchmark -c user.email=github@users.noreply.github.com commit --amend -m "$last_commit_message" + + # TODO: Push gh-pages branch by github-action-bot + # - name: Push benchmark result + # run: git push 'https://alibaba:${{ secrets.GITHUB_TOKEN }}@github.com/alibaba/ilogtail.git' gh-pages:gh-pages + + result: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: [ CI ] + steps: + - name: Build Result + run: echo "Just to make the GitHub merge button green" diff --git a/.github/workflows/static-check.yaml b/.github/workflows/static-check.yaml index db54d1b7a1..b7684a54aa 100644 --- a/.github/workflows/static-check.yaml +++ b/.github/workflows/static-check.yaml @@ -28,6 +28,7 @@ on: branches: - main - 1.* + - benchmark jobs: CI: env: diff --git a/Makefile b/Makefile index 8ba616e018..2d3c129d12 100644 --- a/Makefile +++ b/Makefile @@ -181,12 +181,12 @@ e2e-core: clean gocdocker e2edocker ./scripts/e2e.sh e2e core .PHONY: e2e-performance -e2e-performance: clean docker gocdocker +e2e-performance: clean docker ./scripts/e2e.sh e2e performance .PHONY: unittest_e2e_engine unittest_e2e_engine: clean gocdocker - cd test && go test $$(go list ./... | grep -Ev "engine|e2e") -coverprofile=../e2e-engine-coverage.txt -covermode=atomic -tags docker_ready + cd test && go test $$(go list ./... | grep -Ev "engine|e2e|benchmark") -coverprofile=../e2e-engine-coverage.txt -covermode=atomic -tags docker_ready .PHONY: unittest_plugin unittest_plugin: clean import_plugins @@ -210,6 +210,13 @@ unittest_pluginmanager: clean import_plugins go test $$(go list ./...|grep -Ev "telegraf|external|envconfig"| grep -E "plugin_main|pluginmanager") -coverprofile .coretestCoverage.txt mv ./plugins/input/prometheus/input_prometheus.go.bak ./plugins/input/prometheus/input_prometheus.go +# benchmark +.PHONY: benchmark +benchmark: clean e2edocker + ./scripts/e2e.sh benchmark performance + ./scripts/benchmark_collect_result.sh + + .PHONY: all all: clean import_plugins ./scripts/gen_build_scripts.sh all "$(GENERATED_HOME)" "$(VERSION)" "$(BUILD_REPOSITORY)" "$(OUT_DIR)" "$(DOCKER_BUILD_EXPORT_GO_ENVS)" "$(DOCKER_BUILD_COPY_GIT_CONFIGS)" "$(PLUGINS_CONFIG_FILE)" "$(GO_MOD_FILE)" diff --git a/docs/cn/developer-guide/test/benchmark.md b/docs/cn/developer-guide/test/benchmark.md new file mode 100644 index 0000000000..ed1a59ef93 --- /dev/null +++ b/docs/cn/developer-guide/test/benchmark.md @@ -0,0 +1,59 @@ +# Benchmark测试 + +## 工作原理 +与e2e测试工作原理相同,详情可见: +- [e2e-test.md](./e2e-test.md) + +## 测试流程 + +### 环境准备 + +目前仅支持通过docker-compose搭建测试环境,在准备开始进行benchmark测试前,您首先需要准备以下内容: + +- 测试环境:Docker-Compose环境(需在本地安装docker-compose) + +### 配置文件 + +对于每一个新的benchmark,您需要在`./test/benchmark/test_cases/`目录下创建一个新的feature配置文件。每个配置文件中可以包含多个测试场景,每个测试场景由一个或多个步骤组成。 + +配置文件的基本框架如下: + +```plain +@input +Feature: performance file to blackhole vector + Performance file to blackhole vector + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeVector + Given {docker-compose} environment + Given docker-compose type {benchmark} + When start docker-compose {performance_file_to_blackhole_vector} + When start monitor {vector} + When generate random json logs to file, speed {10}MB/s, total {1}min, to file {./a.log} + When wait monitor until log processing finished +``` + +- `@e2e-performance @docker-compose`: 表示测试场景为e2e-performance,测试场景由本地docker-compose运行 +- `Given {docker-compose} environment`: 配置启动测试环境,以docker-compose环境启动测试 +- `Given docker-compose boot type {benchmark}`: 配置docker-compose启动模式,以benchmark模式启动docker-compose,`{}`中参数有两种选项,`e2e`/`benchmark`。以`e2e`模式启动会默认启动ilogtail、goc-server容器,用作e2e测试;以`benchmark`模式启动会默认启动cadvisor容器,用于监控容器运行过程中的资源占用;若在配置文件中不配置该参数,则默认以上一个scenario的启动模式启动。 +- `When start docker-compose {directory}`: `{}`中参数为当前scenario的文件夹名,该行动作会读取`directory`文件夹下的docker-compose.yaml文件,通过docker-compose命令启动所有容器 +- `When start monitor {vector}`: `{}`中参数为待监控的容器,该参数需要与docker-compose中的service name相同 +- `When generate random logs to file`: 向文件中按照速率生成json格式测试数据,其他生成测试数据的方法请参考[e2e-test-step.md](./e2e-test-step.md) +- `When wait monitor util log processing finished`: 等待采集agent日志收集完成 + +### 运行测试 + +在所有测试内容准备完毕后,您可以直接在test目录下以go test的方式运行E2E测试。根据您的需求,可以选择运行所有测试或者指定测试。 + +```shell +# 运行所有benchmark测试 +go test -v -timeout 30m -run ^TestE2EOnDockerComposePerformance$ github.com/alibaba/ilogtail/test/benchmark + +# 以正则表达式匹配Scenario运行测试,以下为运行Scenario以Vector为结尾的test_case +go test -v -timeout 30m -run ^TestE2EOnDockerComposePerformance$/^.*Vector$ github.com/alibaba/ilogtail/test/benchmark +``` + +### 测试结果 + +- 所有统计结果将以json格式记录在`test/benchmark/report/_statistic.json`中,目前记录了测试过程中CPU最大使用率、CPU平均使用率、内存最大使用率、内存平均使用率参数;所有实时结果序列将以json格式记录在`test/benchmark/report/_records.json`中,目前记录了测试运行过程中的CPU使用率、内存使用率时间序列。 +- 运行`scripts/benchmark_collect_result.sh`会将数据以github benchmark action所需格式汇总,会将`test/benchmark/report/*ilogtail_statistic.json`下所有结果收集并生成汇总结果到`test/benchmark/report/ilogtail_statistic_all.json`中,并将`test/benchmark/report/*records.json`汇总到`test/benchmark/report/records_all.json` \ No newline at end of file diff --git a/licenses/LICENSE_OF_ILOGTAIL_DEPENDENCIES.md b/licenses/LICENSE_OF_ILOGTAIL_DEPENDENCIES.md index a0cdaa4078..f8814a01d8 100644 --- a/licenses/LICENSE_OF_ILOGTAIL_DEPENDENCIES.md +++ b/licenses/LICENSE_OF_ILOGTAIL_DEPENDENCIES.md @@ -8,7 +8,6 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [github.com/pingcap/failpoint](https://pkg.go.dev/github.com/pingcap/failpoint?tab=licenses) - [github.com/pingcap/tidb/pkg/parser](https://pkg.go.dev/github.com/pingcap/tidb/pkg/parser?tab=licenses) - [sigs.k8s.io/gateway-api](https://pkg.go.dev/sigs.k8s.io/gateway-api?tab=licenses) -- [cloud.google.com/go/compute/metadata](https://pkg.go.dev/cloud.google.com/go/compute/metadata?tab=licenses) - [github.com/containerd/cgroups](https://pkg.go.dev/github.com/containerd/cgroups?tab=licenses) - [github.com/containerd/containerd](https://pkg.go.dev/github.com/containerd/containerd?tab=licenses) - [github.com/containerd/continuity](https://pkg.go.dev/github.com/containerd/continuity?tab=licenses) @@ -60,7 +59,6 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [github.com/prometheus/prometheus](https://pkg.go.dev/github.com/prometheus/prometheus?tab=licenses) - [github.com/stefanberger/go-pkcs11uri](https://pkg.go.dev/github.com/stefanberger/go-pkcs11uri?tab=licenses) - [github.com/tklauser/numcpus](https://pkg.go.dev/github.com/tklauser/numcpus?tab=licenses) -- [github.com/VictoriaMetrics/metricsql](https://pkg.go.dev/github.com/VictoriaMetrics/metricsql?tab=licenses) - [github.com/vishvananda/netlink](https://pkg.go.dev/github.com/vishvananda/netlink?tab=licenses) - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns?tab=licenses) - [github.com/xdg-go/pbkdf2](https://pkg.go.dev/github.com/xdg-go/pbkdf2?tab=licenses) @@ -102,6 +100,9 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [go.opencensus.io](https://pkg.go.dev/go.opencensus.io?tab=licenses) - [github.com/golang/groupcache](https://pkg.go.dev/github.com/golang/groupcache?tab=licenses) - [sigs.k8s.io/controller-runtime](https://pkg.go.dev/sigs.k8s.io/controller-runtime?tab=licenses) +- [github.com/iLogtail/VictoriaMetrics fork from github.com/VictoriaMetrics/VictoriaMetrics](http://github.com/iLogtail/VictoriaMetrics) based on Apache-2.0 +- [cloud.google.com/go/compute/metadata](https://pkg.go.dev/cloud.google.com/go/compute/metadata?tab=licenses) +- [github.com/VictoriaMetrics/metricsql](https://pkg.go.dev/github.com/VictoriaMetrics/metricsql?tab=licenses) ## BSD licenses @@ -155,7 +156,6 @@ When distributed in a binary form, iLogtail may contain portions of the followin ## MIT licenses -- [github.com/valyala/gozstd](https://pkg.go.dev/github.com/valyala/gozstd?tab=licenses) - [github.com/goccy/go-json](https://pkg.go.dev/github.com/goccy/go-json?tab=licenses) - [github.com/gofrs/uuid](https://pkg.go.dev/github.com/gofrs/uuid?tab=licenses) - [github.com/go-kit/log](https://pkg.go.dev/github.com/go-kit/log?tab=licenses) @@ -166,7 +166,6 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [github.com/Microsoft/go-winio](https://pkg.go.dev/github.com/Microsoft/go-winio?tab=licenses) - [github.com/Microsoft/hcsshim](https://pkg.go.dev/github.com/Microsoft/hcsshim?tab=licenses) - [github.com/IBM/sarama](https://pkg.go.dev/github.com/IBM/sarama?tab=licenses) -- [github.com/VictoriaMetrics/fasthttp](https://pkg.go.dev/github.com/VictoriaMetrics/fasthttp?tab=licenses) - [github.com/buger/jsonparser](https://pkg.go.dev/github.com/buger/jsonparser?tab=licenses) - [github.com/cespare/xxhash](https://pkg.go.dev/github.com/cespare/xxhash?tab=licenses) - [github.com/eapache/go-resiliency](https://pkg.go.dev/github.com/eapache/go-resiliency?tab=licenses) @@ -201,11 +200,6 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus?tab=licenses) - [github.com/tchap/go-patricia](https://pkg.go.dev/github.com/tchap/go-patricia?tab=licenses) - [github.com/valyala/bytebufferpool](https://pkg.go.dev/github.com/valyala/bytebufferpool?tab=licenses) -- [github.com/valyala/fastjson](https://pkg.go.dev/github.com/valyala/fastjson?tab=licenses) -- [github.com/valyala/fastrand](https://pkg.go.dev/github.com/valyala/fastrand?tab=licenses) -- [github.com/valyala/fasttemplate](https://pkg.go.dev/github.com/valyala/fasttemplate?tab=licenses) -- [github.com/valyala/histogram](https://pkg.go.dev/github.com/valyala/histogram?tab=licenses) -- [github.com/valyala/quicktemplate](https://pkg.go.dev/github.com/valyala/quicktemplate?tab=licenses) - [github.com/99designs/keyring](https://pkg.go.dev/github.com/99designs/keyring?tab=licenses) - [github.com/danieljoos/wincred](https://pkg.go.dev/github.com/danieljoos/wincred?tab=licenses) - [github.com/dvsekhvalnov/jose2go](https://pkg.go.dev/github.com/dvsekhvalnov/jose2go?tab=licenses) @@ -237,6 +231,13 @@ When distributed in a binary form, iLogtail may contain portions of the followin - [github.com/stretchr/testify](https://pkg.go.dev/github.com/stretchr/testify?tab=licenses) - [go.uber.org/goleak](https://pkg.go.dev/go.uber.org/goleak?tab=licenses) - [github.com/influxdata/telegraf](https://pkg.go.dev/github.com/influxdata/telegraf?tab=licenses) +- [github.com/valyala/fastjson](https://pkg.go.dev/github.com/valyala/fastjson?tab=licenses) +- [github.com/valyala/fastrand](https://pkg.go.dev/github.com/valyala/fastrand?tab=licenses) +- [github.com/valyala/fasttemplate](https://pkg.go.dev/github.com/valyala/fasttemplate?tab=licenses) +- [github.com/valyala/gozstd](https://pkg.go.dev/github.com/valyala/gozstd?tab=licenses) +- [github.com/valyala/histogram](https://pkg.go.dev/github.com/valyala/histogram?tab=licenses) +- [github.com/valyala/quicktemplate](https://pkg.go.dev/github.com/valyala/quicktemplate?tab=licenses) +- [github.com/VictoriaMetrics/fasthttp](https://pkg.go.dev/github.com/VictoriaMetrics/fasthttp?tab=licenses) ## ISC licenses @@ -258,9 +259,8 @@ When distributed in a binary form, iLogtail may contain portions of the followin ## iLogtail used or modified source code from these projects -- [github.com/iLogtail/VictoriaMetrics fork from github.com/VictoriaMetrics/VictoriaMetrics](http://github.com/iLogtail/VictoriaMetrics) based on Apache-2.0 - [github.com/iLogtail/jfr-parser fork from github.com/pyroscope-io/jfr-parser](http://github.com/iLogtail/jfr-parser) based on Apache-2.0 -- [github.com/iLogtail/metrics fork from github.com/VictoriaMetrics/metrics](http://github.com/iLogtail/metrics) based on MIT - [github.com/iLogtail/pyroscope-lib fork from github.com/pyroscope-io/pyroscope](http://github.com/iLogtail/pyroscope-lib) based on Apache-2.0 - [github.com/iLogtail/gonvml fork from github.com/mindprince/gonvml](https://github.com/iLogtail/gonvml) based on Apache-2.0 - [github.com/iLogtail/handy fork from github.com/streadway/handy](http://github.com/iLogtail/handy) based on BSD-2-Clause +- [github.com/iLogtail/metrics fork from github.com/VictoriaMetrics/metrics](http://github.com/iLogtail/metrics) based on MIT diff --git a/licenses/LICENSE_OF_TESTENGINE_DEPENDENCIES.md b/licenses/LICENSE_OF_TESTENGINE_DEPENDENCIES.md index b255f4c012..f617eec5ae 100644 --- a/licenses/LICENSE_OF_TESTENGINE_DEPENDENCIES.md +++ b/licenses/LICENSE_OF_TESTENGINE_DEPENDENCIES.md @@ -16,7 +16,6 @@ When distributed in a binary form, Logtailplugin Test Engine may contain portion - [github.com/opencontainers/go-digest](https://pkg.go.dev/github.com/opencontainers/go-digest?tab=licenses) - [github.com/opencontainers/image-spec](https://pkg.go.dev/github.com/opencontainers/image-spec?tab=licenses) - [github.com/opencontainers/runc](https://pkg.go.dev/github.com/opencontainers/runc?tab=licenses) -- [google.golang.org/genproto](https://pkg.go.dev/google.golang.org/genproto?tab=licenses) - [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc?tab=licenses) - [gopkg.in/ini.v1](https://pkg.go.dev/gopkg.in/ini.v1?tab=licenses) - [gopkg.in/yaml.v2](https://pkg.go.dev/gopkg.in/yaml.v2?tab=licenses) @@ -45,10 +44,12 @@ When distributed in a binary form, Logtailplugin Test Engine may contain portion - [sigs.k8s.io/json](https://pkg.go.dev/sigs.k8s.io/json?tab=licenses) - [sigs.k8s.io/structured-merge-diff](https://pkg.go.dev/sigs.k8s.io/structured-merge-diff?tab=licenses) - [sigs.k8s.io/yaml](https://pkg.go.dev/sigs.k8s.io/yaml?tab=licenses) +- [github.com/google/cadvisor](https://pkg.go.dev/github.com/google/cadvisor?tab=licenses) - [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer?tab=licenses) - [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference?tab=licenses) - [github.com/go-openapi/swag](github.com/go-openapi/swag) - [github.com/google/gnostic](https://pkg.go.dev/github.com/google/gnostic?tab=licenses) +- [google.golang.org/genproto/googleapis/rpc](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc?tab=licenses) ## BSD licenses diff --git a/scripts/benchmark_collect_result.sh b/scripts/benchmark_collect_result.sh new file mode 100755 index 0000000000..27a1625eb0 --- /dev/null +++ b/scripts/benchmark_collect_result.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Combine the statistic and records files from each benchmark run into a single file + +# Define the input files and the output file +input_statistic_files=($(find test/benchmark/report -type f -name '*ilogtail_statistic.json')) +output_statistic_file="test/benchmark/report/ilogtail_statistic_all.json" + +# Start the output file with an opening square bracket +rm -f "$output_statistic_file" +touch "$output_statistic_file" +echo '[' > "$output_statistic_file" + +# Loop through each input file +for i in "${!input_statistic_files[@]}"; do + # Read the file, remove the first and last line (the square brackets), and append to the output file + cat "${input_statistic_files[$i]}" | sed '1d;$d' >> "$output_statistic_file" + + # If this is not the last file, append a comma to separate the arrays + if [ $i -lt $((${#input_statistic_files[@]} - 1)) ]; then + echo ',' >> "$output_statistic_file" + fi +done + +# Finish the output file with a closing square bracket +echo ']' >> "$output_statistic_file" + +# Define the input files and the output file +input_records_files=($(find test/benchmark/report -type f -name '*records.json')) +output_records_file="test/benchmark/report/records_all.json" + +# Start the output file with an opening square bracket +rm -f "$output_records_file" +touch "$output_records_file" +echo '[' > "$output_records_file" + +# Loop through each input file +for i in "${!input_records_files[@]}"; do + # Read the file, remove the first and last line (the square brackets), and append to the output file + cat "${input_records_files[$i]}" | sed '1d;$d' >> "$output_records_file" + + # If this is not the last file, append a comma to separate the arrays + if [ $i -lt $((${#input_records_files[@]} - 1)) ]; then + echo ',' >> "$output_records_file" + fi +done + +# Finish the output file with a closing square bracket +echo ']' >> "$output_records_file" diff --git a/test/benchmark/benchmark_docker_test.go b/test/benchmark/benchmark_docker_test.go new file mode 100644 index 0000000000..f029c0831a --- /dev/null +++ b/test/benchmark/benchmark_docker_test.go @@ -0,0 +1,38 @@ +// Copyright 2024 iLogtail Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package e2e + +import ( + "testing" + + "github.com/cucumber/godog" + + "github.com/alibaba/ilogtail/test/engine" +) + +func TestE2EOnDockerComposePerformance(t *testing.T) { + suite := godog.TestSuite{ + Name: "E2EOnDockerCompose", + ScenarioInitializer: engine.ScenarioInitializer, + Options: &godog.Options{ + Format: "pretty", + Paths: []string{"test_cases"}, + Tags: "@e2e-performance && @docker-compose && ~@ebpf", + TestingT: t, + }, + } + if suite.Run() != 0 { + t.Fail() + } +} diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/case.feature b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/case.feature new file mode 100644 index 0000000000..b8bbf86d1a --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/case.feature @@ -0,0 +1,12 @@ +@input +Feature: performance file to blackhole filebeat + Performance file to blackhole filebeat + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeFilebeat + Given {docker-compose} environment + Given docker-compose boot type {benchmark} + When start docker-compose {performance_file_to_blackhole_filebeat} + When start monitor {filebeat} + When generate random nginx logs to file, speed {10}MB/s, total {3}min, to file {./a.log} + When wait monitor until log processing finished diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/docker-compose.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/docker-compose.yaml new file mode 100644 index 0000000000..ce6b83c442 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/docker-compose.yaml @@ -0,0 +1,10 @@ +version: '3.8' + +services: + filebeat: + image: docker.elastic.co/beats/filebeat:8.14.2 + user: root + volumes: + - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro + - .:/home/filebeat + command: filebeat -e --strict.perms=false diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/filebeat.yml b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/filebeat.yml new file mode 100644 index 0000000000..b4ad00ac22 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_filebeat/filebeat.yml @@ -0,0 +1,20 @@ +filebeat.inputs: +- type: filestream + id: input-file + paths: + - /home/filebeat/*.log + prospector.scanner.check_interval: 1s + +processors: + - dissect: + tokenizer: '%{ip} %{ident} %{auth} [%{timestamp}] "%{method} %{request} HTTP/%{http_version}" %{response_code} %{bytes} "%{referrer}" "%{user_agent}"' + field: "message" + target_prefix: "parsed" + - drop_event: + when: + not: + equals: + parsed.user_agent: "no-agent" + +output.console: + pretty: true diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/case.feature b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/case.feature new file mode 100644 index 0000000000..449511f10d --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/case.feature @@ -0,0 +1,12 @@ +@input +Feature: performance file to blackhole fluentbit + Performance file to blackhole fluentbit + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeFluentbit + Given {docker-compose} environment + Given docker-compose boot type {benchmark} + When start docker-compose {performance_file_to_blackhole_fluentbit} + When start monitor {fluent-bit} + When generate random nginx logs to file, speed {10}MB/s, total {3}min, to file {./a.log} + When wait monitor until log processing finished diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/docker-compose.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/docker-compose.yaml new file mode 100644 index 0000000000..aeb15b1f07 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/docker-compose.yaml @@ -0,0 +1,14 @@ +version: '3.8' + +services: + + fluent-bit: + image: cr.fluentbit.io/fluent/fluent-bit + command: ["-c", "/tmp/main.conf"] + volumes: + - ./main.conf:/tmp/main.conf + - ./parsers.conf:/tmp/parsers.conf + - .:/home/fluentbit + restart: always + + diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/main.conf b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/main.conf new file mode 100644 index 0000000000..307b6d1d04 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/main.conf @@ -0,0 +1,17 @@ +[SERVICE] + parsers_file /tmp/parsers.conf + +[INPUT] + name tail + path /home/fluentbit/*.log + parser nginx + refresh_interval 1 + +[FILTER] + name grep + match * + regex user_agent no-agent + +[OUTPUT] + name stdout + match * diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/parsers.conf b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/parsers.conf new file mode 100644 index 0000000000..387b51f0cc --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_fluentbit/parsers.conf @@ -0,0 +1,4 @@ +[PARSER] + Name nginx + Format regex + Regex ^(?[^ ]*) (?[^ ]*) (?[^ ]*) \[(?[^\]]*)\] "(?\S+)(?: +(?[^\"]*?)(?: +\S*)?)?" (?[^ ]*) (?[^ ]*)(?: "(?[^\"]*)" "(?[^\"]*)") \ No newline at end of file diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/case.feature b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/case.feature new file mode 100644 index 0000000000..92bb93f5d6 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/case.feature @@ -0,0 +1,12 @@ +@input +Feature: performance file to blackhole iLogtail + Performance file to blackhole iLogtail + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeiLogtail + Given {docker-compose} environment + Given docker-compose boot type {benchmark} + When start docker-compose {performance_file_to_blackhole_ilogtail} + When start monitor {ilogtailC} + When generate random nginx logs to file, speed {10}MB/s, total {3}min, to file {./a.log} + When wait monitor until log processing finished diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/docker-compose.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/docker-compose.yaml new file mode 100644 index 0000000000..f5f31279dc --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/docker-compose.yaml @@ -0,0 +1,26 @@ +# Copyright 2021 iLogtail Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.8' + +services: + ilogtailC: + image: aliyun/loongcollector:0.0.1 + volumes: + - ./ilogtail.yaml:/loongcollector/conf/pipeline_config/local/ilogtail.yaml + - .:/home/ilogtail + healthcheck: + test: "cat /loongcollector/log/loongcollector.LOG" + interval: 15s + timeout: 5s diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/ilogtail.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/ilogtail.yaml new file mode 100644 index 0000000000..a346a84261 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtail/ilogtail.yaml @@ -0,0 +1,32 @@ +enable: true +inputs: + - Type: input_file + FilePaths: + - /home/ilogtail/*.log +processors: + - Type: processor_parse_regex_native + SourceKey: content + Regex: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (.*) (.*) \[(\d{2}\/\w{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\] \"(\w+) (.*?) HTTP\/(\d+\.\d+)\" (\d{3}) (\d+) \"(.*?)\" \"(.*?)\" + Keys: + - ip + - ident + - auth + - timestamp + - method + - request + - http_version + - response_code + - bytes + - referrer + - user_agent + - Type: processor_filter_regex_native + FilterKey: + - user_agent + FilterRegex: + - ^no-agent$ +flushers: + - Type: flusher_sls + Region: cn-hangzhou + Endpoint: cn-hangzhou.log.aliyuncs.com + Project: test_project + Logstore: test_logstore \ No newline at end of file diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/case.feature b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/case.feature new file mode 100644 index 0000000000..327b8d27a1 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/case.feature @@ -0,0 +1,12 @@ +@input +Feature: performance file to blackhole iLogtail + Performance file to blackhole iLogtail + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeiLogtailSPL + Given {docker-compose} environment + Given docker-compose boot type {benchmark} + When start docker-compose {performance_file_to_blackhole_ilogtailspl} + When start monitor {ilogtailC} + When generate random nginx logs to file, speed {10}MB/s, total {3}min, to file {./a.log} + When wait monitor until log processing finished diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/docker-compose.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/docker-compose.yaml new file mode 100644 index 0000000000..f5f31279dc --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/docker-compose.yaml @@ -0,0 +1,26 @@ +# Copyright 2021 iLogtail Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.8' + +services: + ilogtailC: + image: aliyun/loongcollector:0.0.1 + volumes: + - ./ilogtail.yaml:/loongcollector/conf/pipeline_config/local/ilogtail.yaml + - .:/home/ilogtail + healthcheck: + test: "cat /loongcollector/log/loongcollector.LOG" + interval: 15s + timeout: 5s diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/ilogtail.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/ilogtail.yaml new file mode 100644 index 0000000000..99cf637fe2 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_ilogtailspl/ilogtail.yaml @@ -0,0 +1,17 @@ +enable: true +inputs: + - Type: input_file + FilePaths: + - /home/ilogtail/*.log +processors: + - Type: processor_spl + Script: | + * | parse-regexp content, '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (.*) (.*) \[(\d{2}\/\w{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\] \"(\w+) (.*?) HTTP\/(\d+\.\d+)\" (\d{3}) (\d+) \"(.*?)\" \"(.*?)\"' as ip, ident, auth, timestamp, method, request, http_version, response_code, bytes, referrer, user_agent + | where user_agent='no-agent' +flushers: + - Type: flusher_sls + Region: cn-hangzhou + Endpoint: cn-hangzhou.log.aliyuncs.com + Project: test_project + Logstore: test_logstore + diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_vector/case.feature b/test/benchmark/test_cases/performance_file_to_blackhole_vector/case.feature new file mode 100644 index 0000000000..b0e54b85c1 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_vector/case.feature @@ -0,0 +1,12 @@ +@input +Feature: performance file to blackhole vector + Performance file to blackhole vector + + @e2e-performance @docker-compose + Scenario: PerformanceFileToBlackholeVector + Given {docker-compose} environment + Given docker-compose boot type {benchmark} + When start docker-compose {performance_file_to_blackhole_vector} + When start monitor {vector} + When generate random nginx logs to file, speed {10}MB/s, total {3}min, to file {./a.log} + When wait monitor until log processing finished diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_vector/docker-compose.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_vector/docker-compose.yaml new file mode 100644 index 0000000000..635282b58d --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_vector/docker-compose.yaml @@ -0,0 +1,8 @@ +version: '3.8' + +services: + vector: + image: timberio/vector:0.39.0-debian + volumes: + - ./vector.yaml:/etc/vector/vector.yaml + - .:/home/vector-log diff --git a/test/benchmark/test_cases/performance_file_to_blackhole_vector/vector.yaml b/test/benchmark/test_cases/performance_file_to_blackhole_vector/vector.yaml new file mode 100644 index 0000000000..48dceff3a2 --- /dev/null +++ b/test/benchmark/test_cases/performance_file_to_blackhole_vector/vector.yaml @@ -0,0 +1,28 @@ +sources: + input_file: + type: file + include: + - /home/vector-log/*.log + +transforms: + transform_regex: + type: remap + inputs: + - input_file + source: |- + . = parse_regex!(.message, r'^(?P[^ ]*) (?P[^ ]*) (?P[^ ]*) \[(?P[^\]]*)\] "(?P\S+)(?: +(?P[^\"]*?)(?: +\S*)?)?" (?P[^ ]*) (?P[^ ]*)(?: "(?P[^\"]*)" "(?P[^\"]*)")') + filter_agent: + type: filter + inputs: + - transform_regex + condition: + type: "vrl" + source: ."user_agent" == "no-agent" + +sinks: + output_std: + type: console + inputs: + - filter_agent + encoding: + codec: json \ No newline at end of file diff --git a/test/engine/cleanup/helper.go b/test/engine/cleanup/helper.go index c223800104..0a9408e749 100644 --- a/test/engine/cleanup/helper.go +++ b/test/engine/cleanup/helper.go @@ -48,6 +48,7 @@ func All() { _, _ = AllGeneratedLog(ctx) _, _ = GoTestCache(ctx) _, _ = DeleteContainers(ctx) + // FIXME: if this test case has no subscriber and the previous one has subscriber, it will panic if subscriber.TestSubscriber != nil { _ = subscriber.TestSubscriber.Stop() } diff --git a/test/engine/setup/controller/docker_compose_boot.go b/test/engine/setup/controller/docker_compose_boot.go index 1ffbc83636..dff979a41f 100644 --- a/test/engine/setup/controller/docker_compose_boot.go +++ b/test/engine/setup/controller/docker_compose_boot.go @@ -27,9 +27,9 @@ import ( type BootController struct { } -func (c *BootController) Init() error { +func (c *BootController) Init(bootType dockercompose.BootType) error { logger.Info(context.Background(), "boot controller is initializing....") - return dockercompose.Load() + return dockercompose.Load(bootType) } func (c *BootController) Start(ctx context.Context) error { diff --git a/test/engine/setup/docker_compose.go b/test/engine/setup/docker_compose.go index 10c2e3439e..2c85bbbec9 100644 --- a/test/engine/setup/docker_compose.go +++ b/test/engine/setup/docker_compose.go @@ -12,12 +12,25 @@ import ( "github.com/alibaba/ilogtail/pkg/protocol" "github.com/alibaba/ilogtail/test/config" "github.com/alibaba/ilogtail/test/engine/setup/controller" + "github.com/alibaba/ilogtail/test/engine/setup/dockercompose" ) const dependencyHome = "test_cases" type DockerComposeEnv struct { BootController *controller.BootController + BootType dockercompose.BootType +} + +func SetDockerComposeBootType(t dockercompose.BootType) error { + if dockerComposeEnv, ok := Env.(*DockerComposeEnv); ok { + if t != dockercompose.DockerComposeBootTypeE2E && t != dockercompose.DockerComposeBootTypeBenchmark { + return fmt.Errorf("invalid docker compose boot type, not e2e or benchmark") + } + dockerComposeEnv.BootType = t + return nil + } + return fmt.Errorf("env is not docker-compose") } func StartDockerComposeEnv(ctx context.Context, dependencyName string) (context.Context, error) { @@ -28,7 +41,7 @@ func StartDockerComposeEnv(ctx context.Context, dependencyName string) (context. return ctx, err } dockerComposeEnv.BootController = new(controller.BootController) - if err = dockerComposeEnv.BootController.Init(); err != nil { + if err = dockerComposeEnv.BootController.Init(dockerComposeEnv.BootType); err != nil { return ctx, err } @@ -93,6 +106,7 @@ func NewDockerComposeEnv() *DockerComposeEnv { reportDir := root + "/report/" _ = os.Mkdir(reportDir, 0750) config.ConfigDir = reportDir + "config" + env.BootType = dockercompose.DockerComposeBootTypeE2E return env } diff --git a/test/engine/setup/dockercompose/common.go b/test/engine/setup/dockercompose/common.go index f9662ef8d7..867ac55dd2 100644 --- a/test/engine/setup/dockercompose/common.go +++ b/test/engine/setup/dockercompose/common.go @@ -20,6 +20,13 @@ import ( "sync" ) +type BootType = string + +const ( + DockerComposeBootTypeE2E BootType = "e2e" + DockerComposeBootTypeBenchmark BootType = "benchmark" +) + var networkMapping = make(map[string]string) var mu sync.Mutex var instance Booter @@ -33,10 +40,17 @@ type Booter interface { } // Load configuration to the Booter. -func Load() error { +func Load(bootType BootType) error { mu.Lock() defer mu.Unlock() - instance = NewComposeBooter() + switch bootType { + case DockerComposeBootTypeE2E: + instance = NewComposeBooter() + case DockerComposeBootTypeBenchmark: + instance = NewComposeBenchmarkBooter() + default: + return errors.New("invalid load type") + } return nil } diff --git a/test/engine/setup/dockercompose/compose_benchmark.go b/test/engine/setup/dockercompose/compose_benchmark.go new file mode 100644 index 0000000000..f82607db4c --- /dev/null +++ b/test/engine/setup/dockercompose/compose_benchmark.go @@ -0,0 +1,189 @@ +// Copyright 2021 iLogtail Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dockercompose + +import ( + "context" + "os" + + "github.com/docker/docker/api/types" + dockertypes "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" + "github.com/testcontainers/testcontainers-go" + "gopkg.in/yaml.v3" + + "github.com/alibaba/ilogtail/pkg/logger" + "github.com/alibaba/ilogtail/test/config" +) + +const ( + benchmarkIdentifier = "benchmark" + cadvisorTemplate = `version: '3.8' +services: + cadvisor: + image: gcr.io/cadvisor/cadvisor:v0.49.1 + volumes: + - /:/rootfs:ro + - /var/run:/var/run:ro + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /dev/disk/:/dev/disk:ro + ports: + - "8080:8080" + privileged: true + devices: + - /dev/kmsg + restart: unless-stopped +` +) + +// ComposeBooter control docker-compose to start or stop containers. +type ComposeBenchmarkBooter struct { + cli *client.Client + cadvisorID string +} + +// NewComposeBooter create a new compose booter. +func NewComposeBenchmarkBooter() *ComposeBenchmarkBooter { + return &ComposeBenchmarkBooter{} +} + +func (c *ComposeBenchmarkBooter) Start(ctx context.Context) error { + if err := c.createComposeFile(); err != nil { + return err + } + compose := testcontainers.NewLocalDockerCompose([]string{config.CaseHome + finalFileName}, benchmarkIdentifier).WithCommand([]string{"up", "-d", "--build"}) + strategyWrappers := withExposedService(compose) + execError := compose.Invoke() + if execError.Error != nil { + logger.Error(context.Background(), "START_DOCKER_COMPOSE_ERROR", + "stdout", execError.Error.Error()) + return execError.Error + } + cli, err := CreateDockerClient() + if err != nil { + return err + } + c.cli = cli + + list, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ + Filters: filters.NewArgs(filters.Arg("name", "benchmark-cadvisor")), + }) + if len(list) != 1 { + logger.Errorf(context.Background(), "CADVISOR_COMPOSE_ALARM", "cadvisor container size is not equal 1, got %d count", len(list)) + return err + } + c.cadvisorID = list[0].ID + + // the docker engine cannot access host on the linux platform, more details please see: https://github.com/docker/for-linux/issues/264 + cmd := []string{ + "sh", + "-c", + "env |grep HOST_OS|grep Linux && ip -4 route list match 0/0|awk '{print $3\" host.docker.internal\"}' >> /etc/hosts", + } + if err = c.exec(c.cadvisorID, cmd); err != nil { + return err + } + err = registerDockerNetMapping(strategyWrappers) + logger.Debugf(context.Background(), "registered net mapping: %v", networkMapping) + return err +} + +func (c *ComposeBenchmarkBooter) Stop() error { + execError := testcontainers.NewLocalDockerCompose([]string{config.CaseHome + finalFileName}, benchmarkIdentifier).Down() + if execError.Error != nil { + logger.Error(context.Background(), "STOP_DOCKER_COMPOSE_ERROR", + "stdout", execError.Stdout.Error(), "stderr", execError.Stderr.Error()) + return execError.Error + } + _ = os.Remove(config.CaseHome + finalFileName) + return nil +} + +func (c *ComposeBenchmarkBooter) exec(id string, cmd []string) error { + cfg := dockertypes.ExecConfig{ + User: "root", + Cmd: cmd, + } + resp, err := c.cli.ContainerExecCreate(context.Background(), id, cfg) + if err != nil { + logger.Errorf(context.Background(), "DOCKER_EXEC_ALARM", "cannot create exec config: %v", err) + return err + } + err = c.cli.ContainerExecStart(context.Background(), resp.ID, dockertypes.ExecStartCheck{ + Detach: false, + Tty: false, + }) + if err != nil { + logger.Errorf(context.Background(), "DOCKER_EXEC_ALARM", "cannot start exec config: %v", err) + return err + } + return nil +} + +func (c *ComposeBenchmarkBooter) CopyCoreLogs() { +} + +func (c *ComposeBenchmarkBooter) createComposeFile() error { + // read the case docker compose file. + if _, err := os.Stat(config.CaseHome); os.IsNotExist(err) { + if err = os.MkdirAll(config.CaseHome, 0750); err != nil { + return err + } + } + _, err := os.Stat(config.CaseHome + config.DockerComposeFileName) + var bytes []byte + if err != nil { + if !os.IsNotExist(err) { + return err + } + } else { + if bytes, err = os.ReadFile(config.CaseHome + config.DockerComposeFileName); err != nil { + return err + } + } + cfg := c.getAdvisorConfig() + services := cfg["services"].(map[string]interface{}) + // merge docker compose file. + if len(bytes) > 0 { + caseCfg := make(map[string]interface{}) + if err = yaml.Unmarshal(bytes, &caseCfg); err != nil { + return err + } + newServices := caseCfg["services"].(map[string]interface{}) + for k := range newServices { + services[k] = newServices[k] + } + } + yml, err := yaml.Marshal(cfg) + if err != nil { + return err + } + return os.WriteFile(config.CaseHome+finalFileName, yml, 0600) +} + +// getLogtailpluginConfig find the docker compose configuration of the ilogtail. +func (c *ComposeBenchmarkBooter) getAdvisorConfig() map[string]interface{} { + cfg := make(map[string]interface{}) + f, _ := os.Create(config.CoverageFile) + _ = f.Close() + if err := yaml.Unmarshal([]byte(cadvisorTemplate), &cfg); err != nil { + panic(err) + } + bytes, _ := yaml.Marshal(cfg) + println(string(bytes)) + return cfg +} diff --git a/test/engine/setup/monitor/monitor.go b/test/engine/setup/monitor/monitor.go new file mode 100644 index 0000000000..183df3ec14 --- /dev/null +++ b/test/engine/setup/monitor/monitor.go @@ -0,0 +1,147 @@ +package monitor + +import ( + "context" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "sync/atomic" + "time" + + "github.com/google/cadvisor/client" + v1 "github.com/google/cadvisor/info/v1" + + "github.com/alibaba/ilogtail/test/config" +) + +const ( + cadvisorURL = "http://localhost:8080/" + interval = 3 +) + +const ( + exitCodeSuccess = iota + exitCodeErrorNotProcessing + exitCodeErrorGetContainerInfo +) + +var monitor Monitor + +type Monitor struct { + isMonitoring atomic.Bool + statistic *Statistic + stopCh chan int +} + +func StartMonitor(ctx context.Context, containerName string) (context.Context, error) { + return monitor.Start(ctx, containerName) +} + +func WaitMonitorUntilProcessingFinished(ctx context.Context) (context.Context, error) { + errCode := <-monitor.Done() + switch errCode { + case exitCodeSuccess: + return ctx, nil + case exitCodeErrorNotProcessing: + return ctx, fmt.Errorf("monitoring error: CPU usage is too low, not processing") + case exitCodeErrorGetContainerInfo: + return ctx, fmt.Errorf("monitoring error: failed to get container info, maybe container crashed") + default: + return ctx, fmt.Errorf("monitoring error: unknown error") + } +} + +func (m *Monitor) Start(ctx context.Context, containerName string) (context.Context, error) { + // connect to cadvisor + client, err := client.NewClient("http://localhost:8080/") + if err != nil { + return ctx, err + } + // 获取所有容器信息 + allContainers, err := client.AllDockerContainers(&v1.ContainerInfoRequest{NumStats: 10}) + if err != nil { + fmt.Println("Error getting all containers info:", err) + return ctx, err + } + for _, container := range allContainers { + containerFullName := container.Aliases[0] + if strings.Contains(containerFullName, containerName) { + m.isMonitoring.Store(true) + m.statistic = NewMonitorStatistic(config.CaseName) + m.stopCh = make(chan int) + fmt.Println("Start monitoring container:", containerFullName) + go m.monitoring(client, containerFullName) + return ctx, nil + } + } + err = fmt.Errorf("container %s not found", containerName) + return ctx, err +} + +func (m *Monitor) monitoring(client *client.Client, containerName string) { + // create csv file + root, _ := filepath.Abs(".") + reportDir := root + "/report/" + statisticFile := reportDir + config.CaseName + "_statistic.json" + recordsFile := reportDir + config.CaseName + "_records.json" + // calculate low threshold after 60 seconds + timerCal := time.NewTimer(60 * time.Second) + lowThreshold := 0.0 + outlierCnt := 0 + // read from cadvisor per interval seconds + ticker := time.NewTicker(interval * time.Second) + defer ticker.Stop() + request := &v1.ContainerInfoRequest{NumStats: 10} + for { + select { + case <-timerCal.C: + // 计算CPU使用率的下阈值 + cpuRawData := make([]float64, len(m.statistic.GetCPURawData())) + copy(cpuRawData, m.statistic.GetCPURawData()) + sort.Float64s(cpuRawData) + lowThreshold = cpuRawData[len(cpuRawData)/2] * 0.3 + fmt.Println("median of CPU usage rate(%):", cpuRawData[len(cpuRawData)/2]) + fmt.Println("Low threshold of CPU usage rate(%):", lowThreshold) + if lowThreshold < 1 { + m.isMonitoring.Store(false) + m.stopCh <- exitCodeErrorNotProcessing + m.statistic.ClearStatistic() + return + } + case <-ticker.C: + // 获取容器信息 + containerInfo, err := client.DockerContainer(containerName, request) + if err != nil { + m.isMonitoring.Store(false) + m.stopCh <- exitCodeErrorGetContainerInfo + m.statistic.ClearStatistic() + return + } + for _, stat := range containerInfo.Stats { + m.statistic.UpdateStatistic(stat) + } + cpuRawData := m.statistic.GetCPURawData() + if cpuRawData[len(cpuRawData)-1] < lowThreshold { + outlierCnt++ + } else { + outlierCnt = 0 + } + if outlierCnt > 5 { + bytes, _ := m.statistic.MarshalStatisticJSON() + _ = os.WriteFile(statisticFile, bytes, 0600) + bytes, _ = m.statistic.MarshalRecordsJSON() + _ = os.WriteFile(recordsFile, bytes, 0600) + m.isMonitoring.Store(false) + m.stopCh <- exitCodeSuccess + m.statistic.ClearStatistic() + return + } + } + } +} + +func (m *Monitor) Done() <-chan int { + return m.stopCh +} diff --git a/test/engine/setup/monitor/statistic.go b/test/engine/setup/monitor/statistic.go new file mode 100644 index 0000000000..d5e900a105 --- /dev/null +++ b/test/engine/setup/monitor/statistic.go @@ -0,0 +1,156 @@ +package monitor + +import ( + "encoding/json" + "fmt" + "sort" + + v1 "github.com/google/cadvisor/info/v1" +) + +type Info struct { + values []float64 +} + +func (s *Info) Add(val float64) { + s.values = append(s.values, val) +} + +func (s *Info) CalculateMax() float64 { + maxVal := 0.0 + for _, val := range s.values { + if val > maxVal { + maxVal = val + } + } + return maxVal +} + +func (s *Info) CalculateAvg() float64 { + valuesCopy := make([]float64, len(s.values)) + copy(valuesCopy, s.values) + + // Step 1: Sort the valuesCopy + sort.Float64s(valuesCopy) + + // Step 2: Calculate Q1 and Q3 + Q1 := valuesCopy[len(valuesCopy)/4] + Q3 := valuesCopy[3*len(valuesCopy)/4] + + // Step 3: Calculate IQR + IQR := Q3 - Q1 + + // Step 4: Determine the lower and upper bounds for outliers + lowerBound := Q1 - 1.5*IQR + upperBound := Q3 + 1.5*IQR + + // Step 5: Filter out the outliers + cnt := 0 + avg := 0.0 + for _, value := range valuesCopy { + if value >= lowerBound && value <= upperBound { + if cnt == 0 { + avg = value + } else { + avg = float64(cnt)/float64(cnt+1)*avg + value/float64(cnt+1) + } + cnt++ + } + } + + return avg +} + +type Statistic struct { + name string + cpu Info + mem Info + lastStat *v1.ContainerStats +} + +func NewMonitorStatistic(name string) *Statistic { + return &Statistic{ + name: name, + cpu: Info{}, + mem: Info{}, + lastStat: nil, + } +} + +func (m *Statistic) UpdateStatistic(stat *v1.ContainerStats) { + if m.lastStat != nil && !stat.Timestamp.After(m.lastStat.Timestamp) { + return + } + cpuUsageRateTotal := calculateCPUUsageRate(m.lastStat, stat) + m.cpu.Add(cpuUsageRateTotal) + m.mem.Add(float64(stat.Memory.Usage) / 1024 / 1024) + m.lastStat = stat + // fmt.Println("CPU Usage Rate(%):", cpuUsageRateTotal, "CPU Usage Rate Max(%):", m.cpu.maxVal, "CPU Usage Rate Avg(%):", m.cpu.avgVal, "Memory Usage Max(MB):", m.mem.maxVal, "Memory Usage Avg(MB):", m.mem.avgVal) +} + +func (m *Statistic) ClearStatistic() { + m.cpu.values = m.cpu.values[:0] + m.mem.values = m.mem.values[:0] + m.lastStat = nil +} + +func (m *Statistic) GetCPURawData() []float64 { + return m.cpu.values +} + +func calculateCPUUsageRate(lastStat, stat *v1.ContainerStats) float64 { + if lastStat == nil { + return 0 + } + cpuUsageTotal := stat.Cpu.Usage.Total - lastStat.Cpu.Usage.Total + cpuUsageRateTotal := float64(cpuUsageTotal) * 100 / float64(stat.Timestamp.Sub(lastStat.Timestamp).Nanoseconds()) + return cpuUsageRateTotal +} + +type StatisticItem struct { + Name string `json:"name"` + Value float64 `json:"value"` + Unit string `json:"unit"` +} + +func (m *Statistic) MarshalStatisticJSON() ([]byte, error) { + items := []StatisticItem{ + {"CPU_Usage_Max - " + m.name, m.cpu.CalculateMax(), "%"}, + {"CPU_Usage_Avg - " + m.name, m.cpu.CalculateAvg(), "%"}, + {"Memory_Usage_Max - " + m.name, m.mem.CalculateMax(), "MB"}, + {"Memory_Usage_Avg - " + m.name, m.mem.CalculateAvg(), "MB"}, + } + + // Serialize the slice to JSON + jsonData, err := json.MarshalIndent(items, "", " ") + if err != nil { + fmt.Println("Error serializing statistics:", err) + return nil, err + } + + // Output the JSON string + return jsonData, nil +} + +type RecordsItem struct { + Name string `json:"name"` + Records []float64 `json:"records"` + Unit string `json:"unit"` +} + +func (m *Statistic) MarshalRecordsJSON() ([]byte, error) { + items := []RecordsItem{ + {"CPU_Usage - " + m.name, m.cpu.values, "%"}, + {"Memory_Usage - " + m.name, m.mem.values, "MB"}, + } + + // Serialize the slice to JSON + jsonData, err := json.MarshalIndent(items, "", " ") + if err != nil { + fmt.Println("Error serializing statistics:", err) + return nil, err + } + + // Output the JSON string + return jsonData, nil +} diff --git a/test/engine/steps.go b/test/engine/steps.go index 8e5e0d59ee..b3ec512458 100644 --- a/test/engine/steps.go +++ b/test/engine/steps.go @@ -10,6 +10,7 @@ import ( "github.com/alibaba/ilogtail/test/engine/cleanup" "github.com/alibaba/ilogtail/test/engine/control" "github.com/alibaba/ilogtail/test/engine/setup" + "github.com/alibaba/ilogtail/test/engine/setup/monitor" "github.com/alibaba/ilogtail/test/engine/setup/subscriber" "github.com/alibaba/ilogtail/test/engine/trigger" "github.com/alibaba/ilogtail/test/engine/verify" @@ -26,6 +27,7 @@ func ScenarioInitializer(ctx *godog.ScenarioContext) { ctx.Given(`^remove http config \{(.*)\}`, control.RemoveHTTPConfig) ctx.Given(`^subcribe data from \{(\S+)\} with config`, subscriber.InitSubscriber) ctx.Given(`^mkdir \{(.*)\}`, setup.Mkdir) + ctx.Given(`^docker-compose boot type \{(\S+)\}$`, setup.SetDockerComposeBootType) // When ctx.When(`^generate \{(\d+)\} regex logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.RegexSingle) @@ -40,6 +42,9 @@ func ScenarioInitializer(ctx *godog.ScenarioContext) { ctx.When(`^query through \{(.*)\}`, control.SetQuery) ctx.When(`^begin trigger`, trigger.BeginTrigger) ctx.When(`^execute \{(\d+)\} commands to generate file security events on files \{(.*)\}$`, trigger.TrigerFileSecurityEvents) + ctx.When(`^generate random nginx logs to file, speed \{(\d+)\}MB/s, total \{(\d+)\}min, to file \{(.*)\}`, trigger.GenerateRandomNginxLogToFile) + ctx.When(`^start monitor \{(\S+)\}`, monitor.StartMonitor) + ctx.When(`^wait monitor until log processing finished$`, monitor.WaitMonitorUntilProcessingFinished) // Then ctx.Then(`^there is \{(\d+)\} logs$`, verify.LogCount) diff --git a/test/engine/trigger/file.go b/test/engine/trigger/file.go new file mode 100644 index 0000000000..373aebbe52 --- /dev/null +++ b/test/engine/trigger/file.go @@ -0,0 +1,114 @@ +package trigger + +import ( + "context" + "fmt" + "math/rand" + "os" + "path/filepath" + "time" + + "golang.org/x/time/rate" + + "github.com/alibaba/ilogtail/test/config" +) + +// JSON template +func GenerateRandomNginxLogToFile(ctx context.Context, speed, totalTime int, path string) (context.Context, error) { + + // clear file + path = filepath.Clean(path) + path = filepath.Join(config.CaseHome, path) + fmt.Println(path) + _ = os.WriteFile(path, []byte{}, 0600) + file, _ := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) // #nosec G304 + + rand.Seed(time.Now().UnixNano()) + maxLogLen := 1024 + nginxLog := genNginxLog() + + limiter := rate.NewLimiter(rate.Limit(speed*1024*1024), maxLogLen) + + timeout := time.After(time.Minute * time.Duration(totalTime)) + + for { + select { + // context is done + case <-ctx.Done(): + // clear file + _ = file.Close() + return ctx, nil + // all time is done + case <-timeout: + // clear file + _ = file.Close() + return ctx, nil + default: + if limiter.AllowN(time.Now(), len(nginxLog)) { + _, _ = file.WriteString(nginxLog + "\n") // #nosec G307 + nginxLog = genNginxLog() + } + } + } +} + +var ipAddresses = []string{ + "103.159.151.180", + "12.55.18.241", + "182.233.128.102", + "221.85.57.231", + "76.245.65.224", + "86.250.231.93", + "44.201.253.252", + "218.7.2.219", + "172.118.174.109", + "208.16.46.154", + "7.138.80.41", + "214.73.25.80", + "83.124.20.79", + "80.226.48.153", + "92.129.204.161", + "212.103.145.159", + "148.188.8.90", + "148.212.244.121", + "106.186.172.157", + "30.127.196.158", +} + +var userAgents = []string{ + "aliyun-sdk-java", + "aliyun-sdk-golang", + "aliyun-sdk-python", +} + +var statusCodes = []string{ + "400", + "401", + "402", + "403", + "404", + "200", +} + +const bytesMean = 5500.0 +const bytesStddev = 1500.0 + +func genNginxLog() string { + nginxLogTemplate := `%s - - [%s] "GET http://www.districtdot-com.biz/syndicate HTTP/1.1" %s %d "http://www.chiefscalable.biz/webservices" "%s"` + currentTime := time.Now().Format("02/Jan/2006:15:04:05 +0800") + ipAddress := ipAddresses[rand.Intn(len(ipAddresses))] // #nosec G404 + statusIdx := rand.Intn(len(statusCodes) * 10) // #nosec G404 + if statusIdx >= len(statusCodes) { + statusIdx = len(statusCodes) - 1 + } + bytesSize := int32(rand.NormFloat64()*bytesStddev + bytesMean) + if bytesSize < 1000 { + bytesSize = 0 + } else if bytesSize > 10000 { + bytesSize = 10000 + } + statusCode := statusCodes[statusIdx] + userAgent := userAgents[rand.Intn(len(userAgents))] // #nosec G404 + + return fmt.Sprintf(nginxLogTemplate, ipAddress, currentTime, statusCode, bytesSize, userAgent) +} diff --git a/test/go.mod b/test/go.mod index c6f5af3f05..2aa11b458a 100644 --- a/test/go.mod +++ b/test/go.mod @@ -10,15 +10,18 @@ require ( github.com/alibabacloud-go/tea v1.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/cucumber/godog v0.14.1 - github.com/docker/docker v20.10.23+incompatible + github.com/docker/docker v20.10.27+incompatible github.com/docker/go-connections v0.4.0 github.com/elastic/go-elasticsearch/v8 v8.6.0 + github.com/google/cadvisor v0.49.1 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/melbahja/goph v1.4.0 github.com/mitchellh/mapstructure v1.5.0 github.com/testcontainers/testcontainers-go v0.14.0 - golang.org/x/crypto v0.10.0 - google.golang.org/grpc v1.53.0 + golang.org/x/crypto v0.16.0 + golang.org/x/text v0.14.0 + golang.org/x/time v0.3.0 + google.golang.org/grpc v1.58.3 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.24.0 k8s.io/apimachinery v0.24.0 @@ -55,7 +58,7 @@ require ( github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect github.com/cucumber/messages/go/v21 v21.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/distribution v2.8.1+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/elastic-transport-go/v8 v8.0.0-20211216131617-bbee439d559c // indirect github.com/emicklei/go-restful v2.15.0+incompatible // indirect @@ -86,7 +89,7 @@ require ( github.com/moby/spdystream v0.2.0 // indirect github.com/moby/sys/mount v0.3.3 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect @@ -94,7 +97,7 @@ require ( github.com/onsi/gomega v1.19.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect - github.com/opencontainers/runc v1.1.3 // indirect + github.com/opencontainers/runc v1.1.12 // indirect github.com/paulmach/orb v0.8.0 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect @@ -108,22 +111,19 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.11.2 // indirect go.opentelemetry.io/otel/trace v1.11.2 // indirect - golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 - golang.org/x/net v0.11.0 // indirect - golang.org/x/oauth2 v0.5.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/klog/v2 v2.60.1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect @@ -132,4 +132,5 @@ require ( replace ( github.com/alibaba/ilogtail => ../ github.com/alibaba/ilogtail/pkg => ../pkg + github.com/google/cadvisor v0.49.1 => github.com/google/cadvisor v0.49.0 ) diff --git a/test/go.sum b/test/go.sum index e7d5a1abe2..a2de9f3bb7 100644 --- a/test/go.sum +++ b/test/go.sum @@ -352,8 +352,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= github.com/cucumber/godog v0.14.1 h1:HGZhcOyyfaKclHjJ+r/q93iaTJZLKYW6Tv3HkmUE6+M= @@ -382,12 +382,13 @@ github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.23+incompatible h1:1ZQUUYAdh+oylOT85aA2ZcfRp22jmLhoaEcVEfK8dyA= -github.com/docker/docker v20.10.23+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.27+incompatible h1:Id/ZooynV4ZlD6xX20RCd3SR0Ikn7r4QZDa2ECK2TgA= +github.com/docker/docker v20.10.27+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -549,6 +550,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cadvisor v0.49.0 h1:1PYeiORXmcFYi609M4Qvq5IzcvcVaWgYxDt78uH8jYA= +github.com/google/cadvisor v0.49.0/go.mod h1:s6Fqwb2KiWG6leCegVhw4KW40tf9f7m+SF1aXiE8Wsk= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -768,8 +771,9 @@ github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGq github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -820,8 +824,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -843,8 +847,9 @@ github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84 github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1116,8 +1121,9 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1127,7 +1133,6 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1221,8 +1226,9 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1237,8 +1243,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1363,8 +1369,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1373,8 +1380,9 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1386,8 +1394,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1553,8 +1562,8 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1584,8 +1593,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1699,8 +1708,9 @@ k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= @@ -1712,8 +1722,9 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=