From 62e2116cf33f84d22e4fef117501b1055d09275f Mon Sep 17 00:00:00 2001 From: Abingcbc Date: Sun, 27 Oct 2024 17:49:31 +0800 Subject: [PATCH 1/8] add more steps in E2E framework --- test/config/config.go | 4 +- test/config/context.go | 1 + .../aggregator_context/docker-compose.yaml | 4 +- .../aggregator_context/ilogtail-e2e.yaml | 54 ------ .../flusher_clickhouse/case.feature | 2 +- .../flusher_elasticsearch/case.feature | 2 +- test/e2e/test_cases/flusher_http/case.feature | 2 +- test/e2e/test_cases/flusher_loki/case.feature | 10 +- test/e2e/test_cases/input_canal/case.feature | 2 +- .../input_canal_binfile_mode/case.feature | 2 +- .../docker-compose.yaml | 2 +- .../docker-compose.yaml | 2 +- .../test_cases/input_http_server/case.feature | 4 +- test/e2e/test_cases/input_mssql/case.feature | 2 +- test/e2e/test_cases/input_mysql/case.feature | 2 +- test/e2e/test_cases/input_pgsql/case.feature | 2 +- .../test_cases/input_static_file/case.feature | 2 +- .../test_cases/reader_deleted/case.feature | 2 +- .../reader_deleted/docker-compose.yaml | 2 +- .../reader_flush_timeout/case.feature | 2 +- .../test_cases/reader_log_rotate/case.feature | 2 +- .../case.feature | 2 +- test/engine/cleanup/cache.go | 2 +- test/engine/cleanup/helper.go | 1 - test/engine/cleanup/log.go | 2 +- test/engine/control/config.go | 9 +- test/engine/control/filter.go | 22 +++ test/engine/setup/controller/kubernetes.go | 93 +++++++++- test/engine/setup/docker_compose.go | 8 +- test/engine/setup/dockercompose/compose.go | 30 ++-- test/engine/setup/env.go | 24 ++- test/engine/setup/host.go | 12 +- test/engine/setup/k8s.go | 54 +++--- test/engine/setup/subscriber/clickhouse.go | 2 +- test/engine/setup/subscriber/grpc.go | 2 +- test/engine/setup/subscriber/loki.go | 2 +- test/engine/setup/subscriber/subscriber.go | 4 +- test/engine/steps.go | 51 ++++-- test/engine/trigger/ebpf_trigger.go | 14 +- test/engine/trigger/generator/apsara_test.go | 47 +++-- .../trigger/generator/delimiter_test.go | 99 ++++++++--- .../trigger/generator/ebpf_file_mmap_test.go | 2 +- test/engine/trigger/generator/helper.go | 57 ++++++ test/engine/trigger/generator/json_test.go | 119 +++++++++++++ test/engine/trigger/generator/regex_test.go | 164 +++++++++++++----- test/engine/trigger/generator/stdout_test.go | 61 +++++++ test/engine/trigger/trigger.go | 90 ++++++++-- test/engine/verify/agent.go | 45 +++++ test/engine/verify/apsara.go | 94 ---------- test/engine/verify/count.go | 44 +++++ test/engine/verify/{regex.go => log_order.go} | 66 ++++--- test/go.mod | 33 ++-- test/go.sum | 53 +++--- 53 files changed, 976 insertions(+), 439 deletions(-) delete mode 100644 test/e2e/test_cases/aggregator_context/ilogtail-e2e.yaml create mode 100644 test/engine/trigger/generator/json_test.go create mode 100644 test/engine/trigger/generator/stdout_test.go create mode 100644 test/engine/verify/agent.go delete mode 100644 test/engine/verify/apsara.go rename test/engine/verify/{regex.go => log_order.go} (61%) diff --git a/test/config/config.go b/test/config/config.go index 398928a0bb..915bd08c6d 100644 --- a/test/config/config.go +++ b/test/config/config.go @@ -25,6 +25,7 @@ var TestConfig Config type Config struct { // Log + LocalConfigDir string `mapstructure:"local_config_dir" yaml:"local_config_dir"` GeneratedLogDir string `mapstructure:"generated_log_dir" yaml:"generated_log_dir"` WorkDir string `mapstructure:"work_dir" yaml:"work_dir"` // Host @@ -65,9 +66,10 @@ func ParseConfig() { TestConfig = Config{} // Log + TestConfig.LocalConfigDir = os.Getenv("LOCAL_CONFIG_DIR") TestConfig.GeneratedLogDir = os.Getenv("GENERATED_LOG_DIR") if len(TestConfig.GeneratedLogDir) == 0 { - TestConfig.GeneratedLogDir = "/tmp/ilogtail" + TestConfig.GeneratedLogDir = "/tmp/loongcollector" } TestConfig.WorkDir = os.Getenv("WORK_DIR") diff --git a/test/config/context.go b/test/config/context.go index ad0018d4dc..d6f4c0d57a 100644 --- a/test/config/context.go +++ b/test/config/context.go @@ -22,4 +22,5 @@ const ( ExposePortKey ContextKey = "exposePort" CurrentWorkingDeploymentKey ContextKey = "currentWorkingDeployment" QueryKey ContextKey = "query" + AgentPIDKey ContextKey = "agentPID" ) diff --git a/test/e2e/test_cases/aggregator_context/docker-compose.yaml b/test/e2e/test_cases/aggregator_context/docker-compose.yaml index 3070014ee2..6635e84189 100644 --- a/test/e2e/test_cases/aggregator_context/docker-compose.yaml +++ b/test/e2e/test_cases/aggregator_context/docker-compose.yaml @@ -23,7 +23,7 @@ services: environment: - STDOUT_SWITCH=true depends_on: - - ilogtailC + - loongcollectorC container_2: build: context: . @@ -37,4 +37,4 @@ services: timeout: 5s retries: 3 depends_on: - - ilogtailC + - loongcollectorC diff --git a/test/e2e/test_cases/aggregator_context/ilogtail-e2e.yaml b/test/e2e/test_cases/aggregator_context/ilogtail-e2e.yaml deleted file mode 100644 index 0dd724af88..0000000000 --- a/test/e2e/test_cases/aggregator_context/ilogtail-e2e.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# 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. - -boot: - category: docker-compose -ilogtail: - config: - - name: aggregator-context-case - detail: - - global: - DefaultLogQueueSize: 10 - inputs: - - Type: input_file - FilePaths: - - /root/test/example.log - EnableContainerDiscovery: true - ContainerFilters: - IncludeEnv: - STDOUT_SWITCH: "true" - processors: - - Type: processor_split_char - SourceKey: content - SplitSep: "|" - SplitKeys: ["no", "content"] - aggregators: - - Type: aggregator_context - close_wait: 5s -verify: - log_rules: - - name: log-context-check - validator: log_context - spec: - system_rules: - - name: counter-check - validator: sys_counter - spec: - expect_equal_processed_log: true - expect_equal_flush_log: true - expect_received_minimum_log_num: 200 -testing_interval: 15s -retry: - times: 0 - interval: 10s diff --git a/test/e2e/test_cases/flusher_clickhouse/case.feature b/test/e2e/test_cases/flusher_clickhouse/case.feature index 84669e46e4..02fd8f8d61 100644 --- a/test/e2e/test_cases/flusher_clickhouse/case.feature +++ b/test/e2e/test_cases/flusher_clickhouse/case.feature @@ -36,7 +36,7 @@ Feature: flusher clickhouse BufferMinBytes: 10000000 BufferMaxBytes: 100000000 """ - Given iLogtail depends on containers {["clickhouse"]} + Given loongcollector depends on containers {["clickhouse"]} When start docker-compose {flusher_clickhouse} Then there is at least {10} logs Then the log fields match kv diff --git a/test/e2e/test_cases/flusher_elasticsearch/case.feature b/test/e2e/test_cases/flusher_elasticsearch/case.feature index 5e092e7e49..78b9343e8d 100644 --- a/test/e2e/test_cases/flusher_elasticsearch/case.feature +++ b/test/e2e/test_cases/flusher_elasticsearch/case.feature @@ -30,7 +30,7 @@ Feature: flusher elasticsearch Username: elastic Password: BtpoRTeyjmC=ruTIUoNN """ - Given iLogtail depends on containers {["elasticsearch"]} + Given loongcollector depends on containers {["elasticsearch"]} When start docker-compose {flusher_elasticsearch} Then there is at least {10} logs Then the log fields match kv diff --git a/test/e2e/test_cases/flusher_http/case.feature b/test/e2e/test_cases/flusher_http/case.feature index b660f48240..b4c430069c 100644 --- a/test/e2e/test_cases/flusher_http/case.feature +++ b/test/e2e/test_cases/flusher_http/case.feature @@ -38,7 +38,7 @@ Feature: flusher http - Type: ext_request_breaker FailureRatio: 0.1 """ - Given iLogtail depends on containers {["influxdb"]} + Given loongcollector depends on containers {["influxdb"]} When start docker-compose {flusher_http} Then there is at least {10} logs Then the log fields match kv diff --git a/test/e2e/test_cases/flusher_loki/case.feature b/test/e2e/test_cases/flusher_loki/case.feature index 37bf0209e2..59ad65b702 100644 --- a/test/e2e/test_cases/flusher_loki/case.feature +++ b/test/e2e/test_cases/flusher_loki/case.feature @@ -8,10 +8,10 @@ Feature: flusher loki Given subcribe data from {loki} with config """ address: http://loki:3100 - tenant_id: ilogtail + tenant_id: loongcollector target_labels: loki_name: hello - source: ilogtail + source: loongcollector """ Given {flusher-loki-case} local config as below """ @@ -29,7 +29,7 @@ Feature: flusher loki TagFieldsRename: loki_name: name URL: http://loki:3100/loki/api/v1/push - TenantID: ilogtail + TenantID: loongcollector MaxMessageWait: 100000000 MaxMessageBytes: 1024 Timeout: 1000000000000 @@ -39,9 +39,9 @@ Feature: flusher loki DynamicLabels: - tag.loki_name StaticLabels: - source: ilogtail + source: loongcollector """ - Given iLogtail depends on containers {["loki"]} + Given loongcollector depends on containers {["loki"]} When start docker-compose {flusher_loki} Then there is at least {10} logs Then the log fields match kv diff --git a/test/e2e/test_cases/input_canal/case.feature b/test/e2e/test_cases/input_canal/case.feature index 223353782f..2599a69850 100644 --- a/test/e2e/test_cases/input_canal/case.feature +++ b/test/e2e/test_cases/input_canal/case.feature @@ -22,7 +22,7 @@ Feature: input canal TextToString: true EnableDDL: true """ - Given iLogtail depends on containers {["mysql"]} + Given loongcollector depends on containers {["mysql"]} When start docker-compose {input_canal} When generate {10} http logs, with interval {10}ms, url: {http://client:10999/add/data}, method: {GET}, body: """ diff --git a/test/e2e/test_cases/input_canal_binfile_mode/case.feature b/test/e2e/test_cases/input_canal_binfile_mode/case.feature index dbe5e93df5..86a6dc6892 100644 --- a/test/e2e/test_cases/input_canal_binfile_mode/case.feature +++ b/test/e2e/test_cases/input_canal_binfile_mode/case.feature @@ -22,7 +22,7 @@ Feature: input canal binfile mode TextToString: true EnableDDL: true """ - Given iLogtail depends on containers {["mysql"]} + Given loongcollector depends on containers {["mysql"]} When start docker-compose {input_canal} When generate {10} http logs, with interval {10}ms, url: {http://client:10999/add/data}, method: {GET}, body: """ diff --git a/test/e2e/test_cases/input_docker_rawstdout/docker-compose.yaml b/test/e2e/test_cases/input_docker_rawstdout/docker-compose.yaml index a5812868cb..2e620913b3 100644 --- a/test/e2e/test_cases/input_docker_rawstdout/docker-compose.yaml +++ b/test/e2e/test_cases/input_docker_rawstdout/docker-compose.yaml @@ -23,4 +23,4 @@ services: environment: - STDOUT_SWITCH=true depends_on: - - ilogtailC + - loongcollectorC diff --git a/test/e2e/test_cases/input_docker_rawstdout_multiline/docker-compose.yaml b/test/e2e/test_cases/input_docker_rawstdout_multiline/docker-compose.yaml index a5812868cb..2e620913b3 100644 --- a/test/e2e/test_cases/input_docker_rawstdout_multiline/docker-compose.yaml +++ b/test/e2e/test_cases/input_docker_rawstdout_multiline/docker-compose.yaml @@ -23,4 +23,4 @@ services: environment: - STDOUT_SWITCH=true depends_on: - - ilogtailC + - loongcollectorC diff --git a/test/e2e/test_cases/input_http_server/case.feature b/test/e2e/test_cases/input_http_server/case.feature index 45b3f86cae..e32241b31b 100644 --- a/test/e2e/test_cases/input_http_server/case.feature +++ b/test/e2e/test_cases/input_http_server/case.feature @@ -27,9 +27,9 @@ Feature: input http server FieldType: json ExpondJson: true """ - Given iLogtail expose port {18089} to {18089} + Given loongcollector expose port {18089} to {18089} When start docker-compose {input_http_server} - When generate {10} http logs, with interval {10}ms, url: {http://ilogtailC:18089/?db=mydb}, method: {POST}, body: + When generate {10} http logs, with interval {10}ms, url: {http://loongcollectorC:18089/?db=mydb}, method: {POST}, body: """ weather,city=hz value=32 """ diff --git a/test/e2e/test_cases/input_mssql/case.feature b/test/e2e/test_cases/input_mssql/case.feature index 94b611afff..1916cda023 100644 --- a/test/e2e/test_cases/input_mssql/case.feature +++ b/test/e2e/test_cases/input_mssql/case.feature @@ -28,7 +28,7 @@ Feature: input mssql Password: MSsqlpa#1word StateMent: "select * from LogtailTestTable where id > ? ORDER BY id" """ - Given iLogtail depends on containers {["setup"]} + Given loongcollector depends on containers {["setup"]} When start docker-compose {input_mssql} Then there is at least {4} logs Then the log fields match as below diff --git a/test/e2e/test_cases/input_mysql/case.feature b/test/e2e/test_cases/input_mysql/case.feature index 3f5dafa48c..92e5d3e8d4 100644 --- a/test/e2e/test_cases/input_mysql/case.feature +++ b/test/e2e/test_cases/input_mysql/case.feature @@ -28,7 +28,7 @@ Feature: input mysql CheckPointStart: "0" IntervalMs: 1000 """ - Given iLogtail depends on containers {["mysql"]} + Given loongcollector depends on containers {["mysql"]} When start docker-compose {input_mysql} Then there is at least {500} logs Then the log fields match as below diff --git a/test/e2e/test_cases/input_pgsql/case.feature b/test/e2e/test_cases/input_pgsql/case.feature index b28f47f1cc..10a44f1f38 100644 --- a/test/e2e/test_cases/input_pgsql/case.feature +++ b/test/e2e/test_cases/input_pgsql/case.feature @@ -28,7 +28,7 @@ Feature: input pgsql Password: postgres StateMent: "select * from specialalarmtest where id > $1" """ - Given iLogtail depends on containers {["pgsql"]} + Given loongcollector depends on containers {["pgsql"]} When start docker-compose {input_pgsql} Then there is at least {10} logs Then the log fields match as below diff --git a/test/e2e/test_cases/input_static_file/case.feature b/test/e2e/test_cases/input_static_file/case.feature index ae703115a7..27ecf88dae 100644 --- a/test/e2e/test_cases/input_static_file/case.feature +++ b/test/e2e/test_cases/input_static_file/case.feature @@ -20,7 +20,7 @@ Feature: input static file - "/root/test/**/a*.log" MaxDirSearchDepth: 10 """ - Given iLogtail container mount {./a.log} to {/root/test/1/2/3/axxxx.log} + Given loongcollector container mount {./a.log} to {/root/test/1/2/3/axxxx.log} When start docker-compose {input_static_file} Then there is at least {1000} logs Then the log fields match kv diff --git a/test/e2e/test_cases/reader_deleted/case.feature b/test/e2e/test_cases/reader_deleted/case.feature index 7fb295c6c1..16b29a166f 100644 --- a/test/e2e/test_cases/reader_deleted/case.feature +++ b/test/e2e/test_cases/reader_deleted/case.feature @@ -17,6 +17,6 @@ Feature: reader deleted - /root/test/simple.log FlushTimeoutSecs: 3 """ - Given iLogtail container mount {./volume} to {/root/test} + Given loongcollector container mount {./volume} to {/root/test} When start docker-compose {reader_deleted} Then there is at least {1} logs \ No newline at end of file diff --git a/test/e2e/test_cases/reader_deleted/docker-compose.yaml b/test/e2e/test_cases/reader_deleted/docker-compose.yaml index 8be92134c3..4bb16a628e 100644 --- a/test/e2e/test_cases/reader_deleted/docker-compose.yaml +++ b/test/e2e/test_cases/reader_deleted/docker-compose.yaml @@ -25,4 +25,4 @@ services: environment: - STDOUT_SWITCH=true depends_on: - - ilogtailC + - loongcollectorC diff --git a/test/e2e/test_cases/reader_flush_timeout/case.feature b/test/e2e/test_cases/reader_flush_timeout/case.feature index 081426c104..3f5697e66e 100644 --- a/test/e2e/test_cases/reader_flush_timeout/case.feature +++ b/test/e2e/test_cases/reader_flush_timeout/case.feature @@ -17,6 +17,6 @@ Feature: reader flush timeout - /root/test/simple.log FlushTimeoutSecs: 1 """ - Given iLogtail container mount {./a.log} to {/root/test/simple.log} + Given loongcollector container mount {./a.log} to {/root/test/simple.log} When start docker-compose {reader_flush_timeout} Then there is at least {5} logs \ No newline at end of file diff --git a/test/e2e/test_cases/reader_log_rotate/case.feature b/test/e2e/test_cases/reader_log_rotate/case.feature index 426c501e57..2c77fcd3e9 100644 --- a/test/e2e/test_cases/reader_log_rotate/case.feature +++ b/test/e2e/test_cases/reader_log_rotate/case.feature @@ -17,6 +17,6 @@ Feature: reader log rotate - /root/test/simple.log FlushTimeoutSecs: 2 """ - Given iLogtail container mount {./volume} to {/root/test} + Given loongcollector container mount {./volume} to {/root/test} When start docker-compose {reader_log_rotate} Then there is at least {6} logs \ No newline at end of file diff --git a/test/e2e/test_cases/reader_new_line_after_timeout/case.feature b/test/e2e/test_cases/reader_new_line_after_timeout/case.feature index ddb701f93a..c1d29ea848 100644 --- a/test/e2e/test_cases/reader_new_line_after_timeout/case.feature +++ b/test/e2e/test_cases/reader_new_line_after_timeout/case.feature @@ -17,6 +17,6 @@ Feature: reader new line after timeout - /root/test/a.log FlushTimeoutSecs: 1 """ - Given iLogtail container mount {./a.log} to {/root/test/a.log} + Given loongcollector container mount {./a.log} to {/root/test/a.log} When start docker-compose {reader_new_line_after_timeout} Then there is at least {6} logs \ No newline at end of file diff --git a/test/engine/cleanup/cache.go b/test/engine/cleanup/cache.go index a0224ba376..18d73319bb 100644 --- a/test/engine/cleanup/cache.go +++ b/test/engine/cleanup/cache.go @@ -21,7 +21,7 @@ import ( func GoTestCache(ctx context.Context) (context.Context, error) { command := "/usr/local/go/bin/go clean -testcache" - if err := setup.Env.ExecOnSource(ctx, command); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, command); err != nil { return ctx, err } return ctx, nil diff --git a/test/engine/cleanup/helper.go b/test/engine/cleanup/helper.go index 0a9408e749..c223800104 100644 --- a/test/engine/cleanup/helper.go +++ b/test/engine/cleanup/helper.go @@ -48,7 +48,6 @@ 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/cleanup/log.go b/test/engine/cleanup/log.go index a1a701c094..90780df8fa 100644 --- a/test/engine/cleanup/log.go +++ b/test/engine/cleanup/log.go @@ -23,7 +23,7 @@ import ( func AllGeneratedLog(ctx context.Context) (context.Context, error) { command := fmt.Sprintf("rm -rf %s/*", config.TestConfig.GeneratedLogDir) - if err := setup.Env.ExecOnSource(ctx, command); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, command); err != nil { return ctx, err } return ctx, nil diff --git a/test/engine/control/config.go b/test/engine/control/config.go index 3e68a8bd1d..bbde3ad4a0 100644 --- a/test/engine/control/config.go +++ b/test/engine/control/config.go @@ -32,7 +32,6 @@ import ( "github.com/alibaba/ilogtail/test/engine/setup/subscriber" ) -const iLogtailLocalConfigDir = "/usr/local/loongcollector/conf/local" const lotailpluginHTTPAddress = "ilogtailC:18689" const E2EProjectName = "e2e-test-project" const E2ELogstoreName = "e2e-test-logstore" @@ -55,8 +54,8 @@ func AddLocalConfig(ctx context.Context, configName, c string) (context.Context, } } else { command := fmt.Sprintf(`cd %s && cat << 'EOF' > %s.yaml -%s`, iLogtailLocalConfigDir, configName, c) - if err := setup.Env.ExecOnLogtail(command); err != nil { +%s`, config.TestConfig.LocalConfigDir, configName, c) + if _, err := setup.Env.ExecOnLogtail(command); err != nil { return ctx, err } time.Sleep(5 * time.Second) @@ -65,8 +64,8 @@ func AddLocalConfig(ctx context.Context, configName, c string) (context.Context, } func RemoveAllLocalConfig(ctx context.Context) (context.Context, error) { - command := fmt.Sprintf("cd %s && rm -rf *.yaml", iLogtailLocalConfigDir) - if err := setup.Env.ExecOnLogtail(command); err != nil { + command := fmt.Sprintf("cd %s && rm -rf *.yaml", config.TestConfig.LocalConfigDir) + if _, err := setup.Env.ExecOnLogtail(command); err != nil { return ctx, err } return ctx, nil diff --git a/test/engine/control/filter.go b/test/engine/control/filter.go index f90c08f811..4a7272aba2 100644 --- a/test/engine/control/filter.go +++ b/test/engine/control/filter.go @@ -57,3 +57,25 @@ func RemoveLabel(ctx context.Context, labelStr string) (context.Context, error) } return ctx, nil } + +func ApplyYaml(ctx context.Context, yaml string) (context.Context, error) { + if k8sEnv, ok := setup.Env.(*setup.K8sEnv); ok { + if err := k8sEnv.Apply(yaml); err != nil { + return ctx, err + } + } else { + return ctx, fmt.Errorf("try to apply yaml, but env is not k8s env") + } + return ctx, nil +} + +func DeleteYaml(ctx context.Context, yaml string) (context.Context, error) { + if k8sEnv, ok := setup.Env.(*setup.K8sEnv); ok { + if err := k8sEnv.Delete(yaml); err != nil { + return ctx, err + } + } else { + return ctx, fmt.Errorf("try to delete yaml, but env is not k8s env") + } + return ctx, nil +} diff --git a/test/engine/setup/controller/kubernetes.go b/test/engine/setup/controller/kubernetes.go index f17ed7e72a..99765c85a4 100644 --- a/test/engine/setup/controller/kubernetes.go +++ b/test/engine/setup/controller/kubernetes.go @@ -16,12 +16,18 @@ package controller import ( "context" "fmt" + "os" "time" "github.com/avast/retry-go/v4" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" "github.com/alibaba/ilogtail/test/config" ) @@ -39,6 +45,14 @@ type DeploymentController struct { k8sClient *kubernetes.Clientset } +type DaemonSetController struct { + k8sClient *kubernetes.Clientset +} + +type DynamicController struct { + dynamicClient dynamic.Interface +} + func NewDeploymentController(k8sClient *kubernetes.Clientset) *DeploymentController { return &DeploymentController{k8sClient: k8sClient} } @@ -182,10 +196,6 @@ func (c *DeploymentController) DeleteDeployment(deploymentName, deploymentNamesp return c.k8sClient.AppsV1().Deployments(deploymentNamespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{}) } -type DaemonSetController struct { - k8sClient *kubernetes.Clientset -} - func NewDaemonSetController(k8sClient *kubernetes.Clientset) *DaemonSetController { return &DaemonSetController{k8sClient: k8sClient} } @@ -204,3 +214,78 @@ func (c *DaemonSetController) GetDaemonSetPods(dsName, dsNamespace string) (*cor } return pods, nil } + +func NewDynamicController(dynamicClient dynamic.Interface) *DynamicController { + return &DynamicController{dynamicClient: dynamicClient} +} + +func (c *DynamicController) Apply(filePath string) error { + // Parse the object from the YAML file + mapping, obj, err := c.parseObjFromYaml(filePath) + if err != nil { + return err + } + + // Apply the object to the Kubernetes cluster + namespace := obj.GetNamespace() + if namespace == "" { + namespace = "default" // Use default namespace if not specified + } + resourceInterface := c.dynamicClient.Resource(mapping.Resource).Namespace(namespace) + if _, err := resourceInterface.Get(context.TODO(), obj.GetName(), metav1.GetOptions{}); err != nil { + // Object does not exist, create it + if _, err := resourceInterface.Create(context.TODO(), obj, metav1.CreateOptions{}); err != nil { + return err + } + } else { + // Object exists, update it + if _, err := resourceInterface.Update(context.TODO(), obj, metav1.UpdateOptions{}); err != nil { + return err + } + } + return nil +} + +func (c *DynamicController) Delete(filePath string) error { + // Parse the object from the YAML file + mapping, obj, err := c.parseObjFromYaml(filePath) + if err != nil { + return err + } + + // Delete the object from the Kubernetes cluster + namespace := obj.GetNamespace() + if namespace == "" { + namespace = "default" // Use default namespace if not specified + } + resourceInterface := c.dynamicClient.Resource(mapping.Resource).Namespace(namespace) + if err := resourceInterface.Delete(context.TODO(), obj.GetName(), metav1.DeleteOptions{}); err != nil { + return err + } + return nil +} + +func (c *DynamicController) parseObjFromYaml(filePath string) (*meta.RESTMapping, *unstructured.Unstructured, error) { + // Read the YAML file + yamlFile, err := os.ReadFile(filePath) + if err != nil { + return nil, nil, err + } + + // Decode the YAML file into an unstructured.Unstructured object + decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + obj := &unstructured.Unstructured{} + _, gvk, err := decUnstructured.Decode(yamlFile, nil, obj) + if err != nil { + return nil, nil, err + } + + // Retrieve the REST mapping for the GVK + restMapper := meta.NewDefaultRESTMapper(scheme.Scheme.PreferredVersionAllGroups()) + mapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, nil, err + } + + return mapping, obj, nil +} diff --git a/test/engine/setup/docker_compose.go b/test/engine/setup/docker_compose.go index 2c85bbbec9..6a7e3fc4de 100644 --- a/test/engine/setup/docker_compose.go +++ b/test/engine/setup/docker_compose.go @@ -123,10 +123,10 @@ func (d *DockerComposeEnv) Clean() error { return nil } -func (d *DockerComposeEnv) ExecOnLogtail(command string) error { - return fmt.Errorf("not implemented") +func (d *DockerComposeEnv) ExecOnLogtail(command string) (string, error) { + return "", fmt.Errorf("not implemented") } -func (d *DockerComposeEnv) ExecOnSource(ctx context.Context, command string) error { - return fmt.Errorf("not implemented") +func (d *DockerComposeEnv) ExecOnSource(ctx context.Context, command string) (string, error) { + return "", fmt.Errorf("not implemented") } diff --git a/test/engine/setup/dockercompose/compose.go b/test/engine/setup/dockercompose/compose.go index 351552f7e1..4163354568 100644 --- a/test/engine/setup/dockercompose/compose.go +++ b/test/engine/setup/dockercompose/compose.go @@ -55,9 +55,9 @@ services: timeout: 5s interval: 1s retries: 10 - ilogtailC: + loongcollectorC: image: aliyun/loongcollector:0.0.1 - hostname: ilogtail + hostname: loongcollector privileged: true pid: host volumes: @@ -139,8 +139,8 @@ func (c *ComposeBooter) Start(ctx context.Context) error { list, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ Filters: filters.NewArgs( - filters.Arg("name", fmt.Sprintf("%s_ilogtailC*", projectName)), - filters.Arg("name", fmt.Sprintf("%s-ilogtailC*", projectName)), + filters.Arg("name", fmt.Sprintf("%s_loongcollectorC*", projectName)), + filters.Arg("name", fmt.Sprintf("%s-loongcollectorC*", projectName)), ), }) if len(list) != 1 { @@ -265,7 +265,7 @@ func (c *ComposeBooter) createComposeFile(ctx context.Context) error { } cfg := c.getLogtailpluginConfig() services := cfg["services"].(map[string]interface{}) - ilogtail := services["ilogtailC"].(map[string]interface{}) + loongcollector := services["loongcollectorC"].(map[string]interface{}) // merge docker compose file. if len(bytes) > 0 { caseCfg := make(map[string]interface{}) @@ -273,14 +273,14 @@ func (c *ComposeBooter) createComposeFile(ctx context.Context) error { return err } // depend on - ilogtailDependOn := map[string]interface{}{ + loongcollectorDependOn := map[string]interface{}{ "goc": map[string]string{ "condition": "service_healthy", }, } if dependOnContainers, ok := ctx.Value(config.DependOnContainerKey).([]string); ok { for _, container := range dependOnContainers { - ilogtailDependOn[container] = map[string]string{ + loongcollectorDependOn[container] = map[string]string{ "condition": "service_healthy", } } @@ -289,24 +289,24 @@ func (c *ComposeBooter) createComposeFile(ctx context.Context) error { for k := range newServices { services[k] = newServices[k] } - ilogtail["depends_on"] = ilogtailDependOn + loongcollector["depends_on"] = loongcollectorDependOn } // volume - ilogtailMount := services["ilogtailC"].(map[string]interface{})["volumes"].([]interface{}) + loongcollectorMount := services["loongcollectorC"].(map[string]interface{})["volumes"].([]interface{}) if volumes, ok := ctx.Value(config.MountVolumeKey).([]string); ok { for _, volume := range volumes { - ilogtailMount = append(ilogtailMount, volume) + loongcollectorMount = append(loongcollectorMount, volume) } } // ports - ilogtailPort := services["ilogtailC"].(map[string]interface{})["ports"].([]interface{}) + loongcollectorPort := services["loongcollectorC"].(map[string]interface{})["ports"].([]interface{}) if ports, ok := ctx.Value(config.ExposePortKey).([]string); ok { for _, port := range ports { - ilogtailPort = append(ilogtailPort, port) + loongcollectorPort = append(loongcollectorPort, port) } } - ilogtail["volumes"] = ilogtailMount - ilogtail["ports"] = ilogtailPort + loongcollector["volumes"] = loongcollectorMount + loongcollector["ports"] = loongcollectorPort yml, err := yaml.Marshal(cfg) if err != nil { return err @@ -314,7 +314,7 @@ func (c *ComposeBooter) createComposeFile(ctx context.Context) error { return os.WriteFile(config.CaseHome+finalFileName, yml, 0600) } -// getLogtailpluginConfig find the docker compose configuration of the ilogtail. +// getLogtailpluginConfig find the docker compose configuration of the loongcollector. func (c *ComposeBooter) getLogtailpluginConfig() map[string]interface{} { cfg := make(map[string]interface{}) f, _ := os.Create(config.CoverageFile) diff --git a/test/engine/setup/env.go b/test/engine/setup/env.go index 75a60cc595..c72cd5f65c 100644 --- a/test/engine/setup/env.go +++ b/test/engine/setup/env.go @@ -15,17 +15,19 @@ package setup import ( "context" + + "github.com/alibaba/ilogtail/test/config" ) var Env TestEnv type TestEnv interface { GetType() string - ExecOnLogtail(command string) error - ExecOnSource(ctx context.Context, command string) error + ExecOnLogtail(command string) (string, error) + ExecOnSource(ctx context.Context, command string) (string, error) } -func InitEnv(envType string) { +func InitEnv(ctx context.Context, envType string) (context.Context, error) { switch envType { case "host": Env = NewHostEnv() @@ -36,9 +38,23 @@ func InitEnv(envType string) { case "deployment": Env = NewDeploymentEnv() } + return SetAgentPID(ctx) } func Mkdir(ctx context.Context, dir string) (context.Context, error) { command := "mkdir -p " + dir - return ctx, Env.ExecOnSource(ctx, command) + _, err := Env.ExecOnSource(ctx, command) + return ctx, err +} + +func SetAgentPID(ctx context.Context) (context.Context, error) { + command := "ps -e | grep loongcollector | grep -v grep | awk '{print $1}'" + result, err := Env.ExecOnLogtail(command) + if err != nil { + if err.Error() == "not implemented" { + return ctx, nil + } + return ctx, err + } + return context.WithValue(ctx, config.AgentPIDKey, result), nil } diff --git a/test/engine/setup/host.go b/test/engine/setup/host.go index ea6fe500a8..830d195306 100644 --- a/test/engine/setup/host.go +++ b/test/engine/setup/host.go @@ -38,23 +38,23 @@ func (h *HostEnv) GetType() string { return "host" } -func (h *HostEnv) ExecOnLogtail(command string) error { +func (h *HostEnv) ExecOnLogtail(command string) (string, error) { return h.exec(command) } -func (h *HostEnv) ExecOnSource(ctx context.Context, command string) error { +func (h *HostEnv) ExecOnSource(ctx context.Context, command string) (string, error) { return h.exec(command) } -func (h *HostEnv) exec(command string) error { +func (h *HostEnv) exec(command string) (string, error) { if h.sshClient == nil { - return fmt.Errorf("ssh client init failed") + return "", fmt.Errorf("ssh client init failed") } result, err := h.sshClient.Run(command) if err != nil { - return fmt.Errorf("%v, %v", string(result), err) + return "", fmt.Errorf("%v, %v", string(result), err) } - return nil + return string(result), nil } func (h *HostEnv) initSSHClient() { diff --git a/test/engine/setup/k8s.go b/test/engine/setup/k8s.go index 7ee1c61aa9..85eaef8e6d 100644 --- a/test/engine/setup/k8s.go +++ b/test/engine/setup/k8s.go @@ -19,8 +19,10 @@ import ( "crypto/rand" "fmt" "math/big" + "strings" corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -37,6 +39,7 @@ type K8sEnv struct { k8sClient *kubernetes.Clientset deploymentController *controller.DeploymentController daemonsetController *controller.DaemonSetController + dynamicController *controller.DynamicController } func NewDaemonSetEnv() *K8sEnv { @@ -59,34 +62,37 @@ func (k *K8sEnv) GetType() string { return k.deployType } -func (k *K8sEnv) ExecOnLogtail(command string) error { +func (k *K8sEnv) ExecOnLogtail(command string) (string, error) { if k.k8sClient == nil { - return fmt.Errorf("k8s client init failed") + return "", fmt.Errorf("k8s client init failed") } var pods *corev1.PodList var err error if k.deployType == "daemonset" { pods, err = k.daemonsetController.GetDaemonSetPods("logtail-ds", "kube-system") if err != nil { - return err + return "", err } } else if k.deployType == "deployment" { pods, err = k.deploymentController.GetRunningDeploymentPods("cluster-agent", "loong-collector") if err != nil { - return err + return "", err } } + results := make([]string, 0) for _, pod := range pods.Items { - if err := k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"bash", "-c", command}); err != nil { - return err + if result, err := k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"bash", "-c", command}); err != nil { + return "", err + } else { + results = append(results, result) } } - return nil + return strings.Join(results, "\n"), nil } -func (k *K8sEnv) ExecOnSource(ctx context.Context, command string) error { +func (k *K8sEnv) ExecOnSource(ctx context.Context, command string) (string, error) { if k.k8sClient == nil { - return fmt.Errorf("k8s client init failed") + return "", fmt.Errorf("k8s client init failed") } deploymentName := "e2e-generator" if ctx.Value(config.CurrentWorkingDeploymentKey) != nil { @@ -94,18 +100,15 @@ func (k *K8sEnv) ExecOnSource(ctx context.Context, command string) error { } pods, err := k.deploymentController.GetRunningDeploymentPods(deploymentName, "default") if err != nil { - return err + return "", err } randomIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(pods.Items)))) if err != nil { - return err + return "", err } pod := pods.Items[randomIndex.Int64()] - fmt.Println("exec on pod: ", pod.Name) - if err := k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"sh", "-c", command}); err != nil { - return err - } - return nil + fmt.Println("exec on pod: ", pod.Name, "command: ", command) + return k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"sh", "-c", command}) } func (k *K8sEnv) AddFilter(filter controller.ContainerFilter) error { @@ -116,6 +119,14 @@ func (k *K8sEnv) RemoveFilter(filter controller.ContainerFilter) error { return k.deploymentController.RemoveFilter("e2e-generator", filter) } +func (k *K8sEnv) Apply(filePath string) error { + return k.dynamicController.Apply(filePath) +} + +func (k *K8sEnv) Delete(filePath string) error { + return k.dynamicController.Delete(filePath) +} + func SwitchCurrentWorkingDeployment(ctx context.Context, deploymentName string) (context.Context, error) { return context.WithValue(ctx, config.CurrentWorkingDeploymentKey, deploymentName), nil } @@ -139,9 +150,12 @@ func (k *K8sEnv) init() { k.k8sClient = k8sClient k.deploymentController = controller.NewDeploymentController(k.k8sClient) k.daemonsetController = controller.NewDaemonSetController(k.k8sClient) + + dynamicClient, err := dynamic.NewForConfig(c) + k.dynamicController = controller.NewDynamicController(dynamicClient) } -func (k *K8sEnv) execInPod(config *rest.Config, namespace, podName, containerName string, command []string) error { +func (k *K8sEnv) execInPod(config *rest.Config, namespace, podName, containerName string, command []string) (string, error) { req := k.k8sClient.CoreV1().RESTClient(). Post(). Resource("pods"). @@ -158,7 +172,7 @@ func (k *K8sEnv) execInPod(config *rest.Config, namespace, podName, containerNam }, scheme.ParameterCodec) executor, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) if err != nil { - return err + return "", err } var stdout, stderr bytes.Buffer err = executor.Stream(remotecommand.StreamOptions{ @@ -167,7 +181,7 @@ func (k *K8sEnv) execInPod(config *rest.Config, namespace, podName, containerNam Stderr: &stderr, }) if err != nil { - return err + return "", err } - return nil + return stdout.String(), nil } diff --git a/test/engine/setup/subscriber/clickhouse.go b/test/engine/setup/subscriber/clickhouse.go index 1d7b1b43e5..f6afd0a8ba 100644 --- a/test/engine/setup/subscriber/clickhouse.go +++ b/test/engine/setup/subscriber/clickhouse.go @@ -33,7 +33,7 @@ import ( ) const clickHouseName = "clickhouse" -const clickhouseQuerySQL = "select _timestamp,_log from `%s`.`ilogtail_%s_buffer` where _timestamp > %v order by _timestamp" +const clickhouseQuerySQL = "select _timestamp,_log from `%s`.`loongcollector_%s_buffer` where _timestamp > %v order by _timestamp" type ClickHouseSubscriber struct { Address string `mapstructure:"address" comment:"the clickhouse address"` diff --git a/test/engine/setup/subscriber/grpc.go b/test/engine/setup/subscriber/grpc.go index e05137255b..ed02a4cd1e 100644 --- a/test/engine/setup/subscriber/grpc.go +++ b/test/engine/setup/subscriber/grpc.go @@ -44,7 +44,7 @@ type GrpcSubscriber struct { } func (g *GrpcSubscriber) Description() string { - return "this a gRPC subscriber, which is the default mock backend for Ilogtail." + return "this a gRPC subscriber, which is the default mock backend for loongcollector." } type GRPCService struct { diff --git a/test/engine/setup/subscriber/loki.go b/test/engine/setup/subscriber/loki.go index 702d13e8c7..82c77b0835 100644 --- a/test/engine/setup/subscriber/loki.go +++ b/test/engine/setup/subscriber/loki.go @@ -73,7 +73,7 @@ func (l *LokiSubscriber) Name() string { } func (l *LokiSubscriber) Description() string { - return "this a loki subscriber, which is the default mock backend for Ilogtail." + return "this a loki subscriber, which is the default mock backend for loongcollector." } func (l *LokiSubscriber) GetData(sql string, startTime int32) ([]*protocol.LogGroup, error) { diff --git a/test/engine/setup/subscriber/subscriber.go b/test/engine/setup/subscriber/subscriber.go index 62ea6bca32..247ffdd44c 100644 --- a/test/engine/setup/subscriber/subscriber.go +++ b/test/engine/setup/subscriber/subscriber.go @@ -36,7 +36,7 @@ var mu sync.Mutex // Creator creates a new subscriber instance according to the spec. type Creator func(spec map[string]interface{}) (Subscriber, error) -// Subscriber receives the logs transfer by ilogtail. +// Subscriber receives the logs transfer by loongcollector. type Subscriber interface { doc.Doc // Name of subscriber @@ -45,7 +45,7 @@ type Subscriber interface { Stop() error // Get data GetData(sql string, startTime int32) ([]*protocol.LogGroup, error) - // FlusherConfig returns the default flusher config for Ilogtail container to transfer the received or self telemetry data. + // FlusherConfig returns the default flusher config for loongcollector container to transfer the received or self telemetry data. FlusherConfig() string } diff --git a/test/engine/steps.go b/test/engine/steps.go index b3ec512458..43df1f980a 100644 --- a/test/engine/steps.go +++ b/test/engine/steps.go @@ -10,7 +10,6 @@ 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" @@ -18,37 +17,49 @@ import ( func ScenarioInitializer(ctx *godog.ScenarioContext) { // Given + // ------------------------------------------ ctx.Given(`^\{(\S+)\} environment$`, setup.InitEnv) - ctx.Given(`^iLogtail depends on containers \{(.*)\}`, setup.SetDockerComposeDependOn) - ctx.Given(`^iLogtail container mount \{(.*)\} to \{(.*)\}`, setup.MountVolume) - ctx.Given(`^iLogtail expose port \{(.*)\} to \{(.*)\}`, setup.ExposePort) + ctx.Given(`^loongcollector depends on containers \{(.*)\}`, setup.SetDockerComposeDependOn) + ctx.Given(`^loongcollector container mount \{(.*)\} to \{(.*)\}`, setup.MountVolume) + ctx.Given(`^loongcollector expose port \{(.*)\} to \{(.*)\}`, setup.ExposePort) ctx.Given(`^\{(.*)\} local config as below`, control.AddLocalConfig) ctx.Given(`^\{(.*)\} http config as below`, control.AddHTTPConfig) 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) - ctx.When(`^generate \{(\d+)\} regex gbk logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.RegexSingleGBK) - ctx.When(`^generate \{(\d+)\} http logs, with interval \{(\d+)\}ms, url: \{(.*)\}, method: \{(.*)\}, body:`, trigger.HTTP) + // ------------------------------------------ ctx.When(`^add k8s label \{(.*)\}`, control.AddLabel) ctx.When(`^remove k8s label \{(.*)\}`, control.RemoveLabel) ctx.When(`^start docker-compose \{(\S+)\}`, setup.StartDockerComposeEnv) ctx.When(`^switch working on deployment \{(.*)\}`, setup.SwitchCurrentWorkingDeployment) - ctx.When(`^generate \{(\d+)\} apsara logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.Apsara) - ctx.When(`^generate \{(\d+)\} delimiter logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.DelimiterSingle) ctx.When(`^query through \{(.*)\}`, control.SetQuery) + ctx.When(`^apply yaml \{(.*)\} to k8s`, control.ApplyYaml) + ctx.When(`^delete yaml \{(.*)\} from k8s`, control.DeleteYaml) + + // generate ctx.When(`^begin trigger`, trigger.BeginTrigger) + ctx.When(`^generate \{(\d+)\} regex logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.RegexSingle) + ctx.When(`^generate \{(\d+)\} multiline regex logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.RegexMultiline) + ctx.When(`^generate \{(\d+)\} regex gbk logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.RegexSingleGBK) + ctx.When(`^generate \{(\d+)\} http logs, with interval \{(\d+)\}ms, url: \{(.*)\}, method: \{(.*)\}, body:`, trigger.HTTP) + ctx.When(`^generate \{(\d+)\} apsara logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.Apsara) + ctx.When(`^generate \{(\d+)\} delimiter logs to file \{(.*)\}, with interval \{(\d+)\}ms, with delimiter \{(.*)\} and quote \{(.*)\}$`, trigger.DelimiterSingle) + ctx.When(`^generate \{(\d+)\} multiline delimiter logs to file \{(.*)\}, with interval \{(\d+)\}ms, with delimiter \{(.*)\} and quote \{(.*)\}$`, trigger.DelimiterMultiline) + ctx.When(`^generate \{(\d+)\} json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JsonSingle) + ctx.When(`^generate \{(\d+)\} multiline json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JsonMultiline) + ctx.When(`^generate \{(\d+)\} logs to stdout, with interval \{(\d+)\}ms$`, trigger.Stdout) + ctx.When(`^generate \{(\d+)\} logs to stderr, with interval \{(\d+)\}ms$`, trigger.Stderr) 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 + // ------------------------------------------ + // log ctx.Then(`^there is \{(\d+)\} logs$`, verify.LogCount) - ctx.Then(`^there is more than \{(\d+)\} metrics in \{(\d+)\} seconds$`, verify.MetricCount) + ctx.Then(`^there is less than \{(\d+)\} logs$`, verify.LogCountLess) ctx.Then(`^there is at least \{(\d+)\} logs$`, verify.LogCountAtLeast) ctx.Then(`^there is at least \{(\d+)\} logs with filter key \{(.*)\} value \{(.*)\}$`, verify.LogCountAtLeastWithFilter) ctx.Then(`^the log fields match kv`, verify.LogFieldKV) @@ -57,13 +68,17 @@ func ScenarioInitializer(ctx *godog.ScenarioContext) { ctx.Then(`^the log fields match as below`, verify.LogField) ctx.Then(`^the log labels match as below`, verify.LogLabel) ctx.Then(`^the logtail log contains \{(\d+)\} times of \{(.*)\}$`, verify.LogtailPluginLog) + ctx.Then(`^the log is in order$`, verify.LogOrder) + + // metric + ctx.Then(`^there is more than \{(\d+)\} metrics in \{(\d+)\} seconds$`, verify.MetricCount) + + // other ctx.Then(`wait \{(\d+)\} seconds`, func(ctx context.Context, t int) context.Context { time.Sleep(time.Duration(t) * time.Second) return ctx }) - // special pattern logs - ctx.Then(`^the log fields match regex single`, verify.RegexSingle) - ctx.Then(`^the log fields match apsara`, verify.Apsara) + // ------------------------------------------ ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) { config.ParseConfig() @@ -72,6 +87,6 @@ func ScenarioInitializer(ctx *godog.ScenarioContext) { }) ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) { cleanup.All() - return ctx, nil + return verify.AgentNotCrash(ctx) }) } diff --git a/test/engine/trigger/ebpf_trigger.go b/test/engine/trigger/ebpf_trigger.go index 6b0aaa5d87..a0558ac3cf 100644 --- a/test/engine/trigger/ebpf_trigger.go +++ b/test/engine/trigger/ebpf_trigger.go @@ -43,17 +43,17 @@ func rwFile(ctx context.Context, commandCnt int, filenames string) error { files := strings.Split(filenames, ",") for _, file := range files { touchFileCommand := "touch " + file + ";" - if err := setup.Env.ExecOnSource(ctx, touchFileCommand); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, touchFileCommand); err != nil { return err } catFileCommand := "echo 'Hello, World!' >> " + file + ";" for i := 0; i < commandCnt; i++ { - if err := setup.Env.ExecOnSource(ctx, catFileCommand); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, catFileCommand); err != nil { return err } } removeCommand := "rm " + file + ";" - if err := setup.Env.ExecOnSource(ctx, removeCommand); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, removeCommand); err != nil { return err } } @@ -74,7 +74,7 @@ func mmapFile(ctx context.Context, commandCnt int, filenames string) error { }); err != nil { return err } - if err := setup.Env.ExecOnSource(ctx, triggerEBPFCommand.String()); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, triggerEBPFCommand.String()); err != nil { return err } } @@ -87,15 +87,15 @@ func truncateFile(ctx context.Context, commandCnt int, filenames string) error { truncateFileCommand1 := "truncate -s 10k " + file + ";" truncateFileCommand2 := "truncate -s 0 " + file + ";" for i := 0; i < commandCnt/2; i++ { - if err := setup.Env.ExecOnSource(ctx, truncateFileCommand1); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, truncateFileCommand1); err != nil { return err } - if err := setup.Env.ExecOnSource(ctx, truncateFileCommand2); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, truncateFileCommand2); err != nil { return err } } if commandCnt%2 != 0 { - if err := setup.Env.ExecOnSource(ctx, truncateFileCommand1); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, truncateFileCommand1); err != nil { return err } } diff --git a/test/engine/trigger/generator/apsara_test.go b/test/engine/trigger/generator/apsara_test.go index f6cacf8996..40329c0cfe 100644 --- a/test/engine/trigger/generator/apsara_test.go +++ b/test/engine/trigger/generator/apsara_test.go @@ -15,7 +15,7 @@ package generator import ( "fmt" - "io" + "math/rand" "os" "strconv" "testing" @@ -24,28 +24,19 @@ import ( // TestGenerateApsara will be executed in the environment being collected. func TestGenerateApsara(t *testing.T) { - gneratedLogDir := getEnvOrDefault("GENERATED_LOG_DIR", "/tmp/ilogtail") - totalLog, err := strconv.Atoi(getEnvOrDefault("TOTAL_LOG", "100")) + config, err := getGenerateFileLogConfigFromEnv() if err != nil { - t.Fatalf("parse TOTAL_LOG failed: %v", err) + t.Fatalf("get generate file log config from env failed: %v", err) return } - interval, err := strconv.Atoi(getEnvOrDefault("INTERVAL", "1")) - if err != nil { - t.Fatalf("parse INTERVAL failed: %v", err) - return - } - fileName := getEnvOrDefault("FILENAME", "apsara.log") - - testLogConent := []string{ - "[%s]\t[ERROR]\t[32337]\t[/build/core/application/Application:12]\tfile:file0\tlogNo:1199997\tmark:-\tmsg:hello world!", - "[%s]\t[ERROR]\t[20964]\t[/build/core/ilogtail.cpp:127]\tfile:file0\tlogNo:1199998\tmark:F\tmsg:这是一条消息", - "[%s]\t[WARNING]\t[32337]\t[/build/core/ilogtail.cpp:127]\tfile:file0\tlogNo:1199999\tmark:-\tmsg:hello world!", - "[%s]\t[INFO]\t[32337]\t[/build/core/ilogtail.cpp:127]\tfile:file0\tlogNo:1200000\tmark:-\tmsg:这是一条消息", - "[%s]\t[ERROR]\t[00001]\t[/build/core/ilogtail.cpp:127]\tfile:file0\tlogNo:1199992\tmark:-\tmsg:password:123456", - "[%s]\t[DEBUG]\t[32337]\t[/build/core/ilogtail.cpp:127]\tfile:file0\tlogNo:1199993\tmark:-\tmsg:hello world!", - } - file, err := os.OpenFile(fmt.Sprintf("%s/%s", gneratedLogDir, fileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + testLogContentTmpl := string2Template([]string{ + "[{{.Time}}]\t[{{.Level}}]\t[32337]\t[/build/core/application/Application:12]\tfile:file{{.FileNo}}\tlogNo:{{.LogNo}}\tmark:{{.Mark}}\tmsg:hello world!\n", + "[{{.Time}}]\t[{{.Level}}]\t[20964]\t[/build/core/ilogtail.cpp:127]\tfile:file{{.FileNo}}\tlogNo:{{.LogNo}}\tmark:{{.Mark}}\tmsg:这是一条消息\n", + "[{{.Time}}]\t[{{.Level}}]\t[32337]\t[/build/core/ilogtail.cpp:127]\tfile:file{{.FileNo}}\tlogNo:{{.LogNo}}\tmark:{{.Mark}}\tmsg:hello world!\n", + "[{{.Time}}]\t[{{.Level}}]\t[32337]\t[/build/core/ilogtail.cpp:127]\tfile:file{{.FileNo}}\tlogNo:{{.LogNo}}\tmark:{{.Mark}}\tmsg:这是一条消息\n", + "[{{.Time}}]\t[{{.Level}}]\t[00001]\t[/build/core/ilogtail.cpp:127]\tfile:file{{.FileNo}}\tlogNo:{{.LogNo}}\tmark:{{.Mark}}\tmsg:password:123456\n", + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { t.Fatalf("open file failed: %v", err) return @@ -53,21 +44,29 @@ func TestGenerateApsara(t *testing.T) { defer file.Close() logIndex := 0 - for i := 0; i < totalLog; i++ { + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + for i := 0; i < config.TotalLog; i++ { var currentTime string if i%2 == 0 { currentTime = time.Now().Format("2006-01-02 15:04:05.000000") } else { currentTime = strconv.FormatInt(time.Now().UnixNano()/1000, 10) } - _, err := io.WriteString(file, fmt.Sprintf(testLogConent[logIndex]+"\n", currentTime)) + err = testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Time": currentTime, + "Level": getRandomLogLevel(), + "LogNo": logNo + i, + "FileNo": fileNo, + "Mark": getRandomMark(), + }) if err != nil { t.Fatalf("write log failed: %v", err) return } - time.Sleep(time.Duration(interval * int(time.Millisecond))) + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConent) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } diff --git a/test/engine/trigger/generator/delimiter_test.go b/test/engine/trigger/generator/delimiter_test.go index 7388636cd1..354b6dea8c 100644 --- a/test/engine/trigger/generator/delimiter_test.go +++ b/test/engine/trigger/generator/delimiter_test.go @@ -15,36 +15,88 @@ package generator import ( "fmt" - "io" + "math/rand" "os" - "strconv" "testing" "time" ) // TestGenerateDelimiterSingle will be executed in the environment being collected. func TestGenerateDelimiterSingle(t *testing.T) { - gneratedLogDir := getEnvOrDefault("GENERATED_LOG_DIR", "/tmp/ilogtail") - totalLog, err := strconv.Atoi(getEnvOrDefault("TOTAL_LOG", "100")) + config, err := getGenerateFileLogConfigFromEnv("Delimiter", "Quote") if err != nil { - t.Fatalf("parse TOTAL_LOG failed: %v", err) + t.Fatalf("get generate file log config from env failed: %v", err) return } - interval, err := strconv.Atoi(getEnvOrDefault("INTERVAL", "1")) + delimiter := config.Custom["Delimiter"] + if delimiter == "" { + delimiter = " " + } + quote := config.Custom["Quote"] + if quote == "" { + quote = "" + } + testLogContentTmpl := string2Template([]string{ + "{{.Quote}}{{.Mark}}{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}0.0.0.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/index.html{{.Quote}}{{.Delimiter}}{{.Quote}}HTTP/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}302{{.Quote}}{{.Delimiter}}{{.Quote}}628{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + "{{.Quote}}{{.Mark}}{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}10.45.26.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/{{.Quote}}{{.Delimiter}}{{.Quote}}HTTP/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}302{{.Quote}}{{.Delimiter}}{{.Quote}}218{{.Quote}}{{.Delimiter}}{{.Quote}}go-sdk{{.Quote}}\n", + "{{.Quote}}{{.Mark}}{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}10.45.26.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/dir/resource.txt{{.Quote}}{{.Delimiter}}{{.Quote}}HTTP/1.1{{.Quote}}{{.Delimiter}}{{.Quote}}404{{.Quote}}{{.Delimiter}}{{.Quote}}744{{.Quote}}{{.Delimiter}}{{.Quote}}Mozilla/5.0{{.Quote}}\n", + "{{.Quote}}{{.Mark}}{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}127.0.0.1{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}PUT{{.Quote}}{{.Delimiter}}{{.Quote}}/{{.Quote}}{{.Delimiter}}{{.Quote}}HTTP/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}200{{.Quote}}{{.Delimiter}}{{.Quote}}320{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + "{{.Quote}}{{.Mark}}{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}192.168.0.3{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}PUT{{.Quote}}{{.Delimiter}}{{.Quote}}/dir/resource.txt{{.Quote}}{{.Delimiter}}{{.Quote}}HTTP/1.1{{.Quote}}{{.Delimiter}}{{.Quote}}404{{.Quote}}{{.Delimiter}}{{.Quote}}949{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { - t.Fatalf("parse INTERVAL failed: %v", err) + t.Fatalf("open file failed: %v", err) return } - fileName := getEnvOrDefault("FILENAME", "apsara.log") + defer file.Close() - testLogConent := []string{ - "'-' 'file0' '13196' '0.0.0.0' '%s' 'GET' '/index.html' 'HTTP/2.0' '302' '628' 'curl/7.10'", - "'-' 'file0' '13197' '10.45.26.0' '%s' 'GET' '/' 'HTTP/2.0' '302' '218' 'go-sdk'", - "'-' 'file0' '13198' '10.45.26.0' '%s' 'GET' '/dir/resource.txt' 'HTTP/1.1' '404' '744' 'Mozilla/5.0'", - "'-' 'file0' '13199' '127.0.0.1' '%s' 'PUT' '/' 'HTTP/2.0' '200' '320' 'curl/7.10'", - "'-' 'file0' '13200' '192.168.0.3' '%s' 'PUT' '/dir/resource.txt' 'HTTP/1.1' '404' '949' 'curl/7.10'", + logIndex := 0 + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + for i := 0; i < config.TotalLog; i++ { + err = testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Mark": getRandomMark(), + "FileNo": fileNo, + "LogNo": logNo, + "Time": time.Now().Format("2006-01-02 15:04:05.000000000"), + "Delimiter": delimiter, + "Quote": quote, + }) + if err != nil { + t.Fatalf("write log failed: %v", err) + return + } + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) + logIndex++ + if logIndex >= len(testLogContentTmpl) { + logIndex = 0 + } + } +} + +// TestGenerateDelimiterMultiline will be executed in the environment being collected. +func TestGenerateDelimiterMultiline(t *testing.T) { + config, err := getGenerateFileLogConfigFromEnv("Delimiter", "Quote") + if err != nil { + t.Fatalf("get generate file log config from env failed: %v", err) + return + } + delimiter := config.Custom["Delimiter"] + if delimiter == "" { + delimiter = " " + } + quote := config.Custom["Quote"] + if quote == "" { + quote = "" } - file, err := os.OpenFile(fmt.Sprintf("%s/%s", gneratedLogDir, fileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + testLogContentTmpl := string2Template([]string{ + "{{.Quote}}F{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}0.0.0.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/index.html{{.Quote}}{{.Delimiter}}{{.Quote}}\nHTTP\n/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}302{{.Quote}}{{.Delimiter}}{{.Quote}}628{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + "{{.Quote}}-{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}10.45.26.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/{{.Quote}}{{.Delimiter}}{{.Quote}}\nHTTP\n/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}302{{.Quote}}{{.Delimiter}}{{.Quote}}218{{.Quote}}{{.Delimiter}}{{.Quote}}go-sdk{{.Quote}}\n", + "{{.Quote}}F{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}10.45.26.0{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}GET{{.Quote}}{{.Delimiter}}{{.Quote}}/dir/resource.txt{{.Quote}}{{.Delimiter}}{{.Quote}}\nHTTP\n/1.1{{.Quote}}{{.Delimiter}}{{.Quote}}404{{.Quote}}{{.Delimiter}}{{.Quote}}744{{.Quote}}{{.Delimiter}}{{.Quote}}Mozilla/5.0{{.Quote}}\n", + "{{.Quote}}-{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}127.0.0.1{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}PUT{{.Quote}}{{.Delimiter}}{{.Quote}}/{{.Quote}}{{.Delimiter}}{{.Quote}}\nHTTP\n/2.0{{.Quote}}{{.Delimiter}}{{.Quote}}200{{.Quote}}{{.Delimiter}}{{.Quote}}320{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + "{{.Quote}}F{{.Quote}}{{.Delimiter}}{{.Quote}}file{{.FileNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}{{.LogNo}}{{.Quote}}{{.Delimiter}}{{.Quote}}192.168.0.3{{.Quote}}{{.Delimiter}}{{.Quote}}{{.Time}}{{.Quote}}{{.Delimiter}}{{.Quote}}PUT{{.Quote}}{{.Delimiter}}{{.Quote}}/dir/resource.txt{{.Quote}}{{.Delimiter}}{{.Quote}}\nHTTP\n/1.1{{.Quote}}{{.Delimiter}}{{.Quote}}404{{.Quote}}{{.Delimiter}}{{.Quote}}949{{.Quote}}{{.Delimiter}}{{.Quote}}curl/7.10{{.Quote}}\n", + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { t.Fatalf("open file failed: %v", err) return @@ -52,16 +104,23 @@ func TestGenerateDelimiterSingle(t *testing.T) { defer file.Close() logIndex := 0 - for i := 0; i < totalLog; i++ { - currentTime := time.Now().Format("2006-01-02 15:04:05.000000000") - _, err := io.WriteString(file, fmt.Sprintf(testLogConent[logIndex]+"\n", currentTime)) + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + for i := 0; i < config.TotalLog; i++ { + err = testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ + "FileNo": fileNo, + "LogNo": logNo, + "Time": time.Now().Format("2006-01-02 15:04:05.000000000"), + "Delimiter": delimiter, + "Quote": quote, + }) if err != nil { t.Fatalf("write log failed: %v", err) return } - time.Sleep(time.Duration(interval * int(time.Millisecond))) + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConent) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } diff --git a/test/engine/trigger/generator/ebpf_file_mmap_test.go b/test/engine/trigger/generator/ebpf_file_mmap_test.go index 618b9af1b4..56e221b54d 100644 --- a/test/engine/trigger/generator/ebpf_file_mmap_test.go +++ b/test/engine/trigger/generator/ebpf_file_mmap_test.go @@ -27,7 +27,7 @@ func TestGenerateMmapCommand(t *testing.T) { t.Fatalf("parse COMMAND_CNT failed: %v", err) return } - filename := getEnvOrDefault("FILE_NAME", "/tmp/ilogtail/ebpfFileSecurityHook3.log") + filename := getEnvOrDefault("FILE_NAME", "/tmp/loongcollector/ebpfFileSecurityHook3.log") f, err := os.Create(filename) if err != nil { panic(err) diff --git a/test/engine/trigger/generator/helper.go b/test/engine/trigger/generator/helper.go index ed80e86727..9e58df2753 100644 --- a/test/engine/trigger/generator/helper.go +++ b/test/engine/trigger/generator/helper.go @@ -14,9 +14,66 @@ package generator import ( + "fmt" + "math/rand" "os" + "strconv" + "text/template" + + "github.com/pkg/errors" ) +var Levels = []string{"ERROR", "INFO", "DEBUG", "WARNING"} + +type GenerateFileLogConfig struct { + GeneratedLogDir string + TotalLog int + Interval int + FileName string + Custom map[string]string +} + +func getGenerateFileLogConfigFromEnv(customKeys ...string) (*GenerateFileLogConfig, error) { + gneratedLogDir := getEnvOrDefault("GENERATED_LOG_DIR", "/tmp/loongcollector") + totalLog, err := strconv.Atoi(getEnvOrDefault("TOTAL_LOG", "100")) + if err != nil { + return nil, errors.Wrap(err, "parse TOTAL_LOG failed") + } + interval, err := strconv.Atoi(getEnvOrDefault("INTERVAL", "1")) + if err != nil { + return nil, errors.Wrap(err, "parse INTERVAL failed") + } + fileName := getEnvOrDefault("FILENAME", "default.log") + custom := make(map[string]string) + for _, key := range customKeys { + custom[key] = getEnvOrDefault(key, "") + } + return &GenerateFileLogConfig{ + GeneratedLogDir: gneratedLogDir, + TotalLog: totalLog, + Interval: interval, + FileName: fileName, + Custom: custom, + }, nil +} + +func string2Template(strings []string) []*template.Template { + templates := make([]*template.Template, len(strings)) + for i, str := range strings { + templates[i], _ = template.New(fmt.Sprintf("template_%d", i)).Parse(str) + } + return templates +} + +func getRandomLogLevel() string { + return Levels[rand.Intn(len(Levels))] +} + +func getRandomMark() string { + marks := []string{"-", "F"} + return marks[rand.Intn(2)] +} + func getEnvOrDefault(env, fallback string) string { if value, ok := os.LookupEnv(env); ok { return value diff --git a/test/engine/trigger/generator/json_test.go b/test/engine/trigger/generator/json_test.go new file mode 100644 index 0000000000..54b98ec3d6 --- /dev/null +++ b/test/engine/trigger/generator/json_test.go @@ -0,0 +1,119 @@ +// 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 generator + +import ( + "fmt" + "math/rand" + "os" + "strconv" + "testing" + "time" +) + +// TestGenerateJsonSingle will be executed in the environment being collected. +func TestGenerateJsonSingle(t *testing.T) { + config, err := getGenerateFileLogConfigFromEnv() + if err != nil { + t.Fatalf("get generate file log config from env failed: %v", err) + return + } + testLogConentTmpl := string2Template([]string{ + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"POST","userAgent":"mozilla firefox","size":263} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"GET","userAgent":"go-sdk","size":569} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"HEAD","userAgent":"go-sdk","size":210} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"192.168.0.3","method":"PUT","userAgent":"curl/7.10","size":267} +`, + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + t.Fatalf("open file failed: %v", err) + return + } + defer file.Close() + + logIndex := 0 + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + for i := 0; i < config.TotalLog; i++ { + var currentTime string + if i%2 == 0 { + currentTime = time.Now().Format("2006-01-02T15:04:05.999999999") + } else { + currentTime = strconv.FormatInt(time.Now().UnixNano()/1000, 10) + } + err = testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Mark": getRandomMark(), + "FileNo": fileNo, + "LogNo": logNo + i, + "Time": currentTime, + }) + + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) + logIndex++ + if logIndex >= len(testLogConentTmpl) { + logIndex = 0 + } + } +} + +func TestGenerateJsonMultiline(t *testing.T) { + config, err := getGenerateFileLogConfigFromEnv() + if err != nil { + t.Fatalf("get generate file log config from env failed: %v", err) + return + } + testLogConentTmpl := string2Template([]string{ + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"POST","userAgent":"mozilla firefox", +"size":263} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"GET","userAgent":"go-sdk", +"size":569} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"HEAD","userAgent":"go-sdk", +"size":210} +`, + `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"192.168.0.3","method":"PUT","userAgent":"curl/7.10", +"size":267} +`, + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + t.Fatalf("open file failed: %v", err) + return + } + defer file.Close() + + logIndex := 0 + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + for i := 0; i < config.TotalLog; i++ { + currentTime := time.Now().Format("2006-01-02T15:04:05.999999999") + err = testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Mark": getRandomMark(), + "FileNo": fileNo, + "LogNo": logNo + i, + "Time": currentTime, + }) + + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) + logIndex++ + if logIndex >= len(testLogConentTmpl) { + logIndex = 0 + } + } +} diff --git a/test/engine/trigger/generator/regex_test.go b/test/engine/trigger/generator/regex_test.go index b5950f3307..c50e65dc6e 100644 --- a/test/engine/trigger/generator/regex_test.go +++ b/test/engine/trigger/generator/regex_test.go @@ -17,8 +17,8 @@ import ( "bytes" "fmt" "io" + "math/rand" "os" - "strconv" "testing" "time" @@ -28,26 +28,22 @@ import ( // TestGenerateRegexLogSingle will be executed in the environment being collected. func TestGenerateRegexLogSingle(t *testing.T) { - gneratedLogDir := getEnvOrDefault("GENERATED_LOG_DIR", "/tmp/ilogtail") - totalLog, err := strconv.Atoi(getEnvOrDefault("TOTAL_LOG", "100")) + config, err := getGenerateFileLogConfigFromEnv() if err != nil { - t.Fatalf("parse TOTAL_LOG failed: %v", err) + t.Fatalf("get config failed: %v", err) return } - interval, err := strconv.Atoi(getEnvOrDefault("INTERVAL", "1")) - if err != nil { - t.Fatalf("parse INTERVAL failed: %v", err) - return - } - fileName := getEnvOrDefault("FILENAME", "regex_single.log") - - testLogConent := []string{ - `- file2:1 127.0.0.1 - [2024-01-07T12:40:10.505120] "HEAD / HTTP/2.0" 302 809 "未知" "这是一条消息,password:123456"`, - `- file2:2 127.0.0.1 - [2024-01-07T12:40:11.392101] "GET /index.html HTTP/2.0" 200 139 "Mozilla/5.0" "这是一条消息,password:123456,这是第二条消息,password:00000"`, - `- file2:3 10.45.26.0 - [2024-01-07T12:40:12.359314] "PUT /index.html HTTP/1.1" 200 913 "curl/7.10" "这是一条消息"`, - `- file2:4 192.168.0.3 - [2024-01-07T12:40:13.002661] "PUT /dir/resource.txt HTTP/2.0" 501 355 "go-sdk" "这是一条消息,password:123456"`, - } - file, err := os.OpenFile(fmt.Sprintf("%s/%s", gneratedLogDir, fileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + testLogContentTmpl := string2Template([]string{ + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 127.0.0.1 - [{{.Time}}] "HEAD / HTTP/2.0" 302 809 "未知" "这是一条消息,password:123456" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 127.0.0.1 - [{{.Time}}] "GET /index.html HTTP/2.0" 200 139 "Mozilla/5.0" "这是一条消息,password:123456,这是第二条消息,password:00000" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 10.45.26.0 - [{{.Time}}] "PUT /index.html HTTP/1.1" 200 913 "curl/7.10" "这是一条消息" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 192.168.0.3 - [{{.Time}}] "PUT /dir/resource.txt HTTP/2.0" 501 355 "go-sdk" "这是一条消息,password:123456" +`, + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { t.Fatalf("open file failed: %v", err) return @@ -55,15 +51,27 @@ func TestGenerateRegexLogSingle(t *testing.T) { defer file.Close() logIndex := 0 - for i := 0; i < totalLog; i++ { - _, err := io.WriteString(file, testLogConent[logIndex]+"\n") + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + location, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + t.Fatalf("load location failed: %v", err) + return + } + for i := 0; i < config.TotalLog; i++ { + err = testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Time": time.Now().In(location).Format("2006-01-02T15:04:05.000000"), + "Mark": getRandomMark(), + "FileNo": fileNo, + "LogNo": logNo + i, + }) if err != nil { t.Fatalf("write log failed: %v", err) return } - time.Sleep(time.Duration(interval * int(time.Millisecond))) + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConent) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } @@ -71,51 +79,119 @@ func TestGenerateRegexLogSingle(t *testing.T) { // TestGenerateRegexLogSingleGBK will be executed in the environment being collected. func TestGenerateRegexLogSingleGBK(t *testing.T) { - gneratedLogDir := getEnvOrDefault("GENERATED_LOG_DIR", "/tmp/ilogtail") - totalLog, err := strconv.Atoi(getEnvOrDefault("TOTAL_LOG", "100")) + config, err := getGenerateFileLogConfigFromEnv() if err != nil { - t.Fatalf("parse TOTAL_LOG failed: %v", err) + t.Fatalf("get config failed: %v", err) return } - interval, err := strconv.Atoi(getEnvOrDefault("INTERVAL", "1")) + encoder := simplifiedchinese.GBK.NewEncoder() + testLogContentTmpl := string2Template([]string{ + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 127.0.0.1 - [{{.Time}}] "HEAD / HTTP/2.0" 302 809 "未知" "这是一条消息,password:123456" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 127.0.0.1 - [{{.Time}}] "GET /index.html HTTP/2.0" 200 139 "Mozilla/5.0" "这是一条消息,password:123456,这是第二条消息,password:00000" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 10.45.26.0 - [{{.Time}}] "PUT /index.html HTTP/1.1" 200 913 "curl/7.10" "这是一条消息" +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} 192.168.0.3 - [{{.Time}}] "PUT /dir/resource.txt HTTP/2.0" 501 355 "go-sdk" "这是一条消息,password:123456" +`, + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { - t.Fatalf("parse INTERVAL failed: %v", err) + t.Fatalf("open file failed: %v", err) return } - fileName := getEnvOrDefault("FILENAME", "regex_single.log") + defer file.Close() - encoder := simplifiedchinese.GBK.NewEncoder() - testLogConentUTF8 := []string{ - `- file2:1 127.0.0.1 - [2024-01-07T12:40:10.505120] "HEAD / HTTP/2.0" 302 809 "未知" "这是一条消息,password:123456"`, - `- file2:2 127.0.0.1 - [2024-01-07T12:40:11.392101] "GET /index.html HTTP/2.0" 200 139 "Mozilla/5.0" "这是一条消息,password:123456,这是第二条消息,password:00000"`, - `- file2:3 10.45.26.0 - [2024-01-07T12:40:12.359314] "PUT /index.html HTTP/1.1" 200 913 "curl/7.10" "这是一条消息"`, - `- file2:4 192.168.0.3 - [2024-01-07T12:40:13.002661] "PUT /dir/resource.txt HTTP/2.0" 501 355 "go-sdk" "这是一条消息,password:123456"`, + logIndex := 0 + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + location, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + t.Fatalf("load location failed: %v", err) + return } - testLogConent := make([]string, 0, len(testLogConentUTF8)) - for _, log := range testLogConentUTF8 { - data, err1 := io.ReadAll(transform.NewReader(bytes.NewBuffer([]byte(log)), encoder)) + for i := 0; i < config.TotalLog; i++ { + var buffer bytes.Buffer + _ = testLogContentTmpl[logIndex].Execute(&buffer, map[string]interface{}{ + "Time": time.Now().In(location).Format("2006-01-02T15:04:05.000000"), + "Mark": getRandomMark(), + "FileNo": fileNo, + "LogNo": logNo + i, + }) + data, err1 := io.ReadAll(transform.NewReader(&buffer, encoder)) if err1 != nil { t.Fatalf("encode log failed: %v", err1) } - testLogConent = append(testLogConent, string(data)) + _, err := io.WriteString(file, string(data)) + if err != nil { + t.Fatalf("write log failed: %v", err) + return + } + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) + logIndex++ + if logIndex >= len(testLogContentTmpl) { + logIndex = 0 + } } - file, err := os.OpenFile(fmt.Sprintf("%s/%s", gneratedLogDir, fileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) +} + +func TestGenerateRegexLogMultiline(t *testing.T) { + config, err := getGenerateFileLogConfigFromEnv() + if err != nil { + t.Fatalf("get config failed: %v", err) + return + } + testLogContentTmpl := string2Template([]string{ + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} [{{.Time}}] [{{.Level}}] java.lang.Exception: exception happened +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f1(RegexMultiLog.java:73) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.run(RegexMultiLog.java:34) +at java.base/java.lang.Thread.run(Thread.java:833) +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} [{{.Time}}] [{{.Level}}] java.lang.Exception: 发生异常 +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f2(RegexMultiLog.java:80) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f1(RegexMultiLog.java:75) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.run(RegexMultiLog.java:34) +at java.base/java.lang.Thread.run(Thread.java:833) +`, + `{{.Mark}} file{{.FileNo}}:{{.LogNo}} [{{.Time}}] [{{.Level}}] java.lang.Exception: exception happened +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f5(RegexMultiLog.java:100) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f4(RegexMultiLog.java:96) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f3(RegexMultiLog.java:89) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f2(RegexMultiLog.java:82) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f1(RegexMultiLog.java:75) +at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.run(RegexMultiLog.java:34) +at java.base/java.lang.Thread.run(Thread.java:833) +`, + }) + file, err := os.OpenFile(fmt.Sprintf("%s/%s", config.GeneratedLogDir, config.FileName), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { t.Fatalf("open file failed: %v", err) return } defer file.Close() - logIndex := 0 - for i := 0; i < totalLog; i++ { - _, err := io.WriteString(file, testLogConent[logIndex]+"\n") + logNo := rand.Intn(10000) + fileNo := rand.Intn(10000) + location, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + t.Fatalf("load location failed: %v", err) + return + } + for i := 0; i < config.TotalLog; i++ { + err = testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ + "Time": time.Now().In(location).Format("2006-01-02T15:04:05.000000"), + "Level": getRandomLogLevel(), + "FileNo": fileNo, + "LogNo": logNo + i, + "Mark": getRandomMark(), + }) if err != nil { t.Fatalf("write log failed: %v", err) return } - time.Sleep(time.Duration(interval * int(time.Millisecond))) + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConent) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } diff --git a/test/engine/trigger/generator/stdout_test.go b/test/engine/trigger/generator/stdout_test.go new file mode 100644 index 0000000000..f62cfe021a --- /dev/null +++ b/test/engine/trigger/generator/stdout_test.go @@ -0,0 +1,61 @@ +// 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 generator + +import ( + "io" + "math/rand" + "os" + "testing" + "time" +) + +// TestGenerateStdout will be executed in the environment being collected. +func TestGenerateStdout(t *testing.T) { + config, err := getGenerateFileLogConfigFromEnv("TestMode") + if err != nil { + t.Fatalf("get config failed: %v", err) + return + } + testLogContentTmpl := string2Template([]string{ + `{{.LogNo}} [{{.Time}}] [INFO] "这是一条消息,password:123456"`, + `{{.LogNo}} [{{.Time}}] [WARN] "这是一条消息,password:123456,这是第二条消息,password:00000"`, + `{{.LogNo}} [{{.Time}}] [ERROR] "这是一条消息"`, + `{{.LogNo}} [{{.Time}}] [DEBUG] "这是一条消息,password:123456"`, + }) + + logIndex := 0 + logNo := rand.Intn(10000) + var wr io.Writer + if config.Custom["TestMode"] == "stdout" { + wr = os.Stdout + } else { + wr = os.Stderr + } + for i := 0; i < config.TotalLog; i++ { + err = testLogContentTmpl[logIndex].Execute(wr, map[string]interface{}{ + "Time": time.Now().Format("2006-01-02T15:04:05.000000"), + "LogNo": logNo + i, + }) + if err != nil { + t.Fatalf("write log failed: %v", err) + return + } + time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) + logIndex++ + if logIndex >= len(testLogContentTmpl) { + logIndex = 0 + } + } +} diff --git a/test/engine/trigger/trigger.go b/test/engine/trigger/trigger.go index 75b038e823..2de29b4618 100644 --- a/test/engine/trigger/trigger.go +++ b/test/engine/trigger/trigger.go @@ -15,15 +15,15 @@ package trigger import ( "context" - "html/template" "strings" + "text/template" "time" "github.com/alibaba/ilogtail/test/config" "github.com/alibaba/ilogtail/test/engine/setup" ) -const triggerRegexTemplate = "cd {{.WorkDir}} && TOTAL_LOG={{.TotalLog}} INTERVAL={{.Interval}} FILENAME={{.Filename}} GENERATED_LOG_DIR={{.GeneratedLogDir}} {{.Command}}" +const triggerTemplate = "cd {{.WorkDir}} && TOTAL_LOG={{.TotalLog}} INTERVAL={{.Interval}} FILENAME={{.Filename}} GENERATED_LOG_DIR={{.GeneratedLogDir}} {{.Custom}} {{.Command}}" func RegexSingle(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { return generate(ctx, totalLog, path, interval, "TestGenerateRegexLogSingle") @@ -33,37 +33,105 @@ func RegexSingleGBK(ctx context.Context, totalLog int, path string, interval int return generate(ctx, totalLog, path, interval, "TestGenerateRegexLogSingleGBK") } +func RegexMultiline(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateRegexLogMultiline") +} + +func JsonSingle(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateJsonSingle") +} + +func JsonMultiline(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateJsonMultiline") +} + func Apsara(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { return generate(ctx, totalLog, path, interval, "TestGenerateApsara") } -func DelimiterSingle(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { - return generate(ctx, totalLog, path, interval, "TestGenerateDelimiterSingle") +func DelimiterSingle(ctx context.Context, totalLog int, path string, interval int, delimiter, quote string) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateDelimiterSingle", "Delimiter", delimiter, "Quote", quote) +} + +func DelimiterMultiline(ctx context.Context, totalLog int, path string, interval int, delimiter, quote string) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateDelimiterMultiline", "Delimiter", delimiter, "Quote", quote) } -func generate(ctx context.Context, totalLog int, path string, interval int, commandName string) (context.Context, error) { +func Stdout(ctx context.Context, totalLog int, interval int) (context.Context, error) { + time.Sleep(3 * time.Second) + command := getRunTriggerCommand("TestGenerateStdout") + var triggerCommand strings.Builder + template := template.Must(template.New("trigger").Parse(triggerTemplate)) + if err := template.Execute(&triggerCommand, map[string]interface{}{ + "WorkDir": "", + "TotalLog": totalLog, + "Interval": interval, + "TestMode": "stdout", + "Filename": "", + "Custom": "", + "Command": command, + }); err != nil { + return ctx, err + } + if _, err := setup.Env.ExecOnSource(ctx, triggerCommand.String()); err != nil { + return ctx, err + } + return ctx, nil +} + +func Stderr(ctx context.Context, totalLog int, interval int) (context.Context, error) { + time.Sleep(3 * time.Second) + command := getRunTriggerCommand("TestGenerateStdout") + var triggerCommand strings.Builder + template := template.Must(template.New("trigger").Parse(triggerTemplate)) + if err := template.Execute(&triggerCommand, map[string]interface{}{ + "WorkDir": "", + "TotalLog": totalLog, + "Interval": interval, + "TestMode": "stderr", + "Filename": "", + "Custom": "", + "Command": command, + }); err != nil { + return ctx, err + } + if _, err := setup.Env.ExecOnSource(ctx, triggerCommand.String()); err != nil { + return ctx, err + } + return ctx, nil +} + +func generate(ctx context.Context, totalLog int, path string, interval int, commandName string, customKV ...string) (context.Context, error) { time.Sleep(3 * time.Second) command := getRunTriggerCommand(commandName) - var triggerRegexCommand strings.Builder - template := template.Must(template.New("trigger").Parse(triggerRegexTemplate)) + var triggerCommand strings.Builder + template := template.Must(template.New("trigger").Parse(triggerTemplate)) splittedPath := strings.Split(path, "/") dir := strings.Join(splittedPath[:len(splittedPath)-1], "/") filename := splittedPath[len(splittedPath)-1] - if err := template.Execute(&triggerRegexCommand, map[string]interface{}{ + customString := strings.Builder{} + for i := 0; i < len(customKV); i++ { + customString.WriteString(customKV[i]) + customString.WriteString("=") + customString.WriteString(customKV[i+1]) + customString.WriteString(" ") + i++ + } + if err := template.Execute(&triggerCommand, map[string]interface{}{ "WorkDir": config.TestConfig.WorkDir, "TotalLog": totalLog, "Interval": interval, "GeneratedLogDir": dir, "Filename": filename, + "Custom": customString.String(), "Command": command, }); err != nil { return ctx, err } - startTime := time.Now().Unix() - if err := setup.Env.ExecOnSource(ctx, triggerRegexCommand.String()); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, triggerCommand.String()); err != nil { return ctx, err } - return context.WithValue(ctx, config.StartTimeContextKey, int32(startTime)), nil + return ctx, nil } func BeginTrigger(ctx context.Context) (context.Context, error) { diff --git a/test/engine/verify/agent.go b/test/engine/verify/agent.go new file mode 100644 index 0000000000..f8aac3233d --- /dev/null +++ b/test/engine/verify/agent.go @@ -0,0 +1,45 @@ +// 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 verify + +import ( + "context" + "fmt" + + "github.com/alibaba/ilogtail/test/config" + "github.com/alibaba/ilogtail/test/engine/setup" +) + +const ( + queryPIDCommand = "ps -e | grep loongcollector | grep -v grep | awk '{print $1}'" +) + +func AgentNotCrash(ctx context.Context) (context.Context, error) { + // verify agent crash + result, err := setup.Env.ExecOnLogtail(queryPIDCommand) + if err != nil { + if err.Error() == "not implemented" { + return ctx, nil + } + return ctx, err + } + agentPID := ctx.Value(config.AgentPIDKey) + if agentPID == nil { + return ctx, fmt.Errorf("agent PID not found in context") + } + if result != agentPID { + return ctx, fmt.Errorf("agent crash, expect PID: %s, but got: %s", agentPID, result) + } + return ctx, nil +} diff --git a/test/engine/verify/apsara.go b/test/engine/verify/apsara.go deleted file mode 100644 index 220cebd3bb..0000000000 --- a/test/engine/verify/apsara.go +++ /dev/null @@ -1,94 +0,0 @@ -// 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 verify - -import ( - "context" - "fmt" - "strconv" - "time" - - "github.com/avast/retry-go/v4" - - "github.com/alibaba/ilogtail/pkg/protocol" - "github.com/alibaba/ilogtail/test/config" - "github.com/alibaba/ilogtail/test/engine/control" - "github.com/alibaba/ilogtail/test/engine/setup/subscriber" -) - -func Apsara(ctx context.Context) (context.Context, error) { - var from int32 - value := ctx.Value(config.StartTimeContextKey) - if value != nil { - from = value.(int32) - } else { - return ctx, fmt.Errorf("no start time") - } - fields := []string{"__FILE__", "__LEVEL__", "__LINE__", "__THREAD__", "file", "logNo", "mark", "microtime", "msg"} - timeoutCtx, cancel := context.WithTimeout(context.TODO(), config.TestConfig.RetryTimeout) - defer cancel() - var groups []*protocol.LogGroup - var err error - err = retry.Do( - func() error { - groups, err = subscriber.TestSubscriber.GetData(control.GetQuery(ctx), from) - if err != nil { - return err - } - for _, group := range groups { - for _, log := range group.Logs { - for _, field := range fields { - found := false - for _, content := range log.Contents { - if content.Key == field { - found = true - break - } - } - if !found { - return fmt.Errorf("field %s not found", field) - } - } - // validate time parse - var microtime int64 - var recordTime int64 - var nanoTime int64 - for _, content := range log.Contents { - if content.Key == "microtime" { - microtime, _ = strconv.ParseInt(content.Value, 10, 64) - } - if content.Key == "__time__" { - recordTime, _ = strconv.ParseInt(content.Value, 10, 64) - } - if content.Key == "__time_ns_part__" { - nanoTime, _ = strconv.ParseInt(content.Value, 10, 64) - } - } - if microtime != recordTime*1000000+nanoTime/1000 { - return fmt.Errorf("time parse error, microtime: %d, recordtime: %d, nanotime: %d", microtime, recordTime, nanoTime) - } - } - } - return err - }, - retry.Context(timeoutCtx), - retry.Delay(5*time.Second), - retry.DelayType(retry.FixedDelay), - ) - if err != nil { - return ctx, err - } - return ctx, nil -} diff --git a/test/engine/verify/count.go b/test/engine/verify/count.go index ea5052d350..71abf7b274 100644 --- a/test/engine/verify/count.go +++ b/test/engine/verify/count.go @@ -70,6 +70,50 @@ func LogCount(ctx context.Context, expect int) (context.Context, error) { return ctx, nil } +func LogCountLess(ctx context.Context, expect int) (context.Context, error) { + var from int32 + value := ctx.Value(config.StartTimeContextKey) + if value != nil { + from = value.(int32) + } else { + return ctx, fmt.Errorf("no start time") + } + timeoutCtx, cancel := context.WithTimeout(context.TODO(), config.TestConfig.RetryTimeout) + defer cancel() + var groups []*protocol.LogGroup + var err error + var count int + err = retry.Do( + func() error { + count = 0 + groups, err = subscriber.TestSubscriber.GetData(control.GetQuery(ctx), from) + if err != nil { + return err + } + for _, group := range groups { + count += len(group.Logs) + } + if count != expect { + return fmt.Errorf("log count not match, expect %d, got %d, from %d", expect, count, from) + } + if expect == 0 { + return fmt.Errorf("log count is 0") + } + return nil + }, + retry.Context(timeoutCtx), + retry.Delay(5*time.Second), + retry.DelayType(retry.FixedDelay), + ) + if count > 0 && count < expect { + return ctx, nil + } + if err != nil { + return ctx, err + } + return ctx, nil +} + func MetricCount(ctx context.Context, expect int, duration int64) (context.Context, error) { timeoutCtx, cancel := context.WithTimeout(context.TODO(), config.TestConfig.RetryTimeout) defer cancel() diff --git a/test/engine/verify/regex.go b/test/engine/verify/log_order.go similarity index 61% rename from test/engine/verify/regex.go rename to test/engine/verify/log_order.go index 45da3962de..a3553e4ede 100644 --- a/test/engine/verify/regex.go +++ b/test/engine/verify/log_order.go @@ -4,29 +4,30 @@ // 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 +// 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 verify import ( "context" "fmt" + "strconv" "time" - "github.com/avast/retry-go/v4" - "github.com/alibaba/ilogtail/pkg/protocol" "github.com/alibaba/ilogtail/test/config" "github.com/alibaba/ilogtail/test/engine/control" "github.com/alibaba/ilogtail/test/engine/setup/subscriber" + "github.com/avast/retry-go/v4" ) -func RegexSingle(ctx context.Context) (context.Context, error) { +func LogOrder(ctx context.Context) (context.Context, error) { var from int32 value := ctx.Value(config.StartTimeContextKey) if value != nil { @@ -34,33 +35,15 @@ func RegexSingle(ctx context.Context) (context.Context, error) { } else { return ctx, fmt.Errorf("no start time") } - fields := []string{"mark", "file", "logNo", "ip", "time", "method", "url", "http", "status", "size", "userAgent", "msg"} + + // Get logs timeoutCtx, cancel := context.WithTimeout(context.TODO(), config.TestConfig.RetryTimeout) defer cancel() - var groups []*protocol.LogGroup var err error + var groups []*protocol.LogGroup err = retry.Do( func() error { groups, err = subscriber.TestSubscriber.GetData(control.GetQuery(ctx), from) - if err != nil { - return err - } - for _, group := range groups { - for _, log := range group.Logs { - for _, field := range fields { - found := false - for _, content := range log.Contents { - if content.Key == field { - found = true - break - } - } - if !found { - return fmt.Errorf("field %s not found", field) - } - } - } - } return err }, retry.Context(timeoutCtx), @@ -70,5 +53,38 @@ func RegexSingle(ctx context.Context) (context.Context, error) { if err != nil { return ctx, err } + + // Check log order + currentLogNo := 0 + for i := 0; i < len(groups); i++ { + for j := 0; j < len(groups[i].Logs); j++ { + if j == 0 { + currentLogNo, _ = getLogNoFromLog(groups[i].Logs[j]) + continue + } + if groups[i].Logs[j].Time > groups[i].Logs[j-1].Time { + if nextLogNo, ok := getLogNoFromLog(groups[i].Logs[j]); ok { + if nextLogNo != currentLogNo+1 { + return ctx, fmt.Errorf("log order is not correct, current logNo: %d, next logNo: %d", currentLogNo, nextLogNo) + } + currentLogNo = nextLogNo + } + continue + } + } + } return ctx, nil } + +func getLogNoFromLog(log *protocol.Log) (int, bool) { + for _, content := range log.Contents { + if content.Key == "logNo" { + logNo, err := strconv.Atoi(content.Value) + if err != nil { + return 0, false + } + return logNo, true + } + } + return 0, false +} diff --git a/test/go.mod b/test/go.mod index 2aa11b458a..c6f5af3f05 100644 --- a/test/go.mod +++ b/test/go.mod @@ -10,18 +10,15 @@ 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.27+incompatible + github.com/docker/docker v20.10.23+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.16.0 - golang.org/x/text v0.14.0 - golang.org/x/time v0.3.0 - google.golang.org/grpc v1.58.3 + golang.org/x/crypto v0.10.0 + google.golang.org/grpc v1.53.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.24.0 k8s.io/apimachinery v0.24.0 @@ -58,7 +55,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.2+incompatible // indirect + github.com/docker/distribution v2.8.1+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 @@ -89,7 +86,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-20221205130635-1aeaba878587 // indirect + github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // 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 @@ -97,7 +94,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.12 // indirect + github.com/opencontainers/runc v1.1.3 // 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 @@ -111,19 +108,22 @@ 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/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 + 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 google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // 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.100.1 // indirect + k8s.io/klog/v2 v2.60.1 // indirect k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // 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,5 +132,4 @@ 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 a2de9f3bb7..e7d5a1abe2 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,13 +382,12 @@ 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.27+incompatible h1:Id/ZooynV4ZlD6xX20RCd3SR0Ikn7r4QZDa2ECK2TgA= -github.com/docker/docker v20.10.27+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-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= @@ -550,8 +549,6 @@ 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= @@ -771,9 +768,8 @@ 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= @@ -824,8 +820,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= @@ -847,9 +843,8 @@ 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= @@ -1121,9 +1116,8 @@ 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= @@ -1133,6 +1127,7 @@ 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= @@ -1226,9 +1221,8 @@ 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= @@ -1243,8 +1237,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.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +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/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= @@ -1369,9 +1363,8 @@ 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= @@ -1380,9 +1373,8 @@ 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= @@ -1394,9 +1386,8 @@ 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= @@ -1562,8 +1553,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/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/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/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= @@ -1593,8 +1584,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.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +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/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= @@ -1708,9 +1699,8 @@ 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= @@ -1722,9 +1712,8 @@ 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= From cd39d49e7ac9373cc237b0141e573c5ca20fd820 Mon Sep 17 00:00:00 2001 From: abingcbc Date: Mon, 28 Oct 2024 15:00:36 +0800 Subject: [PATCH 2/8] fix --- test/engine/setup/subscriber/clickhouse.go | 2 +- test/go.mod | 35 +++++++------- test/go.sum | 53 +++++++++++++--------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/test/engine/setup/subscriber/clickhouse.go b/test/engine/setup/subscriber/clickhouse.go index f6afd0a8ba..1d7b1b43e5 100644 --- a/test/engine/setup/subscriber/clickhouse.go +++ b/test/engine/setup/subscriber/clickhouse.go @@ -33,7 +33,7 @@ import ( ) const clickHouseName = "clickhouse" -const clickhouseQuerySQL = "select _timestamp,_log from `%s`.`loongcollector_%s_buffer` where _timestamp > %v order by _timestamp" +const clickhouseQuerySQL = "select _timestamp,_log from `%s`.`ilogtail_%s_buffer` where _timestamp > %v order by _timestamp" type ClickHouseSubscriber struct { Address string `mapstructure:"address" comment:"the clickhouse address"` diff --git a/test/go.mod b/test/go.mod index c6f5af3f05..7619611a58 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 +) \ No newline at end of file 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= From 35e7fb237a0ebf42ec3c76ad68f3560cd07d0dca Mon Sep 17 00:00:00 2001 From: abingcbc Date: Tue, 29 Oct 2024 15:33:53 +0800 Subject: [PATCH 3/8] fix --- test/engine/setup/controller/kubernetes.go | 21 ++++--- test/engine/setup/k8s.go | 15 +++-- test/engine/steps.go | 6 +- test/engine/trigger/generator/helper.go | 9 ++- test/engine/trigger/generator/json_test.go | 10 ++-- test/engine/trigger/generator/stdout_test.go | 61 -------------------- test/engine/trigger/trigger.go | 52 ++--------------- 7 files changed, 42 insertions(+), 132 deletions(-) delete mode 100644 test/engine/trigger/generator/stdout_test.go diff --git a/test/engine/setup/controller/kubernetes.go b/test/engine/setup/controller/kubernetes.go index 99765c85a4..2cb7ec4d53 100644 --- a/test/engine/setup/controller/kubernetes.go +++ b/test/engine/setup/controller/kubernetes.go @@ -17,6 +17,7 @@ import ( "context" "fmt" "os" + "path/filepath" "time" "github.com/avast/retry-go/v4" @@ -25,9 +26,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/restmapper" "github.com/alibaba/ilogtail/test/config" ) @@ -50,7 +52,8 @@ type DaemonSetController struct { } type DynamicController struct { - dynamicClient dynamic.Interface + discoveryClient discovery.DiscoveryInterface + dynamicClient dynamic.Interface } func NewDeploymentController(k8sClient *kubernetes.Clientset) *DeploymentController { @@ -215,8 +218,8 @@ func (c *DaemonSetController) GetDaemonSetPods(dsName, dsNamespace string) (*cor return pods, nil } -func NewDynamicController(dynamicClient dynamic.Interface) *DynamicController { - return &DynamicController{dynamicClient: dynamicClient} +func NewDynamicController(dynamicClient dynamic.Interface, discoveryClient discovery.DiscoveryInterface) *DynamicController { + return &DynamicController{dynamicClient: dynamicClient, discoveryClient: discoveryClient} } func (c *DynamicController) Apply(filePath string) error { @@ -267,7 +270,8 @@ func (c *DynamicController) Delete(filePath string) error { func (c *DynamicController) parseObjFromYaml(filePath string) (*meta.RESTMapping, *unstructured.Unstructured, error) { // Read the YAML file - yamlFile, err := os.ReadFile(filePath) + basePath := "test_cases" + yamlFile, err := os.ReadFile(filepath.Join(basePath, filePath)) if err != nil { return nil, nil, err } @@ -280,8 +284,11 @@ func (c *DynamicController) parseObjFromYaml(filePath string) (*meta.RESTMapping return nil, nil, err } - // Retrieve the REST mapping for the GVK - restMapper := meta.NewDefaultRESTMapper(scheme.Scheme.PreferredVersionAllGroups()) + apiGroupResources, err := restmapper.GetAPIGroupResources(c.discoveryClient) + if err != nil { + return nil, nil, err + } + restMapper := restmapper.NewDiscoveryRESTMapper(apiGroupResources) mapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { return nil, nil, err diff --git a/test/engine/setup/k8s.go b/test/engine/setup/k8s.go index 85eaef8e6d..826b1e3644 100644 --- a/test/engine/setup/k8s.go +++ b/test/engine/setup/k8s.go @@ -19,6 +19,7 @@ import ( "crypto/rand" "fmt" "math/big" + "sort" "strings" corev1 "k8s.io/api/core/v1" @@ -80,12 +81,15 @@ func (k *K8sEnv) ExecOnLogtail(command string) (string, error) { } } results := make([]string, 0) + sort.Slice(pods.Items, func(i, j int) bool { + return pods.Items[i].Name < pods.Items[j].Name + }) for _, pod := range pods.Items { - if result, err := k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"bash", "-c", command}); err != nil { + result, err := k.execInPod(k.config, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, []string{"bash", "-c", command}) + if err != nil { return "", err - } else { - results = append(results, result) } + results = append(results, result) } return strings.Join(results, "\n"), nil } @@ -152,7 +156,10 @@ func (k *K8sEnv) init() { k.daemonsetController = controller.NewDaemonSetController(k.k8sClient) dynamicClient, err := dynamic.NewForConfig(c) - k.dynamicController = controller.NewDynamicController(dynamicClient) + if err != nil { + panic(err) + } + k.dynamicController = controller.NewDynamicController(dynamicClient, k.k8sClient.Discovery()) } func (k *K8sEnv) execInPod(config *rest.Config, namespace, podName, containerName string, command []string) (string, error) { diff --git a/test/engine/steps.go b/test/engine/steps.go index 43df1f980a..16fd0c622a 100644 --- a/test/engine/steps.go +++ b/test/engine/steps.go @@ -48,10 +48,8 @@ func ScenarioInitializer(ctx *godog.ScenarioContext) { ctx.When(`^generate \{(\d+)\} apsara logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.Apsara) ctx.When(`^generate \{(\d+)\} delimiter logs to file \{(.*)\}, with interval \{(\d+)\}ms, with delimiter \{(.*)\} and quote \{(.*)\}$`, trigger.DelimiterSingle) ctx.When(`^generate \{(\d+)\} multiline delimiter logs to file \{(.*)\}, with interval \{(\d+)\}ms, with delimiter \{(.*)\} and quote \{(.*)\}$`, trigger.DelimiterMultiline) - ctx.When(`^generate \{(\d+)\} json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JsonSingle) - ctx.When(`^generate \{(\d+)\} multiline json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JsonMultiline) - ctx.When(`^generate \{(\d+)\} logs to stdout, with interval \{(\d+)\}ms$`, trigger.Stdout) - ctx.When(`^generate \{(\d+)\} logs to stderr, with interval \{(\d+)\}ms$`, trigger.Stderr) + ctx.When(`^generate \{(\d+)\} json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JSONSingle) + ctx.When(`^generate \{(\d+)\} multiline json logs to file \{(.*)\}, with interval \{(\d+)\}ms$`, trigger.JSONMultiline) ctx.When(`^execute \{(\d+)\} commands to generate file security events on files \{(.*)\}$`, trigger.TrigerFileSecurityEvents) // ------------------------------------------ diff --git a/test/engine/trigger/generator/helper.go b/test/engine/trigger/generator/helper.go index 9e58df2753..2514bb2614 100644 --- a/test/engine/trigger/generator/helper.go +++ b/test/engine/trigger/generator/helper.go @@ -14,8 +14,9 @@ package generator import ( + "crypto/rand" "fmt" - "math/rand" + "math/big" "os" "strconv" "text/template" @@ -66,12 +67,14 @@ func string2Template(strings []string) []*template.Template { } func getRandomLogLevel() string { - return Levels[rand.Intn(len(Levels))] + randInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(Levels)))) + return Levels[randInt.Int64()] } func getRandomMark() string { marks := []string{"-", "F"} - return marks[rand.Intn(2)] + randInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(marks)))) + return marks[randInt.Int64()] } func getEnvOrDefault(env, fallback string) string { diff --git a/test/engine/trigger/generator/json_test.go b/test/engine/trigger/generator/json_test.go index 54b98ec3d6..7f17f0d438 100644 --- a/test/engine/trigger/generator/json_test.go +++ b/test/engine/trigger/generator/json_test.go @@ -22,8 +22,8 @@ import ( "time" ) -// TestGenerateJsonSingle will be executed in the environment being collected. -func TestGenerateJsonSingle(t *testing.T) { +// TestGenerateJSONSingle will be executed in the environment being collected. +func TestGenerateJSONSingle(t *testing.T) { config, err := getGenerateFileLogConfigFromEnv() if err != nil { t.Fatalf("get generate file log config from env failed: %v", err) @@ -56,7 +56,7 @@ func TestGenerateJsonSingle(t *testing.T) { } else { currentTime = strconv.FormatInt(time.Now().UnixNano()/1000, 10) } - err = testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ "Mark": getRandomMark(), "FileNo": fileNo, "LogNo": logNo + i, @@ -71,7 +71,7 @@ func TestGenerateJsonSingle(t *testing.T) { } } -func TestGenerateJsonMultiline(t *testing.T) { +func TestGenerateJSONMultiline(t *testing.T) { config, err := getGenerateFileLogConfigFromEnv() if err != nil { t.Fatalf("get generate file log config from env failed: %v", err) @@ -103,7 +103,7 @@ func TestGenerateJsonMultiline(t *testing.T) { fileNo := rand.Intn(10000) for i := 0; i < config.TotalLog; i++ { currentTime := time.Now().Format("2006-01-02T15:04:05.999999999") - err = testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ "Mark": getRandomMark(), "FileNo": fileNo, "LogNo": logNo + i, diff --git a/test/engine/trigger/generator/stdout_test.go b/test/engine/trigger/generator/stdout_test.go deleted file mode 100644 index f62cfe021a..0000000000 --- a/test/engine/trigger/generator/stdout_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// 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 generator - -import ( - "io" - "math/rand" - "os" - "testing" - "time" -) - -// TestGenerateStdout will be executed in the environment being collected. -func TestGenerateStdout(t *testing.T) { - config, err := getGenerateFileLogConfigFromEnv("TestMode") - if err != nil { - t.Fatalf("get config failed: %v", err) - return - } - testLogContentTmpl := string2Template([]string{ - `{{.LogNo}} [{{.Time}}] [INFO] "这是一条消息,password:123456"`, - `{{.LogNo}} [{{.Time}}] [WARN] "这是一条消息,password:123456,这是第二条消息,password:00000"`, - `{{.LogNo}} [{{.Time}}] [ERROR] "这是一条消息"`, - `{{.LogNo}} [{{.Time}}] [DEBUG] "这是一条消息,password:123456"`, - }) - - logIndex := 0 - logNo := rand.Intn(10000) - var wr io.Writer - if config.Custom["TestMode"] == "stdout" { - wr = os.Stdout - } else { - wr = os.Stderr - } - for i := 0; i < config.TotalLog; i++ { - err = testLogContentTmpl[logIndex].Execute(wr, map[string]interface{}{ - "Time": time.Now().Format("2006-01-02T15:04:05.000000"), - "LogNo": logNo + i, - }) - if err != nil { - t.Fatalf("write log failed: %v", err) - return - } - time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) - logIndex++ - if logIndex >= len(testLogContentTmpl) { - logIndex = 0 - } - } -} diff --git a/test/engine/trigger/trigger.go b/test/engine/trigger/trigger.go index 2de29b4618..63653c5cb6 100644 --- a/test/engine/trigger/trigger.go +++ b/test/engine/trigger/trigger.go @@ -37,12 +37,12 @@ func RegexMultiline(ctx context.Context, totalLog int, path string, interval int return generate(ctx, totalLog, path, interval, "TestGenerateRegexLogMultiline") } -func JsonSingle(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { - return generate(ctx, totalLog, path, interval, "TestGenerateJsonSingle") +func JSONSingle(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateJSONSingle") } -func JsonMultiline(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { - return generate(ctx, totalLog, path, interval, "TestGenerateJsonMultiline") +func JSONMultiline(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { + return generate(ctx, totalLog, path, interval, "TestGenerateJSONMultiline") } func Apsara(ctx context.Context, totalLog int, path string, interval int) (context.Context, error) { @@ -57,50 +57,6 @@ func DelimiterMultiline(ctx context.Context, totalLog int, path string, interval return generate(ctx, totalLog, path, interval, "TestGenerateDelimiterMultiline", "Delimiter", delimiter, "Quote", quote) } -func Stdout(ctx context.Context, totalLog int, interval int) (context.Context, error) { - time.Sleep(3 * time.Second) - command := getRunTriggerCommand("TestGenerateStdout") - var triggerCommand strings.Builder - template := template.Must(template.New("trigger").Parse(triggerTemplate)) - if err := template.Execute(&triggerCommand, map[string]interface{}{ - "WorkDir": "", - "TotalLog": totalLog, - "Interval": interval, - "TestMode": "stdout", - "Filename": "", - "Custom": "", - "Command": command, - }); err != nil { - return ctx, err - } - if _, err := setup.Env.ExecOnSource(ctx, triggerCommand.String()); err != nil { - return ctx, err - } - return ctx, nil -} - -func Stderr(ctx context.Context, totalLog int, interval int) (context.Context, error) { - time.Sleep(3 * time.Second) - command := getRunTriggerCommand("TestGenerateStdout") - var triggerCommand strings.Builder - template := template.Must(template.New("trigger").Parse(triggerTemplate)) - if err := template.Execute(&triggerCommand, map[string]interface{}{ - "WorkDir": "", - "TotalLog": totalLog, - "Interval": interval, - "TestMode": "stderr", - "Filename": "", - "Custom": "", - "Command": command, - }); err != nil { - return ctx, err - } - if _, err := setup.Env.ExecOnSource(ctx, triggerCommand.String()); err != nil { - return ctx, err - } - return ctx, nil -} - func generate(ctx context.Context, totalLog int, path string, interval int, commandName string, customKV ...string) (context.Context, error) { time.Sleep(3 * time.Second) command := getRunTriggerCommand(commandName) From 64fa41b3ee09429c2bb8903e049673823b4b08a1 Mon Sep 17 00:00:00 2001 From: abingcbc Date: Tue, 29 Oct 2024 15:58:50 +0800 Subject: [PATCH 4/8] fix --- test/engine/setup/controller/kubernetes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/engine/setup/controller/kubernetes.go b/test/engine/setup/controller/kubernetes.go index 2cb7ec4d53..39efb316a3 100644 --- a/test/engine/setup/controller/kubernetes.go +++ b/test/engine/setup/controller/kubernetes.go @@ -271,7 +271,7 @@ func (c *DynamicController) Delete(filePath string) error { func (c *DynamicController) parseObjFromYaml(filePath string) (*meta.RESTMapping, *unstructured.Unstructured, error) { // Read the YAML file basePath := "test_cases" - yamlFile, err := os.ReadFile(filepath.Join(basePath, filePath)) + yamlFile, err := os.ReadFile(filepath.Join(basePath, filePath)) // #nosec G304 if err != nil { return nil, nil, err } From 637504bb3d8ca933f843f27c6989c66779daf2ce Mon Sep 17 00:00:00 2001 From: abingcbc Date: Tue, 29 Oct 2024 16:09:37 +0800 Subject: [PATCH 5/8] fix --- test/engine/control/{filter.go => k8s.go} | 0 test/engine/verify/log_order.go | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename test/engine/control/{filter.go => k8s.go} (100%) diff --git a/test/engine/control/filter.go b/test/engine/control/k8s.go similarity index 100% rename from test/engine/control/filter.go rename to test/engine/control/k8s.go diff --git a/test/engine/verify/log_order.go b/test/engine/verify/log_order.go index a3553e4ede..cd2a836681 100644 --- a/test/engine/verify/log_order.go +++ b/test/engine/verify/log_order.go @@ -20,11 +20,12 @@ import ( "strconv" "time" + "github.com/avast/retry-go/v4" + "github.com/alibaba/ilogtail/pkg/protocol" "github.com/alibaba/ilogtail/test/config" "github.com/alibaba/ilogtail/test/engine/control" "github.com/alibaba/ilogtail/test/engine/setup/subscriber" - "github.com/avast/retry-go/v4" ) func LogOrder(ctx context.Context) (context.Context, error) { From 8b642b554a436b97c1ca02e9b565dc800c289123 Mon Sep 17 00:00:00 2001 From: abingcbc Date: Tue, 29 Oct 2024 17:52:33 +0800 Subject: [PATCH 6/8] fix --- test/engine/control/{k8s.go => kubernetes.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/engine/control/{k8s.go => kubernetes.go} (100%) diff --git a/test/engine/control/k8s.go b/test/engine/control/kubernetes.go similarity index 100% rename from test/engine/control/k8s.go rename to test/engine/control/kubernetes.go From 179b58c3ac38a9dbccca75ec6915e8f88a0bcaa6 Mon Sep 17 00:00:00 2001 From: Abingcbc Date: Wed, 30 Oct 2024 13:59:59 +0800 Subject: [PATCH 7/8] typo --- test/engine/trigger/generator/json_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/engine/trigger/generator/json_test.go b/test/engine/trigger/generator/json_test.go index 7f17f0d438..0b4ef51b33 100644 --- a/test/engine/trigger/generator/json_test.go +++ b/test/engine/trigger/generator/json_test.go @@ -29,7 +29,7 @@ func TestGenerateJSONSingle(t *testing.T) { t.Fatalf("get generate file log config from env failed: %v", err) return } - testLogConentTmpl := string2Template([]string{ + testLogContentTmpl := string2Template([]string{ `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"POST","userAgent":"mozilla firefox","size":263} `, `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"GET","userAgent":"go-sdk","size":569} @@ -56,7 +56,7 @@ func TestGenerateJSONSingle(t *testing.T) { } else { currentTime = strconv.FormatInt(time.Now().UnixNano()/1000, 10) } - testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ "Mark": getRandomMark(), "FileNo": fileNo, "LogNo": logNo + i, @@ -65,7 +65,7 @@ func TestGenerateJSONSingle(t *testing.T) { time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConentTmpl) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } @@ -77,7 +77,7 @@ func TestGenerateJSONMultiline(t *testing.T) { t.Fatalf("get generate file log config from env failed: %v", err) return } - testLogConentTmpl := string2Template([]string{ + testLogContentTmpl := string2Template([]string{ `{"mark":"{{.Mark}}","file":"file{{.FileNo}}","logNo":{{.LogNo}},"time":"{{.Time}}","ip":"0.0.0.0","method":"POST","userAgent":"mozilla firefox", "size":263} `, @@ -103,7 +103,7 @@ func TestGenerateJSONMultiline(t *testing.T) { fileNo := rand.Intn(10000) for i := 0; i < config.TotalLog; i++ { currentTime := time.Now().Format("2006-01-02T15:04:05.999999999") - testLogConentTmpl[logIndex].Execute(file, map[string]interface{}{ + testLogContentTmpl[logIndex].Execute(file, map[string]interface{}{ "Mark": getRandomMark(), "FileNo": fileNo, "LogNo": logNo + i, @@ -112,7 +112,7 @@ func TestGenerateJSONMultiline(t *testing.T) { time.Sleep(time.Duration(config.Interval * int(time.Millisecond))) logIndex++ - if logIndex >= len(testLogConentTmpl) { + if logIndex >= len(testLogContentTmpl) { logIndex = 0 } } From be0e2f1a2e0709399cf0494df217d47c304e007f Mon Sep 17 00:00:00 2001 From: abingcbc Date: Thu, 31 Oct 2024 15:21:10 +0800 Subject: [PATCH 8/8] fix --- test/engine/trigger/ebpf_trigger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/engine/trigger/ebpf_trigger.go b/test/engine/trigger/ebpf_trigger.go index 0e0319f227..4b824c557e 100644 --- a/test/engine/trigger/ebpf_trigger.go +++ b/test/engine/trigger/ebpf_trigger.go @@ -39,7 +39,7 @@ func TrigerProcessSecurityEvents(ctx context.Context, commandCnt int) (context.C func execveCommands(ctx context.Context, commandCnt int) error { execveCommand := "ps -ef | grep loongcollector-e2e-test" for i := 0; i < commandCnt; i++ { - if err := setup.Env.ExecOnSource(ctx, execveCommand); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, execveCommand); err != nil { return err } } @@ -62,7 +62,7 @@ func TrigerNetworksSecurityEvents(ctx context.Context, commandCnt int, url strin func curlURL(ctx context.Context, commandCnt int, url string) error { curlCommand := "curl --connect-timeout 1 " + url + ";" for i := 0; i < commandCnt; i++ { - if err := setup.Env.ExecOnSource(ctx, curlCommand); err != nil { + if _, err := setup.Env.ExecOnSource(ctx, curlCommand); err != nil { return err } }