11#! /bin/bash
22# Copyright 2020 Google LLC
3- #
4- # Licensed under the Apache License, Version 2.0 (the "License");
5- # you may not use this file except in compliance with the License.
6- # You may obtain a copy of the License at
7- #
8- # https://www.apache.org/licenses/LICENSE-2.0
9- #
10- # Unless required by applicable law or agreed to in writing, software
11- # distributed under the License is distributed on an "AS IS" BASIS,
12- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- # See the License for the specific language governing permissions and
14- # limitations under the License.
15-
16- # `-e` enables the script to automatically fail when a command fails
17- # `-o pipefail` sets the exit code to non-zero if any command fails,
18- # or zero if all commands in the pipeline exit successfully.
3+ # Licensed under the Apache License, Version 2.0 (the "License"); ...
194set -eo pipefail
205
21- # Disable buffering, so that the logs stream through.
226export PYTHONUNBUFFERED=1
23-
24- # Setup firestore account credentials
257export FIRESTORE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR} /firebase-credentials.json
26-
278export PROJECT_ROOT=$( realpath $( dirname " ${BASH_SOURCE[0]} " ) /..)
289
2910cd " $PROJECT_ROOT "
30-
31- # This is needed in order for `git diff` to succeed
3211git config --global --add safe.directory $( realpath .)
3312
34- RETVAL=0
13+ # HOISTED: Install uv exactly once globally before we fan out
14+ echo " Installing uv globally..."
15+ python3 -m pip install uv
3516
17+ RETVAL=0
3618pwd
3719
3820run_package_test () {
3921 local package_name=$1
4022 local package_path=" packages/${package_name} "
4123
42- # Declare local overrides to prevent bleeding into the next loop iteration
4324 local PROJECT_ID
4425 local GOOGLE_APPLICATION_CREDENTIALS
4526 local NOX_FILE
@@ -51,7 +32,6 @@ run_package_test() {
5132
5233 case " ${package_name} " in
5334 " google-auth" )
54- # Copy files needed for google-auth system tests
5535 mkdir -p " ${package_path} /system_tests/data"
5636 cp " ${KOKORO_GFILE_DIR} /google-auth-service-account.json" " ${package_path} /system_tests/data/service_account.json"
5737 cp " ${KOKORO_GFILE_DIR} /google-auth-authorized-user.json" " ${package_path} /system_tests/data/authorized_user.json"
@@ -70,14 +50,13 @@ run_package_test() {
7050 ;;
7151 esac
7252
73- # Export variables for the duration of this function's sub-processes
7453 export PROJECT_ID GOOGLE_APPLICATION_CREDENTIALS NOX_FILE NOX_SESSION
7554 export GOOGLE_CLOUD_PROJECT=" ${PROJECT_ID} "
55+
56+ # NEW: Subshell-isolated GCP auth. Never modify the global gcloud config!
57+ export CLOUDSDK_CORE_PROJECT=" ${PROJECT_ID} "
58+ export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=" ${GOOGLE_APPLICATION_CREDENTIALS} "
7659
77- gcloud auth activate-service-account --key-file=" $GOOGLE_APPLICATION_CREDENTIALS "
78- gcloud config set project " $PROJECT_ID "
79-
80- # Run the actual test
8160 pushd " ${package_path} " > /dev/null
8261 set +e
8362 " ${system_test_script} "
@@ -108,57 +87,55 @@ packages_with_system_tests=(
10887 " sqlalchemy-spanner"
10988)
11089
111- # A file for running system tests
11290system_test_script=" ${PROJECT_ROOT} /.kokoro/system-single.sh"
113-
114- # Join array elements with | for the pattern match
11591packages_with_system_tests_pattern=$( printf " |*%s*" " ${packages_with_system_tests[@]} " )
116- packages_with_system_tests_pattern=" ${packages_with_system_tests_pattern: 1} " # Remove the leading pipe
92+ packages_with_system_tests_pattern=" ${packages_with_system_tests_pattern: 1} "
11793
11894declare -A pids
11995
120- # Run system tests for each package with directory packages/*/tests/system
12196for path in ` find ' packages' \
12297 \( -type d -wholename ' packages/*/tests/system' \) -o \
12398 \( -type d -wholename ' packages/*/system_tests' \) -o \
12499 \( -type f -wholename ' packages/*/tests/system.py' \) ` ; do
125100
126- # Extract the package name and define the relative package path
127- # 1. Remove the 'packages/' prefix
128- # 2. Remove everything after the first '/'
129101 package_name=${path# packages/ }
130102 package_name=${package_name%%/* }
131103 package_path=" packages/${package_name} "
132104
133- # Determine if we should skip based on git diff
134105 files_to_check=" ${package_path} /CHANGELOG.md"
135106 if [[ $package_name == @ ($packages_with_system_tests_pattern ) ]]; then
136107 files_to_check=" ${package_path} "
137108 fi
138109
139- echo " checking changes with 'git diff " ${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH} ...${KOKORO_GITHUB_PULL_REQUEST_COMMIT} " -- ${files_to_check} '"
110+ echo " checking changes with 'git diff ${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH} ...${KOKORO_GITHUB_PULL_REQUEST_COMMIT} -- ${files_to_check} '"
140111 set +e
141112 package_modified=$( git diff " ${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH} ...${KOKORO_GITHUB_PULL_REQUEST_COMMIT} " -- ${files_to_check} | wc -l)
142113 set -e
143114
144115 if [[ " ${package_modified} " -gt 0 ]]; then
145- echo " Dispatching ${package_name} in the background..."
146- run_package_test " $package_name " &
116+ echo " >>> Dispatching ${package_name} in the background <<<"
117+ # Strict subshell isolation
118+ (
119+ run_package_test " $package_name "
120+ ) &
147121 pids[" $package_name " ]=$!
148122 else
149123 echo " No changes in ${package_name} , skipping."
150124 fi
151125done
152126
153127echo " ============================================================"
154- echo " Waiting for all concurrent system tests to complete ..."
128+ echo " All affected packages dispatched. Waiting for completion ..."
155129echo " ============================================================"
156130
157131for package in " ${! pids[@]} " ; do
158132 wait ${pids[$package]} || {
133+ echo " ============================================================"
159134 echo " ERROR: System tests failed for $package "
135+ echo " ============================================================"
160136 RETVAL=1
161137 }
162138done
163139
140+ echo " All concurrent tests completed."
164141exit ${RETVAL}
0 commit comments