├── .circleci └── config.yml ├── .dockerignore ├── .gitignore ├── .images ├── testsuite-yaml-addschema-intellij.png ├── testsuite-yaml-codecompletion.png └── testsuite-yaml-codevalidation.png ├── AlpineTest.Dockerfile ├── CHANGELOG.md ├── CentOSTest.Dockerfile ├── DOCKER_README.md ├── DOCUMENT.md ├── Dockerfile ├── FAQ.md ├── LICENSE ├── Makefile ├── README.md ├── cmd └── helm-unittest │ └── helm_unittest.go ├── docker-build.sh ├── go.mod ├── go.sum ├── install-binary.sh ├── internal ├── common │ ├── types.go │ └── utilities.go └── printer │ └── printer.go ├── pkg └── unittest │ ├── .snapshots │ ├── TestV2RunJobOk │ ├── TestV2RunJobWithAssertionFail │ ├── TestV2RunJobWithAssertionFailFast │ ├── TestV2RunJobWithCapabilitySettings │ ├── TestV2RunJobWithChartSettings │ ├── TestV2RunJobWithNOTESTemplateOk │ ├── TestV2RunJobWithNoCapabilitySettingsEmptyDoc │ ├── TestV2RunJobWithReleaseSettings │ ├── TestV2RunJobWithTestJobTemplateOk │ ├── TestV2RunJobWithTestJobTemplatesOk │ ├── TestV2RunJobWithTestMissingRequiredValueOk │ ├── TestV2RunJobWithValueSet │ ├── TestV2RunJobWithValuesFile │ ├── TestV2RunSuiteNameOverrideFail │ ├── TestV2RunSuiteWhenFail │ ├── TestV2RunSuiteWhenPass │ ├── TestV2RunSuiteWithMultipleTemplatesWhenPass │ ├── TestV2RunSuiteWithOverridesWhenPass │ ├── TestV2RunSuiteWithSubChartsWhenPass │ ├── TestV2RunSuiteWithSubChartsWithAliasWhenPass │ ├── TestV2RunSuiteWithSubfolderWhenPass │ ├── TestV2RunnerOkWithAbsoluteOverrideValuesPassedTests │ ├── TestV2RunnerOkWithFailedTests │ ├── TestV2RunnerOkWithOverrideValuesPassedTests │ ├── TestV2RunnerOkWithPassedTests │ ├── TestV2RunnerOkWithSubSubfolder │ ├── TestV2RunnerWithTestsInSubchart │ ├── TestV2RunnerWithTestsInSubchartButFlagFalse │ ├── TestV3RunJobOk │ ├── TestV3RunJobWithAssertionFail │ ├── TestV3RunJobWithAssertionFailFast │ ├── TestV3RunJobWithCapabilitySettings │ ├── TestV3RunJobWithChartSettings │ ├── TestV3RunJobWithFailingTemplate │ ├── TestV3RunJobWithNoCapabilitySettingsEmptyDoc │ ├── TestV3RunJobWithReleaseSettings │ ├── TestV3RunJobWithSchema │ ├── TestV3RunJobWithTestJobTemplateOk │ ├── TestV3RunJobWithTestJobTemplatesOk │ ├── TestV3RunJobWithTestMissingRequiredValueOk │ ├── TestV3RunJobWithTooLongReleaseName │ ├── TestV3RunJobWithValueSet │ ├── TestV3RunJobWithValuesFile │ ├── TestV3RunSuiteNameOverrideFail │ ├── TestV3RunSuiteWhenFail │ ├── TestV3RunSuiteWhenPass │ ├── TestV3RunSuiteWithMultipleTemplatesWhenPass │ ├── TestV3RunSuiteWithOverridesWhenPass │ ├── TestV3RunSuiteWithSubChartsWhenPass │ ├── TestV3RunSuiteWithSubChartsWithAliasWhenPass │ ├── TestV3RunSuiteWithSubfolderWhenPass │ ├── TestV3RunnerOkWithAbsoluteOverrideValuesPassedTests │ ├── TestV3RunnerOkWithFailedTests │ ├── TestV3RunnerOkWithFailingTemplatePassedTest │ ├── TestV3RunnerOkWithOverrideValuesPassedTests │ ├── TestV3RunnerOkWithPassedTests │ ├── TestV3RunnerOkWithSubSubChartsPassedTests │ ├── TestV3RunnerOkWithSubSubfolder │ ├── TestV3RunnerWithTestsInSubchart │ └── TestV3RunnerWithTestsInSubchartButFlagFalse │ ├── assertion.go │ ├── assertion_test.go │ ├── formatter │ ├── formatter.go │ ├── formatter_test.go │ ├── junit_report_xml.go │ ├── junit_report_xml_test.go │ ├── nunit_report_xml.go │ ├── nunit_report_xml_test.go │ ├── xunit_report_xml.go │ └── xunit_report_xml_test.go │ ├── results │ ├── assertion_result.go │ ├── test_job_result.go │ ├── test_suite_result.go │ └── test_suite_result_test.go │ ├── snapshot │ ├── cache.go │ ├── cache_test.go │ ├── factory.go │ └── factory_test.go │ ├── test_job.go │ ├── test_job_test.go │ ├── test_runner.go │ ├── test_runner_test.go │ ├── test_suite.go │ ├── test_suite_test.go │ ├── validators │ ├── common.go │ ├── common_test.go │ ├── contains_document_validator.go │ ├── contains_document_validator_test.go │ ├── contains_validator.go │ ├── contains_validator_test.go │ ├── equal_raw_validator.go │ ├── equal_raw_validator_test.go │ ├── equal_validator.go │ ├── equal_validator_test.go │ ├── failed_template_validator.go │ ├── failed_template_validator_test.go │ ├── has_document_validator.go │ ├── has_document_validator_test.go │ ├── is_apiversion_validator.go │ ├── is_apiversion_validator_test.go │ ├── is_empty_validator.go │ ├── is_empty_validator_test.go │ ├── is_kind_validator.go │ ├── is_kind_validator_test.go │ ├── is_null_validator.go │ ├── is_null_validator_test.go │ ├── is_subset_validator.go │ ├── is_subset_validator_test.go │ ├── length_equal_document_validator.go │ ├── length_equal_document_validator_test.go │ ├── match_regex_raw_validator.go │ ├── match_regex_raw_validator_test.go │ ├── match_regex_validator.go │ ├── match_regex_validator_test.go │ ├── snapshot_raw_validator.go │ ├── snapshot_raw_validator_test.go │ ├── snapshot_validator.go │ └── snapshot_validator_test.go │ └── valueutils │ ├── valueutils.go │ └── valueutils_test.go ├── plugin-dbg.yaml ├── plugin.yaml ├── schema └── helm-testsuite.json ├── sonar-project.properties └── test └── data ├── services_values.yaml ├── v2 ├── basic │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yaml │ │ ├── crd_backup.yaml │ │ ├── deployment.yaml │ │ ├── empty_deployment.yaml │ │ ├── ingress.yaml │ │ └── service.yaml │ ├── tests │ │ ├── __snapshot__ │ │ │ ├── deployment_test.yaml.snap │ │ │ └── notes_test.yaml.snap │ │ ├── configmap_test.yaml │ │ ├── crd_test.yaml │ │ ├── deployment_test.yaml │ │ ├── ingress_test.yaml │ │ ├── notes_test.yaml │ │ ├── service_test.yaml │ │ └── values │ │ │ └── image.yaml │ ├── tests_failed │ │ ├── __snapshot__ │ │ │ └── deployment_test.yaml.snap │ │ ├── configmap_test.yaml │ │ ├── deployment_test.yaml │ │ ├── empty_deployment_test.yaml │ │ ├── include_deployment_test.yaml │ │ ├── ingress_test.yaml │ │ ├── nofile_test.yaml │ │ ├── notes_test.yaml │ │ ├── service_test.yaml │ │ └── values │ │ │ └── image.yaml │ └── values.yaml ├── invalidbasic │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ └── deployment.yaml │ └── tests │ │ └── deployment_test.yaml ├── with-subchart │ ├── .helmignore │ ├── Chart.yaml │ ├── charts │ │ ├── child-chart │ │ │ ├── Chart.yaml │ │ │ ├── templates │ │ │ │ ├── NOTES.txt │ │ │ │ ├── _helpers.tpl │ │ │ │ ├── deployment.yaml │ │ │ │ ├── ingress.yaml │ │ │ │ └── service.yaml │ │ │ ├── tests │ │ │ │ ├── __snapshot__ │ │ │ │ │ ├── deployment_test.yaml.snap │ │ │ │ │ └── notes_test.yaml.snap │ │ │ │ ├── deployment_test.yaml │ │ │ │ ├── ingress_test.yaml │ │ │ │ ├── notes_test.yaml │ │ │ │ ├── service_test.yaml │ │ │ │ └── values │ │ │ │ │ └── image.yaml │ │ │ └── values.yaml │ │ ├── mysql-1.2.0.tgz │ │ ├── postgresql-0.8.3.tgz │ │ └── redis-10.5.7.tgz │ ├── requirements.lock │ ├── requirements.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ └── service.yaml │ ├── tests │ │ ├── __snapshot__ │ │ │ ├── deployment_test.yaml.snap │ │ │ ├── notes_test.yaml.snap │ │ │ └── postgresql_deployment_test.yaml.snap │ │ ├── deployment_test.yaml │ │ ├── ingress_test.yaml │ │ ├── notes_test.yaml │ │ ├── postgresql_deployment_test.yaml │ │ ├── service_test.yaml │ │ └── values │ │ │ └── image.yaml │ └── values.yaml └── with-subfolder │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── db │ │ └── deployment.yaml │ └── webserver │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ └── service.yaml │ ├── tests │ ├── __snapshot__ │ │ ├── deployment_test.yaml.snap │ │ └── notes_test.yaml.snap │ ├── deployment_test.yaml │ ├── ingress_test.yaml │ ├── notes_test.yaml │ ├── service_test.yaml │ └── values │ │ └── image.yaml │ └── values.yaml └── v3 ├── basic ├── .helmignore ├── Chart.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── configmap.yaml │ ├── crd_backup.yaml │ ├── deployment.yaml │ ├── empty_deployment.yaml │ ├── ingress.yaml │ └── service.yaml ├── tests │ ├── __snapshot__ │ │ ├── deployment_test.yaml.snap │ │ └── notes_test.yaml.snap │ ├── configmap_test.yaml │ ├── crd_test.yaml │ ├── deployment_test.yaml │ ├── ingress_test.yaml │ ├── notes_test.yaml │ ├── service_test.yaml │ └── values │ │ └── image.yaml ├── tests_failed │ ├── __snapshot__ │ │ └── deployment_test.yaml.snap │ ├── configmap_test.yaml │ ├── deployment_test.yaml │ ├── empty_deployment_test.yaml │ ├── include_deployment_test.yaml │ ├── ingress_test.yaml │ ├── nofile_test.yaml │ ├── notes_test.yaml │ ├── service_test.yaml │ └── values │ │ └── image.yaml └── values.yaml ├── failing-template ├── Chart.yaml ├── templates │ └── configMap.yaml └── tests │ └── configMap_test.yaml ├── invalidbasic ├── .helmignore ├── Chart.yaml ├── templates │ ├── _helpers.tpl │ └── deployment.yaml ├── tests │ └── deployment_test.yaml └── values.yaml ├── with-schema ├── Chart.yaml ├── templates │ └── dummy.yaml └── values.schema.json ├── with-subchart ├── .helmignore ├── Chart.lock ├── Chart.yaml ├── charts │ ├── child-chart │ │ ├── Chart.yaml │ │ ├── templates │ │ │ ├── NOTES.txt │ │ │ ├── _helpers.tpl │ │ │ ├── deployment.yaml │ │ │ ├── ingress.yaml │ │ │ └── service.yaml │ │ ├── tests │ │ │ ├── __snapshot__ │ │ │ │ ├── deployment_test.yaml.snap │ │ │ │ └── notes_test.yaml.snap │ │ │ ├── deployment_test.yaml │ │ │ ├── ingress_test.yaml │ │ │ ├── notes_test.yaml │ │ │ ├── service_test.yaml │ │ │ └── values │ │ │ │ └── image.yaml │ │ └── values.yaml │ └── postgresql-0.8.3.tgz ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── ingress.yaml │ └── service.yaml ├── tests │ ├── __snapshot__ │ │ ├── deployment_test.yaml.snap │ │ ├── notes_test.yaml.snap │ │ └── postgresql_deployment_test.yaml.snap │ ├── deployment_test.yaml │ ├── ingress_test.yaml │ ├── notes_test.yaml │ ├── postgresql_deployment_test.yaml │ ├── service_test.yaml │ └── values │ │ └── image.yaml └── values.yaml ├── with-subfolder ├── .helmignore ├── Chart.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── db │ │ └── deployment.yaml │ └── webserver │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ └── service.yaml ├── tests │ ├── __snapshot__ │ │ ├── deployment_test.yaml.snap │ │ └── notes_test.yaml.snap │ ├── deployment_test.yaml │ ├── ingress_test.yaml │ ├── notes_test.yaml │ ├── service_test.yaml │ └── values │ │ └── image.yaml └── values.yaml └── with-subsubcharts ├── Chart.yaml ├── README.md ├── charts └── example-subchart │ ├── Chart.yaml │ ├── charts │ └── example-sub-subchart │ │ ├── Chart.yaml │ │ ├── templates │ │ └── deployment.yaml │ │ └── values.yaml │ ├── templates │ └── deployment.yaml │ └── values.yaml ├── templates └── deployment.yaml ├── tests └── deployment_test.yaml └── values.yaml /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /.vscode 3 | 4 | _scratch 5 | tpl 6 | vendor/ 7 | _dist/ 8 | 9 | untt 10 | untt-dbg 11 | untt.exe 12 | untt-dbg.exe 13 | _dist 14 | 15 | .DS_Store 16 | 17 | .idea 18 | -------------------------------------------------------------------------------- /.images/testsuite-yaml-addschema-intellij.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/.images/testsuite-yaml-addschema-intellij.png -------------------------------------------------------------------------------- /.images/testsuite-yaml-codecompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/.images/testsuite-yaml-codecompletion.png -------------------------------------------------------------------------------- /.images/testsuite-yaml-codevalidation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/.images/testsuite-yaml-codevalidation.png -------------------------------------------------------------------------------- /AlpineTest.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3 2 | 3 | # variable "HELM_VERSION" and "PLUGIN_VERSION" must be passed as docker environment variables during the image build 4 | # docker build --no-cache --build-arg HELM_VERSION=3.3.0 -t alpine/helm-unittest:test -f AlpineTest.Dockerfile . 5 | 6 | ADD . ~ 7 | 8 | ARG HELM_VERSION 9 | 10 | ENV HELM_BASE_URL="https://get.helm.sh" 11 | ENV HELM_TAR_FILE="helm-v${HELM_VERSION}-linux-amd64.tar.gz" 12 | ENV PLUGIN_URL="~" 13 | # Install the plugin for all users 14 | ENV HELM_DATA_HOME=/usr/local/share/helm 15 | 16 | RUN if printf "$HELM_VERSION" | grep -Eq '^3.+'; then \ 17 | apk add --update --no-cache curl ca-certificates git && \ 18 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 19 | mv linux-amd64/helm /usr/bin/helm && \ 20 | chmod +x /usr/bin/helm && \ 21 | helm plugin install ${PLUGIN_URL} && \ 22 | rm -rf linux-amd64 && \ 23 | apk del curl git && \ 24 | rm -f /var/cache/apk/* ; \ 25 | else \ 26 | apk add --update --no-cache curl ca-certificates git && \ 27 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 28 | mv linux-amd64/helm /usr/bin/helm && \ 29 | chmod +x /usr/bin/helm && \ 30 | helm init --client-only && \ 31 | helm plugin install ${PLUGIN_URL} && \ 32 | rm -rf linux-amd64 && \ 33 | apk del curl git && \ 34 | rm -f /var/cache/apk/* ; \ 35 | fi 36 | 37 | WORKDIR /apps 38 | VOLUME [ "/apps" ] 39 | 40 | ENTRYPOINT ["helm", "unittest"] 41 | CMD ["--help"] -------------------------------------------------------------------------------- /CentOSTest.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | # variable "HELM_VERSION" must be passed as docker environment variables during the image build 4 | # docker build --no-cache --build-arg HELM_VERSION=3.3.0 -t centos/helm-unittest:test -f CentOSTest.Dockerfile . 5 | 6 | ADD . ~ 7 | 8 | ARG HELM_VERSION 9 | 10 | ENV HELM_BASE_URL="https://get.helm.sh" 11 | ENV HELM_TAR_FILE="helm-v${HELM_VERSION}-linux-amd64.tar.gz" 12 | ENV PLUGIN_URL="~" 13 | # Install the plugin for all users 14 | ENV HELM_DATA_HOME=/usr/local/share/helm 15 | 16 | RUN if printf "$HELM_VERSION" | grep -Eq '^3.+'; then \ 17 | yum install -y git && \ 18 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 19 | mv linux-amd64/helm /usr/bin/helm && \ 20 | chmod +x /usr/bin/helm && \ 21 | helm plugin install ${PLUGIN_URL} && \ 22 | rm -rf linux-amd64 && \ 23 | yum remove -y git && \ 24 | rm -rf /var/cache/yum/* ; \ 25 | else \ 26 | yum install -y git && \ 27 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 28 | mv linux-amd64/helm /usr/bin/helm && \ 29 | chmod +x /usr/bin/helm && \ 30 | helm init --client-only && \ 31 | helm plugin install ${PLUGIN_URL} && \ 32 | rm -rf linux-amd64 && \ 33 | yum remove -y git && \ 34 | rm -rf /var/cache/yum/* ; \ 35 | fi 36 | 37 | WORKDIR /apps 38 | VOLUME [ "/apps" ] 39 | 40 | ENTRYPOINT ["helm", "unittest"] 41 | CMD ["--help"] -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3 2 | 3 | # variable "HELM_VERSION" and "PLUGIN_VERSION" must be passed as docker environment variables during the image build 4 | # docker build --no-cache --build-arg HELM_VERSION=3.3.0 PLUGIN_VERSION=0.2.2 -t alpine/helm-unittest:3.3.0-0.2.2 . 5 | 6 | ARG HELM_VERSION 7 | ARG PLUGIN_VERSION 8 | 9 | ENV HELM_BASE_URL="https://get.helm.sh" 10 | ENV HELM_TAR_FILE="helm-v${HELM_VERSION}-linux-amd64.tar.gz" 11 | ENV PLUGIN_URL="https://github.com/quintush/helm-unittest/" 12 | # Install the plugin for all users 13 | ENV HELM_DATA_HOME=/usr/local/share/helm 14 | 15 | RUN if printf "$HELM_VERSION" | grep -Eq '^3.+'; then \ 16 | apk add --update --no-cache curl ca-certificates git bash && \ 17 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 18 | mv linux-amd64/helm /usr/bin/helm && \ 19 | chmod +x /usr/bin/helm && \ 20 | helm plugin install ${PLUGIN_URL} --version ${PLUGIN_VERSION} && \ 21 | rm -rf linux-amd64 && \ 22 | apk del curl git bash && \ 23 | rm -f /var/cache/apk/* ; \ 24 | else \ 25 | apk add --update --no-cache curl ca-certificates git bash && \ 26 | curl -L ${HELM_BASE_URL}/${HELM_TAR_FILE} |tar xvz && \ 27 | mv linux-amd64/helm /usr/bin/helm && \ 28 | chmod +x /usr/bin/helm && \ 29 | helm init --client-only && \ 30 | helm plugin install ${PLUGIN_URL} --version ${PLUGIN_VERSION} && \ 31 | rm -rf linux-amd64 && \ 32 | apk del curl git bash && \ 33 | rm -f /var/cache/apk/* ; \ 34 | fi 35 | 36 | WORKDIR /apps 37 | VOLUME [ "/apps" ] 38 | 39 | ENTRYPOINT ["helm", "unittest"] 40 | CMD ["--help"] -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ## Installation 4 | 5 | Q: **Is is possible to completely remove the plugin installation?**
6 | A: Yes. Using the below command you can uninstall the plugin from usage 7 | ``` 8 | $ helm plugin uninstall helm-unittest 9 | ``` 10 | After the plugin removal, make sure the plugin cache is also cleaned (or at least the folder which contains the unittest plugin). See https://helm.sh/docs/faq/#xdg-base-directory-support for more information to identify the cache location for Helm 2 and Helm 3. 11 | 12 | ## Debugging 13 | Q: **My test is failing but the expected and actual results are the same, what is happening?**
14 | A: The error output is formatted for better readabillity. The result of the formatting is that it removes spaces and line endings, which can result in the same values between the expected and actual results. 15 | With the debug option it is possible to see the the expected and actual content before the formatting is done. 16 | ``` 17 | $ helm helm-unittest ... -d 18 | ``` 19 | 20 | ## DevOps 21 | Q: **How can I setup the helm-unittest plugin in a build environment** 22 | A: The helm-unittest plugin has the options _-t, --output-type_ and _-o, --output-file_ which can be use to generate testresults in a file. Most of the Buildservers have a task that can upload the testresult into the server and generate a buildreport, or determine the success or failure of the tests. 23 | ``` 24 | $ helm helm-unittest ... -t JUnit -o junit-results.xml 25 | ``` 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Patrick Liu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /internal/common/types.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // K8sManifest type for rendered manifest unmarshaled to 4 | type K8sManifest map[string]interface{} 5 | 6 | // RAW the key value for making content parsable as K8sManifest 7 | const RAW string = "raw" 8 | -------------------------------------------------------------------------------- /internal/common/utilities.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import yaml "gopkg.in/yaml.v2" 4 | 5 | // TrustedMarshalYAML marshal yaml without error returned, if an error happens it panics 6 | func TrustedMarshalYAML(d interface{}) string { 7 | s, err := yaml.Marshal(d) 8 | if err != nil { 9 | panic(err) 10 | } 11 | return string(s) 12 | } 13 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=10) "matchRegex", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithAssertionFailFast: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) false, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) (len=13) { 10 | (string) (len=41) "Template:\tbasic/templates/deployment.yaml", 11 | (string) (len=16) "DocumentIndex:\t0", 12 | (string) (len=10) "Path:\tkind", 13 | (string) (len=18) "Expected to equal:", 14 | (string) (len=10) "\tWrongKind", 15 | (string) (len=7) "Actual:", 16 | (string) (len=11) "\tDeployment", 17 | (string) (len=5) "Diff:", 18 | (string) (len=13) "\t--- Expected", 19 | (string) (len=11) "\t+++ Actual", 20 | (string) (len=16) "\t@@ -1,2 +1,2 @@", 21 | (string) (len=11) "\t-WrongKind", 22 | (string) (len=12) "\t+Deployment" 23 | }, 24 | Passed: (bool) false, 25 | AssertType: (string) (len=5) "equal", 26 | Not: (bool) false, 27 | CustomInfo: (string) "" 28 | }) 29 | }, 30 | Duration: (time.Duration) 0s 31 | }) 32 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithCapabilitySettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=12) "hasDocuments", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithChartSettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=5) "equal", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithNOTESTemplateOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=8) "equalRaw", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=13) "matchRegexRaw", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithNoCapabilitySettingsEmptyDoc: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=12) "hasDocuments", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithReleaseSettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithTestJobTemplateOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=10) "matchRegex", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithTestJobTemplatesOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=3) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=5) "equal", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }), 25 | (*results.AssertionResult)({ 26 | Index: (int) 2, 27 | FailInfo: ([]string) { 28 | }, 29 | Passed: (bool) true, 30 | AssertType: (string) (len=9) "isNotNull", 31 | Not: (bool) false, 32 | CustomInfo: (string) "" 33 | }) 34 | }, 35 | Duration: (time.Duration) 0s 36 | }) 37 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithTestMissingRequiredValueOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=14) "failedTemplate", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithValueSet: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunJobWithValuesFile: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunSuiteNameOverrideFail: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=24) "test suite name too long", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=39) "should fail as nameOverride is too long", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=1) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=14) "failedTemplate", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }) 22 | }, 23 | Duration: (time.Duration) 0s 24 | }) 25 | }, 26 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 27 | Total: (uint) 0, 28 | Failed: (uint) 0, 29 | Created: (uint) 0, 30 | Vanished: (uint) 0 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunSuiteWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 2, 37 | Failed: (uint) 0, 38 | Created: (uint) 2, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunSuiteWithOverridesWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=12) "hasDocuments", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 1, 37 | Failed: (uint) 0, 38 | Created: (uint) 1, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunSuiteWithSubChartsWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=24) "test suite with subchart", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 1, 37 | Failed: (uint) 0, 38 | Created: (uint) 1, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunSuiteWithSubfolderWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 2, 37 | Failed: (uint) 0, 38 | Created: (uint) 2, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerOkWithAbsoluteOverrideValuesPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v2/basic 3 | 4 | 5 | PASS Configmap mulit line Test ../../test/data/v2/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v2/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v2/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v2/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v2/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v2/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerOkWithOverrideValuesPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v2/basic 3 | 4 | 5 | PASS Configmap mulit line Test ../../test/data/v2/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v2/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v2/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v2/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v2/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v2/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerOkWithPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v2/basic 3 | 4 | 5 | PASS Configmap mulit line Test ../../test/data/v2/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v2/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v2/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v2/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v2/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v2/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerOkWithSubSubfolder: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subfolder ] ../../test/data/v2/with-subfolder 3 | 4 | 5 | PASS test deployment ../../test/data/v2/with-subfolder/tests/deployment_test.yaml 6 | PASS test ingress ../../test/data/v2/with-subfolder/tests/ingress_test.yaml 7 | PASS test notes ../../test/data/v2/with-subfolder/tests/notes_test.yaml 8 | PASS test service ../../test/data/v2/with-subfolder/tests/service_test.yaml 9 | 10 | 11 | Charts: 1 passed, 1 total 12 | Test Suites: 4 passed, 4 total 13 | Tests: 13 passed, 13 total 14 | Snapshot: 5 passed, 5 total 15 | Time: XX.XXXms 16 | 17 | 18 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerWithTestsInSubchart: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subchart ] ../../test/data/v2/with-subchart 3 | 4 | 5 | PASS test deployment ../../test/data/v2/with-subchart/charts/child-chart/tests/deployment_test.yaml 6 | PASS test deployment ../../test/data/v2/with-subchart/tests/deployment_test.yaml 7 | PASS test ingress ../../test/data/v2/with-subchart/charts/child-chart/tests/ingress_test.yaml 8 | PASS test ingress ../../test/data/v2/with-subchart/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v2/with-subchart/charts/child-chart/tests/notes_test.yaml 10 | PASS test notes ../../test/data/v2/with-subchart/tests/notes_test.yaml 11 | PASS test postgresql deployment ../../test/data/v2/with-subchart/tests/postgresql_deployment_test.yaml 12 | PASS test service ../../test/data/v2/with-subchart/charts/child-chart/tests/service_test.yaml 13 | PASS test service ../../test/data/v2/with-subchart/tests/service_test.yaml 14 | 15 | 16 | Charts: 1 passed, 1 total 17 | Test Suites: 9 passed, 9 total 18 | Tests: 23 passed, 23 total 19 | Snapshot: 11 passed, 11 total 20 | Time: XX.XXXms 21 | 22 | 23 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV2RunnerWithTestsInSubchartButFlagFalse: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subchart ] ../../test/data/v2/with-subchart 3 | 4 | 5 | PASS test deployment ../../test/data/v2/with-subchart/tests/deployment_test.yaml 6 | PASS test ingress ../../test/data/v2/with-subchart/tests/ingress_test.yaml 7 | PASS test notes ../../test/data/v2/with-subchart/tests/notes_test.yaml 8 | PASS test postgresql deployment ../../test/data/v2/with-subchart/tests/postgresql_deployment_test.yaml 9 | PASS test service ../../test/data/v2/with-subchart/tests/service_test.yaml 10 | 11 | 12 | Charts: 1 passed, 1 total 13 | Test Suites: 5 passed, 5 total 14 | Tests: 13 passed, 13 total 15 | Snapshot: 7 passed, 7 total 16 | Time: XX.XXXms 17 | 18 | 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=10) "matchRegex", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithAssertionFailFast: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) false, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) (len=13) { 10 | (string) (len=41) "Template:\tbasic/templates/deployment.yaml", 11 | (string) (len=16) "DocumentIndex:\t0", 12 | (string) (len=10) "Path:\tkind", 13 | (string) (len=18) "Expected to equal:", 14 | (string) (len=10) "\tWrongKind", 15 | (string) (len=7) "Actual:", 16 | (string) (len=11) "\tDeployment", 17 | (string) (len=5) "Diff:", 18 | (string) (len=13) "\t--- Expected", 19 | (string) (len=11) "\t+++ Actual", 20 | (string) (len=16) "\t@@ -1,2 +1,2 @@", 21 | (string) (len=11) "\t-WrongKind", 22 | (string) (len=12) "\t+Deployment" 23 | }, 24 | Passed: (bool) false, 25 | AssertType: (string) (len=5) "equal", 26 | Not: (bool) false, 27 | CustomInfo: (string) "" 28 | }) 29 | }, 30 | Duration: (time.Duration) 0s 31 | }) 32 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithCapabilitySettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=12) "hasDocuments", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithChartSettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=5) "equal", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithFailingTemplate: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=14) "failedTemplate", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithNoCapabilitySettingsEmptyDoc: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=12) "hasDocuments", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithReleaseSettings: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithSchema: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (*errors.errorString)(values don't meet the specifications of the schema(s) in the following chart(s): 6 | with-schema: 7 | - (root): image is required 8 | ), 9 | AssertsResult: ([]*results.AssertionResult) (len=1) { 10 | (*results.AssertionResult)({ 11 | Index: (int) 0, 12 | FailInfo: ([]string) { 13 | }, 14 | Passed: (bool) true, 15 | AssertType: (string) (len=14) "failedTemplate", 16 | Not: (bool) false, 17 | CustomInfo: (string) "" 18 | }) 19 | }, 20 | Duration: (time.Duration) 0s 21 | }) 22 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithTestJobTemplateOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=2) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=10) "matchRegex", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }) 25 | }, 26 | Duration: (time.Duration) 0s 27 | }) 28 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithTestJobTemplatesOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=3) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }), 16 | (*results.AssertionResult)({ 17 | Index: (int) 1, 18 | FailInfo: ([]string) { 19 | }, 20 | Passed: (bool) true, 21 | AssertType: (string) (len=5) "equal", 22 | Not: (bool) false, 23 | CustomInfo: (string) "" 24 | }), 25 | (*results.AssertionResult)({ 26 | Index: (int) 2, 27 | FailInfo: ([]string) { 28 | }, 29 | Passed: (bool) true, 30 | AssertType: (string) (len=9) "isNotNull", 31 | Not: (bool) false, 32 | CustomInfo: (string) "" 33 | }) 34 | }, 35 | Duration: (time.Duration) 0s 36 | }) 37 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithTestMissingRequiredValueOk: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=14) "failedTemplate", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithTooLongReleaseName: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=19) "to long releasename", 3 | Index: (int) 0, 4 | Passed: (bool) false, 5 | ExecError: (*errors.errorString)(invalid release name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 53), 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) (len=2) { 10 | (string) (len=6) "Error:", 11 | (string) (len=84) "\ttemplate \"basic/templates/crd_backup.yaml\" not exists or not selected in test suite" 12 | }, 13 | Passed: (bool) false, 14 | AssertType: (string) (len=12) "hasDocuments", 15 | Not: (bool) false, 16 | CustomInfo: (string) "" 17 | }) 18 | }, 19 | Duration: (time.Duration) 0s 20 | }) 21 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithValueSet: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunJobWithValuesFile: -------------------------------------------------------------------------------- 1 | (*results.TestJobResult)({ 2 | DisplayName: (string) (len=11) "should work", 3 | Index: (int) 0, 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | AssertsResult: ([]*results.AssertionResult) (len=1) { 7 | (*results.AssertionResult)({ 8 | Index: (int) 0, 9 | FailInfo: ([]string) { 10 | }, 11 | Passed: (bool) true, 12 | AssertType: (string) (len=5) "equal", 13 | Not: (bool) false, 14 | CustomInfo: (string) "" 15 | }) 16 | }, 17 | Duration: (time.Duration) 0s 18 | }) 19 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunSuiteNameOverrideFail: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=24) "test suite name too long", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=39) "should fail as nameOverride is too long", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=1) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=14) "failedTemplate", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }) 22 | }, 23 | Duration: (time.Duration) 0s 24 | }) 25 | }, 26 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 27 | Total: (uint) 0, 28 | Failed: (uint) 0, 29 | Created: (uint) 0, 30 | Vanished: (uint) 0 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunSuiteWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 2, 37 | Failed: (uint) 0, 38 | Created: (uint) 2, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunSuiteWithOverridesWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=12) "hasDocuments", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 1, 37 | Failed: (uint) 0, 38 | Created: (uint) 1, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunSuiteWithSubChartsWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=24) "test suite with subchart", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 1, 37 | Failed: (uint) 0, 38 | Created: (uint) 1, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunSuiteWithSubfolderWhenPass: -------------------------------------------------------------------------------- 1 | (*results.TestSuiteResult)({ 2 | DisplayName: (string) (len=15) "test suite name", 3 | FilePath: (string) "", 4 | Passed: (bool) true, 5 | ExecError: (error) , 6 | TestsResult: ([]*results.TestJobResult) (len=1) { 7 | (*results.TestJobResult)({ 8 | DisplayName: (string) (len=11) "should pass", 9 | Index: (int) 0, 10 | Passed: (bool) true, 11 | ExecError: (error) , 12 | AssertsResult: ([]*results.AssertionResult) (len=2) { 13 | (*results.AssertionResult)({ 14 | Index: (int) 0, 15 | FailInfo: ([]string) { 16 | }, 17 | Passed: (bool) true, 18 | AssertType: (string) (len=5) "equal", 19 | Not: (bool) false, 20 | CustomInfo: (string) "" 21 | }), 22 | (*results.AssertionResult)({ 23 | Index: (int) 1, 24 | FailInfo: ([]string) { 25 | }, 26 | Passed: (bool) true, 27 | AssertType: (string) (len=13) "matchSnapshot", 28 | Not: (bool) false, 29 | CustomInfo: (string) "" 30 | }) 31 | }, 32 | Duration: (time.Duration) 0s 33 | }) 34 | }, 35 | SnapshotCounting: (struct { Total uint; Failed uint; Created uint; Vanished uint }) { 36 | Total: (uint) 2, 37 | Failed: (uint) 0, 38 | Created: (uint) 2, 39 | Vanished: (uint) 0 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithAbsoluteOverrideValuesPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v3/basic 3 | 4 | 5 | PASS Configmap multiline Test ../../test/data/v3/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v3/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v3/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v3/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v3/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v3/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithFailingTemplatePassedTest: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ failing-template ] ../../test/data/v3/failing-template 3 | 4 | 5 | PASS Test failing template ../../test/data/v3/failing-template/tests/configMap_test.yaml 6 | 7 | 8 | Charts: 1 passed, 1 total 9 | Test Suites: 1 passed, 1 total 10 | Tests: 1 passed, 1 total 11 | Snapshot: 0 passed, 0 total 12 | Time: XX.XXXms 13 | 14 | 15 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithOverrideValuesPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v3/basic 3 | 4 | 5 | PASS Configmap multiline Test ../../test/data/v3/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v3/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v3/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v3/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v3/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v3/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ basic ] ../../test/data/v3/basic 3 | 4 | 5 | PASS Configmap multiline Test ../../test/data/v3/basic/tests/configmap_test.yaml 6 | PASS Custom Resource Definition Test ../../test/data/v3/basic/tests/crd_test.yaml 7 | PASS test deployment ../../test/data/v3/basic/tests/deployment_test.yaml 8 | PASS test ingress ../../test/data/v3/basic/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v3/basic/tests/notes_test.yaml 10 | PASS test service ../../test/data/v3/basic/tests/service_test.yaml 11 | 12 | 13 | Charts: 1 passed, 1 total 14 | Test Suites: 6 passed, 6 total 15 | Tests: 15 passed, 15 total 16 | Snapshot: 4 passed, 4 total 17 | Time: XX.XXXms 18 | 19 | 20 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithSubSubChartsPassedTests: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subsubcharts ] ../../test/data/v3/with-subsubcharts 3 | 4 | 5 | PASS ../../test/data/v3/with-subsubcharts/tests/deployment_test.yaml 6 | 7 | 8 | Charts: 1 passed, 1 total 9 | Test Suites: 1 passed, 1 total 10 | Tests: 3 passed, 3 total 11 | Snapshot: 0 passed, 0 total 12 | Time: XX.XXXms 13 | 14 | 15 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerOkWithSubSubfolder: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subfolder ] ../../test/data/v3/with-subfolder 3 | 4 | 5 | PASS test deployment ../../test/data/v3/with-subfolder/tests/deployment_test.yaml 6 | PASS test ingress ../../test/data/v3/with-subfolder/tests/ingress_test.yaml 7 | PASS test notes ../../test/data/v3/with-subfolder/tests/notes_test.yaml 8 | PASS test service ../../test/data/v3/with-subfolder/tests/service_test.yaml 9 | 10 | 11 | Charts: 1 passed, 1 total 12 | Test Suites: 4 passed, 4 total 13 | Tests: 13 passed, 13 total 14 | Snapshot: 5 passed, 5 total 15 | Time: XX.XXXms 16 | 17 | 18 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerWithTestsInSubchart: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subchart ] ../../test/data/v3/with-subchart 3 | 4 | 5 | PASS test deployment ../../test/data/v3/with-subchart/charts/child-chart/tests/deployment_test.yaml 6 | PASS test deployment ../../test/data/v3/with-subchart/tests/deployment_test.yaml 7 | PASS test ingress ../../test/data/v3/with-subchart/charts/child-chart/tests/ingress_test.yaml 8 | PASS test ingress ../../test/data/v3/with-subchart/tests/ingress_test.yaml 9 | PASS test notes ../../test/data/v3/with-subchart/charts/child-chart/tests/notes_test.yaml 10 | PASS test notes ../../test/data/v3/with-subchart/tests/notes_test.yaml 11 | PASS test postgresql deployment ../../test/data/v3/with-subchart/tests/postgresql_deployment_test.yaml 12 | PASS test service ../../test/data/v3/with-subchart/charts/child-chart/tests/service_test.yaml 13 | PASS test service ../../test/data/v3/with-subchart/tests/service_test.yaml 14 | 15 | 16 | Charts: 1 passed, 1 total 17 | Test Suites: 9 passed, 9 total 18 | Tests: 21 passed, 21 total 19 | Snapshot: 9 passed, 9 total 20 | Time: XX.XXXms 21 | 22 | 23 | -------------------------------------------------------------------------------- /pkg/unittest/.snapshots/TestV3RunnerWithTestsInSubchartButFlagFalse: -------------------------------------------------------------------------------- 1 | 2 | ### Chart [ with-subchart ] ../../test/data/v3/with-subchart 3 | 4 | 5 | PASS test deployment ../../test/data/v3/with-subchart/tests/deployment_test.yaml 6 | PASS test ingress ../../test/data/v3/with-subchart/tests/ingress_test.yaml 7 | PASS test notes ../../test/data/v3/with-subchart/tests/notes_test.yaml 8 | PASS test postgresql deployment ../../test/data/v3/with-subchart/tests/postgresql_deployment_test.yaml 9 | PASS test service ../../test/data/v3/with-subchart/tests/service_test.yaml 10 | 11 | 12 | Charts: 1 passed, 1 total 13 | Test Suites: 5 passed, 5 total 14 | Tests: 11 passed, 11 total 15 | Snapshot: 5 passed, 5 total 16 | Time: XX.XXXms 17 | 18 | 19 | -------------------------------------------------------------------------------- /pkg/unittest/results/assertion_result.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lrills/helm-unittest/internal/printer" 7 | ) 8 | 9 | // AssertionResult result return by Assertion.Assert 10 | type AssertionResult struct { 11 | Index int 12 | FailInfo []string 13 | Passed bool 14 | AssertType string 15 | Not bool 16 | CustomInfo string 17 | } 18 | 19 | func (ar AssertionResult) print(printer *printer.Printer, verbosity int) { 20 | if ar.Passed { 21 | return 22 | } 23 | 24 | printer.Println(printer.Danger(ar.getTitle()), 2) 25 | for _, infoLine := range ar.FailInfo { 26 | printer.Println(infoLine, 3) 27 | } 28 | printer.Println("", 0) 29 | } 30 | 31 | func (ar AssertionResult) getTitle() string { 32 | var title string 33 | if ar.CustomInfo != "" { 34 | title = ar.CustomInfo 35 | } else { 36 | var notAnnotation string 37 | if ar.Not { 38 | notAnnotation = " NOT" 39 | } 40 | title = fmt.Sprintf("- asserts[%d]%s `%s` fail", ar.Index, notAnnotation, ar.AssertType) 41 | } 42 | return title 43 | } 44 | 45 | // ToString writing the object to a customized formatted string. 46 | func (ar AssertionResult) stringify() string { 47 | content := fmt.Sprintf("\t\t %s \n", ar.getTitle()) 48 | 49 | for _, infoLine := range ar.FailInfo { 50 | content += fmt.Sprintf("\t\t\t %s \n", infoLine) 51 | } 52 | 53 | return content 54 | } 55 | -------------------------------------------------------------------------------- /pkg/unittest/results/test_job_result.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/lrills/helm-unittest/internal/printer" 7 | ) 8 | 9 | // TestJobResult result return by TestJob.Run 10 | type TestJobResult struct { 11 | DisplayName string 12 | Index int 13 | Passed bool 14 | ExecError error 15 | AssertsResult []*AssertionResult 16 | Duration time.Duration 17 | } 18 | 19 | func (tjr TestJobResult) print(printer *printer.Printer, verbosity int) { 20 | if tjr.Passed { 21 | return 22 | } 23 | 24 | if tjr.ExecError != nil { 25 | printer.Println(printer.Highlight("- "+tjr.DisplayName), 1) 26 | printer.Println( 27 | printer.Highlight("Error: ")+ 28 | tjr.ExecError.Error()+"\n", 29 | 2, 30 | ) 31 | return 32 | } 33 | 34 | printer.Println(printer.Danger("- "+tjr.DisplayName+"\n"), 1) 35 | for _, assertResult := range tjr.AssertsResult { 36 | assertResult.print(printer, verbosity) 37 | } 38 | } 39 | 40 | // Stringify writing the object to a customized formatted string. 41 | func (tjr TestJobResult) Stringify() string { 42 | content := "" 43 | if tjr.ExecError != nil { 44 | content += tjr.ExecError.Error() + "\n" 45 | } 46 | 47 | for _, assertResult := range tjr.AssertsResult { 48 | content += assertResult.stringify() 49 | } 50 | 51 | return content 52 | } 53 | -------------------------------------------------------------------------------- /pkg/unittest/snapshot/factory.go: -------------------------------------------------------------------------------- 1 | package snapshot 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | const snapshotDirName = "__snapshot__" 10 | const snapshotFileExt = ".snap" 11 | 12 | // CreateSnapshotOfSuite retruns snapshot.Cache for suite file, create `__snapshot__` dir if not existed 13 | func CreateSnapshotOfSuite(path string, isUpdating bool) (*Cache, error) { 14 | cacheDir := filepath.Join(filepath.Dir(path), snapshotDirName) 15 | if err := ensureDir(cacheDir); err != nil { 16 | return nil, err 17 | } 18 | cacheFileName := filepath.Base(path) + snapshotFileExt 19 | cache := &Cache{ 20 | Filepath: filepath.Join(cacheDir, cacheFileName), 21 | IsUpdating: isUpdating, 22 | } 23 | 24 | if err := cache.RestoreFromFile(); err != nil { 25 | return nil, err 26 | } 27 | return cache, nil 28 | } 29 | 30 | func ensureDir(path string) error { 31 | info, err := os.Stat(path) 32 | if err != nil { 33 | if os.IsNotExist(err) { 34 | return os.Mkdir(path, os.ModePerm) 35 | } 36 | return err 37 | } 38 | 39 | if !info.IsDir() { 40 | return fmt.Errorf("snapshot cache dir %s is not a directory", path) 41 | } 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/unittest/validators/common_test.go: -------------------------------------------------------------------------------- 1 | package validators_test 2 | 3 | import ( 4 | "github.com/lrills/helm-unittest/internal/common" 5 | "github.com/lrills/helm-unittest/pkg/unittest/snapshot" 6 | "github.com/stretchr/testify/mock" 7 | yaml "gopkg.in/yaml.v2" 8 | ) 9 | 10 | func makeManifest(doc string) common.K8sManifest { 11 | manifest := common.K8sManifest{} 12 | yaml.Unmarshal([]byte(doc), &manifest) 13 | return manifest 14 | } 15 | 16 | type mockSnapshotComparer struct { 17 | mock.Mock 18 | } 19 | 20 | func (m *mockSnapshotComparer) CompareToSnapshot(content interface{}) *snapshot.CompareResult { 21 | args := m.Called(content) 22 | return args.Get(0).(*snapshot.CompareResult) 23 | } 24 | -------------------------------------------------------------------------------- /pkg/unittest/validators/has_document_validator.go: -------------------------------------------------------------------------------- 1 | package validators 2 | 3 | import ( 4 | "strconv" 5 | 6 | log "github.com/sirupsen/logrus" 7 | ) 8 | 9 | // HasDocumentsValidator validate whether the count of manifests rendered form template is Count 10 | type HasDocumentsValidator struct { 11 | Count int 12 | } 13 | 14 | func (v HasDocumentsValidator) failInfo(actual int, not bool) []string { 15 | expectedCount := strconv.Itoa(v.Count) 16 | actualCount := strconv.Itoa(actual) 17 | customMessage := " documents count to be" 18 | 19 | log.WithField("validator", "has_document").Debugln("expected content:", expectedCount) 20 | log.WithField("validator", "has_document").Debugln("actual content:", actualCount) 21 | 22 | if not { 23 | return splitInfof( 24 | setFailFormat(not, false, false, false, customMessage), 25 | -1, 26 | expectedCount, 27 | ) 28 | } 29 | return splitInfof( 30 | setFailFormat(not, false, true, false, customMessage), 31 | -1, 32 | expectedCount, 33 | actualCount, 34 | ) 35 | } 36 | 37 | // Validate implement Validatable 38 | func (v HasDocumentsValidator) Validate(context *ValidateContext) (bool, []string) { 39 | if len(context.Docs) == v.Count != context.Negative { 40 | return true, []string{} 41 | } 42 | return false, v.failInfo(len(context.Docs), context.Negative) 43 | } 44 | -------------------------------------------------------------------------------- /plugin-dbg.yaml: -------------------------------------------------------------------------------- 1 | name: "unittest" 2 | version: "0.3.1" 3 | usage: "unittest for helm charts" 4 | description: "Unit test for helm chart in YAML with ease to keep your chart functional and robust." 5 | ignoreFlags: false 6 | command: "dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec $HELM_PLUGIN_DIR/untt-dbg -- " 7 | hooks: 8 | install: "cd $HELM_PLUGIN_DIR; ./install-binary.sh" 9 | update: "cd $HELM_PLUGIN_DIR; HELM_PLUGIN_UPDATE=1 ./install-binary.sh" 10 | -------------------------------------------------------------------------------- /plugin.yaml: -------------------------------------------------------------------------------- 1 | name: "unittest" 2 | version: "0.3.1" 3 | usage: "unittest for helm charts" 4 | description: "Unit test for helm chart in YAML with ease to keep your chart functional and robust." 5 | ignoreFlags: false 6 | command: "$HELM_PLUGIN_DIR/untt" 7 | hooks: 8 | install: "cd $HELM_PLUGIN_DIR; ./install-binary.sh" 9 | update: "cd $HELM_PLUGIN_DIR; HELM_PLUGIN_UPDATE=1 ./install-binary.sh" 10 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=quintush_helm-unittest 2 | sonar.organization=quintush 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | sonar.projectName=helm-unittest 6 | sonar.projectVersion=0.2.11 7 | 8 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 9 | # Define all sources and exclude test-, and vendor files. 10 | sonar.sources=. 11 | sonar.exclusions=**/*_test.go,**/vendor/** 12 | 13 | # Define all test sources and exclude vendor file from testing. 14 | sonar.tests=. 15 | sonar.test.inclusions=**/*_test.go 16 | sonar.test.exclusions=**/vendor/** 17 | 18 | # Encoding of the source code. Default is default system encoding 19 | sonar.sourceEncoding=UTF-8 20 | 21 | # Setup code coverage report path 22 | sonar.go.coverage.reportPaths=/tmp/coverage 23 | -------------------------------------------------------------------------------- /test/data/services_values.yaml: -------------------------------------------------------------------------------- 1 | 2 | service: 3 | type: NodePort 4 | -------------------------------------------------------------------------------- /test/data/v2/basic/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v2/basic/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A basic example chart to demonstrate unittest plugin 3 | name: basic 4 | version: 0.1.0 5 | appVersion: 1.0.0 6 | -------------------------------------------------------------------------------- /test/data/v2/basic/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "basic.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "basic.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "basic.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "basic.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v2/basic/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Check max override length. 4 | */}} 5 | {{- define "basic.checkNameOverrideLength" -}} 6 | {{- if .Values.nameOverride -}} 7 | {{- if gt (len .Values.nameOverride) 20 -}} 8 | {{- fail "nameOverride cannot be longer than 20 characters" -}} 9 | {{- end -}} 10 | {{- end -}} 11 | {{- end -}} 12 | 13 | {{/* 14 | Expand the name of the chart. 15 | */}} 16 | {{- define "basic.name" -}} 17 | {{- include "basic.checkNameOverrideLength" . -}} 18 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 19 | {{- end -}} 20 | 21 | {{/* 22 | Create a default fully qualified app name. 23 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 24 | */}} 25 | {{- define "basic.fullname" -}} 26 | {{- $name := default .Chart.Name .Values.nameOverride -}} 27 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 28 | {{- end -}} 29 | -------------------------------------------------------------------------------- /test/data/v2/basic/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "basic.fullname" . }} 5 | labels: 6 | app: {{ template "basic.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | data: 11 | my.conf: | 12 | {{- if .Values.expose }} 13 | cacertfile = /etc/cert/cacert.pem 14 | certfile = /etc/cert/tls.crt 15 | keyfile = /etc/cert/tls.key 16 | verify = verify_none 17 | {{- end }} 18 | abc = qqq 19 | qqq = abc 20 | my.array: 21 | - value1 22 | - value2 -------------------------------------------------------------------------------- /test/data/v2/basic/templates/crd_backup.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (and (eq .Capabilities.KubeVersion.Major "1") (eq .Capabilities.KubeVersion.Minor "12")) (.Capabilities.APIVersions.Has "br.dev.local/v1") }} 2 | apiVersion: "br.dev.local/v1" 3 | kind: BrPolicy 4 | metadata: 5 | name: {{ template "basic.fullname" . }}-backuppolicy 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: {{ template "basic.fullname" . }} 10 | type: myserver 11 | volumes: 12 | - datadir 13 | {{- end }} -------------------------------------------------------------------------------- /test/data/v2/basic/templates/empty_deployment.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v2/basic/templates/empty_deployment.yaml -------------------------------------------------------------------------------- /test/data/v2/basic/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "basic.fullname" . -}} 3 | {{- $servicePort := required "The externalPort is required" .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "basic.fullname" . }} 8 | labels: 9 | app: {{ template "basic.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | {{- range $key, $value := .Values.ingress.annotations }} 15 | {{ $key }}: {{ $value | quote }} 16 | {{- end }} 17 | spec: 18 | rules: 19 | {{- range $host := .Values.ingress.hosts }} 20 | - host: {{ $host }} 21 | http: 22 | paths: 23 | - path: / 24 | backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | {{- end -}} 28 | {{- if .Values.ingress.tls }} 29 | tls: 30 | {{ toYaml .Values.ingress.tls | indent 4 }} 31 | {{- end -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /test/data/v2/basic/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "basic.fullname" . }} 5 | labels: 6 | app: {{ template "basic.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "basic.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: basic 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: basic 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-basic' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-basic -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-basic) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests/configmap_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Configmap mulit line Test 2 | templates: 3 | - configmap.yaml 4 | tests: 5 | - it: should NOT configure ssl params if NOT set to be exposed 6 | asserts: 7 | - notMatchRegex: 8 | path: data.my\.conf 9 | pattern: cacertfile 10 | - contains: 11 | path: data.my\.array 12 | content: value1 -------------------------------------------------------------------------------- /test/data/v2/basic/tests/crd_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Custom Resource Definition Test 2 | templates: 3 | - crd_backup.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | release: 7 | name: my-release 8 | capabilities: 9 | majorVersion: 1 10 | minorVersion: 12 11 | apiVersions: 12 | - br.dev.local/v1 13 | asserts: 14 | - isKind: 15 | of: BrPolicy 16 | - isAPIVersion: 17 | of: br.dev.local/v1 18 | - equal: 19 | path: metadata.name 20 | value: my-release-basic-backuppolicy 21 | - hasDocuments: 22 | count: 1 23 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-basic) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | set: 9 | service: 10 | type: ClusterIP 11 | asserts: 12 | - contains: 13 | path: spec.ports 14 | content: 15 | port: 80 16 | targetPort: 80 17 | protocol: TCP 18 | name: nginx 19 | - equal: 20 | path: spec.type 21 | value: ClusterIP 22 | - equal: 23 | path: spec.selector 24 | value: 25 | app: basic 26 | release: my-release 27 | 28 | - it: should render right if values given 29 | set: 30 | service: 31 | type: NodePort 32 | internalPort: 1234 33 | externalPort: 4321 34 | name: cool-service 35 | asserts: 36 | - contains: 37 | path: spec.ports 38 | content: 39 | port: 4321 40 | targetPort: 1234 41 | protocol: TCP 42 | name: cool-service 43 | - equal: 44 | path: spec.type 45 | value: NodePort -------------------------------------------------------------------------------- /test/data/v2/basic/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should fail all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: basic 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: basic 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | 2: | 26 | replicas: 1 27 | template: 28 | metadata: 29 | annotations: 30 | some_template: | 31 | --- 32 | apiVersion: ... 33 | this: is test for old separator workaround bug 34 | labels: 35 | app: basic 36 | release: RELEASE-NAME 37 | spec: 38 | containers: 39 | - image: apache:latest 40 | imagePullPolicy: Always 41 | name: basic 42 | ports: 43 | - containerPort: null 44 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/configmap_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Configmap mulit line Test 2 | templates: 3 | - configmap.yaml 4 | tests: 5 | - it: should NOT configure ssl params if NOT set to be exposed 6 | asserts: 7 | - matchRegex: 8 | path: data.my\.conf 9 | pattern: cacertfile 10 | - contains: 11 | path: data.my\.array 12 | content: 'value1' 13 | count: -1 14 | - contains: 15 | path: data.my\.array 16 | content: 'value2' 17 | count: 8.9 18 | - contains: 19 | path: data.my\.array 20 | content: 'value1' 21 | count: 1234578901234567890 22 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/empty_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - empty_deployment.yaml 4 | tests: 5 | - it: should fail 6 | asserts: 7 | - isKind: 8 | of: Deployment -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/include_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment that would be fail 2 | values: 3 | - ./values/image.yaml 4 | templates: 5 | - deployment.yaml 6 | tests: 7 | - it: should fail all kinds of assertion 8 | set: 9 | service.internalPort: 8080 10 | asserts: 11 | - equal: 12 | path: spec.template.spec.containers[0].image 13 | value: nginx:stable 14 | - notEqual: 15 | path: spec.template.spec.containers[0].image 16 | value: apache:latest 17 | - matchRegex: 18 | path: metadata.name 19 | pattern: ^.*-foobar$ 20 | - notMatchRegex: 21 | path: metadata.name 22 | pattern: ^.*-basic$ 23 | - contains: 24 | path: spec.template.spec.containers[0].ports 25 | content: 26 | containerPort: 80 27 | - notContains: 28 | path: spec.template.spec.containers[0].ports 29 | content: 30 | containerPort: 8080 31 | - isNull: 32 | path: spec.template 33 | - isNotNull: 34 | path: spec.template.nodeSelector 35 | - isEmpty: 36 | path: spec.template.spec.containers[0] 37 | - isNotEmpty: 38 | path: spec.template.spec.containers[0].resources 39 | - isKind: 40 | of: Pod 41 | - isAPIVersion: 42 | of: v2 43 | - hasDocuments: 44 | count: 1 45 | - matchSnapshot: 46 | path: spec 47 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/ingress_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test ingress that should fail 2 | templates: 3 | - ingress.yaml 4 | tests: 5 | - it: should fail render nothing if not enabled 6 | asserts: 7 | - hasDocuments: 8 | count: 1 9 | 10 | - it: should fail render ingress right if enabled 11 | set: 12 | ingress.enabled: true 13 | service.externalPort: 12345 14 | release: 15 | name: my-release 16 | asserts: 17 | - contains: 18 | path: spec.rules[0].http.paths 19 | content: 20 | path: / 21 | backend: 22 | serviceName: my-release-basic 23 | servicePort: 54321 24 | - isNotNull: 25 | path: spec.tls 26 | 27 | - it: should fail set annotations if given 28 | set: 29 | ingress.enabled: true 30 | ingress.annotations: 31 | kubernetes.io/ingress.class: nginx 32 | kubernetes.io/tls-acme: "true" 33 | ingress.kubernetes.io/rewrite-target: / 34 | release: 35 | name: my-release 36 | asserts: 37 | - isEmpty: 38 | path: metadata.annotations 39 | 40 | - it: should fail set tls if given 41 | set: 42 | ingress.enabled: true 43 | 44 | release: 45 | name: my-release 46 | asserts: 47 | - equal: 48 | path: spec.tls 49 | value: 50 | - secretName: my-tls-secret 51 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should fail the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - notEqualRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | 14 | - it: should fail the notes file with service type NodePort 15 | set: 16 | service.type: NodePort 17 | asserts: 18 | - equalRaw: 19 | value: | 20 | 1. Get the application URL by running these commands: 21 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services MY-RELEASE) 22 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 23 | echo http://$NODE_IP:$NODE_PORT 24 | 25 | - it: should fail the notes file with service type LoadBalancer 26 | set: 27 | service.type: LoadBalancer 28 | service.externalPort: 9999 29 | asserts: 30 | - matchRegexRaw: 31 | pattern: http://\$SERVICE_IP:80 32 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should failed 6 | release: 7 | name: my-release 8 | asserts: 9 | - notContains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - notEqual: 17 | path: spec.type 18 | value: ClusterIP 19 | - notEqual: 20 | path: spec.selector 21 | value: 22 | app: basic 23 | release: my-release 24 | 25 | - it: should fail renders right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - notContains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - notEqual: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v2/basic/tests_failed/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v2/basic/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: foo 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | annotations: 21 | # kubernetes.io/ingress.class: nginx 22 | # kubernetes.io/tls-acme: "true" 23 | tls: 24 | # Secrets must be manually created in the namespace. 25 | # - secretName: chart-example-tls 26 | # hosts: 27 | # - chart-example.local 28 | resources: {} 29 | # We usually recommend not to specify default resources and to leave this as a conscious 30 | # choice for the user. This also increases chances charts run on environments with little 31 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 32 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 33 | # limits: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | # requests: 37 | # cpu: 100m 38 | # memory: 128Mi 39 | -------------------------------------------------------------------------------- /test/data/v2/invalidbasic/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v2/invalidbasic/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A basic example chart to demonstrate unittest plugin 3 | name: basic 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v2/invalidbasic/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Check max override length. 4 | */}} 5 | {{- define "basic.checkNameOverrideLength" -}} 6 | {{- if .Values.nameOverride -}} 7 | {{- if gt (len .Values.nameOverride) 20 -}} 8 | {{- fail "nameOverride cannot be longer than 20 characters" -}} 9 | {{- end -}} 10 | {{- end -}} 11 | {{- end -}} 12 | 13 | {{/* 14 | Expand the name of the chart. 15 | */}} 16 | {{- define "basic.name" -}} 17 | {{- include "basic.checkNameOverrideLength" . -}} 18 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 19 | {{- end -}} 20 | 21 | {{/* 22 | Create a default fully qualified app name. 23 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 24 | */}} 25 | {{- define "basic.fullname" -}} 26 | {{- $name := default .Chart.Name .Values.nameOverride -}} 27 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 28 | {{- end -}} 29 | -------------------------------------------------------------------------------- /test/data/v2/invalidbasic/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | documentIndex: 0 7 | documentIndex: 0 8 | asserts: 9 | - equal: 10 | path: spec.template.spec.containers[0].image 11 | value: apache:latest 12 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: An example chart with customized subchart 3 | name: with-subchart 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: An customized subchart 3 | name: child-chart 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "child-chart.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "child-chart.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "child-chart.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "child-chart.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "child-chart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "child-chart.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | 18 | {{- define "child-chart.ingressClass" -}} 19 | {{- $ingressClass := .Values.ingress.class -}} 20 | {{- if .Values.global -}} 21 | {{- if .Values.global.ingressClass -}} 22 | {{- $ingressClass = .Values.global.ingressClass -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- printf "%s" $ingressClass -}} 26 | {{- end -}} 27 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "child-chart.fullname" . }} 5 | labels: 6 | app: {{ template "child-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "child-chart.name" . }} 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | ports: 23 | - containerPort: {{ .Values.service.internalPort }} 24 | livenessProbe: 25 | httpGet: 26 | path: / 27 | port: {{ .Values.service.internalPort }} 28 | readinessProbe: 29 | httpGet: 30 | path: / 31 | port: {{ .Values.service.internalPort }} 32 | resources: 33 | {{ toYaml .Values.resources | indent 12 }} 34 | {{- if .Values.nodeSelector }} 35 | nodeSelector: 36 | {{ toYaml .Values.nodeSelector | indent 8 }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "child-chart.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "child-chart.fullname" . }} 8 | labels: 9 | app: {{ template "child-chart.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | kubernetes.io/ingress.class: {{ template "child-chart.ingressClass" . }} 15 | spec: 16 | rules: 17 | {{- range $host := .Values.ingress.hosts }} 18 | - host: {{ $host }} 19 | http: 20 | paths: 21 | - path: / 22 | backend: 23 | serviceName: {{ $serviceName }} 24 | servicePort: {{ $servicePort }} 25 | {{- end -}} 26 | {{- if .Values.ingress.tls }} 27 | tls: 28 | {{ toYaml .Values.ingress.tls | indent 4 }} 29 | {{- end -}} 30 | {{- end -}} 31 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "child-chart.fullname" . }} 5 | labels: 6 | app: {{ template "child-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "child-chart.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: child-chart 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: child-chart 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-child-chart' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-child-chart -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-child-chart) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | values: 7 | - ./values/image.yaml 8 | set: 9 | service.internalPort: 8080 10 | asserts: 11 | - equal: 12 | path: spec.template.spec.containers[0].image 13 | value: apache:latest 14 | - notEqual: 15 | path: spec.template.spec.containers[0].image 16 | value: nginx:stable 17 | - matchRegex: 18 | path: metadata.name 19 | pattern: ^.*-child-chart$ 20 | - notMatchRegex: 21 | path: metadata.name 22 | pattern: ^.*-foobar$ 23 | - contains: 24 | path: spec.template.spec.containers[0].ports 25 | content: 26 | containerPort: 8080 27 | - notContains: 28 | path: spec.template.spec.containers[0].ports 29 | content: 30 | containerPort: 80 31 | - isNull: 32 | path: spec.template.nodeSelector 33 | - isNotNull: 34 | path: spec.template 35 | - isEmpty: 36 | path: spec.template.spec.containers[0].resources 37 | - isNotEmpty: 38 | path: spec.template.spec.containers[0] 39 | - isKind: 40 | of: Deployment 41 | - isAPIVersion: 42 | of: extensions/v1beta1 43 | - hasDocuments: 44 | count: 1 45 | - matchSnapshot: 46 | path: spec 47 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/ingress_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test ingress 2 | templates: 3 | - ingress.yaml 4 | tests: 5 | - it: should render nothing if not enabled 6 | asserts: 7 | - hasDocuments: 8 | count: 0 9 | 10 | - it: should render Ingress right if enabled 11 | set: 12 | ingress: 13 | enabled: true 14 | service: 15 | externalPort: 12345 16 | release: 17 | name: my-release 18 | asserts: 19 | - hasDocuments: 20 | count: 1 21 | - isKind: 22 | of: Ingress 23 | - contains: 24 | path: spec.rules[0].http.paths 25 | content: 26 | path: / 27 | backend: 28 | serviceName: my-release-child-chart 29 | servicePort: 12345 30 | - isNull: 31 | path: spec.tls 32 | 33 | - it: should set annotations if given 34 | set: 35 | ingress: 36 | enabled: true 37 | annotations: 38 | kubernetes.io/ingress.class: nginx 39 | kubernetes.io/tls-acme: "true" 40 | ingress.kubernetes.io/rewrite-target: / 41 | asserts: 42 | - equal: 43 | path: metadata.annotations 44 | value: 45 | kubernetes.io/ingress.class: nginx 46 | 47 | - it: should set tls if given 48 | set: 49 | ingress: 50 | enabled: true 51 | tls: 52 | - secretName: my-tls-secret 53 | asserts: 54 | - equal: 55 | path: spec.tls 56 | value: 57 | - secretName: my-tls-secret 58 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-child-chart) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: child-chart 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/child-chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: nginx 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | tls: 21 | # Secrets must be manually created in the namespace. 22 | # - secretName: chart-example-tls 23 | # hosts: 24 | # - chart-example.local 25 | resources: {} 26 | # We usually recommend not to specify default resources and to leave this as a conscious 27 | # choice for the user. This also increases chances charts run on environments with little 28 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 29 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 30 | # limits: 31 | # cpu: 100m 32 | # memory: 128Mi 33 | # requests: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/mysql-1.2.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v2/with-subchart/charts/mysql-1.2.0.tgz -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/postgresql-0.8.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v2/with-subchart/charts/postgresql-0.8.3.tgz -------------------------------------------------------------------------------- /test/data/v2/with-subchart/charts/redis-10.5.7.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v2/with-subchart/charts/redis-10.5.7.tgz -------------------------------------------------------------------------------- /test/data/v2/with-subchart/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://kubernetes-charts.storage.googleapis.com 4 | version: 0.8.3 5 | - name: postgresql 6 | repository: https://kubernetes-charts.storage.googleapis.com 7 | version: 0.8.3 8 | - name: mysql 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | version: 1.2.0 11 | - name: redis 12 | repository: https://kubernetes-charts.storage.googleapis.com 13 | version: 10.5.7 14 | digest: sha256:d40b8e91634146ea8a5d54d2319e3fe1fe3241cd232e20a449400f2b66adcac4 15 | generated: "2020-09-02T08:50:32.745002421+08:00" 16 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://kubernetes-charts.storage.googleapis.com 4 | version: 0.8.3 5 | - name: postgresql 6 | repository: https://kubernetes-charts.storage.googleapis.com 7 | version: 0.8.3 8 | alias: another-postgresql 9 | - name: mysql 10 | repository: https://kubernetes-charts.storage.googleapis.com 11 | version: 1.2.0 12 | condition: mysql.enabled 13 | - name: redis 14 | repository: https://kubernetes-charts.storage.googleapis.com 15 | version: 10.5.7 16 | condition: redis.enabled 17 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "parent-chart.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "parent-chart.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "parent-chart.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "parent-chart.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "parent-chart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "parent-chart.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "parent-chart.fullname" . }} 5 | labels: 6 | app: {{ template "parent-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "parent-chart.name" . }} 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | ports: 23 | - containerPort: {{ .Values.service.internalPort }} 24 | livenessProbe: 25 | httpGet: 26 | path: / 27 | port: {{ .Values.service.internalPort }} 28 | readinessProbe: 29 | httpGet: 30 | path: / 31 | port: {{ .Values.service.internalPort }} 32 | resources: 33 | {{ toYaml .Values.resources | indent 12 }} 34 | {{- if .Values.nodeSelector }} 35 | nodeSelector: 36 | {{ toYaml .Values.nodeSelector | indent 8 }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "parent-chart.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "parent-chart.fullname" . }} 8 | labels: 9 | app: {{ template "parent-chart.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | {{- range $key, $value := .Values.ingress.annotations }} 15 | {{ $key }}: {{ $value | quote }} 16 | {{- end }} 17 | spec: 18 | rules: 19 | {{- range $host := .Values.ingress.hosts }} 20 | - host: {{ $host }} 21 | http: 22 | paths: 23 | - path: / 24 | backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | {{- end -}} 28 | {{- if .Values.ingress.tls }} 29 | tls: 30 | {{ toYaml .Values.ingress.tls | indent 4 }} 31 | {{- end -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "parent-chart.fullname" . }} 5 | labels: 6 | app: {{ template "parent-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "parent-chart.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-with-subchart' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-with-subchart -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subchart) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/ingress_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test ingress 2 | templates: 3 | - ingress.yaml 4 | tests: 5 | - it: should render nothing if not enabled 6 | asserts: 7 | - hasDocuments: 8 | count: 0 9 | 10 | - it: should render Ingress right if enabled 11 | set: 12 | ingress.enabled: true 13 | service.externalPort: 12345 14 | release: 15 | name: my-release 16 | asserts: 17 | - hasDocuments: 18 | count: 1 19 | - isKind: 20 | of: Ingress 21 | - contains: 22 | path: spec.rules[0].http.paths 23 | content: 24 | path: / 25 | backend: 26 | serviceName: my-release-with-subchart 27 | servicePort: 12345 28 | - isNull: 29 | path: spec.tls 30 | 31 | - it: should set annotations if given 32 | set: 33 | ingress.enabled: true 34 | ingress.annotations: 35 | kubernetes.io/ingress.class: nginx 36 | kubernetes.io/tls-acme: "true" 37 | ingress.kubernetes.io/rewrite-target: / 38 | asserts: 39 | - equal: 40 | path: metadata.annotations 41 | value: 42 | kubernetes.io/ingress.class: nginx 43 | kubernetes.io/tls-acme: "true" 44 | ingress.kubernetes.io/rewrite-target: / 45 | 46 | - it: should set tls if given 47 | set: 48 | ingress.enabled: true 49 | ingress.tls: 50 | - secretName: my-tls-secret 51 | asserts: 52 | - equal: 53 | path: spec.tls 54 | value: 55 | - secretName: my-tls-secret 56 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subchart) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/postgresql_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test postgresql deployment 2 | templates: 3 | - charts/postgresql/templates/deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion for subchart 6 | values: 7 | - ./values/image.yaml 8 | asserts: 9 | - isKind: 10 | of: Deployment 11 | - isAPIVersion: 12 | of: extensions/v1beta1 13 | - hasDocuments: 14 | count: 1 15 | - matchSnapshot: 16 | path: spec 17 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: with-subchart 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | enabled: false 16 | # Used to create an Ingress record. 17 | hosts: 18 | - chart-example.local 19 | annotations: 20 | # kubernetes.io/ingress.class: nginx 21 | # kubernetes.io/tls-acme: "true" 22 | tls: 23 | # Secrets must be manually created in the namespace. 24 | # - secretName: chart-example-tls 25 | # hosts: 26 | # - chart-example.local 27 | resources: {} 28 | # We usually recommend not to specify default resources and to leave this as a conscious 29 | # choice for the user. This also increases chances charts run on environments with little 30 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 31 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 32 | # limits: 33 | # cpu: 100m 34 | # memory: 128Mi 35 | # requests: 36 | # cpu: 100m 37 | # memory: 128Mi 38 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A advanced example chart to demonstrate unittest plugin 3 | name: with-subfolder 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "with-subfolder.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "with-subfolder.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "with-subfolder.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "with-subfolder.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "with-subfolder.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "with-subfolder.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/db/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "with-subfolder.fullname" . }}-db 5 | labels: 6 | app: {{ template "with-subfolder.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "with-subfolder.name" . }} 16 | release: {{ .Release.Name }} 17 | annotations: 18 | some_template: | 19 | --- 20 | apiVersion: ... 21 | this: is test for old separator workaround bug 22 | spec: 23 | containers: 24 | - name: {{ .Chart.Name }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | ports: 28 | - containerPort: {{ .Values.service.dbPort }} 29 | livenessProbe: 30 | httpGet: 31 | path: / 32 | port: {{ .Values.service.internalPort }} 33 | readinessProbe: 34 | httpGet: 35 | path: / 36 | port: {{ .Values.service.internalPort }} 37 | resources: 38 | {{ toYaml .Values.resources | indent 12 }} 39 | {{- if .Values.nodeSelector }} 40 | nodeSelector: 41 | {{ toYaml .Values.nodeSelector | indent 8 }} 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/webserver/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "with-subfolder.fullname" . }} 6 | labels: 7 | app: {{ template "with-subfolder.name" . }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | replicas: {{ .Values.replicaCount }} 13 | template: 14 | metadata: 15 | labels: 16 | app: {{ template "with-subfolder.name" . }} 17 | release: {{ .Release.Name }} 18 | spec: 19 | containers: 20 | - name: {{ .Chart.Name }} 21 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 22 | imagePullPolicy: {{ .Values.image.pullPolicy }} 23 | ports: 24 | - containerPort: {{ .Values.service.internalPort }} 25 | livenessProbe: 26 | httpGet: 27 | path: / 28 | port: {{ .Values.service.internalPort }} 29 | readinessProbe: 30 | httpGet: 31 | path: / 32 | port: {{ .Values.service.internalPort }} 33 | resources: 34 | {{ toYaml .Values.resources | indent 12 }} 35 | {{- if .Values.nodeSelector }} 36 | nodeSelector: 37 | {{ toYaml .Values.nodeSelector | indent 8 }} 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/webserver/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "with-subfolder.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "with-subfolder.fullname" . }} 8 | labels: 9 | app: {{ template "with-subfolder.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | {{- range $key, $value := .Values.ingress.annotations }} 15 | {{ $key }}: {{ $value | quote }} 16 | {{- end }} 17 | spec: 18 | rules: 19 | {{- range $host := .Values.ingress.hosts }} 20 | - host: {{ $host }} 21 | http: 22 | paths: 23 | - path: / 24 | backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | {{- end -}} 28 | {{- if .Values.ingress.tls }} 29 | tls: 30 | {{ toYaml .Values.ingress.tls | indent 4 }} 31 | {{- end -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/templates/webserver/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "with-subfolder.fullname" . }} 5 | labels: 6 | app: {{ template "with-subfolder.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "with-subfolder.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion for both deployments: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | annotations: 7 | some_template: | 8 | --- 9 | apiVersion: ... 10 | this: is test for old separator workaround bug 11 | labels: 12 | app: with-subfolder 13 | release: RELEASE-NAME 14 | spec: 15 | containers: 16 | - image: apache:latest 17 | imagePullPolicy: Always 18 | livenessProbe: 19 | httpGet: 20 | path: / 21 | port: 80 22 | name: with-subfolder 23 | ports: 24 | - containerPort: null 25 | readinessProbe: 26 | httpGet: 27 | path: / 28 | port: 80 29 | resources: {} 30 | 2: | 31 | replicas: 1 32 | template: 33 | metadata: 34 | labels: 35 | app: with-subfolder 36 | release: RELEASE-NAME 37 | spec: 38 | containers: 39 | - image: apache:latest 40 | imagePullPolicy: Always 41 | livenessProbe: 42 | httpGet: 43 | path: / 44 | port: 80 45 | name: with-subfolder 46 | ports: 47 | - containerPort: 80 48 | readinessProbe: 49 | httpGet: 50 | path: / 51 | port: 80 52 | resources: {} 53 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-with-subfolder' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-with-subfolder -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subfolder) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subfolder) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - webserver/service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: with-subfolder 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v2/with-subfolder/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: foo 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | annotations: 21 | # kubernetes.io/ingress.class: nginx 22 | # kubernetes.io/tls-acme: "true" 23 | tls: 24 | # Secrets must be manually created in the namespace. 25 | # - secretName: chart-example-tls 26 | # hosts: 27 | # - chart-example.local 28 | resources: {} 29 | # We usually recommend not to specify default resources and to leave this as a conscious 30 | # choice for the user. This also increases chances charts run on environments with little 31 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 32 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 33 | # limits: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | # requests: 37 | # cpu: 100m 38 | # memory: 128Mi 39 | -------------------------------------------------------------------------------- /test/data/v3/basic/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v3/basic/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: A basic example chart to demonstrate unittest plugin 3 | name: basic 4 | version: 0.1.0 5 | appVersion: 1.0.0 6 | -------------------------------------------------------------------------------- /test/data/v3/basic/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "basic.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "basic.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "basic.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "basic.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v3/basic/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Check max override length. 4 | */}} 5 | {{- define "basic.checkNameOverrideLength" -}} 6 | {{- if .Values.nameOverride -}} 7 | {{- if gt (len .Values.nameOverride) 20 -}} 8 | {{- fail "nameOverride cannot be longer than 20 characters" -}} 9 | {{- end -}} 10 | {{- end -}} 11 | {{- end -}} 12 | 13 | {{/* 14 | Expand the name of the chart. 15 | */}} 16 | {{- define "basic.name" -}} 17 | {{- include "basic.checkNameOverrideLength" . -}} 18 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 19 | {{- end -}} 20 | 21 | {{/* 22 | Create a default fully qualified app name. 23 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 24 | */}} 25 | {{- define "basic.fullname" -}} 26 | {{- $name := default .Chart.Name .Values.nameOverride -}} 27 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 28 | {{- end -}} 29 | -------------------------------------------------------------------------------- /test/data/v3/basic/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "basic.fullname" . }} 5 | labels: 6 | app: {{ template "basic.name" . }} 7 | appVersion: {{ .Chart.AppVersion | quote }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | data: 12 | my.conf: | 13 | {{- if .Values.expose }} 14 | cacertfile = /etc/cert/cacert.pem 15 | certfile = /etc/cert/tls.crt 16 | keyfile = /etc/cert/tls.key 17 | verify = verify_none 18 | {{- end }} 19 | abc = qqq 20 | qqq = abc 21 | my.array: 22 | - value1 23 | - value2 24 | special.array: 25 | - phony-service.phony:graphql -------------------------------------------------------------------------------- /test/data/v3/basic/templates/crd_backup.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (and (eq .Capabilities.KubeVersion.Major "1") (eq .Capabilities.KubeVersion.Minor "12")) (.Capabilities.APIVersions.Has "br.dev.local/v1") }} 2 | apiVersion: "br.dev.local/v1" 3 | kind: BrPolicy 4 | metadata: 5 | name: {{ template "basic.fullname" . }}-backuppolicy 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: {{ template "basic.fullname" . }} 10 | type: myserver 11 | volumes: 12 | - datadir 13 | {{- end }} -------------------------------------------------------------------------------- /test/data/v3/basic/templates/empty_deployment.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v3/basic/templates/empty_deployment.yaml -------------------------------------------------------------------------------- /test/data/v3/basic/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "basic.fullname" . -}} 3 | {{- $servicePort := required "The externalPort is required" .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "basic.fullname" . }} 8 | labels: 9 | app: {{ template "basic.name" . }} 10 | appVersion: {{ .Chart.AppVersion | quote }} 11 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | annotations: 15 | {{- range $key, $value := .Values.ingress.annotations }} 16 | {{ $key }}: {{ $value | quote }} 17 | {{- end }} 18 | spec: 19 | rules: 20 | {{- range $host := .Values.ingress.hosts }} 21 | - host: {{ $host }} 22 | http: 23 | paths: 24 | - path: / 25 | backend: 26 | serviceName: {{ $serviceName }} 27 | servicePort: {{ $servicePort }} 28 | {{- end -}} 29 | {{- if .Values.ingress.tls }} 30 | tls: 31 | {{ toYaml .Values.ingress.tls | indent 4 }} 32 | {{- end -}} 33 | {{- end -}} 34 | -------------------------------------------------------------------------------- /test/data/v3/basic/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "basic.fullname" . }} 5 | labels: 6 | app: {{ template "basic.name" . }} 7 | appVersion: {{ .Chart.AppVersion | quote }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.externalPort }} 15 | targetPort: {{ .Values.service.internalPort }} 16 | protocol: TCP 17 | name: {{ .Values.service.name }} 18 | selector: 19 | app: {{ template "basic.name" . }} 20 | release: {{ .Release.Name }} 21 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: basic 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: basic 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-basic' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-basic -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-basic) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/configmap_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Configmap multiline Test 2 | templates: 3 | - configmap.yaml 4 | tests: 5 | - it: should NOT configure ssl params if NOT set to be exposed 6 | asserts: 7 | - notMatchRegex: 8 | path: data.my\.conf 9 | pattern: cacertfile 10 | - contains: 11 | path: data.my\.array 12 | content: value1 13 | count: 1 14 | - contains: 15 | path: data.special\.array 16 | content: phony-service.phony:graphql 17 | count: 1 18 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/crd_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Custom Resource Definition Test 2 | templates: 3 | - crd_backup.yaml 4 | release: 5 | name: my-release 6 | namespace: my-namespace 7 | revision: 1 8 | upgrade: true 9 | capabilities: 10 | majorVersion: 1 11 | minorVersion: 10 12 | apiVersions: 13 | - br.dev.local/v2 14 | tests: 15 | - it: should pass all kinds of assertion 16 | capabilities: 17 | majorVersion: 1 18 | minorVersion: 12 19 | apiVersions: 20 | - br.dev.local/v1 21 | asserts: 22 | - isKind: 23 | of: BrPolicy 24 | - isAPIVersion: 25 | of: br.dev.local/v1 26 | - equal: 27 | path: metadata.name 28 | value: my-release-basic-backuppolicy 29 | - hasDocuments: 30 | count: 1 31 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-basic) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | set: 9 | service: 10 | type: ClusterIP 11 | asserts: 12 | - contains: 13 | path: spec.ports 14 | content: 15 | port: 80 16 | targetPort: 80 17 | protocol: TCP 18 | name: nginx 19 | - equal: 20 | path: spec.type 21 | value: ClusterIP 22 | - equal: 23 | path: spec.selector 24 | value: 25 | app: basic 26 | release: my-release 27 | 28 | - it: should render right if values given 29 | set: 30 | service: 31 | type: NodePort 32 | internalPort: 1234 33 | externalPort: 4321 34 | name: cool-service 35 | asserts: 36 | - contains: 37 | path: spec.ports 38 | content: 39 | port: 4321 40 | targetPort: 1234 41 | protocol: TCP 42 | name: cool-service 43 | - equal: 44 | path: spec.type 45 | value: NodePort 46 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should fail all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: basic 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: basic 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | 2: | 26 | replicas: 1 27 | template: 28 | metadata: 29 | annotations: 30 | some_template: | 31 | --- 32 | apiVersion: ... 33 | this: is test for old separator workaround bug 34 | labels: 35 | app: basic 36 | release: RELEASE-NAME 37 | spec: 38 | containers: 39 | - image: apache:latest 40 | imagePullPolicy: Always 41 | name: basic 42 | ports: 43 | - containerPort: null 44 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/configmap_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Configmap mulit line Test 2 | templates: 3 | - configmap.yaml 4 | tests: 5 | - it: should NOT configure ssl params if NOT set to be exposed 6 | asserts: 7 | - matchRegex: 8 | path: data.my\.conf 9 | pattern: cacertfile 10 | - contains: 11 | path: data.my\.array 12 | content: 'value1' 13 | count: -1 14 | - contains: 15 | path: data.my\.array 16 | content: 'value2' 17 | count: 8.9 18 | - contains: 19 | path: data.my\.array 20 | content: 'value1' 21 | count: 1234578901234567890 22 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/empty_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - empty_deployment.yaml 4 | tests: 5 | - it: should fail 6 | asserts: 7 | - isKind: 8 | of: Deployment -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/include_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment that would be fail 2 | values: 3 | - ./values/image.yaml 4 | templates: 5 | - deployment.yaml 6 | tests: 7 | - it: should fail all kinds of assertion 8 | set: 9 | service.internalPort: 8080 10 | asserts: 11 | - equal: 12 | path: spec.template.spec.containers[0].image 13 | value: nginx:stable 14 | - notEqual: 15 | path: spec.template.spec.containers[0].image 16 | value: apache:latest 17 | - matchRegex: 18 | path: metadata.name 19 | pattern: ^.*-foobar$ 20 | - notMatchRegex: 21 | path: metadata.name 22 | pattern: ^.*-basic$ 23 | - contains: 24 | path: spec.template.spec.containers[0].ports 25 | content: 26 | containerPort: 80 27 | - notContains: 28 | path: spec.template.spec.containers[0].ports 29 | content: 30 | containerPort: 8080 31 | - isNull: 32 | path: spec.template 33 | - isNotNull: 34 | path: spec.template.nodeSelector 35 | - isEmpty: 36 | path: spec.template.spec.containers[0] 37 | - isNotEmpty: 38 | path: spec.template.spec.containers[0].resources 39 | - isKind: 40 | of: Pod 41 | - isAPIVersion: 42 | of: v2 43 | - hasDocuments: 44 | count: 1 45 | - matchSnapshot: 46 | path: spec 47 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/ingress_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test ingress that should fail 2 | templates: 3 | - ingress.yaml 4 | tests: 5 | - it: should fail render nothing if not enabled 6 | asserts: 7 | - hasDocuments: 8 | count: 1 9 | 10 | - it: should fail render ingress right if enabled 11 | set: 12 | ingress.enabled: true 13 | service.externalPort: 12345 14 | release: 15 | name: my-release 16 | asserts: 17 | - contains: 18 | path: spec.rules[0].http.paths 19 | content: 20 | path: / 21 | backend: 22 | serviceName: my-release-basic 23 | servicePort: 54321 24 | - isNotNull: 25 | path: spec.tls 26 | 27 | - it: should fail set annotations if given 28 | set: 29 | ingress.enabled: true 30 | ingress.annotations: 31 | kubernetes.io/ingress.class: nginx 32 | kubernetes.io/tls-acme: "true" 33 | ingress.kubernetes.io/rewrite-target: / 34 | release: 35 | name: my-release 36 | asserts: 37 | - isEmpty: 38 | path: metadata.annotations 39 | 40 | - it: should fail set tls if given 41 | set: 42 | ingress.enabled: true 43 | 44 | release: 45 | name: my-release 46 | asserts: 47 | - equal: 48 | path: spec.tls 49 | value: 50 | - secretName: my-tls-secret 51 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should fail the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - notEqualRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | 14 | - it: should fail the notes file with service type NodePort 15 | set: 16 | service.type: NodePort 17 | asserts: 18 | - equalRaw: 19 | value: | 20 | 1. Get the application URL by running these commands: 21 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services MY-RELEASE) 22 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 23 | echo http://$NODE_IP:$NODE_PORT 24 | 25 | - it: should fail the notes file with service type LoadBalancer 26 | set: 27 | service.type: LoadBalancer 28 | service.externalPort: 9999 29 | asserts: 30 | - matchRegexRaw: 31 | pattern: http://\$SERVICE_IP:80 32 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should failed 6 | release: 7 | name: my-release 8 | asserts: 9 | - notContains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - notEqual: 17 | path: spec.type 18 | value: ClusterIP 19 | - notEqual: 20 | path: spec.selector 21 | value: 22 | app: basic 23 | release: my-release 24 | 25 | - it: should fail renders right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - notContains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - notEqual: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v3/basic/tests_failed/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v3/basic/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: foo 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | annotations: 21 | # kubernetes.io/ingress.class: nginx 22 | # kubernetes.io/tls-acme: "true" 23 | tls: 24 | # Secrets must be manually created in the namespace. 25 | # - secretName: chart-example-tls 26 | # hosts: 27 | # - chart-example.local 28 | resources: {} 29 | # We usually recommend not to specify default resources and to leave this as a conscious 30 | # choice for the user. This also increases chances charts run on environments with little 31 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 32 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 33 | # limits: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | # requests: 37 | # cpu: 100m 38 | # memory: 128Mi 39 | -------------------------------------------------------------------------------- /test/data/v3/failing-template/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: failing-template 3 | description: Test failed template assert 4 | type: application 5 | version: 0.1.0 6 | -------------------------------------------------------------------------------- /test/data/v3/failing-template/templates/configMap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: test-configmap 5 | data: 6 | my-file.yaml: | 7 | {{- include "non-existing-named-template" . | nindent 4 }} -------------------------------------------------------------------------------- /test/data/v3/failing-template/tests/configMap_test.yaml: -------------------------------------------------------------------------------- 1 | suite: Test failing template 2 | templates: 3 | - configMap.yaml 4 | tests: 5 | - it: template should be failing 6 | asserts: 7 | - failedTemplate: 8 | errorMessage: no template "non-existing-named-template" associated with template "gotpl" 9 | -------------------------------------------------------------------------------- /test/data/v3/invalidbasic/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v3/invalidbasic/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: A basic example chart to demonstrate unittest plugin 3 | name: basic 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v3/invalidbasic/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Check max override length. 4 | */}} 5 | {{- define "basic.checkNameOverrideLength" -}} 6 | {{- if .Values.nameOverride -}} 7 | {{- if gt (len .Values.nameOverride) 20 -}} 8 | {{- fail "nameOverride cannot be longer than 20 characters" -}} 9 | {{- end -}} 10 | {{- end -}} 11 | {{- end -}} 12 | 13 | {{/* 14 | Expand the name of the chart. 15 | */}} 16 | {{- define "basic.name" -}} 17 | {{- include "basic.checkNameOverrideLength" . -}} 18 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 19 | {{- end -}} 20 | 21 | {{/* 22 | Create a default fully qualified app name. 23 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 24 | */}} 25 | {{- define "basic.fullname" -}} 26 | {{- $name := default .Chart.Name .Values.nameOverride -}} 27 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 28 | {{- end -}} 29 | -------------------------------------------------------------------------------- /test/data/v3/invalidbasic/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | documentIndex: 0 7 | documentIndex: 0 8 | asserts: 9 | - equal: 10 | path: spec.template.spec.containers[0].image 11 | value: apache:latest 12 | -------------------------------------------------------------------------------- /test/data/v3/invalidbasic/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: foo 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | annotations: 21 | # kubernetes.io/ingress.class: nginx 22 | # kubernetes.io/tls-acme: "true" 23 | tls: 24 | # Secrets must be manually created in the namespace. 25 | # - secretName: chart-example-tls 26 | # hosts: 27 | # - chart-example.local 28 | resources: {} 29 | # We usually recommend not to specify default resources and to leave this as a conscious 30 | # choice for the user. This also increases chances charts run on environments with little 31 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 32 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 33 | # limits: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | # requests: 37 | # cpu: 100m 38 | # memory: 128Mi 39 | -------------------------------------------------------------------------------- /test/data/v3/with-schema/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: A chart with a JSON schema 3 | name: with-schema 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v3/with-schema/templates/dummy.yaml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /test/data/v3/with-schema/values.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema#", 3 | "type": "object", 4 | "required": [ 5 | "image" 6 | ], 7 | "properties": { 8 | "image": { 9 | "type": "object", 10 | "required": [ 11 | "repository", 12 | "pullPolicy" 13 | ], 14 | "properties": { 15 | "repository": { 16 | "type": "string", 17 | "pattern": "^[a-z0-9-_]+$" 18 | }, 19 | "pullPolicy": { 20 | "type": "string", 21 | "pattern": "^(Always|Never|IfNotPresent)$" 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /test/data/v3/with-subchart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://kubernetes-charts.storage.googleapis.com 4 | version: 0.8.3 5 | - name: postgresql 6 | repository: https://kubernetes-charts.storage.googleapis.com 7 | version: 0.8.3 8 | digest: sha256:6ac88461535205e69bafcee4675ba1d353490d3260c4c13c552024e4ca0b7998 9 | generated: "2020-03-31T17:15:46.7784064+02:00" 10 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: An example chart with customized subchart 3 | name: with-subchart 4 | version: 0.1.0 5 | dependencies: 6 | - name: postgresql 7 | repository: https://kubernetes-charts.storage.googleapis.com 8 | version: 0.8.3 9 | condition: postgresql.enabled 10 | - name: postgresql 11 | repository: https://kubernetes-charts.storage.googleapis.com 12 | version: 0.8.3 13 | alias: another-postgresql 14 | condition: another-postgresql.enabled 15 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: An customized subchart 3 | name: child-chart 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "child-chart.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "child-chart.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "child-chart.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "child-chart.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "child-chart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "child-chart.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | 18 | {{- define "child-chart.ingressClass" -}} 19 | {{- $ingressClass := .Values.ingress.class -}} 20 | {{- if .Values.global -}} 21 | {{- if .Values.global.ingressClass -}} 22 | {{- $ingressClass = .Values.global.ingressClass -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- printf "%s" $ingressClass -}} 26 | {{- end -}} 27 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "child-chart.fullname" . }} 5 | labels: 6 | app: {{ template "child-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "child-chart.name" . }} 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | ports: 23 | - containerPort: {{ .Values.service.internalPort }} 24 | livenessProbe: 25 | httpGet: 26 | path: / 27 | port: {{ .Values.service.internalPort }} 28 | readinessProbe: 29 | httpGet: 30 | path: / 31 | port: {{ .Values.service.internalPort }} 32 | resources: 33 | {{ toYaml .Values.resources | indent 12 }} 34 | {{- if .Values.nodeSelector }} 35 | nodeSelector: 36 | {{ toYaml .Values.nodeSelector | indent 8 }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "child-chart.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "child-chart.fullname" . }} 8 | labels: 9 | app: {{ template "child-chart.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | kubernetes.io/ingress.class: {{ template "child-chart.ingressClass" . }} 15 | spec: 16 | rules: 17 | {{- range $host := .Values.ingress.hosts }} 18 | - host: {{ $host }} 19 | http: 20 | paths: 21 | - path: / 22 | backend: 23 | serviceName: {{ $serviceName }} 24 | servicePort: {{ $servicePort }} 25 | {{- end -}} 26 | {{- if .Values.ingress.tls }} 27 | tls: 28 | {{ toYaml .Values.ingress.tls | indent 4 }} 29 | {{- end -}} 30 | {{- end -}} 31 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "child-chart.fullname" . }} 5 | labels: 6 | app: {{ template "child-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "child-chart.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: child-chart 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: child-chart 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-child-chart' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-child-chart -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-child-chart) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | values: 7 | - ./values/image.yaml 8 | set: 9 | service.internalPort: 8080 10 | asserts: 11 | - equal: 12 | path: spec.template.spec.containers[0].image 13 | value: apache:latest 14 | - notEqual: 15 | path: spec.template.spec.containers[0].image 16 | value: nginx:stable 17 | - matchRegex: 18 | path: metadata.name 19 | pattern: ^.*-child-chart$ 20 | - notMatchRegex: 21 | path: metadata.name 22 | pattern: ^.*-foobar$ 23 | - contains: 24 | path: spec.template.spec.containers[0].ports 25 | content: 26 | containerPort: 8080 27 | - notContains: 28 | path: spec.template.spec.containers[0].ports 29 | content: 30 | containerPort: 80 31 | - isNull: 32 | path: spec.template.nodeSelector 33 | - isNotNull: 34 | path: spec.template 35 | - isEmpty: 36 | path: spec.template.spec.containers[0].resources 37 | - isNotEmpty: 38 | path: spec.template.spec.containers[0] 39 | - isKind: 40 | of: Deployment 41 | - isAPIVersion: 42 | of: extensions/v1beta1 43 | - hasDocuments: 44 | count: 1 45 | - matchSnapshot: 46 | path: spec 47 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/ingress_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test ingress 2 | templates: 3 | - ingress.yaml 4 | tests: 5 | - it: should render nothing if not enabled 6 | asserts: 7 | - hasDocuments: 8 | count: 0 9 | 10 | - it: should render Ingress right if enabled 11 | set: 12 | ingress: 13 | enabled: true 14 | service: 15 | externalPort: 12345 16 | release: 17 | name: my-release 18 | asserts: 19 | - hasDocuments: 20 | count: 1 21 | - isKind: 22 | of: Ingress 23 | - contains: 24 | path: spec.rules[0].http.paths 25 | content: 26 | path: / 27 | backend: 28 | serviceName: my-release-child-chart 29 | servicePort: 12345 30 | - isNull: 31 | path: spec.tls 32 | 33 | - it: should set annotations if given 34 | set: 35 | ingress: 36 | enabled: true 37 | annotations: 38 | kubernetes.io/ingress.class: nginx 39 | kubernetes.io/tls-acme: "true" 40 | ingress.kubernetes.io/rewrite-target: / 41 | asserts: 42 | - equal: 43 | path: metadata.annotations 44 | value: 45 | kubernetes.io/ingress.class: nginx 46 | 47 | - it: should set tls if given 48 | set: 49 | ingress: 50 | enabled: true 51 | tls: 52 | - secretName: my-tls-secret 53 | asserts: 54 | - equal: 55 | path: spec.tls 56 | value: 57 | - secretName: my-tls-secret 58 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-child-chart) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: child-chart 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/child-chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: nginx 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | tls: 21 | # Secrets must be manually created in the namespace. 22 | # - secretName: chart-example-tls 23 | # hosts: 24 | # - chart-example.local 25 | resources: {} 26 | # We usually recommend not to specify default resources and to leave this as a conscious 27 | # choice for the user. This also increases chances charts run on environments with little 28 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 29 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 30 | # limits: 31 | # cpu: 100m 32 | # memory: 128Mi 33 | # requests: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/charts/postgresql-0.8.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v3/with-subchart/charts/postgresql-0.8.3.tgz -------------------------------------------------------------------------------- /test/data/v3/with-subchart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "parent-chart.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "parent-chart.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "parent-chart.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "parent-chart.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "parent-chart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "parent-chart.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "parent-chart.fullname" . }} 5 | labels: 6 | app: {{ template "parent-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "parent-chart.name" . }} 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | ports: 23 | - containerPort: {{ .Values.service.internalPort }} 24 | livenessProbe: 25 | httpGet: 26 | path: / 27 | port: {{ .Values.service.internalPort }} 28 | readinessProbe: 29 | httpGet: 30 | path: / 31 | port: {{ .Values.service.internalPort }} 32 | resources: 33 | {{ toYaml .Values.resources | indent 12 }} 34 | {{- if .Values.nodeSelector }} 35 | nodeSelector: 36 | {{ toYaml .Values.nodeSelector | indent 8 }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "parent-chart.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "parent-chart.fullname" . }} 8 | labels: 9 | app: {{ template "parent-chart.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | {{- range $key, $value := .Values.ingress.annotations }} 15 | {{ $key }}: {{ $value | quote }} 16 | {{- end }} 17 | spec: 18 | rules: 19 | {{- range $host := .Values.ingress.hosts }} 20 | - host: {{ $host }} 21 | http: 22 | paths: 23 | - path: / 24 | backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | {{- end -}} 28 | {{- if .Values.ingress.tls }} 29 | tls: 30 | {{ toYaml .Values.ingress.tls | indent 4 }} 31 | {{- end -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "parent-chart.fullname" . }} 5 | labels: 6 | app: {{ template "parent-chart.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "parent-chart.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | labels: 7 | app: with-subchart 8 | release: RELEASE-NAME 9 | spec: 10 | containers: 11 | - image: apache:latest 12 | imagePullPolicy: Always 13 | livenessProbe: 14 | httpGet: 15 | path: / 16 | port: 8080 17 | name: with-subchart 18 | ports: 19 | - containerPort: 8080 20 | readinessProbe: 21 | httpGet: 22 | path: / 23 | port: 8080 24 | resources: {} 25 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-with-subchart' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-with-subchart -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subchart) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test deployment 2 | templates: 3 | - deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion 6 | values: 7 | - ./values/image.yaml 8 | set: 9 | service.internalPort: 8080 10 | asserts: 11 | - equal: 12 | path: spec.template.spec.containers[0].image 13 | value: apache:latest 14 | - notEqual: 15 | path: spec.template.spec.containers[0].image 16 | value: nginx:stable 17 | - matchRegex: 18 | path: metadata.name 19 | pattern: ^.*-with-subchart$ 20 | - notMatchRegex: 21 | path: metadata.name 22 | pattern: ^.*-foobar$ 23 | - contains: 24 | path: spec.template.spec.containers[0].ports 25 | content: 26 | containerPort: 8080 27 | - notContains: 28 | path: spec.template.spec.containers[0].ports 29 | content: 30 | containerPort: 80 31 | - isNull: 32 | path: spec.template.nodeSelector 33 | - isNotNull: 34 | path: spec.template 35 | - isEmpty: 36 | path: spec.template.spec.containers[0].resources 37 | - isNotEmpty: 38 | path: spec.template.spec.containers[0] 39 | - isKind: 40 | of: Deployment 41 | - isAPIVersion: 42 | of: extensions/v1beta1 43 | - hasDocuments: 44 | count: 1 45 | - matchSnapshot: 46 | path: spec 47 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | 15 | - it: should pass the notes file with service type NodePort 16 | set: 17 | service.type: NodePort 18 | asserts: 19 | - equalRaw: 20 | value: | 21 | 1. Get the application URL by running these commands: 22 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subchart) 23 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 24 | echo http://$NODE_IP:$NODE_PORT 25 | - matchSnapshotRaw: {} 26 | 27 | - it: should pass the notes file with service type LoadBalancer 28 | set: 29 | service.type: LoadBalancer 30 | service.externalPort: 9999 31 | asserts: 32 | - matchRegexRaw: 33 | pattern: http://\$SERVICE_IP:9999 34 | - matchSnapshotRaw: {} 35 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/postgresql_deployment_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test postgresql deployment 2 | templates: 3 | - charts/postgresql/templates/deployment.yaml 4 | tests: 5 | - it: should pass all kinds of assertion for subchart 6 | values: 7 | - ./values/image.yaml 8 | asserts: 9 | - isKind: 10 | of: Deployment 11 | - isAPIVersion: 12 | of: extensions/v1beta1 13 | - hasDocuments: 14 | count: 1 15 | - matchSnapshot: 16 | path: spec 17 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: with-subchart 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v3/with-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | enabled: false 16 | # Used to create an Ingress record. 17 | hosts: 18 | - chart-example.local 19 | annotations: 20 | # kubernetes.io/ingress.class: nginx 21 | # kubernetes.io/tls-acme: "true" 22 | tls: 23 | # Secrets must be manually created in the namespace. 24 | # - secretName: chart-example-tls 25 | # hosts: 26 | # - chart-example.local 27 | resources: {} 28 | # We usually recommend not to specify default resources and to leave this as a conscious 29 | # choice for the user. This also increases chances charts run on environments with little 30 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 31 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 32 | # limits: 33 | # cpu: 100m 34 | # memory: 128Mi 35 | # requests: 36 | # cpu: 100m 37 | # memory: 128Mi 38 | 39 | postgresql: 40 | enabled: true 41 | 42 | another-postgresql: 43 | enabled: true -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | tests 24 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: A advanced example chart to demonstrate unittest plugin 3 | name: with-subfolder 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http://{{ . }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "with-subfolder.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ template "with-subfolder.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "with-subfolder.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "with-subfolder.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "with-subfolder.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "with-subfolder.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/db/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "with-subfolder.fullname" . }}-db 5 | labels: 6 | app: {{ template "with-subfolder.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "with-subfolder.name" . }} 16 | release: {{ .Release.Name }} 17 | annotations: 18 | some_template: | 19 | --- 20 | apiVersion: ... 21 | this: is test for old separator workaround bug 22 | spec: 23 | containers: 24 | - name: {{ .Chart.Name }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | ports: 28 | - containerPort: {{ .Values.service.dbPort }} 29 | livenessProbe: 30 | httpGet: 31 | path: / 32 | port: {{ .Values.service.internalPort }} 33 | readinessProbe: 34 | httpGet: 35 | path: / 36 | port: {{ .Values.service.internalPort }} 37 | resources: 38 | {{ toYaml .Values.resources | indent 12 }} 39 | {{- if .Values.nodeSelector }} 40 | nodeSelector: 41 | {{ toYaml .Values.nodeSelector | indent 8 }} 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/webserver/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "with-subfolder.fullname" . }} 6 | labels: 7 | app: {{ template "with-subfolder.name" . }} 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | replicas: {{ .Values.replicaCount }} 13 | template: 14 | metadata: 15 | labels: 16 | app: {{ template "with-subfolder.name" . }} 17 | release: {{ .Release.Name }} 18 | spec: 19 | containers: 20 | - name: {{ .Chart.Name }} 21 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 22 | imagePullPolicy: {{ .Values.image.pullPolicy }} 23 | ports: 24 | - containerPort: {{ .Values.service.internalPort }} 25 | livenessProbe: 26 | httpGet: 27 | path: / 28 | port: {{ .Values.service.internalPort }} 29 | readinessProbe: 30 | httpGet: 31 | path: / 32 | port: {{ .Values.service.internalPort }} 33 | resources: 34 | {{ toYaml .Values.resources | indent 12 }} 35 | {{- if .Values.nodeSelector }} 36 | nodeSelector: 37 | {{ toYaml .Values.nodeSelector | indent 8 }} 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/webserver/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "with-subfolder.fullname" . -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | apiVersion: extensions/v1beta1 5 | kind: Ingress 6 | metadata: 7 | name: {{ template "with-subfolder.fullname" . }} 8 | labels: 9 | app: {{ template "with-subfolder.name" . }} 10 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 11 | release: {{ .Release.Name }} 12 | heritage: {{ .Release.Service }} 13 | annotations: 14 | {{- range $key, $value := .Values.ingress.annotations }} 15 | {{ $key }}: {{ $value | quote }} 16 | {{- end }} 17 | spec: 18 | rules: 19 | {{- range $host := .Values.ingress.hosts }} 20 | - host: {{ $host }} 21 | http: 22 | paths: 23 | - path: / 24 | backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | {{- end -}} 28 | {{- if .Values.ingress.tls }} 29 | tls: 30 | {{ toYaml .Values.ingress.tls | indent 4 }} 31 | {{- end -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/templates/webserver/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "with-subfolder.fullname" . }} 5 | labels: 6 | app: {{ template "with-subfolder.name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.externalPort }} 14 | targetPort: {{ .Values.service.internalPort }} 15 | protocol: TCP 16 | name: {{ .Values.service.name }} 17 | selector: 18 | app: {{ template "with-subfolder.name" . }} 19 | release: {{ .Release.Name }} 20 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/tests/__snapshot__/deployment_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass all kinds of assertion for both deployments: 2 | 1: | 3 | replicas: 1 4 | template: 5 | metadata: 6 | annotations: 7 | some_template: | 8 | --- 9 | apiVersion: ... 10 | this: is test for old separator workaround bug 11 | labels: 12 | app: with-subfolder 13 | release: RELEASE-NAME 14 | spec: 15 | containers: 16 | - image: apache:latest 17 | imagePullPolicy: Always 18 | livenessProbe: 19 | httpGet: 20 | path: / 21 | port: 80 22 | name: with-subfolder 23 | ports: 24 | - containerPort: null 25 | readinessProbe: 26 | httpGet: 27 | path: / 28 | port: 80 29 | resources: {} 30 | 2: | 31 | replicas: 1 32 | template: 33 | metadata: 34 | labels: 35 | app: with-subfolder 36 | release: RELEASE-NAME 37 | spec: 38 | containers: 39 | - image: apache:latest 40 | imagePullPolicy: Always 41 | livenessProbe: 42 | httpGet: 43 | path: / 44 | port: 80 45 | name: with-subfolder 46 | ports: 47 | - containerPort: 80 48 | readinessProbe: 49 | httpGet: 50 | path: / 51 | port: 80 52 | resources: {} 53 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/tests/__snapshot__/notes_test.yaml.snap: -------------------------------------------------------------------------------- 1 | should pass the notes file with ingress enabled: 2 | 1: | 3 | | 4 | 1. Get the application URL by running these commands: 5 | http://chart-example.local 6 | should pass the notes file with service type LoadBalancer: 7 | 1: | 8 | | 9 | 1. Get the application URL by running these commands: 10 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 11 | You can watch the status of by running 'kubectl get svc -w RELEASE-NAME-with-subfolder' 12 | export SERVICE_IP=$(kubectl get svc --namespace NAMESPACE RELEASE-NAME-with-subfolder -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 13 | echo http://$SERVICE_IP:9999 14 | should pass the notes file with service type NodePort: 15 | 1: | 16 | | 17 | 1. Get the application URL by running these commands: 18 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subfolder) 19 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 20 | echo http://$NODE_IP:$NODE_PORT 21 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/tests/notes_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test notes 2 | templates: 3 | - NOTES.txt 4 | tests: 5 | - it: should pass the notes file with ingress enabled 6 | set: 7 | ingress.enabled: true 8 | asserts: 9 | - equalRaw: 10 | value: | 11 | 1. Get the application URL by running these commands: 12 | http://chart-example.local 13 | - matchSnapshotRaw: {} 14 | - it: should pass the notes file with service type NodePort 15 | set: 16 | service.type: NodePort 17 | asserts: 18 | - equalRaw: 19 | value: | 20 | 1. Get the application URL by running these commands: 21 | export NODE_PORT=$(kubectl get --namespace NAMESPACE -o jsonpath="{.spec.ports[0].nodePort}" services RELEASE-NAME-with-subfolder) 22 | export NODE_IP=$(kubectl get nodes --namespace NAMESPACE -o jsonpath="{.items[0].status.addresses[0].address}") 23 | echo http://$NODE_IP:$NODE_PORT 24 | - matchSnapshotRaw: {} 25 | - it: should pass the notes file with service type LoadBalancer 26 | set: 27 | service.type: LoadBalancer 28 | service.externalPort: 9999 29 | asserts: 30 | - matchRegexRaw: 31 | pattern: http://\$SERVICE_IP:9999 32 | - matchSnapshotRaw: {} 33 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/tests/service_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test service 2 | templates: 3 | - webserver/service.yaml 4 | tests: 5 | - it: should pass 6 | release: 7 | name: my-release 8 | asserts: 9 | - contains: 10 | path: spec.ports 11 | content: 12 | port: 80 13 | targetPort: 80 14 | protocol: TCP 15 | name: nginx 16 | - equal: 17 | path: spec.type 18 | value: ClusterIP 19 | - equal: 20 | path: spec.selector 21 | value: 22 | app: with-subfolder 23 | release: my-release 24 | 25 | - it: should render right if values given 26 | set: 27 | service: 28 | type: NodePort 29 | internalPort: 1234 30 | externalPort: 4321 31 | name: cool-service 32 | asserts: 33 | - contains: 34 | path: spec.ports 35 | content: 36 | port: 4321 37 | targetPort: 1234 38 | protocol: TCP 39 | name: cool-service 40 | - equal: 41 | path: spec.type 42 | value: NodePort 43 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/tests/values/image.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: apache 3 | tag: latest 4 | pullPolicy: Always 5 | -------------------------------------------------------------------------------- /test/data/v3/with-subfolder/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for basic. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: nginx 7 | tag: stable 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: nginx 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 80 14 | ingress: 15 | class: foo 16 | enabled: false 17 | # Used to create an Ingress record. 18 | hosts: 19 | - chart-example.local 20 | annotations: 21 | # kubernetes.io/ingress.class: nginx 22 | # kubernetes.io/tls-acme: "true" 23 | tls: 24 | # Secrets must be manually created in the namespace. 25 | # - secretName: chart-example-tls 26 | # hosts: 27 | # - chart-example.local 28 | resources: {} 29 | # We usually recommend not to specify default resources and to leave this as a conscious 30 | # choice for the user. This also increases chances charts run on environments with little 31 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 32 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 33 | # limits: 34 | # cpu: 100m 35 | # memory: 128Mi 36 | # requests: 37 | # cpu: 100m 38 | # memory: 128Mi 39 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: with-subsubcharts 3 | version: 0.1.0 4 | type: application 5 | 6 | dependencies: 7 | - name: example-subchart 8 | version: 0.2.0 9 | import-values: 10 | - child: local.annotations 11 | parent: annotations 12 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/README.md: -------------------------------------------------------------------------------- 1 | # example-chart 2 | 3 | This repository contains a set-up to reproduce the issue described in . 4 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: example-subchart 3 | version: 0.2.0 4 | 5 | dependencies: 6 | - name: example-sub-subchart 7 | version: 0.3.0 -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/charts/example-sub-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: example-sub-subchart 3 | version: 0.3.0 4 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/charts/example-sub-subchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: example-sub-subchart 5 | spec: 6 | template: 7 | metadata: 8 | annotations: 9 | {{- with .Values.global.app.annotations }} 10 | {{- toYaml . | trim | nindent 8 }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/charts/example-sub-subchart/values.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quintush/helm-unittest/254c582c18d52e07541dbe0185eb64befa20a822/test/data/v3/with-subsubcharts/charts/example-subchart/charts/example-sub-subchart/values.yaml -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: example-subchart 5 | spec: 6 | template: 7 | metadata: 8 | annotations: 9 | {{- with .Values.global.app.annotations }} 10 | {{- toYaml . | trim | nindent 8 }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/charts/example-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | 2 | local: 3 | annotations: 4 | localKey: "localValue" -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: example-deployment 5 | spec: 6 | template: 7 | metadata: 8 | annotations: 9 | {{- with .Values.global.app.annotations }} 10 | {{- toYaml . | trim | nindent 8 }} 11 | {{- end }} 12 | {{- with .Values.annotations }} 13 | {{- toYaml . | trim | nindent 8 }} 14 | {{- end }} 15 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/tests/deployment_test.yaml: -------------------------------------------------------------------------------- 1 | templates: 2 | - deployment.yaml 3 | tests: 4 | - it: should only add annotation `foo` with value `bar` 5 | set: 6 | global.app.annotations: 7 | foo: bar 8 | asserts: 9 | - equal: 10 | path: spec.template.metadata.annotations 11 | value: 12 | foo: bar 13 | localKey: localValue 14 | 15 | - it: should only add annotation `hello` with value `world` 16 | set: 17 | global.app.annotations: 18 | hello: world 19 | annotations: 20 | asserts: 21 | - equal: 22 | path: spec.template.metadata.annotations 23 | value: 24 | hello: world 25 | 26 | - it: should only add annotation `hello` with value `world` 27 | set: 28 | global.app.annotations: 29 | hello: world 30 | asserts: 31 | - equal: 32 | path: spec.template.metadata.annotations 33 | value: 34 | hello: world 35 | localKey: localValue 36 | -------------------------------------------------------------------------------- /test/data/v3/with-subsubcharts/values.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | app: 3 | annotations: {} 4 | --------------------------------------------------------------------------------