From 1cab6fa57a7e97e879364b20e227891065770c45 Mon Sep 17 00:00:00 2001 From: Adriano Cunha <35786489+adrcunha@users.noreply.github.com> Date: Thu, 29 Nov 2018 22:14:23 -0800 Subject: [PATCH] Update the vendored test-infra dir (#80) Updates `test-infra` to comply with knative/serving#2555, while also getting the latest fixes and features. Bonus: update the Gopkg files so the cleanup workaround in `update-deps.sh` is not necessary anymore. --- Gopkg.lock | 10 +- Gopkg.toml | 7 +- hack/update-deps.sh | 3 - vendor/github.com/knative/test-infra/LICENSE | 202 ++++++++++++++++++ .../knative/test-infra/scripts/README.md | 199 ++++++++++++++++- .../knative/test-infra/scripts/dummy.go | 26 +++ .../knative/test-infra/scripts/e2e-tests.sh | 183 ++++++++++------ .../knative/test-infra/scripts/library.sh | 104 ++++++--- .../test-infra/scripts/presubmit-tests.sh | 125 +++++++---- .../knative/test-infra/scripts/release.sh | 140 ++++++++---- 10 files changed, 818 insertions(+), 181 deletions(-) create mode 100644 vendor/github.com/knative/test-infra/LICENSE create mode 100644 vendor/github.com/knative/test-infra/scripts/dummy.go diff --git a/Gopkg.lock b/Gopkg.lock index 7eebaf9..bea0155 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,15 +3,15 @@ [[projects]] branch = "master" - digest = "1:3fb7a8860b93bd7b169fcb22123596763162a51b30c88fd86d5f6d8f92787edc" + digest = "1:0cabae2c3a124c49ed5e862866e1228f08a1a6e49d0daf971e5a72e5e56095a4" name = "github.com/knative/test-infra" - packages = ["."] - pruneopts = "" - revision = "c21d3a832727d5d4334e734c0878eac3a5a07ae7" + packages = ["scripts"] + pruneopts = "UT" + revision = "2377fbc40f81501f2bc09a4e1e359a7ec7c3528e" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - input-imports = ["github.com/knative/test-infra"] + input-imports = ["github.com/knative/test-infra/scripts"] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 9b4d481..87df6f8 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -2,9 +2,14 @@ # for detailed Gopkg.toml documentation. required = [ - "github.com/knative/test-infra", + "github.com/knative/test-infra/scripts", ] +[prune] + go-tests = true + unused-packages = true + non-go = true [[prune.project]] name = "github.com/knative/test-infra" + non-go = false diff --git a/hack/update-deps.sh b/hack/update-deps.sh index f1ac4db..5db46de 100755 --- a/hack/update-deps.sh +++ b/hack/update-deps.sh @@ -33,6 +33,3 @@ rm dummy.go rm -rf $(find vendor/ -name 'OWNERS') rm -rf $(find vendor/ -name '*_test.go') - -# Keep the only dir in knative/test-infra we're interested in -find vendor/github.com/knative/test-infra -mindepth 1 -maxdepth 1 ! -name scripts -exec rm -fr {} \; diff --git a/vendor/github.com/knative/test-infra/LICENSE b/vendor/github.com/knative/test-infra/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/vendor/github.com/knative/test-infra/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/knative/test-infra/scripts/README.md b/vendor/github.com/knative/test-infra/scripts/README.md index 5ff9ccb..0e7ab57 100644 --- a/vendor/github.com/knative/test-infra/scripts/README.md +++ b/vendor/github.com/knative/test-infra/scripts/README.md @@ -1,3 +1,200 @@ # Helper scripts -This directory contains helper scripts used by Prow test jobs, as well and local development scripts. +This directory contains helper scripts used by Prow test jobs, as well and +local development scripts. + +## Using the `presubmit-tests.sh` helper script + +This is a helper script to run the presubmit tests. To use it: + +1. Source this script. + +1. Define the functions `build_tests()` and `unit_tests()`. They should run all +tests (i.e., not fail fast), and return 0 if all passed, 1 if a failure +occurred. The environment variables `RUN_BUILD_TESTS`, `RUN_UNIT_TESTS` and +`RUN_INTEGRATION_TESTS` are set to 0 (false) or 1 (true) accordingly. If +`--emit-metrics` is passed, `EMIT_METRICS` will be set to 1. + +1. [optional] Define the function `integration_tests()`, just like the previous +ones. If you don't define this function, the default action for running the +integration tests is to call the `./test/e2e-tests.sh` script (passing the +`--emit-metrics` flag if necessary). + +1. [optional] Define the functions `pre_integration_tests()` or +`post_integration_tests()`. These functions will be called before or after the +integration tests (either your custom one or the default action) and will cause +the test to fail if they don't return success. + +1. Call the `main()` function passing `$@` (without quotes). + +Running the script without parameters, or with the `--all-tests` flag causes +all tests to be executed, in the right order (i.e., build, then unit, then +integration tests). + +Use the flags `--build-tests`, `--unit-tests` and `--integration-tests` to run +a specific set of tests. The flag `--emit-metrics` is used to emit metrics when +running the tests, and is automatically handled by the default action (see +above). + +### Sample presubmit test script + +```bash +source vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh + +function build_tests() { + go build . +} + +function unit_tests() { + report_go_test . +} + +function pre_integration_tests() { + echo "Cleaning up before integration tests" + rm -fr ./staging-area +} + +# We use the default integration test runner. + +main $@ +``` + +## Using the `e2e-tests.sh` helper script + +This is a helper script for Knative E2E test scripts. To use it: + +1. Source the script. + +1. [optional] Write the `teardown()` function, which will tear down your test +resources. + +1. [optional] Write the `dump_extra_cluster_state()` function. It will be +called when a test fails, and can dump extra information about the current state +of the cluster (tipically using `kubectl`). + +1. [optional] Write the `parse_flags()` function. It will be called whenever an +unrecognized flag is passed to the script, allowing you to define your own flags. +The function must return 0 if the flag is unrecognized, or the number of items +to skip in the command line if the flag was parsed successfully. For example, +return 1 for a simple flag, and 2 for a flag with a parameter. + +1. Call the `initialize()` function passing `$@` (without quotes). + +1. Write logic for the end-to-end tests. Run all go tests using `go_test_e2e()` +(or `report_go_test()` if you need a more fine-grained control) and call +`fail_test()` or `success()` if any of them failed. The environment variables +`DOCKER_REPO_OVERRIDE`, `K8S_CLUSTER_OVERRIDE` and `K8S_USER_OVERRIDE` will be set +according to the test cluster. You can also use the following boolean (0 is false, +1 is true) environment variables for the logic: + * `EMIT_METRICS`: true if `--emit-metrics` was passed. + * `USING_EXISTING_CLUSTER`: true if the test cluster is an already existing one, +and not a temporary cluster created by `kubetest`. + + All environment variables above are marked read-only. + +**Notes:** + +1. Calling your script without arguments will create a new cluster in the GCP +project `$PROJECT_ID` and run the tests against it. + +1. Calling your script with `--run-tests` and the variables `K8S_CLUSTER_OVERRIDE`, +`K8S_USER_OVERRIDE` and `DOCKER_REPO_OVERRIDE` set will immediately start the +tests against the cluster. + +1. You can force running the tests against a specific GKE cluster version by using +the `--cluster-version` flag and passing a X.Y.Z version as the flag value. + +### Sample end-to-end test script + +This script will test that the latest Knative Serving nightly release works. It +defines a special flag (`--no-knative-wait`) that causes the script not to +wait for Knative Serving to be up before running the tests. + +```bash +source vendor/github.com/knative/test-infra/scripts/e2e-tests.sh + +function teardown() { + echo "TODO: tear down test resources" +} + +function parse_flags() { + if [[ "$1" == "--no-knative-wait" ]]; then + WAIT_FOR_KNATIVE=0 + return 1 + fi + return 0 +} + +WAIT_FOR_KNATIVE=1 + +initialize $@ + +start_latest_knative_serving + +if (( WAIT_FOR_KNATIVE )); then + wait_until_pods_running knative-serving || fail_test "Knative Serving is not up" +fi + +# TODO: use go_test_e2e to run the tests. +kubectl get pods || fail_test + +success +``` + +## Using the `release.sh` helper script + +This is a helper script for Knative release scripts. To use it: + +1. Source the script. + +1. Call the `initialize()` function passing `$@` (without quotes). + +1. Call the `run_validation_tests()` function passing the script or executable that +runs the release validation tests. It will call the script to run the tests unless +`--skip_tests` was passed. + +1. Write logic for the release process. Call `publish_yaml()` to publish the manifest(s), +`tag_releases_in_yaml()` to tag the generated images, `branch_release()` to branch +named releases. Use the following boolean (0 is false, 1 is true) and string environment +variables for the logic: + * `RELEASE_VERSION`: contains the release version if `--version` was passed. This +also overrides the value of the `TAG` variable as `v`. + * `RELEASE_BRANCH`: contains the release branch if `--branch` was passed. Otherwise +it's empty and `master` HEAD will be considered the release branch. + * `RELEASE_NOTES`: contains the filename with the release notes if `--release-notes` +was passed. The release notes is a simple markdown file. + * `SKIP_TESTS`: true if `--skip-tests` was passed. This is handled automatically +by the run_validation_tests() function. + * `TAG_RELEASE`: true if `--tag-release` was passed. In this case, the environment +variable `TAG` will contain the release tag in the form `vYYYYMMDD-`. + * `PUBLISH_RELEASE`: true if `--publish` was passed. In this case, the environment +variable `KO_FLAGS` will be updated with the `-L` option. + * `BRANCH_RELEASE`: true if both `--version` and `--publish-release` were passed. + + All boolean environment variables default to false for safety. + + All environment variables above, except `KO_FLAGS`, are marked read-only once +`initialize()` is called. + +### Sample release script + +```bash +source vendor/github.com/knative/test-infra/scripts/release.sh + +initialize $@ + +run_validation_tests ./test/presubmit-tests.sh + +# config/ contains the manifests +KO_DOCKER_REPO=gcr.io/knative-foo +ko resolve ${KO_FLAGS} -f config/ > release.yaml + +tag_images_in_yaml release.yaml $KO_DOCKER_REPO $TAG + +if (( PUBLISH_RELEASE )); then + # gs://knative-foo hosts the manifest + publish_yaml release.yaml knative-foo $TAG +fi + +branch_release "Knative Foo" release.yaml +``` diff --git a/vendor/github.com/knative/test-infra/scripts/dummy.go b/vendor/github.com/knative/test-infra/scripts/dummy.go new file mode 100644 index 0000000..e6cc380 --- /dev/null +++ b/vendor/github.com/knative/test-infra/scripts/dummy.go @@ -0,0 +1,26 @@ +/* +Copyright 2018 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scripts + +import ( + "fmt" +) + +func main() { + fmt.Println("This is a dummy go file so `go dep` can be used with knative/test-infra/scripts") + fmt.Println("This file can be safely removed if one day this directory contains real, useful go code") +} diff --git a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh index 7c92104..b1dd664 100755 --- a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh @@ -14,29 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a helper script for Knative E2E test scripts. To use it: -# 1. Source this script. -# 2. [optional] Write the teardown() function, which will tear down your test -# resources. -# 3. [optional] Write the dump_extra_cluster_state() function. It will be called -# when a test fails, and can dump extra information about the current state of -# the cluster (tipically using kubectl). -# 4. Call the initialize() function passing $@ (without quotes). -# 5. Write logic for the end-to-end tests. Run all go tests using report_go_test() -# and call fail_test() or success() if any of them failed. The envitronment -# variables DOCKER_REPO_OVERRIDE, K8S_CLUSTER_OVERRIDE and K8S_USER_OVERRIDE -# will be set accordingly to the test cluster. You can also use the following -# boolean (0 is false, 1 is true) environment variables for the logic: -# EMIT_METRICS: true if --emit-metrics is passed. -# USING_EXISTING_CLUSTER: true if the test cluster is an already existing one, -# and not a temporary cluster created by kubetest. -# All environment variables above are marked read-only. -# Notes: -# 1. Calling your script without arguments will create a new cluster in the GCP -# project $PROJECT_ID and run the tests against it. -# 2. Calling your script with --run-tests and the variables K8S_CLUSTER_OVERRIDE, -# K8S_USER_OVERRIDE and DOCKER_REPO_OVERRIDE set will immediately start the -# tests against the cluster. +# This is a helper script for Knative E2E test scripts. +# See README.md for instructions on how to use it. source $(dirname ${BASH_SOURCE})/library.sh @@ -51,7 +30,9 @@ function build_resource_name() { if [[ -n "${suffix}" ]]; then suffix=${suffix:${#suffix}<20?0:-20} fi - echo "${prefix:0:20}${suffix}" + local name="${prefix:0:20}${suffix}" + # Ensure name doesn't end with "-" + echo "${name%-}" } # Test cluster parameters @@ -64,23 +45,19 @@ readonly E2E_CLUSTER_NODES=3 readonly E2E_CLUSTER_MACHINE=n1-standard-4 readonly TEST_RESULT_FILE=/tmp/${E2E_BASE_NAME}-e2e-result +# Flag whether test is using a boskos GCP project +IS_BOSKOS=0 + # Tear down the test resources. function teardown_test_resources() { header "Tearing down test environment" # Free resources in GCP project. - if (( ! USING_EXISTING_CLUSTER )) && [[ "$(type -t teardown)" == "function" ]]; then + if (( ! USING_EXISTING_CLUSTER )) && function_exists teardown; then teardown fi - # Delete Knative Serving images when using prow. - if (( IS_PROW )); then - echo "Images in ${DOCKER_REPO_OVERRIDE}:" - gcloud container images list --repository=${DOCKER_REPO_OVERRIDE} - delete_gcr_images ${DOCKER_REPO_OVERRIDE} - else - # Delete the kubernetes source downloaded by kubetest - rm -fr kubernetes kubernetes.tar.gz - fi + # Delete the kubernetes source downloaded by kubetest + rm -fr kubernetes kubernetes.tar.gz } # Exit test, dumping current state info. @@ -91,22 +68,36 @@ function fail_test() { exit 1 } +# Run the given E2E tests. Assume tests are tagged e2e, unless `-tags=XXX` is passed. +# Parameters: $1..$n - any go test flags, then directories containing the tests to run. +function go_test_e2e() { + local test_options="" + local go_options="" + (( EMIT_METRICS )) && test_options="-emitmetrics" + [[ ! " $@" == *" -tags="* ]] && go_options="-tags=e2e" + report_go_test -v -count=1 ${go_options} $@ ${test_options} +} + # Download the k8s binaries required by kubetest. +# Parameters: $1 - GCP project that will host the test cluster. function download_k8s() { - local version=${SERVING_GKE_VERSION} + local version=${E2E_CLUSTER_VERSION} + # Fetch valid versions + local versions="$(gcloud container get-server-config \ + --project=$1 \ + --format='value(validMasterVersions)' \ + --region=${E2E_CLUSTER_REGION})" + local gke_versions=(`echo -n ${versions//;/ /}`) + echo "Valid GKE versions are [${versions//;/, }]" if [[ "${version}" == "latest" ]]; then - # Fetch latest valid version - local versions="$(gcloud container get-server-config \ - --project=${GCP_PROJECT} \ - --format='value(validMasterVersions)' \ - --region=${E2E_CLUSTER_REGION})" - local gke_versions=(`echo -n ${versions//;/ /}`) # Get first (latest) version, excluding the "-gke.#" suffix version="${gke_versions[0]%-*}" - echo "Latest GKE is ${version}, from [${versions//;/, }]" + echo "Using latest version, ${version}" elif [[ "${version}" == "default" ]]; then echo "ERROR: `default` GKE version is not supported yet" return 1 + else + echo "Using command-line supplied version ${version}" fi # Download k8s to staging dir version=v${version} @@ -124,6 +115,7 @@ function download_k8s() { mv kubernetes/client/kubernetes-client-*.tar.gz . rm -fr kubernetes # Create an empty kubernetes test tarball; we don't use it but kubetest will fetch it + # As of August 21 2018 this means avoiding a useless 1.2GB download tar -czf kubernetes-test.tar.gz -T /dev/null fi popd @@ -134,7 +126,7 @@ function download_k8s() { # This is intended to be called when a test fails to provide debugging information. function dump_cluster_state() { echo "***************************************" - echo "*** TEST FAILED ***" + echo "*** E2E TEST FAILED ***" echo "*** Start of information dump ***" echo "***************************************" echo ">>> All resources:" @@ -143,9 +135,9 @@ function dump_cluster_state() { kubectl get services --all-namespaces echo ">>> Events:" kubectl get events --all-namespaces - [[ "$(type -t dump_extra_cluster_state)" == "function" ]] && dump_extra_cluster_state + function_exists dump_extra_cluster_state && dump_extra_cluster_state echo "***************************************" - echo "*** TEST FAILED ***" + echo "*** E2E TEST FAILED ***" echo "*** End of information dump ***" echo "***************************************" } @@ -168,10 +160,10 @@ function create_test_cluster() { --gcp-network="${E2E_NETWORK_NAME}" --gke-environment=prod ) - if (( ! IS_PROW )); then - CLUSTER_CREATION_ARGS+=(--gcp-project=${PROJECT_ID:?"PROJECT_ID must be set to the GCP project where the tests are run."}) - else + if (( IS_BOSKOS )); then CLUSTER_CREATION_ARGS+=(--gcp-service-account=/etc/service-account/service-account.json) + else + CLUSTER_CREATION_ARGS+=(--gcp-project=${GCP_PROJECT}) fi # SSH keys are not used, but kubetest checks for their existence. # Touch them so if they don't exist, empty files are create to satisfy the check. @@ -183,45 +175,52 @@ function create_test_cluster() { # be a writeable docker repo. export K8S_USER_OVERRIDE= export K8S_CLUSTER_OVERRIDE= - # Get the current GCP project - export GCP_PROJECT=${PROJECT_ID} - [[ -z ${GCP_PROJECT} ]] && export GCP_PROJECT=$(gcloud config get-value project) # Assume test failed (see more details at the end of this script). echo -n "1"> ${TEST_RESULT_FILE} local test_cmd_args="--run-tests" (( EMIT_METRICS )) && test_cmd_args+=" --emit-metrics" + [[ -n "${GCP_PROJECT}" ]] && test_cmd_args+=" --gcp-project ${GCP_PROJECT}" + # Get the current GCP project for downloading kubernetes + local gcloud_project="${GCP_PROJECT}" + [[ -z "${gcloud_project}" ]] && gcloud_project="$(gcloud config get-value project)" + echo "gcloud project is ${gcloud_project}" + (( IS_BOSKOS )) && echo "Using boskos for the test cluster" + [[ -n "${GCP_PROJECT}" ]] && echo "GCP project for test cluster is ${GCP_PROJECT}" echo "Test script is ${E2E_SCRIPT}" - download_k8s || return 1 + download_k8s ${gcloud_project} || return 1 # Don't fail test for kubetest, as it might incorrectly report test failure # if teardown fails (for details, see success() below) set +o errexit - kubetest "${CLUSTER_CREATION_ARGS[@]}" \ + run_go_tool k8s.io/test-infra/kubetest \ + kubetest "${CLUSTER_CREATION_ARGS[@]}" \ --up \ --down \ --extract local \ - --gcp-node-image ${SERVING_GKE_IMAGE} \ + --gcp-node-image "${SERVING_GKE_IMAGE}" \ --test-cmd "${E2E_SCRIPT}" \ --test-cmd-args "${test_cmd_args}" echo "Test subprocess exited with code $?" # Ignore any errors below, this is a best-effort cleanup and shouldn't affect the test result. set +o errexit + # Ensure we're using the GCP project used by kubetest + gcloud_project="$(gcloud config get-value project)" # Delete target pools and health checks that might have leaked. # See https://github.com/knative/serving/issues/959 for details. # TODO(adrcunha): Remove once the leak issue is resolved. local http_health_checks="$(gcloud compute target-pools list \ - --project=${GCP_PROJECT} --format='value(healthChecks)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ + --project=${gcloud_project} --format='value(healthChecks)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ grep httpHealthChecks | tr '\n' ' ')" local target_pools="$(gcloud compute target-pools list \ - --project=${GCP_PROJECT} --format='value(name)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ + --project=${gcloud_project} --format='value(name)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ tr '\n' ' ')" if [[ -n "${target_pools}" ]]; then echo "Found leaked target pools, deleting" - gcloud compute forwarding-rules delete -q --project=${GCP_PROJECT} --region=${E2E_CLUSTER_REGION} ${target_pools} - gcloud compute target-pools delete -q --project=${GCP_PROJECT} --region=${E2E_CLUSTER_REGION} ${target_pools} + gcloud compute forwarding-rules delete -q --project=${gcloud_project} --region=${E2E_CLUSTER_REGION} ${target_pools} + gcloud compute target-pools delete -q --project=${gcloud_project} --region=${E2E_CLUSTER_REGION} ${target_pools} fi if [[ -n "${http_health_checks}" ]]; then echo "Found leaked health checks, deleting" - gcloud compute http-health-checks delete -q --project=${GCP_PROJECT} ${http_health_checks} + gcloud compute http-health-checks delete -q --project=${gcloud_project} ${http_health_checks} fi local result="$(cat ${TEST_RESULT_FILE})" echo "Test result code is $result" @@ -257,9 +256,11 @@ function setup_test_cluster() { echo "- User is ${K8S_USER_OVERRIDE}" echo "- Docker is ${DOCKER_REPO_OVERRIDE}" + export KO_DOCKER_REPO="${DOCKER_REPO_OVERRIDE}" + trap teardown_test_resources EXIT - if (( USING_EXISTING_CLUSTER )) && [[ "$(type -t teardown)" == "function" ]]; then + if (( USING_EXISTING_CLUSTER )) && function_exists teardown; then echo "Deleting any previous SUT instance" teardown fi @@ -281,7 +282,7 @@ function success() { # TODO(adrcunha): Get rid of this workaround. echo -n "0"> ${TEST_RESULT_FILE} echo "**************************************" - echo "*** ALL TESTS PASSED ***" + echo "*** E2E TESTS PASSED ***" echo "**************************************" exit 0 } @@ -289,7 +290,14 @@ function success() { RUN_TESTS=0 EMIT_METRICS=0 USING_EXISTING_CLUSTER=1 +GCP_PROJECT="" E2E_SCRIPT="" +E2E_CLUSTER_VERSION="" + +function abort() { + echo "error: $@" + exit 1 +} # Parse flags and initialize the test cluster. function initialize() { @@ -299,21 +307,66 @@ function initialize() { E2E_SCRIPT="$(cd ${E2E_SCRIPT%/*} && echo $PWD/${E2E_SCRIPT##*/})" readonly E2E_SCRIPT + E2E_CLUSTER_VERSION="${SERVING_GKE_VERSION}" + cd ${REPO_ROOT_DIR} - for parameter in $@; do + while [[ $# -ne 0 ]]; do + local parameter=$1 + # Try parsing flag as a custom one. + if function_exists parse_flags; then + parse_flags $@ + local skip=$? + if [[ ${skip} -ne 0 ]]; then + # Skip parsed flag (and possibly argument) and continue + shift ${skip} + continue + fi + fi + # Try parsing flag as a standard one. case $parameter in --run-tests) RUN_TESTS=1 ;; --emit-metrics) EMIT_METRICS=1 ;; + --gcp-project) + shift + [[ $# -ge 1 ]] || abort "missing project name after --gcp-project" + GCP_PROJECT=$1 + ;; + --cluster-version) + shift + [[ $# -ge 1 ]] || abort "missing version after --cluster-version" + [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || abort "kubernetes version must be 'X.Y.Z'" + E2E_CLUSTER_VERSION=$1 + ;; *) - echo "error: unknown option ${parameter}" - echo "usage: $0 [--run-tests][--emit-metrics]" - exit 1 + echo "usage: $0 [--run-tests][--emit-metrics][--cluster-version X.Y.Z][--gcp-project name]" + abort "unknown option ${parameter}" ;; esac shift done + + # Use PROJECT_ID if set, unless --gcp-project was used. + if [[ -n "${PROJECT_ID:-}" && -z "${GCP_PROJECT}" ]]; then + echo "\$PROJECT_ID is set to '${PROJECT_ID}', using it to run the tests" + GCP_PROJECT="${PROJECT_ID}" + fi + if (( ! IS_PROW )) && [[ -z "${GCP_PROJECT}" ]]; then + abort "set \$PROJECT_ID or use --gcp-project to select the GCP project where the tests are run" + fi + + (( IS_PROW )) && [[ -z "${GCP_PROJECT}" ]] && IS_BOSKOS=1 + + # Safety checks + + if [[ "${DOCKER_REPO_OVERRIDE}" =~ ^gcr.io/knative-(releases|nightly)/?$ ]]; then + abort "\$DOCKER_REPO_OVERRIDE is set to ${DOCKER_REPO_OVERRIDE}, which is forbidden" + fi + readonly RUN_TESTS readonly EMIT_METRICS + readonly E2E_CLUSTER_VERSION + readonly GCP_PROJECT + readonly IS_BOSKOS if (( ! RUN_TESTS )); then create_test_cluster diff --git a/vendor/github.com/knative/test-infra/scripts/library.sh b/vendor/github.com/knative/test-infra/scripts/library.sh index a330f4d..ba267d9 100755 --- a/vendor/github.com/knative/test-infra/scripts/library.sh +++ b/vendor/github.com/knative/test-infra/scripts/library.sh @@ -22,11 +22,12 @@ readonly SERVING_GKE_VERSION=latest readonly SERVING_GKE_IMAGE=cos -# Public images and yaml files. -readonly KNATIVE_ISTIO_YAML=https://storage.googleapis.com/knative-releases/serving/latest/istio.yaml -readonly KNATIVE_SERVING_RELEASE=https://storage.googleapis.com/knative-releases/serving/latest/release.yaml -readonly KNATIVE_BUILD_RELEASE=https://storage.googleapis.com/knative-releases/build/latest/release.yaml -readonly KNATIVE_EVENTING_RELEASE=https://storage.googleapis.com/knative-releases/eventing/latest/release.yaml +# Public latest stable nightly images and yaml files. +readonly KNATIVE_ISTIO_CRD_YAML=https://storage.googleapis.com/knative-nightly/serving/latest/istio-crds.yaml +readonly KNATIVE_ISTIO_YAML=https://storage.googleapis.com/knative-nightly/serving/latest/istio.yaml +readonly KNATIVE_SERVING_RELEASE=https://storage.googleapis.com/knative-nightly/serving/latest/release.yaml +readonly KNATIVE_BUILD_RELEASE=https://storage.googleapis.com/knative-nightly/build/latest/release.yaml +readonly KNATIVE_EVENTING_RELEASE=https://storage.googleapis.com/knative-nightly/eventing/latest/release.yaml # Conveniently set GOPATH if unset if [[ -z "${GOPATH:-}" ]]; then @@ -46,7 +47,7 @@ readonly REPO_ROOT_DIR="$(git rev-parse --show-toplevel)" # $2 - banner message. function make_banner() { local msg="$1$1$1$1 $2 $1$1$1$1" - local border="${msg//[-0-9A-Za-z _.,]/$1}" + local border="${msg//[-0-9A-Za-z _.,\/]/$1}" echo -e "${border}\n${msg}\n${border}" } @@ -66,6 +67,11 @@ function warning() { make_banner "!" "$1" } +# Checks whether the given function exists. +function function_exists() { + [[ "$(type -t $1)" == "function" ]] +} + # Remove ALL images in the given GCR repository. # Parameters: $1 - GCR repository. function delete_gcr_images() { @@ -94,7 +100,10 @@ function wait_until_object_does_not_exist() { fi echo -n "Waiting until ${DESCRIPTION} does not exist" for i in {1..150}; do # timeout after 5 minutes - kubectl ${KUBECTL_ARGS} 2>&1 > /dev/null || return 0 + if kubectl ${KUBECTL_ARGS} > /dev/null 2>&1; then + echo "\n${DESCRIPTION} does not exist" + return 0 + fi echo -n "." sleep 2 done @@ -172,13 +181,21 @@ function wait_until_routable() { return 1 } -# Returns the name of the pod of the given app. +# Returns the name of the first pod of the given app. # Parameters: $1 - app name. # $2 - namespace (optional). function get_app_pod() { + local pods=($(get_app_pods $1 $2)) + echo "${pods[0]}" +} + +# Returns the name of all pods of the given app. +# Parameters: $1 - app name. +# $2 - namespace (optional). +function get_app_pods() { local namespace="" [[ -n $2 ]] && namespace="-n $2" - kubectl get pods ${namespace} --selector=app=$1 --output=jsonpath="{.items[0].metadata.name}" + kubectl get pods ${namespace} --selector=app=$1 --output=jsonpath="{.items[*].metadata.name}" } # Sets the given user as cluster admin. @@ -220,8 +237,8 @@ function acquire_cluster_admin_role() { function report_go_test() { # Run tests in verbose mode to capture details. # go doesn't like repeating -v, so remove if passed. - local args=("${@/-v}") - local go_test="go test -race -v ${args[@]}" + local args=" $@ " + local go_test="go test -race -v ${args/ -v / }" # Just run regular go tests if not on Prow. if (( ! IS_PROW )); then ${go_test} @@ -231,13 +248,16 @@ function report_go_test() { local report=$(mktemp) local failed=0 local test_count=0 + local tests_failed=0 ${go_test} > ${report} || failed=$? echo "Finished run, return code is ${failed}" # Tests didn't run. [[ ! -s ${report} ]] && return 1 - # Create WORKSPACE file, required to use bazel + # Create WORKSPACE file, required to use bazel, if necessary. touch WORKSPACE local targets="" + local last_run="" + local test_files="" # Parse the report and generate fake tests for each passing/failing test. echo "Start parsing results, summary:" while read line ; do @@ -245,16 +265,35 @@ function report_go_test() { local field0="${fields[0]}" local field1="${fields[1]}" local name="${fields[2]}" + # Deal with a SIGQUIT log entry (usually a test timeout). + # This is a fallback in case there's no kill signal log entry. + # SIGQUIT: quit + if [[ "${field0}" == "SIGQUIT:" ]]; then + name="${last_run}" + field1="FAIL:" + error="${fields[@]}" + fi # Ignore subtests (those containing slashes) if [[ -n "${name##*/*}" ]]; then local error="" + # Deal with a kill signal log entry (usually a test timeout). + # *** Test killed with quit: ran too long (10m0s). + if [[ "${field0}" == "***" ]]; then + name="${last_run}" + field1="FAIL:" + error="${fields[@]:1}" + fi # Deal with a fatal log entry, which has a different format: # fatal TestFoo foo_test.go:275 Expected "foo" but got "bar" if [[ "${field0}" == "fatal" ]]; then - name="${fields[1]}" + name="${field1}" field1="FAIL:" error="${fields[@]:3}" fi + # Keep track of the test currently running. + if [[ "${field1}" == "RUN" ]]; then + last_run="${name}" + fi # Handle regular go test pass/fail entry for a test. if [[ "${field1}" == "PASS:" || "${field1}" == "FAIL:" ]]; then echo "- ${name} :${field1}" @@ -262,6 +301,7 @@ function report_go_test() { local src="${name}.sh" echo "exit 0" > ${src} if [[ "${field1}" == "FAIL:" ]]; then + tests_failed=$(( tests_failed + 1 )) [[ -z "${error}" ]] && read error echo "cat < ${src} echo "${error}" >> ${src} @@ -269,13 +309,14 @@ function report_go_test() { echo "exit 1" >> ${src} fi chmod +x ${src} + test_files="${test_files} ${src}" # Populate BUILD.bazel echo "sh_test(name=\"${name}\", srcs=[\"${src}\"])" >> BUILD.bazel elif [[ "${field0}" == "FAIL" || "${field0}" == "ok" ]] && [[ -n "${field1}" ]]; then echo "- ${field0} ${field1}" # Create the package structure, move tests and BUILD file local package=${field1/github.com\//} - local bazel_files="$(ls -1 *.sh BUILD.bazel 2> /dev/null)" + local bazel_files="$(ls -1 ${test_files} BUILD.bazel 2> /dev/null)" if [[ -n "${bazel_files}" ]]; then mkdir -p ${package} targets="${targets} //${package}/..." @@ -283,19 +324,24 @@ function report_go_test() { else echo "*** INTERNAL ERROR: missing tests for ${package}, got [${bazel_files/$'\n'/, }]" fi + test_files="" fi fi done < ${report} - echo "Done parsing ${test_count} tests" + echo "Done parsing ${test_count} tests, ${tests_failed} tests failed" # If any test failed, show the detailed report. # Otherwise, we already shown the summary. # Exception: when emitting metrics, dump the full report. if (( failed )) || [[ "$@" == *" -emitmetrics"* ]]; then - echo "At least one test failed, full log:" + if (( failed )); then + echo "There were ${tests_failed} test failures, full log:" + else + echo "Dumping full log as metrics were requested:" + fi cat ${report} fi # Always generate the junit summary. - bazel test ${targets} > /dev/null 2>&1 + bazel test ${targets} > /dev/null 2>&1 || true return ${failed} } @@ -303,6 +349,7 @@ function report_go_test() { function start_latest_knative_serving() { header "Starting Knative Serving" subheader "Installing Istio" + kubectl apply -f ${KNATIVE_ISTIO_CRD_YAML} || return 1 kubectl apply -f ${KNATIVE_ISTIO_YAML} || return 1 wait_until_pods_running istio-system || return 1 kubectl label namespace default istio-injection=enabled || return 1 @@ -323,14 +370,19 @@ function start_latest_knative_build() { wait_until_pods_running knative-build || return 1 } -# Run dep-collector, installing it first if necessary. -# Parameters: $1..$n - parameters passed to dep-collector. -function run_dep_collector() { - local local_dep_collector="$(which dep-collector)" - if [[ -z ${local_dep_collector} ]]; then - go get -u github.com/mattmoor/dep-collector +# Run a go tool, installing it first if necessary. +# Parameters: $1 - tool package/dir for go get/install. +# $2 - tool to run. +# $3..$n - parameters passed to the tool. +function run_go_tool() { + local tool=$2 + if [[ -z "$(which ${tool})" ]]; then + local action=get + [[ $1 =~ ^[\./].* ]] && action=install + go ${action} $1 fi - dep-collector $@ + shift 2 + ${tool} "$@" } # Run dep-collector to update licenses. @@ -340,7 +392,7 @@ function update_licenses() { cd ${REPO_ROOT_DIR} || return 1 local dst=$1 shift - run_dep_collector $@ > ./${dst} + run_go_tool ./vendor/github.com/knative/test-infra/tools/dep-collector dep-collector $@ > ./${dst} } # Run dep-collector to check for forbidden liceses. @@ -349,7 +401,7 @@ function check_licenses() { # Fetch the google/licenseclassifier for its license db go get -u github.com/google/licenseclassifier # Check that we don't have any forbidden licenses in our images. - run_dep_collector -check $@ + run_go_tool ./vendor/github.com/knative/test-infra/tools/dep-collector dep-collector -check $@ } # Run the given linter on the given files, checking it exists first. diff --git a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh index b611681..5818fab 100755 --- a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh @@ -14,26 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a helper script to run the presubmit tests. To use it: -# 1. Source this script. -# 2. Define the functions build_tests(), unit_tests() and -# integration_tests(). They should run all tests (i.e., not fail -# fast), and return 0 if all passed, 1 if a failure occurred. -# The environment variables RUN_BUILD_TESTS, RUN_UNIT_TESTS and -# RUN_INTEGRATION_TESTS are set to 0 (false) or 1 (true) accordingly. -# If --emit-metrics is passed, EMIT_METRICS will be set to 1. -# 3. Call the main() function passing $@ (without quotes). -# -# Running the script without parameters, or with the --all-tests -# flag, causes all tests to be executed, in the right order. -# Use the flags --build-tests, --unit-tests and --integration-tests -# to run a specific set of tests. The flag --emit-metrics is used -# to emit metrics when running the tests. +# This is a helper script for Knative presubmit test scripts. +# See README.md for instructions on how to use it. source $(dirname ${BASH_SOURCE})/library.sh # Extensions or file patterns that don't require presubmit tests. -readonly NO_PRESUBMIT_FILES=(\.md \.png ^OWNERS) +readonly NO_PRESUBMIT_FILES=(\.md \.png ^OWNERS ^OWNERS_ALIASES) # Options set by command-line flags. RUN_BUILD_TESTS=0 @@ -61,62 +48,114 @@ function exit_if_presubmit_not_required() { fi } +function abort() { + echo "error: $@" + exit 1 +} + # Process flags and run tests accordingly. function main() { exit_if_presubmit_not_required - local all_parameters=$@ - [[ -z $1 ]] && all_parameters="--all-tests" + # Show the version of the tools we're using + if (( IS_PROW )); then + # Disable gcloud update notifications + gcloud config set component_manager/disable_update_check true + header "Current test setup" + echo ">> gcloud SDK version" + gcloud version + echo ">> kubectl version" + kubectl version + echo ">> go version" + go version + echo ">> git version" + git version + fi - for parameter in ${all_parameters}; do + [[ -z $1 ]] && set -- "--all-tests" + + local TEST_TO_RUN="" + + while [[ $# -ne 0 ]]; do + local parameter=$1 case ${parameter} in + --build-tests) RUN_BUILD_TESTS=1 ;; + --unit-tests) RUN_UNIT_TESTS=1 ;; + --integration-tests) RUN_INTEGRATION_TESTS=1 ;; + --emit-metrics) EMIT_METRICS=1 ;; --all-tests) RUN_BUILD_TESTS=1 RUN_UNIT_TESTS=1 RUN_INTEGRATION_TESTS=1 - shift ;; - --build-tests) - RUN_BUILD_TESTS=1 - shift - ;; - --unit-tests) - RUN_UNIT_TESTS=1 + --run-test) shift + [[ $# -ge 1 ]] || abort "missing executable after --run-test" + TEST_TO_RUN=$1 ;; - --integration-tests) - RUN_INTEGRATION_TESTS=1 - shift - ;; - --emit-metrics) - EMIT_METRICS=1 - shift - ;; - *) - echo "error: unknown option ${parameter}" - exit 1 - ;; + *) abort "error: unknown option ${parameter}" ;; esac + shift done readonly RUN_BUILD_TESTS readonly RUN_UNIT_TESTS readonly RUN_INTEGRATION_TESTS readonly EMIT_METRICS + readonly TEST_TO_RUN cd ${REPO_ROOT_DIR} # Tests to be performed, in the right order if --all-tests is passed. - local result=0 + local failed=0 + + if [[ -n "${TEST_TO_RUN}" ]]; then + if (( RUN_BUILD_TESTS || RUN_UNIT_TESTS || RUN_INTEGRATION_TESTS )); then + abort "--run-test must be used alone" + fi + ${TEST_TO_RUN} || failed=1 + fi + if (( RUN_BUILD_TESTS )); then - build_tests || result=1 + build_tests || failed=1 fi if (( RUN_UNIT_TESTS )); then - unit_tests || result=1 + unit_tests || failed=1 fi if (( RUN_INTEGRATION_TESTS )); then - integration_tests || result=1 + local e2e_failed=0 + # Run pre-integration tests, if any + if function_exists pre_integration_tests; then + if ! pre_integration_tests; then + failed=1 + e2e_failed=1 + fi + fi + # Don't run integration tests if pre-integration tests failed + if (( ! e2e_failed )); then + if function_exists integration_tests; then + if ! integration_tests; then + failed=1 + e2e_failed=1 + fi + else + local options="" + (( EMIT_METRICS )) && options="--emit-metrics" + for e2e_test in ./test/e2e-*tests.sh; do + echo "Running integration test ${e2e_test}" + if ! ${e2e_test} ${options}; then + failed=1 + e2e_failed=1 + fi + done + fi + fi + # Don't run post-integration + if (( ! e2e_failed )) && function_exists post_integration_tests; then + post_integration_tests || failed=1 + fi fi - exit ${result} + + exit ${failed} } diff --git a/vendor/github.com/knative/test-infra/scripts/release.sh b/vendor/github.com/knative/test-infra/scripts/release.sh index abf89dd..cbde3c6 100755 --- a/vendor/github.com/knative/test-infra/scripts/release.sh +++ b/vendor/github.com/knative/test-infra/scripts/release.sh @@ -14,27 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a helper script for Knative release scripts. To use it: -# 1. Source this script. -# 2. Call the parse_flags() function passing $@ (without quotes). -# 3. Call the run_validation_tests() passing the script or executable that -# runs the release validation tests. -# 4. Write logic for the release process. Use the following boolean (0 is -# false, 1 is true) environment variables for the logic: -# SKIP_TESTS: true if --skip-tests is passed. This is handled automatically -# by the run_validation_tests() function. -# TAG_RELEASE: true if --tag-release is passed. In this case, the -# environment variable TAG will contain the release tag in the -# form vYYYYMMDD-. -# PUBLISH_RELEASE: true if --publish is passed. In this case, the environment -# variable KO_FLAGS will be updated with the -L option. -# SKIP_TESTS, TAG_RELEASE and PUBLISH_RELEASE default to false for safety. -# All environment variables above, except KO_FLAGS, are marked read-only once -# parse_flags() is called. +# This is a helper script for Knative release scripts. +# See README.md for instructions on how to use it. source $(dirname ${BASH_SOURCE})/library.sh # Simple banner for logging purposes. +# Parameters: $1 - message to display. function banner() { make_banner "@" "$1" } @@ -45,8 +31,10 @@ function banner() { # $3 - tag to apply (optional). function tag_images_in_yaml() { [[ -z $3 ]] && return 0 - echo "Tagging images with $3" - for image in $(grep -o "$2/[a-z\./-]\+@sha256:[0-9a-f]\+" $1); do + local src_dir="${GOPATH}/src/" + local BASE_PATH="${REPO_ROOT_DIR/$src_dir}" + echo "Tagging images under '${BASE_PATH}' with $3" + for image in $(grep -o "$2/${BASE_PATH}/[a-z\./-]\+@sha256:[0-9a-f]\+" $1); do gcloud -q container images add-tag ${image} ${image%%@*}:$3 done } @@ -57,54 +45,92 @@ function tag_images_in_yaml() { # $3 - tag to apply (optional). function publish_yaml() { gsutil cp $1 gs://$2/latest/ - [[ -n $3 ]] && gsutil cp $1 gs://$2/previous/$3/ + [[ -n $3 ]] && gsutil cp $1 gs://$2/previous/$3/ || true } +# These are global environment variables. SKIP_TESTS=0 TAG_RELEASE=0 PUBLISH_RELEASE=0 +BRANCH_RELEASE=0 TAG="" -KO_FLAGS="-P -L" +RELEASE_VERSION="" +RELEASE_NOTES="" +RELEASE_BRANCH="" +KO_FLAGS="" + +function abort() { + echo "error: $@" + exit 1 +} # Parses flags and sets environment variables accordingly. function parse_flags() { + TAG="" + RELEASE_VERSION="" + RELEASE_NOTES="" + RELEASE_BRANCH="" + KO_FLAGS="-P" cd ${REPO_ROOT_DIR} - for parameter in $@; do + while [[ $# -ne 0 ]]; do + local parameter=$1 case $parameter in --skip-tests) SKIP_TESTS=1 ;; --tag-release) TAG_RELEASE=1 ;; --notag-release) TAG_RELEASE=0 ;; - --publish) - PUBLISH_RELEASE=1 - # Remove -L from ko flags - KO_FLAGS="${KO_FLAGS/-L}" + --publish) PUBLISH_RELEASE=1 ;; + --nopublish) PUBLISH_RELEASE=0 ;; + --version) + shift + [[ $# -ge 1 ]] || abort "missing version after --version" + [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || abort "version format must be '[0-9].[0-9].[0-9]'" + RELEASE_VERSION=$1 ;; - --nopublish) - PUBLISH_RELEASE=0 - # Add -L to ko flags - KO_FLAGS="-L ${KO_FLAGS}" + --branch) shift + [[ $# -ge 1 ]] || abort "missing branch after --commit" + [[ $1 =~ ^release-[0-9]+\.[0-9]+$ ]] || abort "branch name must be 'release-[0-9].[0-9]'" + RELEASE_BRANCH=$1 ;; - *) - echo "error: unknown option ${parameter}" - exit 1 + --release-notes) + shift + [[ $# -ge 1 ]] || abort "missing release notes file after --release-notes" + [[ ! -f "$1" ]] && abort "file $1 doesn't exist" + RELEASE_NOTES=$1 ;; + *) abort "unknown option ${parameter}" ;; esac shift done - TAG="" + # Update KO_DOCKER_REPO and KO_FLAGS if we're not publishing. + if (( ! PUBLISH_RELEASE )); then + KO_DOCKER_REPO="ko.local" + KO_FLAGS="-L ${KO_FLAGS}" + fi + if (( TAG_RELEASE )); then - # Currently we're not considering the tags in refs/tags namespace. - commit=$(git describe --always --dirty) + # Get the commit, excluding any tags but keeping the "dirty" flag + local commit="$(git describe --always --dirty --match '^$')" + [[ -n "${commit}" ]] || abort "Error getting the current commit" # Like kubernetes, image tag is vYYYYMMDD-commit TAG="v$(date +%Y%m%d)-${commit}" fi + if [[ -n "${RELEASE_VERSION}" ]]; then + TAG="v${RELEASE_VERSION}" + fi + + [[ -n "${RELEASE_VERSION}" ]] && (( PUBLISH_RELEASE )) && BRANCH_RELEASE=1 + readonly SKIP_TESTS readonly TAG_RELEASE readonly PUBLISH_RELEASE + readonly BRANCH_RELEASE readonly TAG + readonly RELEASE_VERSION + readonly RELEASE_NOTES + readonly RELEASE_BRANCH } # Run tests (unless --skip-tests was passed). Conveniently displays a banner indicating so. @@ -113,6 +139,46 @@ function run_validation_tests() { if (( ! SKIP_TESTS )); then banner "Running release validation tests" # Run tests. - $1 + if ! $1; then + banner "Release validation tests failed, aborting" + exit 1 + fi + fi +} + +# Initialize everything (flags, workspace, etc) for a release. +function initialize() { + parse_flags $@ + # Checkout specific branch, if necessary + if (( BRANCH_RELEASE )); then + git checkout upstream/${RELEASE_BRANCH} || abort "cannot checkout branch ${RELEASE_BRANCH}" + fi +} + +# Create a new release on GitHub, also git tagging it (unless this is not a versioned release). +# Parameters: $1 - Module name (e.g., "Knative Serving"). +# $2 - YAML files to add to the release, space separated. +function branch_release() { + (( BRANCH_RELEASE )) || return 0 + local title="$1 release ${TAG}" + local attachments=() + local description="$(mktemp)" + local attachments_dir="$(mktemp -d)" + # Copy each YAML to a separate dir + for yaml in $2; do + cp ${yaml} ${attachments_dir}/ + attachments+=("--attach=${yaml}#$(basename ${yaml})") + done + echo -e "${title}\n" > ${description} + if [[ -n "${RELEASE_NOTES}" ]]; then + cat ${RELEASE_NOTES} >> ${description} fi + git tag -a ${TAG} -m "${title}" + git push $(git remote get-url upstream) tag ${TAG} + run_go_tool github.com/github/hub hub release create \ + --prerelease \ + ${attachments[@]} \ + --file=${description} \ + --commitish=${RELEASE_BRANCH} \ + ${TAG} }