@@ -30,6 +30,8 @@ replica_port=
3030original_sql_mode=
3131current_gtid_mode=
3232sysbench_pid=
33+ test_timeout=120
34+ test_failure_log_tail_lines=50
3335
3436OPTIND=1
3537while getopts " b:s:dtg" OPTION; do
@@ -168,16 +170,20 @@ build_ghost_command() {
168170 --execute ${extra_args[@]} "
169171}
170172
173+ print_log_excerpt () {
174+ echo " === Last $test_failure_log_tail_lines lines of $test_logfile ==="
175+ tail -n $test_failure_log_tail_lines $test_logfile
176+ echo " === End log excerpt ==="
177+ }
178+
171179validate_expected_failure () {
172180 # Check if test expected to fail and validate error message
173181 # Expects: tests_path, test_name, execution_result, test_logfile
174182 if [ -f $tests_path /$test_name /expect_failure ]; then
175183 if [ $execution_result -eq 0 ]; then
176184 echo
177185 echo " ERROR $test_name execution was expected to exit on error but did not."
178- echo " === Last 50 lines of $test_logfile ==="
179- tail -n 50 $test_logfile
180- echo " === End log excerpt ==="
186+ print_log_excerpt
181187 return 1
182188 fi
183189 if [ -s $tests_path /$test_name /expect_failure ]; then
@@ -188,9 +194,7 @@ validate_expected_failure() {
188194 fi
189195 echo
190196 echo " ERROR $test_name execution was expected to exit with error message '${expected_error_message} ' but did not."
191- echo " === Last 50 lines of $test_logfile ==="
192- tail -n 50 $test_logfile
193- echo " === End log excerpt ==="
197+ print_log_excerpt
194198 return 1
195199 fi
196200 # 'expect_failure' file has no content. We generally agree that the failure is correct
@@ -327,10 +331,32 @@ test_single() {
327331
328332 # Check for custom test script
329333 if [ -f $tests_path /$test_name /test.sh ]; then
330- # Source the custom test script which can override default behavior
331- # It has access to all variables and functions from this script
332- source $tests_path /$test_name /test.sh
333- return $?
334+ # Run the custom test script in a subshell with timeout monitoring
335+ # The subshell inherits all functions and variables from the current shell
336+ (source $tests_path /$test_name /test.sh) &
337+ test_pid=$!
338+
339+ # Monitor the test with timeout
340+ timeout_counter=0
341+ while kill -0 $test_pid 2> /dev/null; do
342+ if [ $timeout_counter -ge $test_timeout ]; then
343+ kill -TERM $test_pid 2> /dev/null
344+ sleep 1
345+ kill -KILL $test_pid 2> /dev/null
346+ wait $test_pid 2> /dev/null
347+ echo
348+ echo " ERROR $test_name execution timed out"
349+ print_log_excerpt
350+ return 1
351+ fi
352+ sleep 1
353+ (( timeout_counter++ ))
354+ done
355+
356+ # Get the exit code
357+ wait $test_pid 2> /dev/null
358+ execution_result=$?
359+ return $execution_result
334360 fi
335361
336362 # test with sysbench oltp write load
@@ -358,11 +384,19 @@ test_single() {
358384 echo_dot
359385 echo $cmd > $exec_command_file
360386 echo_dot
361- bash $exec_command_file > $test_logfile 2>&1
387+ timeout $test_timeout bash $exec_command_file > $test_logfile 2>&1
362388
363389 execution_result=$?
364390 cleanup
365391
392+ # Check for timeout (exit code 124)
393+ if [ $execution_result -eq 124 ]; then
394+ echo
395+ echo " ERROR $test_name execution timed out"
396+ print_log_excerpt
397+ return 1
398+ fi
399+
366400 if [ -f $tests_path /$test_name /sql_mode ]; then
367401 gh-ost-test-mysql-master --default-character-set=utf8mb4 test -e " set @@global.sql_mode='${original_sql_mode} '"
368402 gh-ost-test-mysql-replica --default-character-set=utf8mb4 test -e " set @@global.sql_mode='${original_sql_mode} '"
@@ -441,14 +475,19 @@ test_all() {
441475 test_dirs=$( find " $tests_path " -mindepth 1 -maxdepth 1 ! -path . -type d | grep " $test_pattern " | sort)
442476 while read -r test_dir; do
443477 test_name=$( basename " $test_dir " )
478+ local test_start_time=$( date +%s)
444479 if ! test_single " $test_name " ; then
480+ local test_end_time=$( date +%s)
481+ local test_duration=$(( test_end_time - test_start_time))
445482 create_statement=$( gh-ost-test-mysql-replica test -t -e " show create table ${ghost_table_name} \G" )
446483 echo " $create_statement " >> $test_logfile
447- echo " + FAIL"
484+ echo " + FAIL ( ${test_duration} s) "
448485 return 1
449486 else
487+ local test_end_time=$( date +%s)
488+ local test_duration=$(( test_end_time - test_start_time))
450489 echo
451- echo " + pass"
490+ echo " + pass ( ${test_duration} s) "
452491 fi
453492 mysql_version=" $( gh-ost-test-mysql-replica -e " select @@version" ) "
454493 replica_terminology=" slave"
0 commit comments