Skip to content

Commit e9473ee

Browse files
committed
ci: Speed up the integration tests by testing only testable modules (#12038)
Fixes: #12025 Tries to reduce the runtime when running all the ITs (2:30 hrs). This should reduce it down to ~42 min: https://btx.cloud.google.com/invocations/3f075762-7f70-4638-bfb4-e62c41460516/log Results are tested in this PR: #12039
1 parent 440aed3 commit e9473ee

File tree

3 files changed

+89
-26
lines changed

3 files changed

+89
-26
lines changed

.kokoro/build.sh

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,18 @@ case ${JOB_TYPE} in
7171
if [[ "$(release_please_snapshot_pull_request)" == "true" ]]; then
7272
echo "Skipping integration tests as this is Release Please SNAPSHOT pull request."
7373
elif [[ ${#modified_module_list[@]} -gt 0 ]]; then
74-
module_list=$(
75-
IFS=,
76-
echo "${modified_module_list[*]}"
77-
)
78-
setup_cloud "$module_list"
79-
install_modules "$module_list"
80-
run_integration_tests "$module_list"
74+
filter_modules_with_integration_tests
75+
if [[ ${#filtered_it_module_list[@]} -eq 0 ]]; then
76+
echo "No modified modules contain integration tests. Skipping."
77+
else
78+
module_list=$(
79+
IFS=,
80+
echo "${filtered_it_module_list[*]}"
81+
)
82+
setup_cloud "$module_list"
83+
install_modules "$module_list"
84+
run_integration_tests "$module_list"
85+
fi
8186
else
8287
echo "No Integration Tests to run"
8388
fi

.kokoro/common.sh

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,69 @@ function retry_with_backoff {
6262
return $exit_code
6363
}
6464

65+
# Helper function to reliably extract the text between <module> tags strictly
66+
# within the default <modules> block, natively ignoring <profiles>.
67+
# Uses a pure Bash loop to avoid spawning slower external processes like awk or sed,
68+
# and naturally survives single-module components without throwing exit signals.
69+
function extract_pom_modules() {
70+
local pom_file="$1"
71+
local modules_list=""
72+
local in_profiles=false
73+
local in_modules=false
74+
75+
while IFS= read -r line || [ -n "$line" ]; do
76+
if [[ "$line" == *"<profiles>"* ]]; then
77+
in_profiles=true
78+
elif [[ "$line" == *"</profiles>"* ]]; then
79+
in_profiles=false
80+
elif [[ "$line" == *"<modules>"* ]] && [ "$in_profiles" = false ]; then
81+
in_modules=true
82+
elif [[ "$line" == *"</modules>"* ]] && [ "$in_profiles" = false ]; then
83+
in_modules=false
84+
break
85+
elif [ "$in_modules" = true ] && [[ "$line" == *"<module>"* ]]; then
86+
# Extract text between tags
87+
local module="${line#*<module>}"
88+
module="${module%</module>*}"
89+
90+
# Trim whitespace natively
91+
module="${module#"${module%%[![:space:]]*}"}"
92+
module="${module%"${module##*[![:space:]]}"}"
93+
94+
if [ -z "$modules_list" ]; then
95+
modules_list="$module"
96+
else
97+
modules_list="${modules_list} ${module}"
98+
fi
99+
fi
100+
done < "$pom_file"
101+
102+
echo "$modules_list"
103+
}
104+
65105
# Given a folder containing a maven multi-module, assign the variable 'submodules' to a
66106
# comma-delimited list of <folder>/<submodule>.
67107
function parse_submodules() {
68108
submodules_array=()
69-
mvn_submodules=$(mvn help:evaluate -Dexpression=project.modules -pl "$1")
70-
if mvn_submodules=$(grep '<.*>.*</.*>' <<< "$mvn_submodules"); then
71-
mvn_submodules=$(sed -e 's/<.*>\(.*\)<\/.*>/\1/g' <<< "$mvn_submodules")
72-
for submodule in $mvn_submodules; do
73-
# Each entry = <folder>/<submodule>
74-
submodules_array+=("$1/${submodule}");
75-
done
109+
if [ -f "$1/pom.xml" ]; then
110+
local modules
111+
112+
# Use pure Bash extraction to find the modules in the aggregator pom file.
113+
# Faster than invoking mvn help:evaluate to list all the project modules,
114+
# cleanly ignores optional <profiles>, and gracefully skips flat POMs.
115+
modules=$(extract_pom_modules "$1/pom.xml")
116+
if [ -n "$modules" ]; then
117+
for submodule in $modules; do
118+
# Each entry = <folder>/<submodule>
119+
submodules_array+=("$1/${submodule}")
120+
done
121+
else
122+
# If this module contains no submodules, select the module itself.
123+
submodules_array+=("$1")
124+
fi
76125
else
77-
# If this module contains no submodules, select the module itself.
78-
submodules_array+=("$1");
126+
echo "Module does not have a pom.xml file: $1"
127+
exit 1
79128
fi
80129

81130
# Convert from array to comma-delimited string
@@ -216,6 +265,25 @@ function generate_modified_modules_list() {
216265
fi
217266
}
218267

268+
# Filters the modified_module_list to only include modules that contain
269+
# integration test files (matching IT*.java or *IT.java in src/test/java).
270+
# Not all modules will have ITs written and there is not need to test
271+
# modules without ITs.
272+
function filter_modules_with_integration_tests() {
273+
filtered_it_module_list=()
274+
for module in "${modified_module_list[@]}"; do
275+
# 1. Search for files in the Java test directory (*/src/test/java/*)
276+
# 2. Filter for ITs that match the typical file name (IT prefix or suffix)
277+
# 3. Stop searching when a single file match has been found
278+
if find "$module" -path '*/src/test/java/*' \( -name 'IT*.java' -o -name '*IT.java' \) -print -quit 2>/dev/null | grep -q .; then
279+
filtered_it_module_list+=("$module")
280+
fi
281+
done
282+
printf "Modules with integration tests:\n"
283+
printf " %s\n" "${filtered_it_module_list[@]}"
284+
echo "Found ${#filtered_it_module_list[@]} modules with integration tests (out of ${#modified_module_list[@]} modified modules)"
285+
}
286+
219287
function run_integration_tests() {
220288
printf "Running integration tests for modules:\n%s\n" "$1"
221289
parse_all_submodules "$1"

java-bigquerystorage/pom.xml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,4 @@
202202
<module>google-cloud-bigquerystorage-bom</module>
203203
</modules>
204204

205-
<profiles>
206-
<profile>
207-
<id>include-samples</id>
208-
<modules>
209-
<module>samples</module>
210-
<module>tutorials</module>
211-
</modules>
212-
</profile>
213-
</profiles>
214-
215205
</project>

0 commit comments

Comments
 (0)