diff --git a/.github/workflows/test_workflow_scripts/python-docker.sh b/.github/workflows/test_workflow_scripts/python-docker.sh index 0f2f67223..2f1cdb7cf 100755 --- a/.github/workflows/test_workflow_scripts/python-docker.sh +++ b/.github/workflows/test_workflow_scripts/python-docker.sh @@ -22,7 +22,7 @@ sleep 5 docker build -t flask-app:1.0 . for i in {1..2}; do -sudo -E env PATH=$PATH ./../../keployv2 record -c "docker compose up" --containerName flask-app --buildDelay 40s --generateGithubActions=false & +sudo -E env PATH=$PATH ./../../keployv2 record -c "docker compose up" --containerName flask-app --buildDelay 40 --generateGithubActions=false & # Wait for the application to start. app_started=false @@ -50,7 +50,7 @@ docker rm -f flask-app done # Start the app in test mode. -sudo -E env PATH=$PATH ./../../keployv2 test -c "docker compose up" --containerName flask-app --buildDelay 40s --apiTimeout 60 --delay 20 --generateGithubActions=false +sudo -E env PATH=$PATH ./../../keployv2 test -c "docker compose up" --containerName flask-app --buildDelay 40 --apiTimeout 60 --delay 20 --generateGithubActions=false # Get the test results from the testReport file. report_file="./keploy/reports/test-run-0/test-set-0-report.yaml" diff --git a/cli/provider/cmd.go b/cli/provider/cmd.go index 33c221269..c256a7d1b 100644 --- a/cli/provider/cmd.go +++ b/cli/provider/cmd.go @@ -47,21 +47,21 @@ Golang Application sudo -E env PATH=$PATH keploy record -c "/path/to/user/app/binary" Test: - sudo -E env PATH=$PATH keploy test -c "/path/to/user/app/binary" --delay 2 + sudo -E env PATH=$PATH keploy test -c "/path/to/user/app/binary" --delay 10 Node Application Record: sudo -E env PATH=$PATH keploy record -c “npm start --prefix /path/to/node/app" Test: - sudo -E env PATH=$PATH keploy test -c “npm start --prefix /path/to/node/app" --delay 2 + sudo -E env PATH=$PATH keploy test -c “npm start --prefix /path/to/node/app" --delay 10 Java Record: sudo -E env PATH=$PATH keploy record -c "java -jar /path/to/java-project/target/jar" Test: - sudo -E env PATH=$PATH keploy test -c "java -jar /path/to/java-project/target/jar" --delay 2 + sudo -E env PATH=$PATH keploy test -c "java -jar /path/to/java-project/target/jar" --delay 10 Docker Alias: @@ -69,10 +69,10 @@ Docker -v /sys/kernel/debug:/sys/kernel/debug -v /sys/fs/bpf:/sys/fs/bpf -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/keploy/keploy' Record: - keploy record -c "docker run -p 8080:8080 --name --network " --buildDelay 1m + keploy record -c "docker run -p 8080:8080 --name --network " --buildDelay 60 Test: - keploy test -c "docker run -p 8080:8080 --name --network " --delay 1 --buildDelay 1m + keploy test -c "docker run -p 8080:8080 --name --network " --delay 10 --buildDelay 60 ` @@ -82,28 +82,28 @@ Golang Application keploy record -c "/path/to/user/app/binary" Test: - keploy test -c "/path/to/user/app/binary" --delay 2 + keploy test -c "/path/to/user/app/binary" --delay 10 Node Application Record: keploy record -c “npm start --prefix /path/to/node/app" Test: - keploy test -c “npm start --prefix /path/to/node/app" --delay 2 + keploy test -c “npm start --prefix /path/to/node/app" --delay 10 Java Record: keploy record -c "java -jar /path/to/java-project/target/jar" Test: - keploy test -c "java -jar /path/to/java-project/target/jar" --delay 2 + keploy test -c "java -jar /path/to/java-project/target/jar" --delay 10 Docker Record: - keploy record -c "docker run -p 8080:8080 --name --network " --buildDelay 1m + keploy record -c "docker run -p 8080:8080 --name --network " --buildDelay 60 Test: - keploy test -c "docker run -p 8080:8080 --name --network " --delay 1 --buildDelay 1m + keploy test -c "docker run -p 8080:8080 --name --network " --delay 1 --buildDelay 60 ` var RootCustomHelpTemplate = `{{.Short}} @@ -132,10 +132,10 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e var RootExamples = ` Record: - keploy record -c "docker run -p 8080:8080 --name --network keploy-network " --containerName "" --delay 1 --buildDelay 1m + keploy record -c "docker run -p 8080:8080 --name --network keploy-network " --containerName "" --buildDelay 60 Test: - keploy test --c "docker run -p 8080:8080 --name --network keploy-network " --delay 1 --buildDelay 1m + keploy test --c "docker run -p 8080:8080 --name --network keploy-network " --delay 10 --buildDelay 60 Config: keploy config --generate -p "/path/to/localdir" @@ -197,10 +197,11 @@ func (c *CmdConfigurator) AddFlags(cmd *cobra.Command) error { cmd.Flags().Uint32("dnsPort", c.cfg.DNSPort, "Port used by the Keploy DNS server to intercept the DNS queries") cmd.Flags().StringP("command", "c", c.cfg.Command, "Command to start the user application") cmd.Flags().String("cmdType", c.cfg.CommandType, "Type of command to start the user application (native/docker/docker-compose)") - cmd.Flags().DurationP("buildDelay", "b", c.cfg.BuildDelay, "User provided time to wait docker container build") + cmd.Flags().Uint64P("buildDelay", "b", c.cfg.BuildDelay, "User provided time to wait docker container build") cmd.Flags().String("containerName", c.cfg.ContainerName, "Name of the application's docker container") cmd.Flags().StringP("networkName", "n", c.cfg.NetworkName, "Name of the application's docker network") cmd.Flags().UintSlice("passThroughPorts", config.GetByPassPorts(c.cfg), "Ports to bypass the proxy server and ignore the traffic") + cmd.Flags().StringP("appId", "a", c.cfg.AppID, "A unique name for the user's application") cmd.Flags().Bool("generateGithubActions", c.cfg.GenerateGithubActions, "Generate Github Actions workflow file") err = cmd.Flags().MarkHidden("port") if err != nil { @@ -392,9 +393,10 @@ func (c *CmdConfigurator) ValidateFlags(ctx context.Context, cmd *cobra.Command) } } } - if c.cfg.BuildDelay <= 30*time.Second { + // check if the buildDelay is less than 30 seconds + if time.Duration(c.cfg.BuildDelay)*time.Second <= 30*time.Second { c.logger.Warn(fmt.Sprintf("buildDelay is set to %v, incase your docker container takes more time to build use --buildDelay to set custom delay", c.cfg.BuildDelay)) - c.logger.Info(`Example usage: keploy record -c "docker-compose up --build" --buildDelay 35s`) + c.logger.Info(`Example usage: keploy record -c "docker-compose up --build" --buildDelay 35`) } if utils.CmdType(c.cfg.Command) == utils.DockerCompose { if c.cfg.ContainerName == "" { diff --git a/config/config.go b/config/config.go index 2cd5745ae..a74722f6d 100644 --- a/config/config.go +++ b/config/config.go @@ -8,29 +8,30 @@ import ( ) type Config struct { - Path string `json:"path" yaml:"path" mapstructure:"path"` - ReRecord string `json:"rerecord" yaml:"rerecord" mapstructure:"rerecord"` - Command string `json:"command" yaml:"command" mapstructure:"command"` - Port uint32 `json:"port" yaml:"port" mapstructure:"port"` - DNSPort uint32 `json:"dnsPort" yaml:"dnsPort" mapstructure:"dnsPort"` - ProxyPort uint32 `json:"proxyPort" yaml:"proxyPort" mapstructure:"proxyPort"` - Debug bool `json:"debug" yaml:"debug" mapstructure:"debug"` - DisableTele bool `json:"disableTele" yaml:"disableTele" mapstructure:"disableTele"` - DisableANSI bool `json:"disableANSI" yaml:"disableANSI" mapstructure:"disableANSI"` - InDocker bool `json:"inDocker" yaml:"inDocker" mapstructure:"inDocker"` - ContainerName string `json:"containerName" yaml:"containerName" mapstructure:"containerName"` - NetworkName string `json:"networkName" yaml:"networkName" mapstructure:"networkName"` - BuildDelay time.Duration `json:"buildDelay" yaml:"buildDelay" mapstructure:"buildDelay"` - Test Test `json:"test" yaml:"test" mapstructure:"test"` - Record Record `json:"record" yaml:"record" mapstructure:"record"` - Normalize Normalize `json:"normalize" yaml:"normalize" mapstructure:"normalize"` - ConfigPath string `json:"configPath" yaml:"configPath" mapstructure:"configPath"` - BypassRules []BypassRule `json:"bypassRules" yaml:"bypassRules" mapstructure:"bypassRules"` - EnableTesting bool `json:"enableTesting" yaml:"enableTesting" mapstructure:"enableTesting"` - GenerateGithubActions bool `json:"generateGithubActions" yaml:"generateGithubActions" mapstructure:"generateGithubActions"` - KeployContainer string `json:"keployContainer" yaml:"keployContainer" mapstructure:"keployContainer"` - KeployNetwork string `json:"keployNetwork" yaml:"keployNetwork" mapstructure:"keployNetwork"` - CommandType string `json:"cmdType" yaml:"cmdType" mapstructure:"cmdType"` + Path string `json:"path" yaml:"path" mapstructure:"path" ` + AppID string `json:"appId" yaml:"appId" mapstructure:"appId"` + ReRecord string `json:"rerecord" yaml:"rerecord" mapstructure:"rerecord"` + Command string `json:"command" yaml:"command" mapstructure:"command"` + Port uint32 `json:"port" yaml:"port" mapstructure:"port"` + DNSPort uint32 `json:"dnsPort" yaml:"dnsPort" mapstructure:"dnsPort"` + ProxyPort uint32 `json:"proxyPort" yaml:"proxyPort" mapstructure:"proxyPort"` + Debug bool `json:"debug" yaml:"debug" mapstructure:"debug"` + DisableTele bool `json:"disableTele" yaml:"disableTele" mapstructure:"disableTele"` + DisableANSI bool `json:"disableANSI" yaml:"disableANSI" mapstructure:"disableANSI"` + InDocker bool `json:"inDocker" yaml:"inDocker" mapstructure:"inDocker"` + ContainerName string `json:"containerName" yaml:"containerName" mapstructure:"containerName"` + NetworkName string `json:"networkName" yaml:"networkName" mapstructure:"networkName"` + BuildDelay uint64 `json:"buildDelay" yaml:"buildDelay" mapstructure:"buildDelay"` + Test Test `json:"test" yaml:"test" mapstructure:"test"` + Record Record `json:"record" yaml:"record" mapstructure:"record"` + Normalize Normalize `json:"normalize" yaml:"normalize" mapstructure:"normalize"` + ConfigPath string `json:"configPath" yaml:"configPath" mapstructure:"configPath"` + BypassRules []BypassRule `json:"bypassRules" yaml:"bypassRules" mapstructure:"bypassRules"` + EnableTesting bool `json:"enableTesting" yaml:"enableTesting" mapstructure:"enableTesting"` + GenerateGithubActions bool `json:"generateGithubActions" yaml:"generateGithubActions" mapstructure:"generateGithubActions"` + KeployContainer string `json:"keployContainer" yaml:"keployContainer" mapstructure:"keployContainer"` + KeployNetwork string `json:"keployNetwork" yaml:"keployNetwork" mapstructure:"keployNetwork"` + CommandType string `json:"cmdType" yaml:"cmdType" mapstructure:"cmdType"` } type Record struct { diff --git a/config/default.go b/config/default.go index 10a2f4e88..7f17a606d 100644 --- a/config/default.go +++ b/config/default.go @@ -10,6 +10,7 @@ import ( // defaultConfig is a variable to store the default configuration of the Keploy CLI. It is not a constant because enterprise need update the default configuration. var defaultConfig = ` path: "" +appId: "" command: "" port: 0 proxyPort: 16789 @@ -21,7 +22,7 @@ inDocker: false generateGithubActions: true containerName: "" networkName: "" -buildDelay: 30s +buildDelay: 30 test: selectedTests: {} globalNoise: diff --git a/pkg/core/app/app.go b/pkg/core/app/app.go index 5ace2bae8..7b20bd468 100644 --- a/pkg/core/app/app.go +++ b/pkg/core/app/app.go @@ -42,7 +42,7 @@ type App struct { id uint64 cmd string kind utils.CmdType - containerDelay time.Duration + containerDelay uint64 container string containerNetwork string containerIPv4 string @@ -58,7 +58,7 @@ type Options struct { // canExit disables any error returned if the app exits by itself. //CanExit bool Container string - DockerDelay time.Duration + DockerDelay uint64 DockerNetwork string } @@ -313,7 +313,7 @@ func (a *App) getDockerMeta(ctx context.Context) <-chan error { defer a.logger.Debug("exiting from goroutine of docker daemon event listener") errCh := make(chan error, 1) - timer := time.NewTimer(a.containerDelay) + timer := time.NewTimer(time.Duration(a.containerDelay) * time.Second) logTicker := time.NewTicker(1 * time.Second) defer logTicker.Stop() diff --git a/pkg/models/instrument.go b/pkg/models/instrument.go index 5c9b024fa..bf5167bab 100644 --- a/pkg/models/instrument.go +++ b/pkg/models/instrument.go @@ -26,7 +26,7 @@ type IncomingOptions struct { type SetupOptions struct { Container string DockerNetwork string - DockerDelay time.Duration + DockerDelay uint64 } type RunOptions struct { diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index b371ffcb6..4877ca9fe 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -158,12 +158,18 @@ func (r *Replayer) Start(ctx context.Context) error { if abortTestRun { break } + + _, err = emulator.AfterTestHook(ctx, testRunID, testSetID, len(testSetIDs)) + if err != nil { + utils.LogError(r.logger, err, "failed to get after test hook") + } } testRunStatus := "fail" if testRunResult { testRunStatus = "pass" } + r.telemetry.TestRun(totalTestPassed, totalTestFailed, len(testSetIDs), testRunStatus) if !abortTestRun { diff --git a/pkg/service/replay/service.go b/pkg/service/replay/service.go index 34785c86e..fa272e0bb 100644 --- a/pkg/service/replay/service.go +++ b/pkg/service/replay/service.go @@ -64,4 +64,5 @@ type Telemetry interface { // the recorded test case of the user app. type RequestEmulator interface { SimulateRequest(ctx context.Context, appID uint64, tc *models.TestCase, testSetID string) (*models.HTTPResp, error) + AfterTestHook(ctx context.Context, testRunID, testSetID string, totalTestSets int) (*models.TestReport, error) } diff --git a/pkg/service/replay/utils.go b/pkg/service/replay/utils.go index 2b8433d8f..1f7525476 100644 --- a/pkg/service/replay/utils.go +++ b/pkg/service/replay/utils.go @@ -65,3 +65,8 @@ func (t *testUtils) SimulateRequest(ctx context.Context, _ uint64, tc *models.Te } return nil, nil } + +func (t *testUtils) AfterTestHook(_ context.Context, testRunID, testSetID string, tsCnt int) (*models.TestReport, error) { + t.logger.Debug("AfterTestHook", zap.Any("testRunID", testRunID), zap.Any("testSetID", testSetID), zap.Any("totTestSetCount", tsCnt)) + return nil, nil +}