|
|
|
#!/bin/bash
|
|
|
|
##
|
|
|
|
## Copyright contributors to Hyperledger Besu.
|
|
|
|
##
|
|
|
|
## 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.
|
|
|
|
##
|
|
|
|
## SPDX-License-Identifier: Apache-2.0
|
|
|
|
##
|
|
|
|
|
|
|
|
REPORTS_DIR="$1"
|
|
|
|
REPORT_STRIP_PREFIX="$2"
|
|
|
|
REPORT_STRIP_SUFFIX="$3"
|
|
|
|
SPLIT_COUNT=$4
|
|
|
|
SPLIT_INDEX=$5
|
|
|
|
|
|
|
|
# extract tests time from Junit XML reports
|
|
|
|
find "$REPORTS_DIR" -type f -name TEST-*.xml | xargs -I{} bash -c "xmlstarlet sel -t -v 'concat(sum(//testcase/@time), \" \", //testsuite/@name)' '{}'; echo '{}' | sed \"s#${REPORT_STRIP_PREFIX}/\(.*\)/${REPORT_STRIP_SUFFIX}.*# \1#\"" > tmp/timing.tsv
|
|
|
|
|
|
|
|
# Sort times in descending order
|
|
|
|
IFS=$'\n' sorted=($(sort -nr tmp/timing.tsv))
|
|
|
|
unset IFS
|
|
|
|
|
|
|
|
sums=()
|
|
|
|
tests=()
|
|
|
|
|
|
|
|
# Initialize sums
|
|
|
|
for ((i=0; i<SPLIT_COUNT; i++))
|
|
|
|
do
|
|
|
|
sums[$i]=0
|
|
|
|
done
|
|
|
|
|
|
|
|
echo -n '' > tmp/processedTests.list
|
|
|
|
|
|
|
|
# add tests to groups trying to balance the sum of execution time of each group
|
|
|
|
for line in "${sorted[@]}"; do
|
|
|
|
line_parts=( $line )
|
|
|
|
test_time=$( echo "${line_parts[0]} * 1000 / 1" | bc ) # convert to millis without decimals
|
|
|
|
test_name=${line_parts[1]}
|
|
|
|
module_dir=${line_parts[2]}
|
|
|
|
test_with_module="$test_name $module_dir"
|
|
|
|
|
|
|
|
# deduplication check to avoid executing a test multiple time
|
|
|
|
if grep -F -q --line-regexp "$test_with_module" tmp/processedTests.list
|
|
|
|
then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Does the test still exists?
|
|
|
|
if grep -F -q --line-regexp "$test_with_module" tmp/currentTests.list
|
|
|
|
then
|
|
|
|
# Find index of min sum
|
|
|
|
idx_min_sum=0
|
|
|
|
min_sum=${sums[0]}
|
|
|
|
for ((i=0; i<SPLIT_COUNT; i++))
|
|
|
|
do
|
|
|
|
if [[ ${sums[$i]} -lt $min_sum ]]
|
|
|
|
then
|
|
|
|
idx_min_sum=$i
|
|
|
|
min_sum=${sums[$i]}
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# Add the test to the min sum list
|
|
|
|
min_sum_tests=${tests[$idx_min_sum]}
|
|
|
|
tests[$idx_min_sum]="${min_sum_tests}${test_with_module},"
|
|
|
|
|
|
|
|
# Update the sums
|
|
|
|
((sums[idx_min_sum]+=test_time))
|
|
|
|
|
|
|
|
echo "$test_with_module" >> tmp/processedTests.list
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# Any new test?
|
|
|
|
grep -F --line-regexp -v -f tmp/processedTests.list tmp/currentTests.list > tmp/newTests.list
|
|
|
|
idx_new_test=0
|
|
|
|
while read -r new_test_with_module
|
|
|
|
do
|
|
|
|
idx_group=$(( idx_new_test % SPLIT_COUNT ))
|
|
|
|
group=${tests[$idx_group]}
|
|
|
|
tests[$idx_group]="${group}${new_test_with_module},"
|
|
|
|
idx_new_test=$(( idx_new_test + 1 ))
|
|
|
|
done < tmp/newTests.list
|
|
|
|
|
|
|
|
# remove last comma
|
|
|
|
for ((i=0; i<SPLIT_COUNT; i++))
|
|
|
|
do
|
|
|
|
test_list=${tests[$i]%,}
|
|
|
|
tests[$i]="$test_list"
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
# group tests by module
|
|
|
|
module_list=( $( echo "${tests[$SPLIT_INDEX]}" | tr "," "\n" | awk '{print $2}' | sort -u ) )
|
|
|
|
|
|
|
|
declare -A group_by_module
|
|
|
|
for module_dir in "${module_list[@]}"
|
|
|
|
do
|
|
|
|
group_by_module[$module_dir]=""
|
|
|
|
done
|
|
|
|
|
|
|
|
IFS="," test_list=( ${tests[$SPLIT_INDEX]} )
|
|
|
|
unset IFS
|
|
|
|
|
|
|
|
for line in "${test_list[@]}"
|
|
|
|
do
|
|
|
|
line_parts=( $line )
|
|
|
|
test_name=${line_parts[0]}
|
|
|
|
module_dir=${line_parts[1]}
|
|
|
|
|
|
|
|
module_group=${group_by_module[$module_dir]}
|
|
|
|
group_by_module[$module_dir]="$module_group$test_name "
|
|
|
|
done
|
|
|
|
|
|
|
|
# return the requests index, without quotes to drop the last trailing space
|
|
|
|
for module_dir in "${module_list[@]}"
|
|
|
|
do
|
|
|
|
module_test_task=":${module_dir//\//:}:test"
|
|
|
|
module_tests=$( echo "${group_by_module[$module_dir]% }" | sed -e 's/^\| / --tests /g' )
|
|
|
|
echo "$module_test_task $module_tests"
|
|
|
|
done
|