This is an automated email from the ASF dual-hosted git repository. kezhenxu94 pushed a commit to branch bugfix/kind/ready in repository https://gitbox.apache.org/repos/asf/skywalking-infra-e2e.git
commit 31aa9e974d61846612fa47f9896d456d53279d75 Author: kezhenxu94 <kezhenx...@apache.org> AuthorDate: Mon Oct 25 17:16:46 2021 +0800 Migrate timeout config to Duration style and wait for node ready in KinD setup --- README.md | 4 +-- commands/verify/verify.go | 1 + docs/en/setup/Configuration-File.md | 4 +-- examples/compose/e2e.yaml | 2 +- examples/kind/e2e.yaml | 2 +- examples/reusing_cases/e2e.yaml | 4 +-- internal/components/setup/common.go | 9 +----- internal/components/setup/compose.go | 19 ++--------- internal/components/setup/kind.go | 19 +++++++---- internal/config/e2eConfig.go | 63 ++++++++++++++++++++++++++++++++---- internal/config/globalConfig.go | 4 +++ 11 files changed, 85 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 302e29d..353c74f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ SkyWalking Infra E2E is the next generation End-to-End Testing framework that ai To use skywalking-infra-e2e in GitHub Actions, add a step in your GitHub workflow. -```xml +```yaml - name: Run E2E Test uses: apache/skywalking-infra-e2e@main # always prefer to use a revision instead of `main`. with: @@ -30,4 +30,4 @@ To use skywalking-infra-e2e in GitHub Actions, add a step in your GitHub workflo * Submit [an issue](https://github.com/apache/skywalking/issues/new) by using [INFRA] as title prefix. * Mail list: **d...@skywalking.apache.org**. Mail to dev-subscr...@skywalking.apache.org, follow the reply to subscribe the mail list. * Join `skywalking` channel at [Apache Slack](http://s.apache.org/slack-invite). If the link is not working, find the latest one at [Apache INFRA WIKI](https://cwiki.apache.org/confluence/display/INFRA/Slack+Guest+Invites). -* Twitter, [ASFSkyWalking](https://twitter.com/ASFSkyWalking) \ No newline at end of file +* Twitter, [ASFSkyWalking](https://twitter.com/ASFSkyWalking) diff --git a/commands/verify/verify.go b/commands/verify/verify.go index 996bb73..740c4c3 100644 --- a/commands/verify/verify.go +++ b/commands/verify/verify.go @@ -120,6 +120,7 @@ func DoVerifyAccordingConfig() error { return nil } +// TODO remove this in 2.0.0 func parseInterval(retryInterval interface{}) (time.Duration, error) { var interval time.Duration var err error diff --git a/docs/en/setup/Configuration-File.md b/docs/en/setup/Configuration-File.md index f890599..92c191f 100644 --- a/docs/en/setup/Configuration-File.md +++ b/docs/en/setup/Configuration-File.md @@ -25,7 +25,7 @@ Support two kinds of the environment to set up the system. setup: env: kind file: path/to/kind.yaml # Specified kinD manifest file path - timeout: 1200 # timeout second + timeout: 20m # timeout second init-system-environment: path/to/env # Import environment file steps: # customize steps for prepare the environment - name: customize setups # step name @@ -91,7 +91,7 @@ If you want to access the resource from host, should follow these steps: setup: env: compose file: path/to/compose.yaml # Specified docker-compose file path - timeout: 1200 # Timeout second + timeout: 20m # Timeout duration init-system-environment: path/to/env # Import environment file steps: # Customize steps for prepare the environment - name: customize setups # Step name diff --git a/examples/compose/e2e.yaml b/examples/compose/e2e.yaml index fd6348e..397a7a6 100644 --- a/examples/compose/e2e.yaml +++ b/examples/compose/e2e.yaml @@ -18,7 +18,7 @@ setup: env: compose file: docker-compose.yml - timeout: 1200 + timeout: 20m init-system-environment: env steps: - name: install yq diff --git a/examples/kind/e2e.yaml b/examples/kind/e2e.yaml index 581fb72..e92d19b 100644 --- a/examples/kind/e2e.yaml +++ b/examples/kind/e2e.yaml @@ -47,7 +47,7 @@ setup: - namespace: default resource: deployment/nginx1 port: 80 - timeout: 1200 + timeout: 20m cleanup: # always never success failure diff --git a/examples/reusing_cases/e2e.yaml b/examples/reusing_cases/e2e.yaml index 2b3a0c1..77ea9d0 100644 --- a/examples/reusing_cases/e2e.yaml +++ b/examples/reusing_cases/e2e.yaml @@ -18,7 +18,7 @@ setup: env: compose file: docker-compose.yml - timeout: 1200 + timeout: 20m cleanup: # always never success failure @@ -42,4 +42,4 @@ verify: - includes: - simple-cases.yaml - query: swctl --display yaml --base-url=http://127.0.0.1:${oap_12800}/graphql service ls - expected: ../../test/verify/3.expected.yaml \ No newline at end of file + expected: ../../test/verify/3.expected.yaml diff --git a/internal/components/setup/common.go b/internal/components/setup/common.go index e220fa8..9fc2603 100644 --- a/internal/components/setup/common.go +++ b/internal/components/setup/common.go @@ -29,18 +29,11 @@ import ( "k8s.io/client-go/kubernetes" "github.com/apache/skywalking-infra-e2e/internal/config" - "github.com/apache/skywalking-infra-e2e/internal/constant" "github.com/apache/skywalking-infra-e2e/internal/logger" "github.com/apache/skywalking-infra-e2e/internal/util" ) -func RunStepsAndWait(steps []config.Step, timeout int, k8sCluster *util.K8sClusterInfo) error { - var waitTimeout time.Duration - if timeout <= 0 { - waitTimeout = constant.DefaultWaitTimeout - } else { - waitTimeout = time.Duration(timeout) * time.Second - } +func RunStepsAndWait(steps []config.Step, waitTimeout time.Duration, k8sCluster *util.K8sClusterInfo) error { logger.Log.Debugf("wait timeout is %d seconds", int(waitTimeout.Seconds())) // record time now diff --git a/internal/components/setup/compose.go b/internal/components/setup/compose.go index 14b47bb..0543187 100644 --- a/internal/components/setup/compose.go +++ b/internal/components/setup/compose.go @@ -25,13 +25,11 @@ import ( "regexp" "strconv" "strings" - "time" "github.com/docker/go-connections/nat" "github.com/testcontainers/testcontainers-go/wait" "github.com/apache/skywalking-infra-e2e/internal/config" - "github.com/apache/skywalking-infra-e2e/internal/constant" "github.com/apache/skywalking-infra-e2e/internal/logger" "github.com/apache/skywalking-infra-e2e/internal/util" @@ -90,7 +88,7 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error { } // run steps - err = RunStepsAndWait(e2eConfig.Setup.Steps, e2eConfig.Setup.Timeout, nil) + err = RunStepsAndWait(e2eConfig.Setup.Steps, e2eConfig.Setup.GetTimeout(), nil) if err != nil { logger.Log.Errorf("execute steps error: %v", err) return err @@ -159,13 +157,7 @@ func exportComposeEnv(key, value, service string) error { } func bindWaitPort(e2eConfig *config.E2EConfig, compose *testcontainers.LocalDockerCompose) (map[string][]*hostPortCachedStrategy, error) { - timeout := e2eConfig.Setup.Timeout - var waitTimeout time.Duration - if timeout <= 0 { - waitTimeout = constant.DefaultWaitTimeout - } else { - waitTimeout = time.Duration(timeout) * time.Second - } + waitTimeout := e2eConfig.Setup.GetTimeout() serviceWithPorts := make(map[string][]*hostPortCachedStrategy) for service, content := range compose.Services { serviceConfig := content.(map[interface{}]interface{}) @@ -248,12 +240,7 @@ func (hp *hostPortCachedStrategy) WaitUntilReady(ctx context.Context, target wai func waitPortUntilReady(e2eConfig *config.E2EConfig, container *types.Container, dockerProvider *DockerProvider, expectPort int) error { // wait port - var waitTimeout time.Duration - if e2eConfig.Setup.Timeout <= 0 { - waitTimeout = constant.DefaultWaitTimeout - } else { - waitTimeout = time.Duration(e2eConfig.Setup.Timeout) * time.Second - } + waitTimeout := e2eConfig.Setup.GetTimeout() waitPort := nat.Port(fmt.Sprintf("%d/tcp", expectPort)) target := &DockerContainer{ ID: container.ID, diff --git a/internal/components/setup/kind.go b/internal/components/setup/kind.go index eebce1e..7ed8526 100644 --- a/internal/components/setup/kind.go +++ b/internal/components/setup/kind.go @@ -94,7 +94,7 @@ func KindSetup(e2eConfig *config.E2EConfig) error { util.ExportEnvVars(profilePath) } - if err := createKindCluster(kindConfigPath); err != nil { + if err := createKindCluster(kindConfigPath, e2eConfig); err != nil { return err } @@ -118,14 +118,14 @@ func KindSetup(e2eConfig *config.E2EConfig) error { } // run steps - err = RunStepsAndWait(e2eConfig.Setup.Steps, e2eConfig.Setup.Timeout, cluster) + err = RunStepsAndWait(e2eConfig.Setup.Steps, e2eConfig.Setup.GetTimeout(), cluster) if err != nil { logger.Log.Errorf("execute steps error: %v", err) return err } // expose ports - err = exposeKindService(e2eConfig.Setup.Kind.ExposePorts, e2eConfig.Setup.Timeout, kubeConfigPath) + err = exposeKindService(e2eConfig.Setup.Kind.ExposePorts, e2eConfig.Setup.GetTimeout(), kubeConfigPath) if err != nil { logger.Log.Errorf("export ports error: %v", err) return err @@ -148,10 +148,15 @@ func KindCleanNotify() { } } -func createKindCluster(kindConfigPath string) error { +func createKindCluster(kindConfigPath string, e2eConfig *config.E2EConfig) error { // the config file name of the k8s cluster that kind create kubeConfigPath = constant.K8sClusterConfigFilePath - args := []string{"create", "cluster", "--config", kindConfigPath, "--kubeconfig", kubeConfigPath} + args := []string{ + "create", "cluster", + "--config", kindConfigPath, + "--kubeconfig", kubeConfigPath, + "--wait", e2eConfig.Setup.GetTimeout().String(), + } logger.Log.Info("creating kind cluster...") logger.Log.Debugf("cluster create commands: %s %s", constant.KindCommand, strings.Join(args, " ")) @@ -388,7 +393,7 @@ func exposePerKindService(port config.KindExposePort, timeout time.Duration, cli return nil } -func exposeKindService(exports []config.KindExposePort, timeout int, kubeConfig string) error { +func exposeKindService(exports []config.KindExposePort, timeout time.Duration, kubeConfig string) error { // round tripper kubeConfigYaml, err := ioutil.ReadFile(kubeConfig) if err != nil { @@ -421,7 +426,7 @@ func exposeKindService(exports []config.KindExposePort, timeout int, kubeConfig if timeout <= 0 { waitTimeout = constant.DefaultWaitTimeout } else { - waitTimeout = time.Duration(timeout) * time.Second + waitTimeout = timeout } // stop port-forward channel diff --git a/internal/config/e2eConfig.go b/internal/config/e2eConfig.go index e313573..b853309 100644 --- a/internal/config/e2eConfig.go +++ b/internal/config/e2eConfig.go @@ -18,7 +18,14 @@ package config -import "github.com/apache/skywalking-infra-e2e/internal/util" +import ( + "fmt" + "time" + + "github.com/apache/skywalking-infra-e2e/internal/constant" + "github.com/apache/skywalking-infra-e2e/internal/logger" + "github.com/apache/skywalking-infra-e2e/internal/util" +) // E2EConfig corresponds to configuration file e2e.yaml. type E2EConfig struct { @@ -29,12 +36,30 @@ type E2EConfig struct { } type Setup struct { - Env string `yaml:"env"` - File string `yaml:"file"` - Steps []Step `yaml:"steps"` - Timeout int `yaml:"timeout"` - InitSystemEnvironment string `yaml:"init-system-environment"` - Kind KindSetup `yaml:"kind"` + Env string `yaml:"env"` + File string `yaml:"file"` + Steps []Step `yaml:"steps"` + Timeout interface{} `yaml:"timeout"` + InitSystemEnvironment string `yaml:"init-system-environment"` + Kind KindSetup `yaml:"kind"` + + timeout time.Duration +} + +func (s *Setup) Finalize() error { + interval, err := parseInterval(s.Timeout, "setup.timeout") + if err != nil { + return err + } + if interval <= 0 { + interval = constant.DefaultWaitTimeout + } + s.timeout = interval + return nil +} + +func (s *Setup) GetTimeout() time.Duration { + return s.timeout } type Cleanup struct { @@ -120,3 +145,27 @@ func (v *VerifyCase) GetActual() string { func (v *VerifyCase) GetExpected() string { return util.ResolveAbs(v.Expected) } + +// parseInterval parses a Duration field with number and string content for compatibility, +// only use this when we previously allow configuring number like 120 and now string like 2m. +// TODO remove this in 2.0 +func parseInterval(retryInterval interface{}, name string) (time.Duration, error) { + var interval time.Duration + var err error + switch itv := retryInterval.(type) { + case int: + logger.Log.Warnf("configuring %v with number %v is deprecated and will be removed in future version,"+ + " please use Duration style instead, such as 10s, 1m.", name, itv) + interval = time.Duration(itv) * time.Second + case string: + if interval, err = time.ParseDuration(itv); err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("failed to parse %v: %v", name, retryInterval) + } + if interval < 0 { + interval = constant.DefaultWaitTimeout + } + return interval, nil +} diff --git a/internal/config/globalConfig.go b/internal/config/globalConfig.go index 7be0ae9..707621d 100644 --- a/internal/config/globalConfig.go +++ b/internal/config/globalConfig.go @@ -70,6 +70,10 @@ func ReadGlobalConfigFile() { return } + if err = GlobalConfig.E2EConfig.Setup.Finalize(); err != nil { + GlobalConfig.Error = err + } + GlobalConfig.Error = nil logger.Log.Info("load the e2e config successfully") }