Skip to content

Commit

Permalink
feat: cronjob template (#3739)
Browse files Browse the repository at this point in the history
* feat: add cronjob template to model

* feat: cron job temaplte field

* fix: dep update

* fix: test and test suite template typo

* doc: cron job template

* fix: dep update
  • Loading branch information
vsukhin authored May 4, 2023
1 parent b81d731 commit 4437116
Show file tree
Hide file tree
Showing 33 changed files with 232 additions and 68 deletions.
6 changes: 6 additions & 0 deletions api/v1/testkube.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4141,6 +4141,9 @@ components:
jobTemplate:
type: string
description: job template extensions
cronJobTemplate:
type: string
description: cron job template extensions
contentRequest:
$ref: "#/components/schemas/TestContentRequest"
description: adjusting parameters for test content
Expand Down Expand Up @@ -4233,6 +4236,9 @@ components:
runningContext:
$ref: "#/components/schemas/RunningContext"
description: running context for the test suite execution
cronJobTemplate:
type: string
description: cron job template extensions

TestSuiteExecutionUpdateRequest:
description: test suite execution update request body
Expand Down
28 changes: 28 additions & 0 deletions cmd/kubectl-testkube/commands/tests/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,17 @@ func newExecutionRequestFromFlags(cmd *cobra.Command) (request *testkube.Executi
jobTemplateContent = string(b)
}

cronJobTemplateContent := ""
cronJobTemplate := cmd.Flag("cronjob-template").Value.String()
if cronJobTemplate != "" {
b, err := os.ReadFile(cronJobTemplate)
if err != nil {
return nil, err
}

cronJobTemplateContent = string(b)
}

preRunScriptContent := ""
preRunScript := cmd.Flag("prerun-script").Value.String()
if preRunScript != "" {
Expand Down Expand Up @@ -437,6 +448,7 @@ func newExecutionRequestFromFlags(cmd *cobra.Command) (request *testkube.Executi
HttpsProxy: httpsProxy,
ActiveDeadlineSeconds: timeout,
JobTemplate: jobTemplateContent,
CronJobTemplate: cronJobTemplateContent,
PreRunScript: preRunScriptContent,
ScraperTemplate: scraperTemplateContent,
NegativeTest: negativeTest,
Expand Down Expand Up @@ -897,6 +909,22 @@ func newExecutionUpdateRequestFromFlags(cmd *cobra.Command) (request *testkube.E
nonEmpty = true
}

if cmd.Flag("cronjob-template").Changed {
cronJobTemplateContent := ""
cronJobTemplate := cmd.Flag("cronjob-template").Value.String()
if cronJobTemplate != "" {
b, err := os.ReadFile(cronJobTemplate)
if err != nil {
return nil, err
}

cronJobTemplateContent = string(b)
}

request.CronJobTemplate = &cronJobTemplateContent
nonEmpty = true
}

if cmd.Flag("prerun-script").Changed {
preRunScriptContent := ""
preRunScript := cmd.Flag("prerun-script").Value.String()
Expand Down
4 changes: 3 additions & 1 deletion cmd/kubectl-testkube/commands/tests/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type CreateCommonFlags struct {
ArtifactVolumeMountPath string
ArtifactDirs []string
JobTemplate string
CronJobTemplate string
PreRunScript string
ScraperTemplate string
NegativeTest bool
Expand Down Expand Up @@ -178,7 +179,7 @@ func AddCreateFlags(cmd *cobra.Command, flags *CreateCommonFlags) {
cmd.Flags().StringToStringVarP(&flags.Labels, "label", "l", nil, "label key value pair: --label key1=value1")
cmd.Flags().StringToStringVarP(&flags.Variables, "variable", "v", nil, "variable key value pair: --variable key1=value1")
cmd.Flags().StringToStringVarP(&flags.SecretVariables, "secret-variable", "s", nil, "secret variable key value pair: --secret-variable key1=value1")
cmd.Flags().StringVarP(&flags.Schedule, "schedule", "", "", "test schedule in a cronjob form: * * * * *")
cmd.Flags().StringVarP(&flags.Schedule, "schedule", "", "", "test schedule in a cron job form: * * * * *")
cmd.Flags().StringArrayVarP(&flags.ExecutorArgs, "executor-args", "", []string{}, "executor binary additional arguments")
cmd.Flags().StringVarP(&flags.ExecutionName, "execution-name", "", "", "execution name, if empty will be autogenerated")
cmd.Flags().StringVarP(&flags.VariablesFile, "variables-file", "", "", "variables file path, e.g. postman env file - will be passed to executor if supported")
Expand All @@ -196,6 +197,7 @@ func AddCreateFlags(cmd *cobra.Command, flags *CreateCommonFlags) {
cmd.Flags().StringVar(&flags.ArtifactVolumeMountPath, "artifact-volume-mount-path", "", "artifact volume mount path for container executor")
cmd.Flags().StringArrayVarP(&flags.ArtifactDirs, "artifact-dir", "", []string{}, "artifact dirs for container executor")
cmd.Flags().StringVar(&flags.JobTemplate, "job-template", "", "job template file path for extensions to job template")
cmd.Flags().StringVar(&flags.CronJobTemplate, "cronjob-template", "", "cron job template file path for extensions to cron job template")
cmd.Flags().StringVarP(&flags.PreRunScript, "prerun-script", "", "", "path to script to be run before test execution")
cmd.Flags().StringVar(&flags.ScraperTemplate, "scraper-template", "", "scraper template file path for extensions to scraper template")
cmd.Flags().BoolVar(&flags.NegativeTest, "negative-test", false, "negative test, if enabled, makes failure an expected and correct test result. If the test fails the result will be set to success, and vice versa")
Expand Down
4 changes: 4 additions & 0 deletions cmd/kubectl-testkube/commands/tests/renderer/test_obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func TestRenderer(ui *ui.UI, obj interface{}) error {
ui.Warn(" Job template: ", "\n", test.ExecutionRequest.JobTemplate)
}

if test.ExecutionRequest.CronJobTemplate != "" {
ui.Warn(" Cron job template: ", "\n", test.ExecutionRequest.CronJobTemplate)
}

if test.ExecutionRequest.PreRunScript != "" {
ui.Warn(" Pre run script: ", "\n", test.ExecutionRequest.PreRunScript)
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/kubectl-testkube/commands/tests/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func NewUpdateTestsCmd() *cobra.Command {
artifactVolumeMountPath string
artifactDirs []string
jobTemplate string
cronJobTemplate string
preRunScript string
scraperTemplate string
negativeTest bool
Expand Down Expand Up @@ -100,7 +101,7 @@ func NewUpdateTestsCmd() *cobra.Command {
cmd.Flags().StringToStringVarP(&labels, "label", "l", nil, "label key value pair: --label key1=value1")
cmd.Flags().StringToStringVarP(&variables, "variable", "v", nil, "variable key value pair: -v key1=value1")
cmd.Flags().StringToStringVarP(&secretVariables, "secret-variable", "s", nil, "secret variable key value pair: -s key1=value1")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test schedule in a cronjob form: * * * * *")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test schedule in a cron job form: * * * * *")
cmd.Flags().StringArrayVarP(&executorArgs, "executor-args", "", []string{}, "executor binary additional arguments")
cmd.Flags().StringVarP(&executionName, "execution-name", "", "", "execution name, if empty will be autogenerated")
cmd.Flags().StringVarP(&variablesFile, "variables-file", "", "", "variables file path, e.g. postman env file - will be passed to executor if supported")
Expand All @@ -123,6 +124,7 @@ func NewUpdateTestsCmd() *cobra.Command {
cmd.Flags().StringVar(&artifactVolumeMountPath, "artifact-volume-mount-path", "", "artifact volume mount path for container executor")
cmd.Flags().StringArrayVarP(&artifactDirs, "artifact-dir", "", []string{}, "artifact dirs for container executor")
cmd.Flags().StringVar(&jobTemplate, "job-template", "", "job template file path for extensions to job template")
cmd.Flags().StringVar(&cronJobTemplate, "cronjob-template", "", "cron job template file path for extensions to cron job template")
cmd.Flags().StringVarP(&preRunScript, "prerun-script", "", "", "path to script to be run before test execution")
cmd.Flags().StringVar(&scraperTemplate, "scraper-template", "", "scraper template file path for extensions to scraper template")
cmd.Flags().BoolVar(&negativeTest, "negative-test", false, "negative test, if enabled, makes failure an expected and correct test result. If the test fails the result will be set to success, and vice versa")
Expand Down
38 changes: 33 additions & 5 deletions cmd/kubectl-testkube/commands/testsuites/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,25 @@ func NewTestSuiteUpsertOptionsFromFlags(cmd *cobra.Command) (options apiclientv1
return options, fmt.Errorf("validating schedule %w", err)
}

cronJobTemplateContent := ""
cronJobTemplate := cmd.Flag("cronjob-template").Value.String()
if cronJobTemplate != "" {
b, err := os.ReadFile(cronJobTemplate)
if err != nil {
return options, err
}

cronJobTemplateContent = string(b)
}

options.Schedule = schedule
options.ExecutionRequest = &testkube.TestSuiteExecutionRequest{
Variables: variables,
Name: cmd.Flag("execution-name").Value.String(),
HttpProxy: cmd.Flag("http-proxy").Value.String(),
HttpsProxy: cmd.Flag("https-proxy").Value.String(),
Timeout: timeout,
Variables: variables,
Name: cmd.Flag("execution-name").Value.String(),
HttpProxy: cmd.Flag("http-proxy").Value.String(),
HttpsProxy: cmd.Flag("https-proxy").Value.String(),
Timeout: timeout,
CronJobTemplate: cronJobTemplateContent,
}

return options, nil
Expand Down Expand Up @@ -210,6 +222,22 @@ func NewTestSuiteUpdateOptionsFromFlags(cmd *cobra.Command) (options apiclientv1
nonEmpty = true
}

if cmd.Flag("cronjob-template").Changed {
cronJobTemplateContent := ""
cronJobTemplate := cmd.Flag("cronjob-template").Value.String()
if cronJobTemplate != "" {
b, err := os.ReadFile(cronJobTemplate)
if err != nil {
return options, err
}

cronJobTemplateContent = string(b)
}

executionRequest.CronJobTemplate = &cronJobTemplateContent
nonEmpty = true
}

var executionFields = []struct {
name string
destination **string
Expand Down
5 changes: 4 additions & 1 deletion cmd/kubectl-testkube/commands/testsuites/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func NewCreateTestSuitesCmd() *cobra.Command {
httpProxy, httpsProxy string
secretVariableReferences map[string]string
timeout int32
cronJobTemplate string
)

cmd := &cobra.Command{
Expand Down Expand Up @@ -70,12 +71,14 @@ func NewCreateTestSuitesCmd() *cobra.Command {
cmd.Flags().StringToStringVarP(&labels, "label", "l", nil, "label key value pair: --label key1=value1")
cmd.Flags().StringToStringVarP(&variables, "variable", "v", nil, "param key value pair: --variable key1=value1")
cmd.Flags().StringToStringVarP(&secretVariables, "secret-variable", "s", nil, "secret variable key value pair: --secret-variable key1=value1")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test suite schedule in a cronjob form: * * * * *")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test suite schedule in a cron job form: * * * * *")
cmd.Flags().StringVarP(&executionName, "execution-name", "", "", "execution name, if empty will be autogenerated")
cmd.Flags().StringVar(&httpProxy, "http-proxy", "", "http proxy for executor containers")
cmd.Flags().StringVar(&httpsProxy, "https-proxy", "", "https proxy for executor containers")
cmd.Flags().StringToStringVarP(&secretVariableReferences, "secret-variable-reference", "", nil, "secret variable references in a form name1=secret_name1=secret_key1")
cmd.Flags().Int32Var(&timeout, "timeout", 0, "duration in seconds for test suite to timeout. 0 disables timeout.")
cmd.Flags().StringVar(&cronJobTemplate, "cronjob-template", "", "cron job template file path for extensions to cron job template")

return cmd
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,23 @@ func TestSuiteRenderer(ui *ui.UI, obj interface{}) error {
if ts.ExecutionRequest != nil {
ui.Warn("Execution request: ")
if ts.ExecutionRequest.Name != "" {
ui.Warn(" Name: ", ts.ExecutionRequest.Name)
ui.Warn(" Name: ", ts.ExecutionRequest.Name)
}

if len(ts.ExecutionRequest.Variables) > 0 {
renderer.RenderVariables(ts.ExecutionRequest.Variables)
}

if ts.ExecutionRequest.HttpProxy != "" {
ui.Warn(" Http proxy: ", ts.ExecutionRequest.HttpProxy)
ui.Warn(" Http proxy: ", ts.ExecutionRequest.HttpProxy)
}

if ts.ExecutionRequest.HttpsProxy != "" {
ui.Warn(" Https proxy: ", ts.ExecutionRequest.HttpsProxy)
ui.Warn(" Https proxy: ", ts.ExecutionRequest.HttpsProxy)
}

if ts.ExecutionRequest.CronJobTemplate != "" {
ui.Warn(" Cron job template: ", ts.ExecutionRequest.CronJobTemplate)
}
}

Expand Down
4 changes: 3 additions & 1 deletion cmd/kubectl-testkube/commands/testsuites/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func UpdateTestSuitesCmd() *cobra.Command {
httpProxy, httpsProxy string
secretVariableReferences map[string]string
timeout int32
cronJobTemplate string
)

cmd := &cobra.Command{
Expand Down Expand Up @@ -56,12 +57,13 @@ func UpdateTestSuitesCmd() *cobra.Command {
cmd.Flags().StringToStringVarP(&labels, "label", "l", nil, "label key value pair: --label key1=value1")
cmd.Flags().StringToStringVarP(&variables, "variable", "v", nil, "param key value pair: --variable key1=value1")
cmd.Flags().StringToStringVarP(&secretVariables, "secret-variable", "s", nil, "secret variable key value pair: --secret-variable key1=value1")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test suite schedule in a cronjob form: * * * * *")
cmd.Flags().StringVarP(&schedule, "schedule", "", "", "test suite schedule in a cron job form: * * * * *")
cmd.Flags().StringVarP(&executionName, "execution-name", "", "", "execution name, if empty will be autogenerated")
cmd.Flags().StringVar(&httpProxy, "http-proxy", "", "http proxy for executor containers")
cmd.Flags().StringToStringVarP(&secretVariableReferences, "secret-variable-reference", "", nil, "secret variable references in a form name1=secret_name1=secret_key1")
cmd.Flags().StringVar(&httpsProxy, "https-proxy", "", "https proxy for executor containers")
cmd.Flags().Int32Var(&timeout, "timeout", 0, "duration in seconds for test suite to timeout. 0 disables timeout.")
cmd.Flags().StringVar(&cronJobTemplate, "cronjob-template", "", "cron job template file path for extensions to cron job template")

return cmd
}
21 changes: 21 additions & 0 deletions docs/docs/concepts/tests/tests-creating.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,27 @@ spec:
```
Add `imagePullSecrets` option if you use your own Image Registry. This will add the secret for both `init` and `executor` containers.


### Changing the Default CronJob Template Used for Scheduled Test Execution

Sometimes you need to adjust an existing cron job template for scheduled tests with a few parameters. In this case you can use additional parameter `--cronjob-template` when you create the test:

```sh
testkube create test --git-branch main --git-uri https://github.com/kubeshop/testkube-example-cypress-project.git --git-path "cypress" --name template-test --type cypress/project --cronjob-template cronjob.yaml --schedule "*/5 * * * *"
```

Where `cronjob.yaml` file contains adjusted cron job template parts for merging with default cron job template:

```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
test: kube
```
When such a test is created you will see additional annotations for its cron job, when the default cron job template doesn't have any annotations.
### Executing a Prerun Script
If you need to provide additional configuration for your executor environment, you can submit a prerun script to be executed before the test is started. For example, we have a simple shell script stored in `script.sh` file:
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/reference/cli/testkube_create_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ testkube create test [flags]
--artifact-volume-mount-path string artifact volume mount path for container executor
--command stringArray command passed to image in container executor
--copy-files stringArray file path mappings from host to pod of form source:destination
--cronjob-template string cron job template file path for extensions to cron job template
--env stringToString envs in a form of name1=val1 passed to executor (default [])
--execution-name string execution name, if empty will be autogenerated
--executor-args stringArray executor binary additional arguments
Expand Down Expand Up @@ -45,7 +46,7 @@ testkube create test [flags]
-n, --name string unique test name - mandatory
--negative-test negative test, if enabled, makes failure an expected and correct test result. If the test fails the result will be set to success, and vice versa
--prerun-script string path to script to be run before test execution
--schedule string test schedule in a cronjob form: * * * * *
--schedule string test schedule in a cron job form: * * * * *
--scraper-template string scraper template file path for extensions to scraper template
--secret-env stringToString secret envs in a form of secret_key1=secret_name1 passed to executor (default [])
-s, --secret-variable stringToString secret variable key value pair: --secret-variable key1=value1 (default [])
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/reference/cli/testkube_create_testsuite.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ testkube create testsuite [flags]
### Options

```
--cronjob-template string cron job template file path for extensions to cron job template
--execution-name string execution name, if empty will be autogenerated
-f, --file string JSON test suite file - will be read from stdin if not specified, look at testkube.TestUpsertRequest
-h, --help help for testsuite
--http-proxy string http proxy for executor containers
--https-proxy string https proxy for executor containers
-l, --label stringToString label key value pair: --label key1=value1 (default [])
--name string Set/Override test suite name
--schedule string test suite schedule in a cronjob form: * * * * *
--schedule string test suite schedule in a cron job form: * * * * *
-s, --secret-variable stringToString secret variable key value pair: --secret-variable key1=value1 (default [])
--secret-variable-reference stringToString secret variable references in a form name1=secret_name1=secret_key1 (default [])
--timeout int32 duration in seconds for test suite to timeout. 0 disables timeout.
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/reference/cli/testkube_generate_tests-crds.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ testkube generate tests-crds <manifestDirectory> [flags]
--artifact-volume-mount-path string artifact volume mount path for container executor
--command stringArray command passed to image in container executor
--copy-files stringArray file path mappings from host to pod of form source:destination
--cronjob-template string cron job template file path for extensions to cron job template
--env stringToString envs in a form of name1=val1 passed to executor (default [])
--execution-name string execution name, if empty will be autogenerated
--executor-args stringArray executor binary additional arguments
Expand All @@ -41,7 +42,7 @@ testkube generate tests-crds <manifestDirectory> [flags]
--mount-secret stringToString secret value pair for mounting it to executor pod: --mount-secret secret_name=secret_mountpath (default [])
--negative-test negative test, if enabled, makes failure an expected and correct test result. If the test fails the result will be set to success, and vice versa
--prerun-script string path to script to be run before test execution
--schedule string test schedule in a cronjob form: * * * * *
--schedule string test schedule in a cron job form: * * * * *
--scraper-template string scraper template file path for extensions to scraper template
--secret-env stringToString secret envs in a form of secret_key1=secret_name1 passed to executor (default [])
-s, --secret-variable stringToString secret variable key value pair: --secret-variable key1=value1 (default [])
Expand Down
Loading

0 comments on commit 4437116

Please sign in to comment.