diff --git a/.kokoro/tests/run_single_test.sh b/.kokoro/tests/run_single_test.sh new file mode 100755 index 000000000000..94ce92762b0c --- /dev/null +++ b/.kokoro/tests/run_single_test.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# +# 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. + +# Run the test, assuming it's already in the target directory. +# Requirements: +# The current directory is the test target directory. +# Env var `PROJECT_ROOT` is defined. + +echo "------------------------------------------------------------" +echo "- testing ${PWD}" +echo "------------------------------------------------------------" + +# If no local noxfile exists, copy the one from root +if [[ ! -f "noxfile.py" ]]; then + PARENT_DIR=$(cd ../ && pwd) + while [[ "$PARENT_DIR" != "${PROJECT_ROOT}" && \ + ! -f "$PARENT_DIR/noxfile-template.py" ]]; + do + PARENT_DIR=$(dirname "$PARENT_DIR") + done + cp "$PARENT_DIR/noxfile-template.py" "./noxfile.py" + echo -e "\n Using noxfile-template from parent folder ($PARENT_DIR). \n" + cleanup_noxfile=1 +else + cleanup_noxfile=0 +fi + +# Use nox to execute the tests for the project. +nox -s "$RUN_TESTS_SESSION" +EXIT=$? + +# If REPORT_TO_BUILD_COP_BOT is set to "true", send the test log +# to the Build Cop Bot. +# See: +# https://github.com/googleapis/repo-automation-bots/tree/master/packages/buildcop. +if [[ "${REPORT_TO_BUILD_COP_BOT:-}" == "true" ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop +fi + +if [[ "${EXIT}" -ne 0 ]]; then + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" +else + echo -e "\n Testing completed.\n" +fi + +# Remove noxfile.py if we copied. +if [[ $cleanup_noxfile -eq 1 ]]; then + rm noxfile.py +fi + +exit ${EXIT} diff --git a/.kokoro/tests/run_tests.sh b/.kokoro/tests/run_tests.sh index 8f3bfe0887c4..5c10a877aacb 100755 --- a/.kokoro/tests/run_tests.sh +++ b/.kokoro/tests/run_tests.sh @@ -39,7 +39,16 @@ fi # `--only-diff-head` will only run tests on project changes from the # previous commit. if [[ $* == *--only-diff-head* ]]; then - DIFF_FROM="HEAD~.." + set +e + git diff --quiet "HEAD~.." .kokoro/tests .kokoro/docker \ + .kokoro/trampoline_v2.sh + CHANGED=$? + set -e + if [[ "${CHANGED}" -eq 0 ]]; then + DIFF_FROM="HEAD~.." + else + echo "Changes to test driver files detected. Running full tests." + fi fi if [[ -z "${PROJECT_ROOT:-}" ]]; then @@ -94,97 +103,32 @@ set +e RTN=0 ROOT=$(pwd) -# Find all requirements.txt in the repository (may break on whitespace). -for file in **/requirements.txt; do - cd "$ROOT" - # Navigate to the project folder. - file=$(dirname "$file") - cd "$file" - - # First we look up the environment variable `RUN_TESTS_DIRS`. If - # the value is set, we'll iterate through the colon separated - # directory list. If the target directory is not under any - # directory in the list, we skip this directory. - # This environment variables are primarily for - # `scripts/run_tests_local.sh`. - # - # The value must be a colon separated list of relative paths from - # the project root. - # - # Example: - # cdn:appengine/flexible - # run tests for `cdn` and `appengine/flexible` directories. - # logging/cloud-client - # only run tests for `logging/cloud-client` directory. - # - if [[ -n "${RUN_TESTS_DIRS:-}" ]]; then - match=0 - for d in $(echo "${RUN_TESTS_DIRS}" | tr ":" "\n"); do - # If the current dir starts with one of the - # RUN_TESTS_DIRS, we should run the tests. - if [[ "${file}" = "${d}"* ]]; then - match=1 - break - fi - done - if [[ $match -eq 0 ]]; then - continue - fi - fi - # If $DIFF_FROM is set, use it to check for changes in this directory. - if [[ -n "${DIFF_FROM:-}" ]]; then - git diff --quiet "$DIFF_FROM" . - CHANGED=$? - if [[ "$CHANGED" -eq 0 ]]; then - # echo -e "\n Skipping $file: no changes in folder.\n" - continue - fi - fi +test_prog="${PROJECT_ROOT}/.kokoro/tests/run_single_test.sh" - echo "------------------------------------------------------------" - echo "- testing $file" - echo "------------------------------------------------------------" - - # If no local noxfile exists, copy the one from root - if [[ ! -f "noxfile.py" ]]; then - PARENT_DIR=$(cd ../ && pwd) - while [[ "$PARENT_DIR" != "$ROOT" && ! -f "$PARENT_DIR/noxfile-template.py" ]]; - do - PARENT_DIR=$(dirname "$PARENT_DIR") - done - cp "$PARENT_DIR/noxfile-template.py" "./noxfile.py" - echo -e "\n Using noxfile-template from parent folder ($PARENT_DIR). \n" - cleanup_noxfile=1 - else - cleanup_noxfile=0 - fi +btlr_args=( + "run" + "**/requirements.txt" + "--max-concurrency" + "30" +) - # Use nox to execute the tests for the project. - nox -s "$RUN_TESTS_SESSION" - EXIT=$? - - # If REPORT_TO_BUILD_COP_BOT is set to "true", send the test log - # to the Build Cop Bot. - # See: - # https://github.com/googleapis/repo-automation-bots/tree/master/packages/buildcop. - if [[ "${REPORT_TO_BUILD_COP_BOT:-}" == "true" ]]; then - chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop - $KOKORO_GFILE_DIR/linux_amd64/buildcop - fi +if [[ -n "${DIFF_FROM:-}" ]]; then + btlr_args+=( + "--git-diff" + "${DIFF_FROM} ." + ) +fi - if [[ $EXIT -ne 0 ]]; then - RTN=1 - echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" - else - echo -e "\n Testing completed.\n" - fi +btlr_args+=( + "--" + "${test_prog}" +) - # Remove noxfile.py if we copied. - if [[ $cleanup_noxfile -eq 1 ]]; then - rm noxfile.py - fi +echo "testing/btlr" "${btlr_args[@]}" + +testing/btlr "${btlr_args[@]}" -done +RTN=$? cd "$ROOT" # Remove secrets if we used decrypt-secrets.sh. diff --git a/.kokoro/tests/run_tests_orig.sh b/.kokoro/tests/run_tests_orig.sh new file mode 100755 index 000000000000..918ed7929792 --- /dev/null +++ b/.kokoro/tests/run_tests_orig.sh @@ -0,0 +1,204 @@ +#!/bin/bash +# Copyright 2019 Google LLC +# +# 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. + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +DIFF_FROM="" + +# `--only-diff-master` will only run tests on project changes on the +# last common commit from the master branch. +if [[ $* == *--only-diff-master* ]]; then + set +e + git diff --quiet "origin/master..." .kokoro/tests .kokoro/docker \ + .kokoro/trampoline_v2.sh + CHANGED=$? + set -e + if [[ "${CHANGED}" -eq 0 ]]; then + DIFF_FROM="origin/master..." + else + echo "Changes to test driver files detected. Running full tests." + fi +fi + +# `--only-diff-head` will only run tests on project changes from the +# previous commit. +if [[ $* == *--only-diff-head* ]]; then + set +e + git diff --quiet "HEAD~.." .kokoro/tests .kokoro/docker \ + .kokoro/trampoline_v2.sh + CHANGED=$? + set -e + if [[ "${CHANGED}" -eq 0 ]]; then + DIFF_FROM="HEAD~.." + else + echo "Changes to test driver files detected. Running full tests." + fi +fi + +if [[ -z "${PROJECT_ROOT:-}" ]]; then + PROJECT_ROOT="github/python-docs-samples" +fi + +cd "${PROJECT_ROOT}" + +# add user's pip binary path to PATH +export PATH="${HOME}/.local/bin:${PATH}" + +# install nox for testing +pip install --user -q nox + +# Use secrets acessor service account to get secrets. +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" + # This script will create 3 files: + # - testing/test-env.sh + # - testing/service-account.json + # - testing/client-secrets.json + ./scripts/decrypt-secrets.sh +fi + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +# For Datalabeling samples to hit the testing endpoint +export DATALABELING_ENDPOINT="test-datalabeling.sandbox.googleapis.com:443" + +# Run Cloud SQL proxy (background process exit when script does) +wget --quiet https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 \ + -O ${HOME}/cloud_sql_proxy && chmod +x ${HOME}/cloud_sql_proxy +${HOME}/cloud_sql_proxy -instances="${MYSQL_INSTANCE}"=tcp:3306 &>> \ + ${HOME}/cloud_sql_proxy.log & +${HOME}/cloud_sql_proxy -instances="${POSTGRES_INSTANCE}"=tcp:5432 &>> \ + ${HOME}/cloud_sql_proxy-postgres.log & +echo -e "\nCloud SQL proxy started." + +echo -e "\n******************** TESTING PROJECTS ********************" +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) + +# Find all requirements.txt in the repository (may break on whitespace). +for file in **/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + # First we look up the environment variable `RUN_TESTS_DIRS`. If + # the value is set, we'll iterate through the colon separated + # directory list. If the target directory is not under any + # directory in the list, we skip this directory. + # This environment variables are primarily for + # `scripts/run_tests_local.sh`. + # + # The value must be a colon separated list of relative paths from + # the project root. + # + # Example: + # cdn:appengine/flexible + # run tests for `cdn` and `appengine/flexible` directories. + # logging/cloud-client + # only run tests for `logging/cloud-client` directory. + # + if [[ -n "${RUN_TESTS_DIRS:-}" ]]; then + match=0 + for d in $(echo "${RUN_TESTS_DIRS}" | tr ":" "\n"); do + # If the current dir starts with one of the + # RUN_TESTS_DIRS, we should run the tests. + if [[ "${file}" = "${d}"* ]]; then + match=1 + break + fi + done + if [[ $match -eq 0 ]]; then + continue + fi + fi + # If $DIFF_FROM is set, use it to check for changes in this directory. + if [[ -n "${DIFF_FROM:-}" ]]; then + git diff --quiet "$DIFF_FROM" . + CHANGED=$? + if [[ "$CHANGED" -eq 0 ]]; then + # echo -e "\n Skipping $file: no changes in folder.\n" + continue + fi + fi + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # If no local noxfile exists, copy the one from root + if [[ ! -f "noxfile.py" ]]; then + PARENT_DIR=$(cd ../ && pwd) + while [[ "$PARENT_DIR" != "$ROOT" && ! -f "$PARENT_DIR/noxfile-template.py" ]]; + do + PARENT_DIR=$(dirname "$PARENT_DIR") + done + cp "$PARENT_DIR/noxfile-template.py" "./noxfile.py" + echo -e "\n Using noxfile-template from parent folder ($PARENT_DIR). \n" + cleanup_noxfile=1 + else + cleanup_noxfile=0 + fi + + # Use nox to execute the tests for the project. + nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If REPORT_TO_BUILD_COP_BOT is set to "true", send the test log + # to the Build Cop Bot. + # See: + # https://github.com/googleapis/repo-automation-bots/tree/master/packages/buildcop. + if [[ "${REPORT_TO_BUILD_COP_BOT:-}" == "true" ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + + # Remove noxfile.py if we copied. + if [[ $cleanup_noxfile -eq 1 ]]; then + rm noxfile.py + fi + +done +cd "$ROOT" + +# Remove secrets if we used decrypt-secrets.sh. +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + rm testing/{test-env.sh,client-secrets.json,service-account.json} +fi + +exit "$RTN" diff --git a/appengine/flexible/websockets/main_test.py b/appengine/flexible/websockets/main_test.py index 547954bdfb8a..05f8b816dbde 100644 --- a/appengine/flexible/websockets/main_test.py +++ b/appengine/flexible/websockets/main_test.py @@ -37,10 +37,16 @@ def server(): bind_to = '127.0.0.1:{}'.format(port) server = subprocess.Popen( - ['gunicorn', '-b', bind_to, '-k' 'flask_sockets.worker', 'main:app']) - + ['gunicorn', '-b', bind_to, '-k' 'flask_sockets.worker', 'main:app'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + + # With btlr, there can be many processes are spawned and the + # server might be in a tight memory situation, so let's wait for 2 + # mins. # Wait until the server responds before proceeding. - @retry(wait_fixed=50, stop_max_delay=5000) + @retry(wait_fixed=50, stop_max_delay=120000) def check_server(url): requests.get(url) @@ -50,6 +56,11 @@ def check_server(url): server.kill() + # Dump the logs for debugging + out, err = server.communicate() + print("gunicorn stdout: {}".format(out)) + print("gunicorn stderr: {}".format(err)) + def test_http(server): result = requests.get('http://{}/'.format(server)) diff --git a/dlp/inspect_content_test.py b/dlp/inspect_content_test.py index e2192bdd6c41..cbf4476f5473 100644 --- a/dlp/inspect_content_test.py +++ b/dlp/inspect_content_test.py @@ -40,7 +40,7 @@ BIGQUERY_DATASET_ID = "dlp_test_dataset" + UNIQUE_STRING BIGQUERY_TABLE_ID = "dlp_test_table" + UNIQUE_STRING -TIMEOUT = 300 # 5 minutes +TIMEOUT = 900 # 15 minutes @pytest.fixture(scope="module") diff --git a/dlp/risk_test.py b/dlp/risk_test.py index 36f7f54a0951..9a53c835c46b 100644 --- a/dlp/risk_test.py +++ b/dlp/risk_test.py @@ -36,7 +36,7 @@ BIGQUERY_TABLE_ID = "dlp_test_table" + UNIQUE_STRING BIGQUERY_HARMFUL_TABLE_ID = "harmful" + UNIQUE_STRING -TIMEOUT = 60 # 1 minutes +TIMEOUT = 120 # 2 minutes # Create new custom topic/subscription diff --git a/dns/api/main_test.py b/dns/api/main_test.py index 051ddb52b885..5b7a8b77292b 100644 --- a/dns/api/main_test.py +++ b/dns/api/main_test.py @@ -12,6 +12,7 @@ # limitations under the License. import os +import time import uuid from google.cloud import dns @@ -27,6 +28,11 @@ TEST_ZONE_DESCRIPTION = 'Test zone' +def delay_rerun(*args): + time.sleep(5) + return True + + @pytest.yield_fixture def client(): client = dns.Client(PROJECT) @@ -69,7 +75,7 @@ def test_create_zone(client): assert zone.description == TEST_ZONE_DESCRIPTION -@pytest.mark.flaky +@pytest.mark.flaky(max_runs=3, min_passes=1, rerun_filter=delay_rerun) def test_get_zone(client, zone): zone = main.get_zone(PROJECT, TEST_ZONE_NAME) @@ -78,27 +84,27 @@ def test_get_zone(client, zone): assert zone.description == TEST_ZONE_DESCRIPTION -@pytest.mark.flaky +@pytest.mark.flaky(max_runs=3, min_passes=1, rerun_filter=delay_rerun) def test_list_zones(client, zone): zones = main.list_zones(PROJECT) assert TEST_ZONE_NAME in zones -@pytest.mark.flaky +@pytest.mark.flaky(max_runs=3, min_passes=1, rerun_filter=delay_rerun) def test_list_resource_records(client, zone): records = main.list_resource_records(PROJECT, TEST_ZONE_NAME) assert records -@pytest.mark.flaky +@pytest.mark.flaky(max_runs=3, min_passes=1, rerun_filter=delay_rerun) def test_list_changes(client, zone): changes = main.list_changes(PROJECT, TEST_ZONE_NAME) assert changes -@pytest.mark.flaky +@pytest.mark.flaky(max_runs=3, min_passes=1, rerun_filter=delay_rerun) def test_delete_zone(client, zone): main.delete_zone(PROJECT, TEST_ZONE_NAME) diff --git a/iam/api-client/grantable_roles.py b/iam/api-client/grantable_roles.py index ec8e87706b96..354345157d6d 100644 --- a/iam/api-client/grantable_roles.py +++ b/iam/api-client/grantable_roles.py @@ -37,7 +37,8 @@ def view_grantable_roles(full_resource_name): if 'title' in role: print('Title: ' + role['title']) print('Name: ' + role['name']) - print('Description: ' + role['description']) + if 'description' in role: + print('Description: ' + role['description']) print(' ') # [END iam_view_grantable_roles] diff --git a/iot/api-client/end_to_end_example/cloudiot_pubsub_example_server_test.py b/iot/api-client/end_to_end_example/cloudiot_pubsub_example_server_test.py index 246fc08fdeec..097cdaa86378 100644 --- a/iot/api-client/end_to_end_example/cloudiot_pubsub_example_server_test.py +++ b/iot/api-client/end_to_end_example/cloudiot_pubsub_example_server_test.py @@ -14,6 +14,7 @@ import os import time +import uuid import cloudiot_pubsub_example_server as example_server @@ -25,7 +26,7 @@ service_account_json = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] pubsub_topic = 'projects/{}/topics/{}'.format(project_id, topic_id) -registry_id = 'test-registry-{}'.format(int(time.time())) +registry_id = 'test-registry-{}-{}'.format(uuid.uuid4().hex, int(time.time())) def test_config_turn_on(capsys): diff --git a/iot/api-client/gcs_file_to_device/gcs_send_to_device_test.py b/iot/api-client/gcs_file_to_device/gcs_send_to_device_test.py index c3309e89f7dc..71d954b7e8cb 100644 --- a/iot/api-client/gcs_file_to_device/gcs_send_to_device_test.py +++ b/iot/api-client/gcs_file_to_device/gcs_send_to_device_test.py @@ -15,6 +15,7 @@ import os import sys import tempfile +import time import uuid from google.cloud import pubsub @@ -36,7 +37,7 @@ topic_id = 'test-device-events-{}'.format(str(uuid.uuid4())) device_id = 'test-device-{}'.format(str(uuid.uuid4())) -registry_id = 'test-registry-{}'.format(str(uuid.uuid4())) +registry_id = 'test-registry-{}-{}'.format(uuid.uuid4().hex, int(time.time())) pubsub_topic = 'projects/{}/topics/{}'.format(project_id, topic_id) cloud_region = 'us-central1' diff --git a/iot/api-client/http_example/cloudiot_http_example_test.py b/iot/api-client/http_example/cloudiot_http_example_test.py index 8497d1ffb334..067547ed5261 100644 --- a/iot/api-client/http_example/cloudiot_http_example_test.py +++ b/iot/api-client/http_example/cloudiot_http_example_test.py @@ -14,6 +14,7 @@ import os import sys import time +import uuid from google.cloud import pubsub import pytest @@ -36,7 +37,7 @@ service_account_json = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] pubsub_topic = 'projects/{}/topics/{}'.format(project_id, topic_id) -registry_id = 'test-registry-{}'.format(int(time.time())) +registry_id = 'test-registry-{}-{}'.format(uuid.uuid4().hex, int(time.time())) _BASE_URL = 'https://cloudiotdevice.googleapis.com/v1' diff --git a/iot/api-client/manager/manager_test.py b/iot/api-client/manager/manager_test.py index 20bac093a5f2..7291e1f35234 100644 --- a/iot/api-client/manager/manager_test.py +++ b/iot/api-client/manager/manager_test.py @@ -41,7 +41,7 @@ pubsub_topic = 'projects/{}/topics/{}'.format(project_id, topic_id) # This format is used in the `clean_up_registries()` below. -registry_id = 'test-registry-{}-{}'.format(uuid.uuid1(), int(time.time())) +registry_id = 'test-registry-{}-{}'.format(uuid.uuid4().hex, int(time.time())) @pytest.fixture(scope="session", autouse=True) diff --git a/iot/api-client/mqtt_example/cloudiot_mqtt_example_test.py b/iot/api-client/mqtt_example/cloudiot_mqtt_example_test.py index 5ef4dc95ed70..743c9a5593ae 100644 --- a/iot/api-client/mqtt_example/cloudiot_mqtt_example_test.py +++ b/iot/api-client/mqtt_example/cloudiot_mqtt_example_test.py @@ -185,9 +185,6 @@ def test_gateway_send_data_for_device( out, _ = capsys.readouterr() assert 'Publishing message 5/5' in out assert 'Received message' in out - # We know we sometimes get 'Out of memory' in the output. - # We'd like to know when this occurs with verbose log output. - assert 'Out of memory' not in out # Indicates could not connect def test_gateway_trigger_error_topic( diff --git a/iot/api-client/mqtt_example/fixtures.py b/iot/api-client/mqtt_example/fixtures.py index d78f72001c22..65196e8023e6 100644 --- a/iot/api-client/mqtt_example/fixtures.py +++ b/iot/api-client/mqtt_example/fixtures.py @@ -36,7 +36,7 @@ subscription_name = 'test-device-images-{}'.format(uuid.uuid4()) project_id = os.environ['GCLOUD_PROJECT'] service_account_json = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] -registry_id = 'test-registry-{}-{}'.format(uuid.uuid4(), int(time.time())) +registry_id = 'test-registry-{}-{}'.format(uuid.uuid4().hex, int(time.time())) @pytest.fixture(scope='session') diff --git a/monitoring/api/v3/cloud-client/README.rst b/monitoring/api/v3/cloud-client/README.rst index 18d2acccf7de..280f9c4e0a79 100644 --- a/monitoring/api/v3/cloud-client/README.rst +++ b/monitoring/api/v3/cloud-client/README.rst @@ -16,6 +16,14 @@ This directory contains samples for Google Stackdriver Monitoring API. Stackdriv .. _Google Stackdriver Monitoring API: https://cloud.google.com/monitoring/docs/ +To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/monitoring.googleapis.com + +To run the sample, you need to have `Monitoring Admin` role. + + +Please visit [the Cloud Console UI of this API](https://console.cloud.google.com/monitoring) and create a new Workspace with the same name of your Cloud project. + + Setup ------------------------------------------------------------------------------- diff --git a/monitoring/api/v3/cloud-client/README.rst.in b/monitoring/api/v3/cloud-client/README.rst.in index d6a0dd460997..0ab6b2258b78 100644 --- a/monitoring/api/v3/cloud-client/README.rst.in +++ b/monitoring/api/v3/cloud-client/README.rst.in @@ -12,6 +12,13 @@ product: and many others. Stackdriver ingests that data and generates insights via dashboards, charts, and alerts. +required_api_url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com +required_role: Monitoring Admin +other_required_steps: > + Please visit [the Cloud Console UI of this + API](https://console.cloud.google.com/monitoring) and create a new + Workspace with the same name of your Cloud project. + setup: - auth - install_deps @@ -25,4 +32,4 @@ samples: cloud_client_library: true -folder: monitoring/api/v3/cloud-client \ No newline at end of file +folder: monitoring/api/v3/cloud-client diff --git a/monitoring/api/v3/cloud-client/noxfile_config.py b/monitoring/api/v3/cloud-client/noxfile_config.py new file mode 100644 index 000000000000..6dc471102c62 --- /dev/null +++ b/monitoring/api/v3/cloud-client/noxfile_config.py @@ -0,0 +1,42 @@ +# Copyright 2020 Google LLC +# +# 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # Declare optional test sessions you want to opt-in. Currently we + # have the following optional test sessions: + # 'cloud_run' # Test session for Cloud Run application. + 'opt_in_sessions': [], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + # 'gcloud_project_env': 'GCLOUD_PROJECT', + 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} diff --git a/run/markdown-preview/editor/noxfile.py b/run/markdown-preview/editor/noxfile.py new file mode 100644 index 000000000000..b23055f14a65 --- /dev/null +++ b/run/markdown-preview/editor/noxfile.py @@ -0,0 +1,225 @@ +# Copyright 2019 Google LLC +# +# 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. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GCLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret['GCLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/run/markdown-preview/renderer/noxfile.py b/run/markdown-preview/renderer/noxfile.py new file mode 100644 index 000000000000..b23055f14a65 --- /dev/null +++ b/run/markdown-preview/renderer/noxfile.py @@ -0,0 +1,225 @@ +# Copyright 2019 Google LLC +# +# 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. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GCLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret['GCLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/scripts/run_tests_local.sh b/scripts/run_tests_local.sh index b4e8b79ae396..9b971fb70c82 100755 --- a/scripts/run_tests_local.sh +++ b/scripts/run_tests_local.sh @@ -55,7 +55,7 @@ relative_dir=${directory#"${PROJECT_ROOT}/"} export RUN_TESTS_DIRS="${relative_dir}" # We want to test this directory regardless of whether there's a change. -export TRAMPOLINE_BUILD_FILE=".kokoro/tests/run_tests.sh" +export TRAMPOLINE_BUILD_FILE=".kokoro/tests/run_tests_orig.sh" if [[ $# -ge 2 ]]; then sessions=("${@:2}") diff --git a/testing/btlr b/testing/btlr new file mode 100755 index 000000000000..afe46d556a6b Binary files /dev/null and b/testing/btlr differ diff --git a/translate/automl/translate_v3_batch_translate_text_with_model_test.py b/translate/automl/translate_v3_batch_translate_text_with_model_test.py index 36c52ae22e4d..a7801f604024 100644 --- a/translate/automl/translate_v3_batch_translate_text_with_model_test.py +++ b/translate/automl/translate_v3_batch_translate_text_with_model_test.py @@ -28,7 +28,7 @@ @pytest.fixture(scope="function") def bucket(): """Create a temporary bucket to store annotation output.""" - bucket_name = str(uuid.uuid1()) + bucket_name = f'tmp-{uuid.uuid4().hex}' storage_client = storage.Client() bucket = storage_client.create_bucket(bucket_name) diff --git a/translate/cloud-client/beta_snippets_test.py b/translate/cloud-client/beta_snippets_test.py index 4852168567ac..453fcb7ec4a1 100644 --- a/translate/cloud-client/beta_snippets_test.py +++ b/translate/cloud-client/beta_snippets_test.py @@ -28,7 +28,7 @@ @pytest.fixture(scope='function') def bucket(): """Create a temporary bucket to store annotation output.""" - bucket_name = str(uuid.uuid1()) + bucket_name = f'tmp-{uuid.uuid4().hex}' storage_client = storage.Client() bucket = storage_client.create_bucket(bucket_name) diff --git a/translate/cloud-client/translate_v3_batch_translate_text_with_glossary_test.py b/translate/cloud-client/translate_v3_batch_translate_text_with_glossary_test.py index dd2e688786ac..c2033ad3630c 100644 --- a/translate/cloud-client/translate_v3_batch_translate_text_with_glossary_test.py +++ b/translate/cloud-client/translate_v3_batch_translate_text_with_glossary_test.py @@ -57,7 +57,7 @@ def delete_glossary(): @pytest.fixture(scope="function") def bucket(): """Create a temporary bucket to store annotation output.""" - bucket_name = str(uuid.uuid1()) + bucket_name = f'tmp-{uuid.uuid4().hex}' storage_client = storage.Client() bucket = storage_client.create_bucket(bucket_name) diff --git a/video/cloud-client/analyze/beta_snippets_test.py b/video/cloud-client/analyze/beta_snippets_test.py index 09aa67c235a4..a0ac30ffbf8d 100644 --- a/video/cloud-client/analyze/beta_snippets_test.py +++ b/video/cloud-client/analyze/beta_snippets_test.py @@ -53,7 +53,7 @@ def video_path(tmpdir_factory): @pytest.fixture(scope="function") def bucket(): # Create a temporaty bucket to store annotation output. - bucket_name = str(uuid.uuid1()) + bucket_name = f'tmp-{uuid.uuid4().hex}' storage_client = storage.Client() bucket = storage_client.create_bucket(bucket_name)