{"id":16744022,"url":"https://github.com/goccy/kubetest","last_synced_at":"2025-03-17T01:32:13.755Z","repository":{"id":38348799,"uuid":"276069079","full_name":"goccy/kubetest","owner":"goccy","description":"A CLI for distributed execution of tasks on Kubernetes","archived":false,"fork":false,"pushed_at":"2024-07-22T09:11:23.000Z","size":709,"stargazers_count":19,"open_issues_count":6,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T16:38:54.814Z","etag":null,"topics":["cli","distributed-computing","go","golang","kubernetes","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goccy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-30T10:33:28.000Z","updated_at":"2025-01-07T05:10:09.000Z","dependencies_parsed_at":"2024-10-27T11:52:21.976Z","dependency_job_id":"7e1698ea-e922-4fc8-b286-394af5897768","html_url":"https://github.com/goccy/kubetest","commit_stats":{"total_commits":258,"total_committers":3,"mean_commits":86.0,"dds":"0.011627906976744207","last_synced_commit":"f1f7c4731f8440b8092279a4c0f96af632f8e0a4"},"previous_names":[],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fkubetest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fkubetest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fkubetest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fkubetest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goccy","download_url":"https://codeload.github.com/goccy/kubetest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243836980,"owners_count":20355807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","distributed-computing","go","golang","kubernetes","testing"],"created_at":"2024-10-13T01:42:15.171Z","updated_at":"2025-03-17T01:32:13.399Z","avatar_url":"https://github.com/goccy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kubetest\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/goccy/kubetest)](https://pkg.go.dev/github.com/goccy/kubetest)\n![Go](https://github.com/goccy/kubetest/workflows/test/badge.svg)\n[![codecov](https://codecov.io/gh/goccy/kubetest/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/kubetest)\n\nA CLI for distributed execution of tasks on Kubernetes.  \n\nThis tool is developed based on the following concept.\n\n- Distributed processing: divide time-consuming tasks based on certain rules, and efficient use of cluster resources by processing each task using different pods\n- One container per task: since the divided tasks are processed in different containers, they are less affected by the processing of different tasks.\n\n# Installation\n\n```bash\n$ go install github.com/goccy/kubetest/cmd/kubetest\n```\n\n# How to use\n\n```\nUsage:\n  kubetest [OPTIONS]\n\nApplication Options:\n  -n, --namespace=  specify namespace (default: default)\n      --in-cluster  specify whether in cluster\n  -c, --config=     specify local kubeconfig path. ( default: $HOME/.kube/config )\n      --list=       specify path to get the list for test\n      --log-level=  specify log level (debug/info/warn/error)\n      --dry-run     specify dry run mode\n      --template=   specify template parameter for testjob file\n  -o, --output=     specify output path of report\n\nHelp Options:\n  -h, --help        Show this help message\n```\n\n## 1. Run simple task\n\nFirst, We will introduce a sample that performs the simplest task processing.\n\nDescribe the manifest file of task processing as follows and execute it by passing it as an argument of kubetest CLI.\n\nIf you've already written a Kubernetes Job, you've probably noticed that the spec under the `mainStep` of simplest example is the same as using a Kubernetes Job :)\n\n- _examples/simple.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: simple-testjob\n  namespace: default\nspec:\n  mainStep:\n    template:\n      metadata:\n        generateName: simple-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /go/src\n            command:\n              - echo\n            args:\n              - \"hello\"\n```\n\n### Run CLI with manifest\n\n```console\nkubetest --log-level=info _examples/simple.yaml\n```\n\n### Output\n\nThe content consists of the following elements.\n\n- Command\n- Log of command\n- Elapsed time of running command\n- Summary of all tasks ( JSON format )\n\n```console\necho hello\nhello\n\n[INFO] elapsed time: 0.184144 sec.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"test\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 10,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T07:36:07.893339674Z\",\n  \"status\": \"success\",\n  \"successNum\": 1,\n  \"totalNum\": 1\n}\n```\n\n## 2. Run task with public repository\n\nYou'll want to use versioned data and code by `git` when processing tasks.\nIn kubetest, you can write the repository definition in `repos` and specify it in ` volumes`. The repository defined in `volumes` can be mounted in any container by using `volumeMounts` like `emptyDir` .\n\n- _examples/public-repo.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: public-repo-testjob\n  namespace: default\nspec:\n  repos:\n    - name: kubetest-repo\n      value:\n        url: https://github.com/goccy/kubetest.git\n        branch: master\n  mainStep:\n    template:\n      metadata:\n        generateName: public-repo-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - ls\n            args:\n              - README.md\n            volumeMounts:\n              - name: repo\n                mountPath: /work\n        volumes:\n          - name: repo\n            repo:\n              name: kubetest-repo\n```\n\n### Run CLI with manifest\n\n```console\nkubetest --log-level=info _examples/public-repo.yaml\n```\n### Output\n\n```console\n[INFO] clone repository: https://github.com/goccy/kubetest.git\nls README.md\nREADME.md\n\n[INFO] elapsed time: 0.050960 sec.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"test\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 14,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T07:41:51.54612701Z\",\n  \"status\": \"success\",\n  \"successNum\": 1,\n  \"totalNum\": 1\n}\n```\n\n## 3. Run task with private repository\n\nYou can also use a private repository with kubetest.\nYou can define GitHub personal token or token by GitHub App in `tokens` .\nGitHub persoanl token data or GitHub App key data are managed by Kubernetes Secrets.\n`kubetest` get token by referring to them.\nBy describing the name of the token to be used in the definition of private repository in the form of `token: github-app-token`, the repository will be cloned using that token.\n\nIn addition, the token can be mounted on any path using `volumeMounts` by writing the following in `volumes`. By combining this with `prestep`, which will be described later, you can devise so that you do not need a token when processing the main task. This makes task processing more secure.\n\n```yaml\nvolumes:\n- name: token-volume\n  token:\n    name: \u003cdefined token name\u003e\n```\n\n- _examples/private-repo.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: private-repo-testjob\n  namespace: default\nspec:\n  tokens:\n    - name: github-app-token\n      value:\n        githubApp:\n          organization: goccy\n          appId: 134426\n          keyFile:\n            name: github-app\n            key: private-key\n  repos:\n    - name: kubetest-repo\n      value:\n        # specify the private repository url\n        url: https://github.com/goccy/kubetest.git\n        branch: master\n        token: github-app-token\n  mainStep:\n    template:\n      metadata:\n        generateName: private-repo-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - ls\n            args:\n              - README.md\n            volumeMounts:\n              - name: repo\n                mountPath: /work\n        volumes:\n          - name: repo\n            repo:\n              name: kubetest-repo\n```\n\n### Output\n\n```console\n[INFO] clone repository: https://github.com/goccy/kubetest.git\nls README.md\nREADME.md\n\n[INFO] elapsed time: 0.055823 sec.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"test\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 14,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T07:43:34.607701724Z\",\n  \"status\": \"success\",\n  \"successNum\": 1,\n  \"totalNum\": 1\n}\n```\n\n## 4. Run task with prestep\n\nIf there is any pre-processing required before performing the main task processing, you can define it in `preSteps` and pass only the processing result to the subsequent tasks.\nBy making effective use of this step, the pre-processing required for each distributed process can be limited to one time, and the resources of the cluster can be used efficiently.\nSince multiple preSteps can be defined and executed in order, the result of the previous step can be used to execute the next step.\n\nThe artifacts created by `preStep` can be reused in the subsequent task processing by describing the container name and path where the artifacts exists in `artifacts` spec.\n\nIf you want to use the already created artifacts, you can write the name of the defined artifact in `volumes` as follows. As with the repository, you can use `volumeMounts` to mount it on any path.\n\n```yaml\nvolumes:\n- name: artifact-volume\n  artifact:\n    name: \u003cdefined artifact name\u003e\n```\n\n- _examples/prestep.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: prestep-testjob\n  namespace: default\nspec:\n  repos:\n    - name: kubetest-repo\n      value:\n        url: https://github.com/goccy/kubetest.git\n        branch: master\n  preSteps:\n    - name: create-awesome-stuff\n      template:\n        metadata:\n          generateName: create-awesome-stuff-\n        spec:\n          artifacts:\n            - name: awesome-stuff\n              container:\n                name: create-awesome-stuff-container\n                path: /work/awesome-stuff\n          containers:\n            - name: create-awesome-stuff-container\n              image: alpine\n              workingDir: /work\n              command: [\"sh\", \"-c\"]\n              args:\n                - |\n                  echo \"AWESOME!!!\" \u003e awesome-stuff\n              volumeMounts:\n                - name: repo\n                  mountPath: /work\n          volumes:\n            - name: repo\n              repo:\n                name: kubetest-repo\n  mainStep:\n    template:\n      metadata:\n        generateName: prestep-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - cat\n            args:\n              - awesome-stuff\n            volumeMounts:\n              - name: repo\n                mountPath: /work\n              - name: prestep-artifact\n                mountPath: /work/awesome-stuff\n        volumes:\n          - name: repo\n            repo:\n              name: kubetest-repo\n          - name: prestep-artifact\n            artifact:\n              name: awesome-stuff\n```\n\n### Output\n\n```console\n[INFO] clone repository: https://github.com/goccy/kubetest.git\n[INFO] run prestep: create-awesome-stuff\nsh -c echo \"AWESOME!!!\" \u003e awesome-stuff\n\n[INFO] create-awesome-stuff: elapsed time: 0.062056 sec.\ncat awesome-stuff\nAWESOME!!!\n\n[INFO] elapsed time: 0.053780 sec.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"test\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 24,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T08:00:43.033808187Z\",\n  \"status\": \"success\",\n  \"successNum\": 1,\n  \"totalNum\": 1\n}\n```\n\n## 5. Run distributed task with static keys\n\nDescribes the distributed processing, which is the main feature of kubetest.\nDistributed processing is realized by defining a **`distributed key`** and passing that value as an environment variable to different tasks.\nThe `distributed key` can be determined statically or dynamically.\nIn the following, we will explain using the static determination pattern.\n\n- _examples/strategy-static.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: strategy-static-testjob\n  namespace: default\nspec:\n  mainStep:\n    strategy:\n      key:\n        env: TASK_KEY\n        source:\n          static:\n            - TASK_KEY_1\n            - TASK_KEY_2\n            - TASK_KEY_3\n      scheduler:\n        maxContainersPerPod: 10\n        maxConcurrentNumPerPod: 10\n    template:\n      metadata:\n        generateName: strategy-static-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - echo\n            args:\n              - $TASK_KEY\n```\n\nDescribe the definition of distributed execution under `strategy` as described above.\n`key` defines the name of the environment variable to be referenced as the distribution key and the value of the distribution key itself.\n\nIn this example, if you refer to the environment variable named `TASK_KEY`, you can get one of the values ​​from `TASK_KEY_1` to `TASK_KEY_3`.\nAfter that, define a command that uses the value of this environment variable in `spec.template.spec.containers[].command`.\n\nIn `strategy.scheduler`, define the resources such as `Pod` and `Container` used for distributed execution.\nIn this example, `maxContainersPerPod` is `10`, which means that up to `10` containers can be launched per Pod, and `maxConcurrentNumPerPod` is also `10`, which means that `10` containers can process tasks at the same time per Pod.\nSince the number of distributed keys is `3`, only one Pod will be launched, but if the number of distributed keys exceeds `10`, two Pods will be launched and processed.\nSimilarly, if you set the number of `maxContainersPerPod` to `1`, only one container will be started per Pod, so three Pods will be started and processed.\n\n### Output\n\n```console\n[INFO] found 3 static keys to start distributed task\n[TASK_KEY:TASK_KEY_1] echo $TASK_KEY\nTASK_KEY_1\n\n[INFO] elapsed time: 0.194488 sec.\n[INFO] 1/3 (33.333336%) finished.\n[TASK_KEY:TASK_KEY_3] echo $TASK_KEY\nTASK_KEY_3\n\n[INFO] elapsed time: 0.194521 sec.\n[INFO] 2/3 (66.666672%) finished.\n[TASK_KEY:TASK_KEY_2] echo $TASK_KEY\nTASK_KEY_2\n\n[INFO] elapsed time: 0.304037 sec.\n[INFO] 3/3 (100.000000%) finished.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_1\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_3\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_2\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 13,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T08:23:11.568491828Z\",\n  \"status\": \"success\",\n  \"successNum\": 3,\n  \"totalNum\": 3\n}\n```\n\n## 6. Run distributed task with dynamic keys\n\nUse `strategy.key.source.dynamic` to create a distributed key dynamically.\nThe `distributed key` is the output result of the command defined here divided by the line feed character. ( There is also a way of splitting and a method of filtering unnecessary output results )\n\n- _examples/strategy-dynamic.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: strategy-dynamic-testjob\n  namespace: default\nspec:\n  mainStep:\n    strategy:\n      key:\n        env: TASK_KEY\n        source:\n          dynamic:\n            template:\n              metadata:\n                generateName: strategy-dynamic-keys-\n              spec:\n                containers:\n                  - name: key\n                    image: alpine\n                    command: [\"sh\", \"-c\"]\n                    args:\n                      - |\n                        echo -n \"\n                        TASK_KEY_1\n                        TASK_KEY_2\n                        TASK_KEY_3\n                        TASK_KEY_4\"\n      scheduler:\n        maxContainersPerPod: 10\n        maxConcurrentNumPerPod: 10\n    template:\n      metadata:\n        generateName: strategy-dynamic-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - echo\n            args:\n              - $TASK_KEY\n```\n\n### Output\n\n```console\nsh -c echo -n \"\nTASK_KEY_1\nTASK_KEY_2\nTASK_KEY_3\nTASK_KEY_4\"\n\n\nTASK_KEY_1\nTASK_KEY_2\nTASK_KEY_3\nTASK_KEY_4\n[INFO] elapsed time: 0.103151 sec.\n[INFO] found 4 dynamic keys to start distributed task.\n[TASK_KEY:TASK_KEY_2] echo $TASK_KEY\nTASK_KEY_2\n\n[INFO] elapsed time: 0.163853 sec.\n[INFO] 1/4 (25.000000%) finished.\n[TASK_KEY:TASK_KEY_3] echo $TASK_KEY\nTASK_KEY_3\n\n[INFO] elapsed time: 0.201432 sec.\n[INFO] 2/4 (50.000000%) finished.\n[TASK_KEY:TASK_KEY_4] echo $TASK_KEY\nTASK_KEY_4\n\n[INFO] elapsed time: 0.352685 sec.\n[INFO] 3/4 (75.000000%) finished.\n[TASK_KEY:TASK_KEY_1] echo $TASK_KEY\nTASK_KEY_1\n\n[INFO] elapsed time: 0.351710 sec.\n[INFO] 4/4 (100.000000%) finished.\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_2\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_3\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_4\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_1\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 21,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T08:40:25.441356613Z\",\n  \"status\": \"success\",\n  \"successNum\": 4,\n  \"totalNum\": 4\n}\n```\n\n## 7. Export Artifacts\n\nIf you want to get the artifacts of task processing, use `exportArtifacts`.\n\n- _examples/export-artifact.yaml\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: strategy-static-testjob\n  namespace: default\nspec:\n  mainStep:\n    strategy:\n      key:\n        env: TASK_KEY\n        source:\n          static:\n            - TASK_KEY_1\n            - TASK_KEY_2\n            - TASK_KEY_3\n      scheduler:\n        maxContainersPerPod: 10\n        maxConcurrentNumPerPod: 10\n    template:\n      metadata:\n        generateName: strategy-static-testjob-\n      spec:\n        artifacts:\n          - name: result\n            container:\n              name: test\n              path: /work/result.txt\n        containers:\n          - name: test\n            image: alpine\n            workingDir: /work\n            command:\n              - touch\n            args:\n              - result.txt\n  exportArtifacts:\n    - name: result\n      path: /tmp/artifacts\n```\n\n### Output\n\n```console\n[INFO] found 3 static keys to start distributed task\n[TASK_KEY:TASK_KEY_2] touch result.txt\n[INFO] elapsed time: 0.191768 sec.\n[INFO] 1/3 (33.333336%) finished.\n[TASK_KEY:TASK_KEY_3] touch result.txt\n[INFO] elapsed time: 0.191810 sec.\n[INFO] 2/3 (66.666672%) finished.\n[TASK_KEY:TASK_KEY_1] touch result.txt\n[INFO] elapsed time: 0.191841 sec.\n[INFO] 3/3 (100.000000%) finished.\n[INFO] export artifact result\n{\n  \"details\": [\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_2\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_3\",\n      \"status\": \"success\"\n    },\n    {\n      \"elapsedTimeSec\": 0,\n      \"name\": \"TASK_KEY_1\",\n      \"status\": \"success\"\n    }\n  ],\n  \"elapsedTimeSec\": 14,\n  \"failureNum\": 0,\n  \"startedAt\": \"2021-10-05T09:12:18.296041274Z\",\n  \"status\": \"success\",\n  \"successNum\": 3,\n  \"totalNum\": 3\n}\n```\n\n#### Path Rule\n\nArtifacts are created under the directory `\u003cContainer Name\u003e\u003cPod Index\u003e-\u003cContainer Index\u003e` .\n\n```console\n/tmp/artifacts\n|-- test0-0\n|   `-- result.txt\n|-- test0-1\n|   `-- result.txt\n`-- test0-2\n    `-- result.txt\n```\n\n## 8. Use kubetest-agent\n\nNormally, when communicating with the container of Job started by kubetest, use the Kubernetes API.\nHowever, if you need to copy large files or run a large number of commands and don't want to overload the Kubernetes API, or if you don't have a shell or tar command in your container image, you can use the `kubetest-agent` method.\n\nkubetest-agent is a CLI tool that can be installed by the following methods.\n\n```console\n$ go install github.com/goccy/kubetest/cmd/kubetest-agent\n```\n\nInclude this tool in your container image and specify the path to kubetest-agent as follows:\n\n```yaml\napiVersion: kubetest.io/v1\nkind: TestJob\nmetadata:\n  name: kubetest-agent-job\n  namespace: default\nspec:\n  mainStep:\n    template:\n      metadata:\n        generateName: kubetest-agent-testjob-\n      spec:\n        containers:\n          - name: test\n            image: alpine\n            agent:\n              installedPath: /bin/kubetest-agent\n            workingDir: /go/src\n            command:\n              - echo\n            args:\n              - \"hello\"\n```\n\nThis will switch from communication using the Kubernetes API to gRPC-based communication with kubetest-agent.\nCommunication with `kubetest-agent` is performed using JWT issued using the RSA Key issued each time Kubernetes Job is started, so requests cannot be sent directly to the container from other processes.\nIt makes use of the features of `kubejob-agent`. See here for [details](https://github.com/goccy/kubejob#execution-with-kubejob-agent)\n\n\n# Specification of TestJob\n\n## TestJob\n\n| field | type | description |\n| ---- | ---- | ---- |\n| spec | TestJobSpec | specification of TestJob |\n\n## TestJobSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| repos | []RepositorySpec | Array of repository specifications |\n| tokens | []TokenSpec | Array of token specifications |\n| preSteps | []PreStep | Array of prestep specifications |\n| exportArtifacts | []ExportArtifact | Array of exportArtifact specifications |\n| strategy | Strategy | strategy specification for distributed processing |\n| log | LogSpec | log specification |\n\n## RepositorySpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | specify the name to be used when referencing the repository in the TestJob spec. This name must be unique within the TestJob spec. |\n|  value  | Repository | |\n\n## Repository\n\n| field | type | description |\n| ---- | ---- | ---- |\n| url | string | url to the repository like `https://github.com/goccy/kubetest.git` |\n| branch | string | branch name |\n| rev | string | revision |\n| token | string | token name. This must match the name of a Token |\n| merge | MergeSpec | specify base branch name to merge before task processing |\n\n## MergeSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| base | string | base branch name |\n\n## TokenSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string |  |\n| value | TokenSource |  |\n\n\n## TokenSource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| githubApp | GitHubAppTokenSource |  |\n| githubToken | SecretKeySelector |  |\n\n## GitHubAppTokenSource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| organization | string |  |\n| appId | number |  |\n| installationId | number | |\n| keyFile | SecretKeySelector | |\n\n## SecretKeySelector\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | secret name to the secret data |\n| key | string | key name to the secret data |\n\n## PreStep\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | name of prestep |\n| template | TestJobTemplateSpec | template specification of prestep |\n\n## TestJobTemplateSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| metadata | ObjectMeta | the metadata |\n| main | string | The main container name ( not sidecar container ). If used multiple containers, this parameter must be specified |\n| spec | TestJobPodSpec | specification of the desired behavior of the Pod for TestJob |\n\n## TestJobPodSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| volumes | []TestJobVolume | |\n| artifacts | []ArtifactSpec | |\n\nAnd all PodSpec fields.\n\n## ArtifactSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n| container | ArtifactContainer | |\n\n## ArtifactContainer\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | The name for the container |\n| path | string | The path to the artifact |\n\n## TestJobVolume\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n| repo | RepositoryVolumeSource | |\n| artifact | ArtifactVolumeSource | |\n| token | TokenVolumeSource | |\n\nAnd default volume types ( See: https://kubernetes.io/docs/concepts/storage/volumes/#volume-types )\n\n## RepositoryVolumeSource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n\n## ArtifactVolumeSource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n\n## TokenVolumeSource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n\n## ExportArtifact\n\n| field | type | description |\n| ---- | ---- | ---- |\n| name | string | |\n| path | string | |\n\n## LogSpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| extParam | Object | key/value pairs to add the result log |\n\n## Strategy\n\n| field | type | description |\n| ---- | ---- | ---- |\n| key | StrategyKeySpec | |\n| scheduler | Scheduler | |\n| retest | boolean | |\n\n## StrategyKeySpec\n\n| field | type | description |\n| ---- | ---- | ---- |\n| env | string | |\n| source | StrategyKeySource | |\n\n## StrategyKeySource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| static | []string | Array of distributed key names |\n| dynamic | StrategyDynamicKeySource | |\n\n## StrategyDynamicKeySource\n\n| field | type | description |\n| ---- | ---- | ---- |\n| template | TestJobTemplateSpec | |\n| delimiter | string | Delimiter for strategy keys ( default: new line character (`\\n`) ) |\n| filter | string | filter got strategy keys ( use regular expression ) |\n\n## Scheduler\n\n| field | type | description |\n| ---- | ---- | ---- |\n| maxContainersPerPod | number | |\n| maxConcurrentNumPerPod | number | |\n\n# Requirements\n\nThe ServiceAccount settings that need to be assigned to Pod that use the kubetest CLI is as follows.\n\n```yaml\nkind: ServiceAccount\napiVersion: v1\nmetadata:\n  name: kubetest\n---\nkind: Role\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n  name: kubetest\nrules:\n  - apiGroups:\n      - batch\n    resources:\n      - jobs\n    verbs:\n      - create\n      - delete\n  - apiGroups:\n      - \"\"\n    resources:\n      - pods\n    verbs:\n      - get\n      - list\n      - watch\n      - delete\n  - apiGroups:\n      - \"\"\n    resources:\n      - pods/log\n    verbs:\n      - get\n      - watch\n  - apiGroups:\n      - \"\"\n    resources:\n      - pods/exec\n    verbs:\n      - create\n  - apiGroups:\n      - \"\"\n    resources:\n      - secrets\n    verbs:\n      - get\n---\nkind: RoleBinding\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n  name: kubetest\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: kubetest\nsubjects:\n- kind: ServiceAccount\n  name: kubetest\n---\n```\n\n\n# How it works\n\nComing soon...\n\n# License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoccy%2Fkubetest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoccy%2Fkubetest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoccy%2Fkubetest/lists"}