Merge lp:~akopytov/percona-xtrabackup/test-suite-cleanups-2.0 into lp:percona-xtrabackup/2.0

Proposed by Alexey Kopytov
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 565
Proposed branch: lp:~akopytov/percona-xtrabackup/test-suite-cleanups-2.0
Merge into: lp:percona-xtrabackup/2.0
Diff against target: 1804 lines (+792/-621)
16 files modified
patches/innodb56.patch (+17/-1)
src/xtrabackup.cc (+6/-14)
test/inc/common.sh (+102/-65)
test/run.sh (+653/-96)
test/subunit.sh (+4/-1)
test/t/bug1085099.sh (+1/-3)
test/t/bug664986.sh (+0/-8)
test/t/bug996493.sh (+0/-4)
test/t/ib_stream_incremental.sh (+1/-1)
test/t/remote_tablespaces.sh (+1/-1)
test/t/undo_tablespaces.sh (+1/-1)
test/t/xb_part_range.sh (+2/-12)
test/t/xb_perm_basic.sh (+0/-2)
test/t/xb_perm_stream.sh (+0/-2)
test/t/xb_stats_datadir.sh (+4/-5)
test/testrun.c (+0/-405)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/test-suite-cleanups-2.0
Reviewer Review Type Date Requested Status
George Ormond Lorch III (community) g2 Approve
Stewart Smith Pending
Review via email: mp+172962@code.launchpad.net

Description of the change

  Various test suite cleanups:

    * Re-implemented testrun.c in testrun.sh. This allows cleaner and
      more efficient implementations of parallel tests execution and
      status aggregation. Unlike previously, a server instance to detect
      version is now started just once before tests execution, which
      should save a lot of time. And we don't need to hash the
      binary. Progress is now reported and stats are also collected in
      the main script. And we also don't need multuple subunit files.

    * As we don't need the run.sh wrapper now either, renamed testrun.sh
      back to its original name.

    * Fixed bug #1097434 "CTRL-C or kill run.sh only terminates current
      test, not entire run" by defining appropriate signal handler in
      the script.

    * Fixed bug #1097444 "xtrabackup test suite leaves
      xtrabackup.mysql.sock and xtrabackup_port_lock files behind in
      /tmp" by making sure everything is killed and cleaned up in all
      circumstances

    * Fixed bug #1194813 "The port lock mechanism in XB test suite does
      not work"

    * Time taken by each test is now reported

    * The summary is now a lot more similar to MTR and includes test
      execution time stats and skipped tests summary.

    * When a test fails in debug mode, information on where the
      artifacts can be found is now displayed in the summary

    * record_db_state / verify_db_state now pass --skip-extended-insert
      to mysqldump, which makes identifying difference in data rows much
      easier.

    * reduced the time we are waiting for a server to start by tweaking
      mysql_ping()

    * fixed bug #1196475 "xtrabackup does not recognize checkpoint #0 as
      a valid checkpoint on --prepare" as the previous change result in
      sporatic test failures without the fix.

    * fixed bug #1196894 "Wrong check for partitioning support in
      xb_part_range.sh"

    * fixed bug #1197249 "Debug xtrabackup_56 builds are affected by
      upstream bug #69653"

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :

http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.0-param/476/

xtradb56 failures on Lucid/Debian is bug #1193950 (will be fixed after updating links in bootstrap.sh)

xtradb56 failure on Centos5 is another (unreported) issue with PS 5.6.10 (should be fixed in later releases).

ddl.sh failure on Precise/Raring is bug #1098501.

galera55 failure on Quantal is JIRA JEN-60.

Debug build failures on Quantal/Raring is bug #1192454.

Revision history for this message
George Ormond Lorch III (gl-az) wrote :

One minor thing, line 1172 of the diff. run.sh sources ./inc/common.sh, then a few lines later sources the test which may (likely) also source ./inc/common.sh. Not a huge deal as they should both be sourcing the same file and common.sh doesn't do much of anything in the global space. If something changes in the future it could be possible for a test to potentially source a different common.sh or if any new scripting is added to the common.sh global space it would/could be executed twice possibly unknowingly causing some kind of issue.

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Hi George,

On Tue, 09 Jul 2013 18:48:26 -0000, George Ormond Lorch III wrote:
> One minor thing, line 1172 of the diff. run.sh sources ./inc/common.sh, then a few lines later sources the test which may (likely) also source ./inc/common.sh. Not a huge deal as they should both be sourcing the same file and common.sh doesn't do much of anything in the global space. If something changes in the future it could be possible for a test to potentially source a different common.sh or if any new scripting is added to the common.sh global space it would/could be executed twice possibly unknowingly causing some kind of issue.
>

Yes, basically inc/common.sh is now redundant and not required to be
included by tests. So it can be merged to run.sh.

Currently it can be safely included any number of times (i.e. does not
change anything in the environment), so I decided to leave it as is for
now. Should it cause any problems, we can implement the above in the
next cleanups round :)

Revision history for this message
George Ormond Lorch III (gl-az) wrote :

Also I see that common is included at the head of run.sh as well as later included in the sub statement () that sources the tests. Another possible redundancy but again, very, very minor issue that can/will be eliminated as you say if/when common.sh is absorbed into run.sh.

Revision history for this message
George Ormond Lorch III (gl-az) wrote :

Overall, some very nice work here. You do write quite pretty code. Everything appears to work well and I do not see anything obvious that needs fixing but I am pretty sure I missed some little juicy nugget that will cause heartache later on :) As always, I learned another cool scripting trick or two from this that I will likely use in PTB.

review: Approve (g2)
Revision history for this message
Stewart Smith (stewart) wrote :

Alexey Kopytov <email address hidden> writes:
> Yes, basically inc/common.sh is now redundant and not required to be
> included by tests. So it can be merged to run.sh.

If you're going to clean this up at some point it may be good to rename
the files to something that isn't .sh too, as otherwise it trips up some
automated check-for-copyright-headers checkers for Debian packaging.

--
Stewart Smith

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'patches/innodb56.patch'
--- patches/innodb56.patch 2013-07-01 12:20:49 +0000
+++ patches/innodb56.patch 2013-07-04 07:45:32 +0000
@@ -1303,4 +1303,20 @@
1303 int main()1303 int main()
1304 {1304 {
1305 extern void __attribute__((weak)) foo(void);1305 extern void __attribute__((weak)) foo(void);
13061306--- a/mysys/my_thr_init.c
1307+++ b/mysys/my_thr_init.c
1308@@ -462,8 +462,12 @@
1309
1310 extern void **my_thread_var_dbug()
1311 {
1312- struct st_my_thread_var *tmp=
1313- my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
1314+ struct st_my_thread_var *tmp;
1315+
1316+ if (!my_thread_global_init_done)
1317+ return NULL;
1318+
1319+ tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
1320 return tmp && tmp->init ? &tmp->dbug : 0;
1321 }
1322 #endif /* DBUG_OFF */
13071323
=== modified file 'src/xtrabackup.cc'
--- src/xtrabackup.cc 2013-06-18 14:46:51 +0000
+++ src/xtrabackup.cc 2013-07-04 07:45:32 +0000
@@ -6471,6 +6471,8 @@
64716471
6472 ulint fold;6472 ulint fold;
64736473
6474 bool checkpoint_found;
6475
6474 max_no = ut_dulint_zero;6476 max_no = ut_dulint_zero;
64756477
6476 if (!xb_init_log_block_size()) {6478 if (!xb_init_log_block_size()) {
@@ -6587,6 +6589,8 @@
6587 // ' ', 4);6589 // ' ', 4);
6588 }6590 }
65896591
6592 checkpoint_found = false;
6593
6590 /* read last checkpoint lsn */6594 /* read last checkpoint lsn */
6591 for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;6595 for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
6592 field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {6596 field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
@@ -6599,25 +6603,13 @@
6599 if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {6603 if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
6600 max_no = checkpoint_no;6604 max_no = checkpoint_no;
6601 max_lsn = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_LSN);6605 max_lsn = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_LSN);
6602/*6606 checkpoint_found = true;
6603 mach_write_to_4(log_buf + field + LOG_CHECKPOINT_OFFSET,
6604 LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
6605 ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
6606
6607 ulint fold;
6608 fold = ut_fold_binary(log_buf + field, LOG_CHECKPOINT_CHECKSUM_1);
6609 mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_1, fold);
6610
6611 fold = ut_fold_binary(log_buf + field + LOG_CHECKPOINT_LSN,
6612 LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
6613 mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_2, fold);
6614*/
6615 }6607 }
6616not_consistent:6608not_consistent:
6617 ;6609 ;
6618 }6610 }
66196611
6620 if (ut_dulint_cmp(max_no, ut_dulint_zero) == 0) {6612 if (!checkpoint_found) {
6621 msg("xtrabackup: No valid checkpoint found.\n");6613 msg("xtrabackup: No valid checkpoint found.\n");
6622 goto error;6614 goto error;
6623 }6615 }
66246616
=== modified file 'test/inc/common.sh'
--- test/inc/common.sh 2013-06-28 15:21:38 +0000
+++ test/inc/common.sh 2013-07-04 07:45:32 +0000
@@ -16,9 +16,12 @@
16}16}
1717
1818
19function clean()19########################################################################
20# Remove server var* directories from the worker's var root
21########################################################################
22function remove_var_dirs()
20{23{
21 rm -rf ${TEST_BASEDIR}/var[0-9]24 rm -rf ${TEST_VAR_ROOT}/var[0-9]
22}25}
2326
24function die()27function die()
@@ -34,29 +37,33 @@
34 $MYSQL_INSTALL_DB --defaults-file=${MYSQLD_VARDIR}/my.cnf \37 $MYSQL_INSTALL_DB --defaults-file=${MYSQLD_VARDIR}/my.cnf \
35 --basedir=${MYSQL_BASEDIR} \38 --basedir=${MYSQL_BASEDIR} \
36 ${MYSQLD_EXTRA_ARGS}39 ${MYSQLD_EXTRA_ARGS}
37 cd -40 cd - >/dev/null 2>&1
38}41}
3942
40########################################################################43########################################################################
41# Checks whether MySQL is alive44# Checks whether MySQL with the PID specified as an argument is alive
42########################################################################45########################################################################
43function mysql_ping()46function mysql_ping()
44{47{
45 $MYSQLADMIN $MYSQL_ARGS --wait=100 ping >/dev/null 2>&1 || return 148 local pid=$1
46}49 local attempts=60
50 local i
4751
48function kill_leftovers()52 for ((i=1; i<=attempts; i++))
49{
50 local file
51 for file in ${TEST_BASEDIR}/mysqld*.pid
52 do53 do
53 if [ -f $file ]54 $MYSQLADMIN $MYSQL_ARGS ping >/dev/null 2>&1 && return 0
54 then55 sleep 1
55 vlog "Found a leftover mysqld processes with PID `cat $file`, stopping it"56 # Is the server process still alive?
56 kill -9 `cat $file` 2>/dev/null || true57 if ! kill -0 $pid >/dev/null 2>&1
57 rm -f $file58 then
58 fi59 vlog "Server process PID=$pid died."
60 wait $pid
61 return 1
62 fi
63 vlog "Made $i attempts to connect to server"
59 done64 done
65
66 return 1
60}67}
6168
62function run_cmd()69function run_cmd()
@@ -123,21 +130,14 @@
123 local port130 local port
124 local lockfile131 local lockfile
125132
126 for (( port=PORT_BASE+id; port < 65535; port++))133 for (( port=3307 + RANDOM; port < 65535; port++))
127 do134 do
128 lockfile="/tmp/xtrabackup_port_lock.$port"135 lockfile="/tmp/xtrabackup_port_lock.$port"
129 # Try to atomically lock the current port number136 # Try to atomically lock the current port number
130 if ! set -C > $lockfile137 if ! (set -C; > $lockfile)
131 then138 then
132 set +C139 continue;
133 # check if the process still exists
134 if kill -0 "`cat $lockfile`"
135 then
136 continue;
137 fi
138 # stale file, overwrite it with the current PID
139 fi140 fi
140 set +C
141 echo $$ > $lockfile141 echo $$ > $lockfile
142 if ! nc -z -w1 localhost $port >/dev/null 2>&1142 if ! nc -z -w1 localhost $port >/dev/null 2>&1
143 then143 then
@@ -173,13 +173,14 @@
173 fi173 fi
174174
175 SRV_MYSQLD_IDS[$id]="$id"175 SRV_MYSQLD_IDS[$id]="$id"
176 local vardir="${TEST_BASEDIR}/var${id}"176 local vardir="${TEST_VAR_ROOT}/var${id}"
177 SRV_MYSQLD_VARDIR[$id]="$vardir"177 SRV_MYSQLD_VARDIR[$id]="$vardir"
178 SRV_MYSQLD_DATADIR[$id]="$vardir/data"178 SRV_MYSQLD_DATADIR[$id]="$vardir/data"
179 SRV_MYSQLD_TMPDIR[$id]="$vardir/tmp"179 SRV_MYSQLD_TMPDIR[$id]="$vardir/tmp"
180 SRV_MYSQLD_PIDFILE[$id]="${TEST_BASEDIR}/mysqld${id}.pid"180 SRV_MYSQLD_PIDFILE[$id]="${TEST_VAR_ROOT}/mysqld${id}.pid"
181 SRV_MYSQLD_ERRFILE[$id]="$vardir/data/mysqld${id}.err"
181 SRV_MYSQLD_PORT[$id]=`get_free_port $id`182 SRV_MYSQLD_PORT[$id]=`get_free_port $id`
182 SRV_MYSQLD_SOCKET[$id]=`mktemp -t xtrabackup.mysql.sock.XXXXXX`183 SRV_MYSQLD_SOCKET[$id]=`mktemp -t mysql.sock.XXXXXX`
183}184}
184185
185########################################################################186########################################################################
@@ -200,6 +201,7 @@
200 SRV_MYSQLD_DATADIR[$id]=201 SRV_MYSQLD_DATADIR[$id]=
201 SRV_MYSQLD_TMPDIR[$id]=202 SRV_MYSQLD_TMPDIR[$id]=
202 SRV_MYSQLD_PIDFILE[$id]=203 SRV_MYSQLD_PIDFILE[$id]=
204 SRV_MYSQLD_ERRFILE[$id]=
203 SRV_MYSQLD_PORT[$id]=205 SRV_MYSQLD_PORT[$id]=
204 SRV_MYSQLD_SOCKET[$id]=206 SRV_MYSQLD_SOCKET[$id]=
205}207}
@@ -216,6 +218,7 @@
216 MYSQLD_DATADIR="${SRV_MYSQLD_DATADIR[$id]}"218 MYSQLD_DATADIR="${SRV_MYSQLD_DATADIR[$id]}"
217 MYSQLD_TMPDIR="${SRV_MYSQLD_TMPDIR[$id]}"219 MYSQLD_TMPDIR="${SRV_MYSQLD_TMPDIR[$id]}"
218 MYSQLD_PIDFILE="${SRV_MYSQLD_PIDFILE[$id]}"220 MYSQLD_PIDFILE="${SRV_MYSQLD_PIDFILE[$id]}"
221 MYSQLD_ERRFILE="${SRV_MYSQLD_ERRFILE[$id]}"
219 MYSQLD_PORT="${SRV_MYSQLD_PORT[$id]}"222 MYSQLD_PORT="${SRV_MYSQLD_PORT[$id]}"
220 MYSQLD_SOCKET="${SRV_MYSQLD_SOCKET[$id]}"223 MYSQLD_SOCKET="${SRV_MYSQLD_SOCKET[$id]}"
221224
@@ -242,27 +245,36 @@
242function start_server_with_id()245function start_server_with_id()
243{246{
244 local id=$1247 local id=$1
248 local attempts=0
249 local max_attempts=5
245 shift250 shift
246251
247 vlog "Starting server with id=$id..."252 vlog "Starting server with id=$id..."
248253
249 init_server_variables $id254 while true
250 switch_server $id255 do
251256 init_server_variables $id
252 if [ ! -d "$MYSQLD_VARDIR" ]257 switch_server $id
253 then258
254 vlog "Creating server root directory: $MYSQLD_VARDIR"259 if [ ! -d "$MYSQLD_VARDIR" ]
255 mkdir "$MYSQLD_VARDIR"260 then
256 fi261 vlog "Creating server root directory: $MYSQLD_VARDIR"
257 if [ ! -d "$MYSQLD_TMPDIR" ]262 mkdir "$MYSQLD_VARDIR"
258 then263 fi
259 vlog "Creating server temporary directory: $MYSQLD_TMPDIR"264 if [ ! -d "$MYSQLD_TMPDIR" ]
260 mkdir "$MYSQLD_TMPDIR"265 then
261 fi266 vlog "Creating server temporary directory: $MYSQLD_TMPDIR"
262267 mkdir "$MYSQLD_TMPDIR"
263 # Create the configuration file used by mysql_install_db, the server268 fi
264 # and the xtrabackup binary269
265 cat > ${MYSQLD_VARDIR}/my.cnf <<EOF270 if [ -f "$MYSQLD_ERRFILE" ]
271 then
272 rm "$MYSQLD_ERRFILE"
273 fi
274
275 # Create the configuration file used by mysql_install_db, the server
276 # and the xtrabackup binary
277 cat > ${MYSQLD_VARDIR}/my.cnf <<EOF
266[mysqld]278[mysqld]
267socket=${MYSQLD_SOCKET}279socket=${MYSQLD_SOCKET}
268port=${MYSQLD_PORT}280port=${MYSQLD_PORT}
@@ -270,6 +282,7 @@
270basedir=${MYSQL_BASEDIR}282basedir=${MYSQL_BASEDIR}
271datadir=${MYSQLD_DATADIR}283datadir=${MYSQLD_DATADIR}
272tmpdir=${MYSQLD_TMPDIR}284tmpdir=${MYSQLD_TMPDIR}
285log-error=${MYSQLD_ERRFILE}
273log-bin=mysql-bin286log-bin=mysql-bin
274relay-log=mysql-relay-bin287relay-log=mysql-relay-bin
275pid-file=${MYSQLD_PIDFILE}288pid-file=${MYSQLD_PIDFILE}
@@ -281,22 +294,42 @@
281user=root294user=root
282EOF295EOF
283296
284 # Create datadir and call mysql_install_db if it doesn't exist297 # Create datadir and call mysql_install_db if it doesn't exist
285 if [ ! -d "$MYSQLD_DATADIR" ]298 if [ ! -d "$MYSQLD_DATADIR" ]
286 then299 then
287 vlog "Creating server data directory: $MYSQLD_DATADIR"300 vlog "Creating server data directory: $MYSQLD_DATADIR"
288 mkdir -p "$MYSQLD_DATADIR"301 mkdir -p "$MYSQLD_DATADIR"
289 call_mysql_install_db302 call_mysql_install_db
290 fi303 fi
291304
292 # Start the server305 # Start the server
293 echo "Starting ${MYSQLD} ${MYSQLD_ARGS} $* "306 echo "Starting ${MYSQLD} ${MYSQLD_ARGS} $* "
294 ${MYSQLD} ${MYSQLD_ARGS} $* &307 ${MYSQLD} ${MYSQLD_ARGS} $* &
295 if ! mysql_ping308 if ! mysql_ping $!
296 then309 then
297 die "Can't start the server!"310 if grep "another mysqld server running on port" $MYSQLD_ERRFILE
298 fi311 then
299 vlog "Server with id=$id has been started on port $MYSQLD_PORT, \312 if ((++attempts < max_attempts))
313 then
314 vlog "Made $attempts attempts to find a free port"
315 reset_server_variables $id
316 free_reserved_port $MYSQLD_PORT
317 continue
318 else
319 vlog "Failed to find a free port after $attempts attempts"
320 fi
321 fi
322 vlog "Can't start the server. Server log (if exists):"
323 vlog "----------------"
324 cat ${MYSQLD_ERRFILE} >&2 || true
325 vlog "----------------"
326 exit -1
327 else
328 break
329 fi
330 done
331
332 vlog "Server with id=$id has been started on port $MYSQLD_PORT, \
300socket $MYSQLD_SOCKET"333socket $MYSQLD_SOCKET"
301}334}
302335
@@ -313,7 +346,9 @@
313346
314 if [ -f "${MYSQLD_PIDFILE}" ]347 if [ -f "${MYSQLD_PIDFILE}" ]
315 then348 then
316 kill -9 `cat ${MYSQLD_PIDFILE}`349 local pid=`cat $MYSQLD_PIDFILE`
350 kill -9 $pid
351 wait $pid || true
317 rm -f ${MYSQLD_PIDFILE}352 rm -f ${MYSQLD_PIDFILE}
318 else353 else
319 vlog "Server PID file '${MYSQLD_PIDFILE}' doesn't exist!"354 vlog "Server PID file '${MYSQLD_PIDFILE}' doesn't exist!"
@@ -480,7 +515,8 @@
480##########################################################################515##########################################################################
481function record_db_state()516function record_db_state()
482{517{
483 $MYSQLDUMP $MYSQL_ARGS -t --compact $1 >"$topdir/tmp/$1_old.sql"518 $MYSQLDUMP $MYSQL_ARGS -t --compact --skip-extended-insert \
519 $1 >"$topdir/tmp/$1_old.sql"
484}520}
485521
486522
@@ -490,7 +526,8 @@
490##########################################################################526##########################################################################
491function verify_db_state()527function verify_db_state()
492{528{
493 $MYSQLDUMP $MYSQL_ARGS -t --compact $1 >"$topdir/tmp/$1_new.sql"529 $MYSQLDUMP $MYSQL_ARGS -t --compact --skip-extended-insert \
530 $1 >"$topdir/tmp/$1_new.sql"
494 diff -u "$topdir/tmp/$1_old.sql" "$topdir/tmp/$1_new.sql"531 diff -u "$topdir/tmp/$1_old.sql" "$topdir/tmp/$1_new.sql"
495}532}
496533
497534
=== removed file 'test/run.sh'
--- test/run.sh 2012-11-30 04:28:06 +0000
+++ test/run.sh 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1#!/bin/bash
2
3XB_BUILD="autodetect"
4while getopts "fc:" options; do
5 case $options in
6 c ) XB_BUILD="$OPTARG";;
7 f ) ;; # ignored
8 esac
9done
10
11rm -rf results/ var/ test_results.subunit
12
13CFLAGS=-g make testrun
14./testrun -c $XB_BUILD
150
=== renamed file 'test/testrun.sh' => 'test/run.sh'
--- test/testrun.sh 2013-05-07 07:53:25 +0000
+++ test/run.sh 2013-07-04 07:45:32 +0000
@@ -2,14 +2,39 @@
22
3export DEBUG=3export DEBUG=
44
5shopt -s extglob
6
7set +e
8
5. inc/common.sh9. inc/common.sh
610. subunit.sh
7trap kill_leftovers 1 2 3 1511
812trap cleanup_on_exit EXIT
9set +e13trap terminate SIGHUP SIGINT SIGQUIT SIGTERM
1014
11result=015result=0
1216
17# Default test timeout in seconds
18TEST_TIMEOUT=600
19
20# Magic exit code to indicate a skipped test
21export SKIPPED_EXIT_CODE=200
22
23# Default server installation directory (-d option)
24MYSQL_BASEDIR=${MYSQL_BASEDIR:-"$PWD/server"}
25
26TEST_BASEDIR="$PWD"
27TEST_VAR_ROOT="$TEST_BASEDIR/var"
28
29# Global statistics
30FAILED_COUNT=0
31FAILED_TESTS=
32SKIPPED_COUNT=0
33SKIPPED_TESTS=
34SUCCESSFUL_COUNT=0
35TOTAL_COUNT=0
36TOTAL_TIME=0
37
13function usage()38function usage()
14{39{
15cat <<EOF40cat <<EOF
@@ -24,7 +49,183 @@
24-c conf XtraBackup build configuration as specified to build.sh.49-c conf XtraBackup build configuration as specified to build.sh.
25 Default is 'autodetect', i.e. xtrabackup binary is determined based50 Default is 'autodetect', i.e. xtrabackup binary is determined based
26 on the MySQL version.51 on the MySQL version.
27EOF52-j N Run tests in N parallel processes.
53-T seconds Test timeout (default is $TEST_TIMEOUT seconds).
54EOF
55}
56
57###############################################################################
58# Calculate the number of parallel workers automatically based on the number of
59# available cores
60###############################################################################
61function autocalc_nworkers()
62{
63 if [ -r /proc/cpuinfo ]
64 then
65 NWORKERS=`grep processor /proc/cpuinfo | wc -l`
66 elif which sysctl >/dev/null 2>&1
67 then
68 NWORKERS=`sysctl -n hw.ncpu`
69 fi
70
71 if [[ ! $NWORKERS =~ ^[0-9]+$ || $NWORKERS < 1 ]]
72 then
73 echo "Cannot determine the number of available CPU cures!"
74 exit -1
75 fi
76
77 if [ "$NWORKERS" -gt 16 ]
78 then
79 echo "Autodetected number of cores: $NWORKERS"
80 echo "Limiting to 16 to avoid excessive resource consumption"
81
82 NWORKERS=16
83 fi
84}
85
86###############################################################################
87# Kill a specified worker
88###############################################################################
89function kill_worker()
90{
91 local worker=$1
92 local pid=${worker_pids[$worker]}
93
94 worker_pids[$worker]=""
95
96 if ! kill -0 $pid >/dev/null 2>&1
97 then
98 wait $pid >/dev/null 2>&1 || true
99 return 0
100 fi
101
102 # First send SIGTERM to let worker exit gracefully
103 kill -SIGTERM $pid >/dev/null 2>&1 || true
104
105 sleep 1
106
107 if ! kill -0 $pid >/dev/null 2>&1
108 then
109 wait $pid >/dev/null 2>&1 || true
110 return 0
111 fi
112
113 # Now kill with SIGKILL
114 kill -SIGKILL $pid >/dev/null 2>&1 || true
115 wait $pid >/dev/null 2>&1 || true
116 release_port_locks $pid
117}
118
119########################################################################
120# Kill all running workers
121########################################################################
122function kill_all_workers()
123{
124 while true
125 do
126 found=""
127
128 # First send SIGTERM to let workers exit gracefully
129 for ((i = 1; i <= NWORKERS; i++))
130 do
131 [ -z ${worker_pids[$i]:-""} ] && continue
132
133 found="yes"
134
135 if ! kill -0 ${worker_pids[$i]} >/dev/null 2>&1
136 then
137 worker_pids[$i]=""
138 continue
139 fi
140
141 kill -SIGTERM ${worker_pids[$i]} >/dev/null 2>&1 || true
142 done
143
144 [ -z "$found" ] && break
145
146 sleep 1
147
148 # Now kill with SIGKILL
149 for ((i = 1; i <= NWORKERS; i++))
150 do
151 [ -z ${worker_pids[$i]:-""} ] && continue
152
153 if ! kill -0 ${worker_pids[$i]} >/dev/null 2>&1
154 then
155 wait ${worker_pids[$i]} >/dev/null 2>&1 || true
156 worker_pids[$i]=""
157 continue
158 fi
159
160 kill -SIGKILL ${worker_pids[$i]} >/dev/null 2>&1 || true
161 wait ${worker_pids[$i]} >/dev/null 2>&1 || true
162 release_port_locks ${worker_pids[$i]}
163 worker_pids[$i]=""
164 done
165 done
166}
167
168########################################################################
169# Handler called from a fatal signal handler trap
170########################################################################
171function terminate()
172{
173 echo "Terminated, cleaning up..."
174
175 # The following will call cleanup_on_exit()
176 exit 2
177}
178
179########################################################################
180# Display the test run summary and exit
181########################################################################
182function print_status_and_exit()
183{
184 local test_time=$((`now` - TEST_START_TIME))
185 cat <<EOF
186==============================================================================
187Spent $TOTAL_TIME of $test_time seconds executing testcases
188
189SUMMARY: $TOTAL_COUNT run, $SUCCESSFUL_COUNT successful, $SKIPPED_COUNT skipped, $FAILED_COUNT failed
190
191EOF
192
193 if [ -n "$SKIPPED_TESTS" ]
194 then
195 echo "Skipped tests: $SKIPPED_TESTS"
196 echo
197 fi
198
199 if [ -n "$FAILED_TESTS" ]
200 then
201 echo "Failed tests: $FAILED_TESTS"
202 echo
203 fi
204
205 echo "See results/ for detailed output"
206
207 if [ "$FAILED_COUNT" = 0 ]
208 then
209 exit 0
210 fi
211
212 exit 1
213}
214
215########################################################################
216# Cleanup procedure invoked on process exit
217########################################################################
218function cleanup_on_exit()
219{
220 kill_servers $TEST_VAR_ROOT
221
222 remove_var_dirs
223
224 release_port_locks $$
225
226 kill_all_workers
227
228 cleanup_all_workers
28}229}
29230
30function find_program()231function find_program()
@@ -52,12 +253,11 @@
52 fi253 fi
53}254}
54255
256########################################################################
257# Explore environment and setup global variables
258########################################################################
55function set_vars()259function set_vars()
56{260{
57 TEST_BASEDIR=${TEST_BASEDIR:-"$PWD"}
58 MYSQL_BASEDIR=${MYSQL_BASEDIR:-"$PWD/server"}
59 PORT_BASE=$((3306 + $RANDOM))
60
61 if gnutar --version > /dev/null 2>&1261 if gnutar --version > /dev/null 2>&1
62 then262 then
63 TAR=gnutar263 TAR=gnutar
@@ -88,7 +288,7 @@
88 fi288 fi
89 DYLD_LIBRARY_PATH="$LD_LIBRARY_PATH"289 DYLD_LIBRARY_PATH="$LD_LIBRARY_PATH"
90290
91 export TEST_BASEDIR PORT_BASE TAR MYSQL_BASEDIR MYSQL MYSQLD MYSQLADMIN \291 export TAR MYSQL_BASEDIR MYSQL MYSQLD MYSQLADMIN \
92MYSQL_INSTALL_DB PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH MYSQLDUMP292MYSQL_INSTALL_DB PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH MYSQLDUMP
93}293}
94294
@@ -232,7 +432,7 @@
232 return 1432 return 1
233 fi433 fi
234434
235 stop_server435 stop_server >>$OUTFILE 2>&1
236436
237 export MYSQL_VERSION MYSQL_VERSION_COMMENT MYSQL_FLAVOR \437 export MYSQL_VERSION MYSQL_VERSION_COMMENT MYSQL_FLAVOR \
238 INNODB_VERSION XTRADB_VERSION INNODB_FLAVOR \438 INNODB_VERSION XTRADB_VERSION INNODB_FLAVOR \
@@ -240,39 +440,362 @@
240 DEFAULT_IBDATA_SIZE440 DEFAULT_IBDATA_SIZE
241}441}
242442
243export SKIPPED_EXIT_CODE=200443###########################################################################
444# Kill all server processes started by a worker specified with its var root
445# directory
446###########################################################################
447function kill_servers()
448{
449 local var_root=$1
450 local file
451
452 [ -d $var_root ] || return 0
453
454 cd $var_root
455
456 for file in mysqld*.pid
457 do
458 if [ -f $file ]
459 then
460 vlog "Found a leftover mysqld processes with PID `cat $file`, \
461stopping it"
462 kill -9 `cat $file` 2>/dev/null || true
463 rm -f $file
464 fi
465 done
466
467 cd - >/dev/null 2>&1
468}
469
470###########################################################################
471# Kill all server processes started by a worker specified with its number
472###########################################################################
473function kill_servers_for_worker()
474{
475 local worker=$1
476
477 kill_servers $TEST_BASEDIR/var/w$worker
478}
479
480################################################################################
481# Clean up all workers (except DEBUG_WORKER if set) We can't use worker* arrays
482# here and examine the directory structure, because the same functions is called
483# on startup when we want to cleanup all workers started on previous invokations
484################################################################################
485function cleanup_all_workers() { local worker
486
487 for worker_dir in $TEST_BASEDIR/var/w+([0-9])
488 do
489 [ -d $worker_dir ] || continue
490 [[ $worker_dir =~ w([0-9]+)$ ]] || continue
491
492 worker=${BASH_REMATCH[1]}
493
494 if [ "$worker" = "$DEBUG_WORKER" ]
495 then
496 echo
497 echo "Skipping cleanup for worker #$worker due to debug mode."
498 echo "You can do post-mortem analysis by examining test data in \
499$worker_dir"
500 echo "and the server process if it was running at the failure time."
501 continue
502 fi
503
504 cleanup_worker $worker
505 done
506}
507########################################################################
508# Clean up a specified worker
509########################################################################
510function cleanup_worker()
511{
512 local worker=$1
513 local tmpdir
514
515 kill_servers_for_worker $worker >>$OUTFILE 2>&1
516
517 # It is possible that a file is created while rm is in progress
518 # which results in "rm: cannot remove ...: Directory not empty
519 # hence the loop below
520 while true
521 do
522 # Fix permissions as some tests modify them so the following 'rm' fails
523 chmod -R 0700 $TEST_BASEDIR/var/w$worker >/dev/null 2>&1
524 rm -rf $TEST_BASEDIR/var/w$worker && break
525 done
526
527 tmpdir=${worker_tmpdirs[$worker]:-""}
528 if [ -n "$tmpdir" ]
529 then
530 rm -rf $tmpdir
531 fi
532}
533
534########################################################################
535# Return the number of seconds since the Epoch, UTC
536########################################################################
537function now()
538{
539 date '+%s'
540}
541
542########################################################################
543# Process the exit code of a specified worker
544########################################################################
545function reap_worker()
546{
547 local worker=$1
548 local pid=${worker_pids[$worker]}
549 local skip_file=${worker_skip_files[$worker]}
550 local tpath=${worker_names[$worker]}
551 local tname=`basename $tpath .sh`
552 local test_time=$((`now` - worker_stime[$worker]))
553 local status_file=${worker_status_files[$worker]}
554 local rc
555
556 if [ -f "$status_file" ]
557 then
558 rc=`cat $status_file`
559 # Assume exit code 1 if status file is empty
560 rc=${rc:-"1"}
561 else
562 # Assume exit code 1 if status file does not exist
563 rc="1"
564 fi
565
566 printf "%-40s w%d\t" $tname $worker
567
568 ((TOTAL_TIME+=test_time))
569
570 # Have to call subunit_start_test here, as currently tests cannot be
571 # interleaved in the subunit output
572 subunit_start_test $tpath "${worker_stime_txt[$worker]}" >> $SUBUNIT_OUT
573
574 if [ $rc -eq 0 ]
575 then
576 echo "[passed] $test_time"
577
578 SUCCESSFUL_COUNT=$((SUCCESSFUL_COUNT + 1))
579 subunit_pass_test $tpath >> $SUBUNIT_OUT
580
581 cleanup_worker $worker
582 elif [ $rc -eq $SKIPPED_EXIT_CODE ]
583 then
584 sreason=""
585 test -r $skip_file && sreason=`cat $skip_file`
586
587 SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
588 SKIPPED_TESTS="$SKIPPED_TESTS $tname"
589
590 echo "[skipped] $sreason"
591
592 subunit_skip_test $tpath >> $SUBUNIT_OUT
593
594 cleanup_worker $worker
595 else
596 echo "[failed] $test_time"
597
598 (
599 (echo "Something went wrong running $tpath. Exited with $rc";
600 echo; echo; cat ${worker_outfiles[$worker]}
601 ) | subunit_fail_test $tpath
602 ) >> $SUBUNIT_OUT
603
604 FAILED_COUNT=$((FAILED_COUNT + 1))
605 FAILED_TESTS="$FAILED_TESTS $tname"
606
607 # Return 0 on failed tests in the -f mode
608 if [ -z "$force" ]
609 then
610
611 if [ -z "$DEBUG" ]
612 then
613 cleanup_worker $worker
614 else
615 DEBUG_WORKER=$worker
616 fi
617
618 return 1
619 else
620 cleanup_worker $worker
621
622 return 0
623 fi
624 fi
625
626}
627
628#############################################################################
629# Check if a specified worker has exceed TEST_TIMEOUT and if so, terminate it
630#############################################################################
631function check_timeout_for_worker()
632{
633 local worker=$1
634 local tpath=${worker_names[$worker]}
635 local tname=`basename $tpath .sh`
636
637 if (( `now` - worker_stime[$worker] > TEST_TIMEOUT ))
638 then
639 kill_worker $worker
640 printf "%-40s w%d\t" $tname $worker
641 echo "[failed] Timed out after $TEST_TIMEOUT seconds."
642
643 (
644 # Have to call subunit_start_test here, as currently tests cannot be
645 # interleaved in the subunit output
646 subunit_start_test $tpath "${worker_stime_txt[$worker]}"
647
648 (echo "Timeout exceeded running $tpath.";
649 echo; echo; cat ${worker_outfiles[$worker]}
650 ) | subunit_fail_test $tpath
651 ) >> $SUBUNIT_OUT
652
653 FAILED_COUNT=$((FAILED_COUNT + 1))
654 FAILED_TESTS="$FAILED_TESTS $tname"
655
656 # Return 0 on failed tests in the -f mode
657 if [ -z "$force" ]
658 then
659
660 if [ -z "$DEBUG" ]
661 then
662 cleanup_worker $worker
663 else
664 DEBUG_WORKER=$worker
665 fi
666
667 return 1
668 else
669 cleanup_worker $worker
670
671 return 0
672 fi
673 fi
674}
675#########################################################################
676# Wait for all currently running worker to finish
677#########################################################################
678function reap_all_workers()
679{
680 while true
681 do
682 found=""
683
684 for ((i = 1; i <= NWORKERS; i++))
685 do
686 [ -z ${worker_pids[$i]:-""} ] && continue
687
688 found="yes"
689
690 # Check if it's alive
691 if kill -0 ${worker_pids[$i]} >/dev/null 2>&1
692 then
693 check_timeout_for_worker $i || print_status_and_exit
694 continue
695 fi
696
697 reap_worker $i || print_status_and_exit
698
699 worker_pids[$i]=""
700 done
701
702 [ -z "$found" ] && break
703
704 sleep 1
705 done
706}
707
708########################################################################
709# Release all port locks reserved by the current process
710# Used by the EXIT trap (in both normal and abnormal shell termination)
711########################################################################
712function release_port_locks()
713{
714 local process=$1
715 local lockfile
716
717 # Suppress errors when no port lock files are found
718 shopt -s nullglob
719
720 for lockfile in /tmp/xtrabackup_port_lock.*
721 do
722 if [ "`cat $lockfile 2>/dev/null`" = $process ]
723 then
724 rm -rf $lockfile
725 fi
726 done
727
728 shopt -u nullglob
729}
730
731########################################################################
732# Report status and release port locks on exit
733########################################################################
734function cleanup_on_test_exit()
735{
736 local rc=$?
737
738 echo $rc > $STATUS_FILE
739
740 release_port_locks $$
741}
742
743########################################################################
744# Script body
745########################################################################
746
747TEST_START_TIME=`now`
244748
245tname=""749tname=""
246XTRACE_OPTION=""750XTRACE_OPTION=""
247XB_BUILD="autodetect"751XB_BUILD="autodetect"
248force=""752force=""
249KEEP_RESULTS=0
250SUBUNIT_OUT=test_results.subunit753SUBUNIT_OUT=test_results.subunit
251754NWORKERS=
252while getopts "fgh?:t:s:d:c:b:nr:" options; do755DEBUG_WORKER=""
253 case $options in756
254 f ) force="yes";;757while getopts "fgh?:t:s:d:c:j:T:" options; do
255 t ) tname="$OPTARG";;758 case $options in
256 g ) XTRACE_OPTION="-x"; DEBUG=on;;759 f ) force="yes";;
257 h ) usage; exit;;760 t )
258 s ) tname="$OPTARG/*.sh";;761
259 d ) export MYSQL_BASEDIR="$OPTARG";;762 tname="$OPTARG";
260 b ) TEST_BASEDIR="$OPTARG";;763 if ! [ -r "$tname" ]
261 c ) XB_BUILD="$OPTARG";;764 then
262 n ) KEEP_RESULTS=1;;765 echo "Cannot find test $tname."
263 r ) SUBUNIT_OUT="$OPTARG";;766 exit -1
264 ? ) echo "Use \`$0 -h' for the list of available options."767 fi
768 ;;
769
770 g ) DEBUG=on;;
771 h ) usage; exit;;
772 s ) tname="$OPTARG/*.sh";;
773 d ) export MYSQL_BASEDIR="$OPTARG";;
774 c ) XB_BUILD="$OPTARG";;
775 j )
776
777 if [[ ! $OPTARG =~ ^[0-9]+$ || $NWORKERS < 1 ]]
778 then
779 echo "Wrong -j argument: $OPTARG"
780 exit -1
781 fi
782 NWORKERS="$OPTARG"
783 ;;
784
785 T )
786 if [[ ! $OPTARG =~ ^[0-9]+$ ]]
787 then
788 echo "Wrong -T argument: $OPTARG"
789 exit -1
790 fi
791 TEST_TIMEOUT="$OPTARG"
792 ;;
793
794 ? ) echo "Use \`$0 -h' for the list of available options."
265 exit -1;;795 exit -1;;
266 esac796 esac
267done797done
268798
269if [ $KEEP_RESULTS -eq 0 ];
270then
271 rm -rf results
272 rm -f $SUBUNIT_OUT
273fi
274mkdir results
275
276set_vars799set_vars
277800
278if [ -n "$tname" ]801if [ -n "$tname" ]
@@ -282,13 +805,17 @@
282 tests="t/*.sh"805 tests="t/*.sh"
283fi806fi
284807
285failed_count=0
286failed_tests=
287total_count=0
288
289export OUTFILE="$PWD/results/setup"808export OUTFILE="$PWD/results/setup"
290809
291clean >>$OUTFILE 2>&1810rm -rf results
811mkdir results
812
813cleanup_all_workers >>$OUTFILE 2>&1
814
815rm -rf var test_results.subunit
816mkdir var
817
818echo "Detecting server version..." | tee -a $OUTFILE
292819
293if ! get_version_info820if ! get_version_info
294then821then
@@ -300,69 +827,99 @@
300 tee -a $OUTFILE827 tee -a $OUTFILE
301828
302echo "Using '`basename $XB_BIN`' as xtrabackup binary" | tee -a $OUTFILE829echo "Using '`basename $XB_BIN`' as xtrabackup binary" | tee -a $OUTFILE
830
831[ -z "$NWORKERS" ] && autocalc_nworkers
832
833if [ "$NWORKERS" -gt 1 ]
834then
835 echo "Using $NWORKERS parallel workers" | tee -a $OUTFILE
836fi
303echo | tee -a $OUTFILE837echo | tee -a $OUTFILE
304838
305kill_leftovers >>$OUTFILE 2>&1839cat <<EOF
306clean >>$OUTFILE 2>&1840==============================================================================
307841TEST WORKER RESULT TIME(s) or COMMENT
308source subunit.sh842------------------------------------------------------------------------------
309843EOF
310echo "========================================================================"
311844
312for t in $tests845for t in $tests
313do846do
314 total_count=$((total_count+1))847 # Check if we have available workers
315848 found=""
316 printf "%-40s" $t849
317 subunit_start_test $t >> $SUBUNIT_OUT850 while [ -z "$found" ]
851 do
852 for ((i = 1; i <= NWORKERS; i++))
853 do
854 if [ -z ${worker_pids[$i]:-""} ]
855 then
856 found="yes"
857 break
858 else
859 # Check if it's alive
860 if kill -0 ${worker_pids[$i]} >/dev/null 2>&1
861 then
862 check_timeout_for_worker $i || print_status_and_exit
863 continue
864 fi
865 reap_worker $i || print_status_and_exit
866
867 worker_pids[$i]=""
868 found="yes"
869
870 break
871 fi
872 done
873
874 if [ -z "$found" ]
875 then
876 sleep 1
877 fi
878 done
879
880 worker=$i
881
882 TOTAL_COUNT=$((TOTAL_COUNT+1))
883
318 name=`basename $t .sh`884 name=`basename $t .sh`
319 export OUTFILE="$PWD/results/$name"885 worker_names[$worker]=$t
320 export SKIPPED_REASON="$PWD/results/$name.skipped"886 worker_outfiles[$worker]="$PWD/results/$name"
321 bash $XTRACE_OPTION $t > $OUTFILE 2>&1887 worker_skip_files[$worker]="$PWD/results/$name.skipped"
322 rc=$?888 worker_status_files[$worker]="$PWD/results/$name.status"
323889 # Create a unique TMPDIR for each worker so that it can be removed as a part
324 if [[ -z "$DEBUG" || -n "$force" ]]890 # of the cleanup procedure. Server socket files will also be created there.
325 then891 worker_tmpdirs[$worker]="`mktemp -d -t xbtemp.XXXXXX`"
326 kill_leftovers >>$OUTFILE 2>&1892
327 clean >>$OUTFILE 2>&1893 (
328 fi894 set -eu
329895 if [ -n "$DEBUG" ]
330 if [ $rc -eq 0 ]
331 then
332 echo "[passed]"
333 subunit_pass_test $t >> $SUBUNIT_OUT
334 elif [ $rc -eq $SKIPPED_EXIT_CODE ]
335 then
336 sreason=""
337 test -r $SKIPPED_REASON && sreason=`cat $SKIPPED_REASON`
338 echo "[skipped] $sreason"
339 subunit_skip_test $t >> $SUBUNIT_OUT
340 else
341 echo "[failed]"
342
343 (
344 (echo "Something went wrong running $t. Exited with $rc";
345 echo; echo; cat $OUTFILE
346 ) | subunit_fail_test $t
347 ) >> $SUBUNIT_OUT
348
349 failed_count=$((failed_count+1))
350 failed_tests="$failed_tests $t"
351 result=1
352 if [ -z "$force" ]
353 then896 then
354 break;897 set -x
355 fi898 fi
356 fi 899
900 trap "cleanup_on_test_exit" EXIT
901
902 . inc/common.sh
903
904 export OUTFILE=${worker_outfiles[$worker]}
905 export SKIPPED_REASON=${worker_skip_files[$worker]}
906 export TEST_VAR_ROOT=$TEST_BASEDIR/var/w$worker
907 export TMPDIR=${worker_tmpdirs[$worker]}
908 export STATUS_FILE=${worker_status_files[$worker]}
909
910 mkdir $TEST_VAR_ROOT
911
912 . $t
913 ) > ${worker_outfiles[$worker]} 2>&1 &
914
915 worker_pids[$worker]=$!
916 worker_stime[$worker]="`now`"
917 # Used in subunit reports
918 worker_stime_txt[$worker]="`date -u '+%Y-%m-%d %H:%M:%S'`"
357done919done
358920
359echo "========================================================================"921# Wait for in-progress workers to finish
360echo922reap_all_workers
361923
362if [ $result -eq 1 ]924print_status_and_exit
363then925
364 echo
365 echo "$failed_count/$total_count tests have failed: $failed_tests"
366 echo "See results/ for detailed output"
367 exit -1
368fi
369926
=== modified file 'test/subunit.sh'
--- test/subunit.sh 2011-06-12 09:57:00 +0000
+++ test/subunit.sh 2013-07-04 07:45:32 +0000
@@ -15,8 +15,11 @@
15#15#
1616
17subunit_start_test () {17subunit_start_test () {
18 local stime=$2
18 # emit the current protocol start-marker for test $119 # emit the current protocol start-marker for test $1
19 echo "time: `date -u '+%Y-%m-%d %H:%M:%S'`"20 # adjust time by the number of seconds to execute the test to get the actual
21 # start time
22 echo "time: $stime"
20 echo "test: $1"23 echo "test: $1"
21}24}
2225
2326
=== modified file 'test/t/bug1085099.sh'
--- test/t/bug1085099.sh 2013-03-06 10:04:13 +0000
+++ test/t/bug1085099.sh 2013-07-04 07:45:32 +0000
@@ -13,9 +13,7 @@
13# Create a new tmpdir13# Create a new tmpdir
14mkdir $topdir/new_tmpdir14mkdir $topdir/new_tmpdir
1515
16# Make the default tmpdir inaccessible and make sure permissions are restored on16# Make the default tmpdir inaccessible
17# failure
18trap "chmod 755 $MYSQLD_TMPDIR" INT TERM EXIT
19chmod 000 $MYSQLD_TMPDIR17chmod 000 $MYSQLD_TMPDIR
2018
21innobackupex --tmpdir=$topdir/new_tmpdir --no-timestamp $topdir/backup19innobackupex --tmpdir=$topdir/new_tmpdir --no-timestamp $topdir/backup
2220
=== modified file 'test/t/bug664986.sh'
--- test/t/bug664986.sh 2013-03-03 11:01:19 +0000
+++ test/t/bug664986.sh 2013-07-04 07:45:32 +0000
@@ -15,14 +15,6 @@
1515
16EOF16EOF
1717
18# Make sure we restore permissions to not leave stale files in Jenkins
19# on a test failure
20trap "vlog restoring directories and files permissions ; \
21 chmod 777 $MYSQLD_DATADIR/test_bug664986_innodb; \
22 chmod 777 $MYSQLD_DATADIR/test_bug664986_myisam; \
23 chmod 644 $MYSQLD_DATADIR/test_bug664986_innodb/*; \
24 chmod 644 $MYSQLD_DATADIR/test_bug664986_myisam/*" INT TERM EXIT
25
26# Test that wrong directory permissions result in a backup failure18# Test that wrong directory permissions result in a backup failure
27# for both InnoDB and non-InnoDB files19# for both InnoDB and non-InnoDB files
28chmod 000 $MYSQLD_DATADIR/test_bug664986_innodb20chmod 000 $MYSQLD_DATADIR/test_bug664986_innodb
2921
=== modified file 'test/t/bug996493.sh'
--- test/t/bug996493.sh 2012-11-29 04:37:56 +0000
+++ test/t/bug996493.sh 2013-07-04 07:45:32 +0000
@@ -20,9 +20,6 @@
20vlog "Remove my.cnf"20vlog "Remove my.cnf"
21mv $topdir/my.cnf $topdir/my.cnf.bak21mv $topdir/my.cnf $topdir/my.cnf.bak
2222
23trap "vlog restoring $topdir/my.cnf ; \
24mv $topdir/my.cnf.bak $topdir/my.cnf" INT TERM EXIT
25
26vlog "Apply log"23vlog "Apply log"
27# Do not run innobackupex, because it pass option --defaults-file24# Do not run innobackupex, because it pass option --defaults-file
28# which we should avoid. Our goal is to test that backup-my.cnf25# which we should avoid. Our goal is to test that backup-my.cnf
@@ -31,7 +28,6 @@
3128
32vlog "Get my.cnf back"29vlog "Get my.cnf back"
33mv $topdir/my.cnf.bak $topdir/my.cnf30mv $topdir/my.cnf.bak $topdir/my.cnf
34trap "vlog test exit" INT TERM EXIT
3531
36vlog "Copy back"32vlog "Copy back"
37innobackupex --copy-back $backup_dir33innobackupex --copy-back $backup_dir
3834
=== modified file 'test/t/ib_stream_incremental.sh'
--- test/t/ib_stream_incremental.sh 2012-06-05 12:35:33 +0000
+++ test/t/ib_stream_incremental.sh 2013-07-04 07:45:32 +0000
@@ -98,7 +98,7 @@
98 exit -198 exit -1
99 fi99 fi
100 100
101 clean101 remove_var_dirs
102}102}
103103
104stream_format="xbstream"104stream_format="xbstream"
105105
=== modified file 'test/t/remote_tablespaces.sh'
--- test/t/remote_tablespaces.sh 2013-04-23 06:38:06 +0000
+++ test/t/remote_tablespaces.sh 2013-07-04 07:45:32 +0000
@@ -12,7 +12,7 @@
1212
13start_server --innodb_file_per_table13start_server --innodb_file_per_table
1414
15remote_dir=$TEST_BASEDIR/var1/remote_dir15remote_dir=$TEST_VAR_ROOT/var1/remote_dir
1616
17$MYSQL $MYSQL_ARGS test <<EOF17$MYSQL $MYSQL_ARGS test <<EOF
18CREATE TABLE t(id INT AUTO_INCREMENT PRIMARY KEY, c INT)18CREATE TABLE t(id INT AUTO_INCREMENT PRIMARY KEY, c INT)
1919
=== modified file 'test/t/undo_tablespaces.sh'
--- test/t/undo_tablespaces.sh 2013-04-27 18:46:54 +0000
+++ test/t/undo_tablespaces.sh 2013-07-04 07:45:32 +0000
@@ -23,7 +23,7 @@
23EOF23EOF
24}24}
2525
26undo_directory=$TEST_BASEDIR/var1/undo_dir26undo_directory=$TEST_VAR_ROOT/var1/undo_dir
2727
28MYSQLD_EXTRA_MY_CNF_OPTS="28MYSQLD_EXTRA_MY_CNF_OPTS="
29innodb_file_per_table=129innodb_file_per_table=1
3030
=== modified file 'test/t/xb_part_range.sh'
--- test/t/xb_part_range.sh 2012-07-06 05:13:15 +0000
+++ test/t/xb_part_range.sh 2013-07-04 07:45:32 +0000
@@ -1,19 +1,9 @@
1. inc/common.sh1. inc/common.sh
2. inc/ib_part.sh
23
3start_server4start_server
45
5function check_partitioning()6require_partitioning
6{
7 $MYSQL $MYSQL_ARGS -Ns -e "show variables like 'have_partitioning'"
8}
9
10PARTITION_CHECK=`check_partitioning`
11
12if [ -z "$PARTITION_CHECK" ]; then
13 echo "Requires Partitioning." > $SKIPPED_REASON
14 stop_server
15 exit $SKIPPED_EXIT_CODE
16fi
177
18run_cmd $MYSQL $MYSQL_ARGS test <<EOF8run_cmd $MYSQL $MYSQL_ARGS test <<EOF
19CREATE TABLE test (9CREATE TABLE test (
2010
=== modified file 'test/t/xb_perm_basic.sh'
--- test/t/xb_perm_basic.sh 2012-10-15 16:14:59 +0000
+++ test/t/xb_perm_basic.sh 2013-07-04 07:45:32 +0000
@@ -4,6 +4,4 @@
4start_server4start_server
55
6chmod -R 500 $mysql_datadir6chmod -R 500 $mysql_datadir
7trap "vlog restoring permissions on datadir $mysql_datadir ; \
8chmod -R 700 $mysql_datadir" INT TERM EXIT
9innobackupex --no-timestamp $topdir/backup7innobackupex --no-timestamp $topdir/backup
108
=== modified file 'test/t/xb_perm_stream.sh'
--- test/t/xb_perm_stream.sh 2012-10-15 16:14:59 +0000
+++ test/t/xb_perm_stream.sh 2013-07-04 07:45:32 +0000
@@ -5,7 +5,5 @@
55
6# Take backup6# Take backup
7chmod -R 500 $mysql_datadir7chmod -R 500 $mysql_datadir
8trap "vlog restoring permissions on datadir $mysql_datadir ; \
9chmod -R 700 $mysql_datadir" INT TERM EXIT
10mkdir -p $topdir/backup8mkdir -p $topdir/backup
11innobackupex --stream=tar $topdir/backup > $topdir/backup/out.tar9innobackupex --stream=tar $topdir/backup > $topdir/backup/out.tar
1210
=== modified file 'test/t/xb_stats_datadir.sh'
--- test/t/xb_stats_datadir.sh 2013-05-02 13:05:59 +0000
+++ test/t/xb_stats_datadir.sh 2013-07-04 07:45:32 +0000
@@ -5,12 +5,11 @@
55
6. inc/common.sh6. inc/common.sh
77
8mkdir ${TEST_BASEDIR}/logs8logdir=${TEST_VAR_ROOT}/logs
99mkdir $logdir
10trap "rm -rf ${TEST_BASEDIR}/logs" INT TERM EXIT
1110
12MYSQLD_EXTRA_MY_CNF_OPTS="11MYSQLD_EXTRA_MY_CNF_OPTS="
13innodb_log_group_home_dir=${TEST_BASEDIR}/logs12innodb_log_group_home_dir=$logdir
14"13"
1514
16start_server15start_server
@@ -28,6 +27,6 @@
28# we pass all necessary options as an arguments, so if someday this27# we pass all necessary options as an arguments, so if someday this
29# will be changed, test still will work28# will be changed, test still will work
30xtrabackup --stats --datadir=${MYSQLD_DATADIR} \29xtrabackup --stats --datadir=${MYSQLD_DATADIR} \
31 --innodb_log_group_home_dir=${TEST_BASEDIR}/logs30 --innodb_log_group_home_dir=$logdir
3231
33vlog "stats did not fail"32vlog "stats did not fail"
3433
=== removed file 'test/testrun.c'
--- test/testrun.c 2012-11-30 04:28:06 +0000
+++ test/testrun.c 1970-01-01 00:00:00 +0000
@@ -1,405 +0,0 @@
1/*
2 * testrun.c - a parallel test runner for the XtraBackup test suite
3 */
4/* BEGIN LICENSE
5 * Copyright (C) 2012 Percona Inc.
6 *
7 * Written by Stewart Smith
8 *
9 * This program is free software: you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2, as published
11 * by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranties of
15 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 * END LICENSE */
21
22#include <stdio.h>
23#include <unistd.h>
24#include <dirent.h>
25#include <string.h>
26#include <limits.h>
27#include <stdlib.h>
28#include <sys/select.h>
29
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <sys/wait.h>
33#include <fcntl.h>
34#include <assert.h>
35
36#include <signal.h>
37
38struct testcase
39{
40 char *name;
41 char *buf;
42 size_t end_of_buf;
43 size_t bufsz;
44};
45
46pid_t *childpid;
47int nchildpid=0;
48
49static void kill_children(int sig)
50{
51 int i;
52 int status;
53
54 (void)sig;
55
56 fprintf(stderr, "Killing child processes...\n");
57
58 for(i=0; i<nchildpid; i++)
59 if(childpid[i] > 0)
60 {
61 kill(childpid[i], SIGKILL);
62 wait(&status);
63 }
64
65 exit(EXIT_SUCCESS);
66}
67
68int collect_testcases_filter(const struct dirent *a)
69{
70 int l;
71
72 if (a->d_name[0] == '.')
73 return 0;
74
75 l= strlen(a->d_name);
76
77 if (l > 2 && strncmp(a->d_name + l - 3, ".sh", 3)==0)
78 return 1;
79
80 return 0;
81}
82
83static int collect_testcases(const char* suitedir, struct testcase **cases)
84{
85 struct dirent **namelist;
86 int n;
87 int i;
88
89 n= scandir(suitedir, &namelist, collect_testcases_filter, alphasort);
90
91 *cases= (struct testcase*) malloc(sizeof(struct testcase)*n);
92
93 for(i=0; i<n; i++)
94 {
95 (*cases)[i].name= strdup(namelist[i]->d_name);
96 (*cases)[i].buf= NULL;
97 (*cases)[i].end_of_buf= 0;
98 (*cases)[i].bufsz= 0;
99 free(namelist[i]);
100 }
101
102 free(namelist);
103
104 return n;
105}
106
107static void free_testcases(struct testcase *cases, int n)
108{
109 while (n>0)
110 {
111 free(cases[--n].name);
112 }
113 free(cases);
114}
115
116static int run_testcase_in_child(int nr, struct testcase *t, pid_t *cpid, const char* xbtarget)
117{
118 int fd[2];
119
120 printf("[%d] LAUNCHING - %s\n", nr, t->name);
121
122 if (pipe(fd) == -1)
123 {
124 perror("pipe");
125 exit(EXIT_FAILURE);
126 }
127
128 *cpid= fork();
129 if (*cpid == 0)
130 {
131 /* child */
132 close(fd[0]);
133
134 char tname[500];
135 snprintf(tname, sizeof(tname), "t/%s",t->name);
136
137 char basedir[PATH_MAX];
138 char cwd[PATH_MAX];
139 snprintf(basedir, sizeof(basedir), "%s/var/%d", getcwd(cwd,sizeof(cwd)), nr);
140
141 mkdir("var",0700);
142 mkdir(basedir,0700);
143
144 char logname[PATH_MAX];
145 snprintf(logname, sizeof(logname), "%s/var/%d.log", getcwd(cwd,sizeof(cwd)), nr);
146
147 int logfd= open(logname, O_WRONLY|O_APPEND|O_CREAT, 0600);
148 dup2(logfd, STDOUT_FILENO);
149 dup2(logfd, STDERR_FILENO);
150 close(logfd);
151
152 char subunitfd[50];
153 snprintf(subunitfd, sizeof(subunitfd), "/dev/fd/%d", fd[1]);
154
155 char* xbtarget_param;
156 if (xbtarget)
157 xbtarget_param= strdup(xbtarget);
158 else
159 xbtarget_param= NULL;
160
161 char *const newargv[] = {"testrun.sh", "-n",
162 "-t", tname,
163 "-b", basedir,
164 "-r", subunitfd,
165 (xbtarget)? "-c" : NULL, xbtarget_param,
166 NULL };
167 char *newenviron[] = { NULL };
168 execve(newargv[0], newargv, newenviron);
169 perror("execve");
170 exit(EXIT_FAILURE);
171 }
172 else
173 {
174 /* parent */
175 close(fd[1]);
176 fcntl(fd[0], F_SETFL, O_NONBLOCK);
177 return fd[0];
178 }
179}
180
181static inline void subunit_progress_sign(int fd, int n, char *sign)
182{
183 char *buf;
184 const char* fmt= "progress: %s%d\n";
185 size_t sz= 1+strlen(fmt)+100;
186 size_t l;
187
188 buf= (char*)malloc(sz);
189
190 l= snprintf(buf, sz, fmt, sign, n);
191 assert(l < sz);
192
193 write(fd, buf, l);
194
195 free(buf);
196}
197
198static void run_testcases(struct testcase *testcases, int nrcases,
199 int njobs, int timeout, const char* xbtarget)
200{
201 int childfd[njobs];
202 int nfds= 0;
203 int retval;
204 pid_t chpid[njobs];
205 int status;
206 int next_testcase= 0;
207 int i;
208 fd_set rfds;
209 fd_set efds;
210 struct timeval tv;
211 int nchildren;
212 int childtest[njobs];
213
214 int subunitfd= open("test_results.subunit", O_TRUNC|O_WRONLY|O_APPEND|O_CREAT, 0600);
215 subunit_progress_sign(subunitfd, nrcases, "");
216
217 if (nrcases < njobs)
218 njobs= nrcases;
219
220 childpid= chpid;
221 nchildpid= njobs;
222
223 for(i=0; i<njobs; i++)
224 {
225 childtest[i]=next_testcase++;
226 childfd[i]= run_testcase_in_child(i, &testcases[childtest[i]], &childpid[i], xbtarget);
227 }
228
229 fflush(stdout);
230
231loop:
232 FD_ZERO(&efds);
233 FD_ZERO(&rfds);
234
235 nchildren=0;
236
237 for (i=0; i<njobs; i++)
238 {
239 if (childfd[i] != -1)
240 {
241 FD_SET(childfd[i], &efds);
242 FD_SET(childfd[i], &rfds);
243 nfds= (childfd[i] > nfds)? childfd[i] : nfds;
244 nchildren++;
245 }
246 }
247
248 tv.tv_sec= timeout;
249 tv.tv_usec= 0;
250
251 retval = select(nfds+1, &rfds, NULL, &efds, &tv);
252
253 if (retval == -1)
254 perror("select()");
255 else if (retval)
256 {
257 int childexited=0;
258
259 for (i=0; i<njobs; i++)
260 {
261 if(childfd[i] != -1
262 && (FD_ISSET(childfd[i], &efds) || FD_ISSET(childfd[i], &rfds)))
263 {
264 ssize_t r=0;
265
266 do {
267 struct testcase *t= &testcases[childtest[i]];
268
269 if(t->bufsz == t->end_of_buf)
270 {
271 t->bufsz+=4000;
272 t->buf= (char*)realloc(t->buf, t->bufsz);
273 }
274
275 r= read(childfd[i], t->buf+t->end_of_buf, t->bufsz - t->end_of_buf);
276 if (r>0)
277 t->end_of_buf+= r;
278 } while(r>0);
279
280 pid_t waited= waitpid(childpid[i], &status, WNOHANG);
281 if (!(WIFEXITED(status) || WIFSIGNALED(status)))
282 continue;
283
284 if (waited != childpid[i])
285 continue;
286
287 write(subunitfd, testcases[childtest[i]].buf,
288 testcases[childtest[i]].end_of_buf);
289
290 close(childfd[i]);
291 printf("[%d] completed %s status %d\n",
292 i, testcases[childtest[i]].name, WEXITSTATUS(status));
293 childfd[i]=-1;
294 nchildren--;
295
296 if (next_testcase < nrcases)
297 {
298 childtest[i]=next_testcase++;
299 childfd[i]= run_testcase_in_child(i, &testcases[childtest[i]], &childpid[i], xbtarget);
300 nfds= (childfd[i] > nfds)? childfd[i] : nfds;
301 nchildren++;
302 }
303 printf("\nnrchildren= %d, %d tests remaining\n",
304 nchildren, nrcases-next_testcase);
305 childexited=1;
306 fflush(stdout);
307 }
308 }
309 if (childexited)
310 {
311 printf ("Running: ");
312 for(i=0; i<njobs; i++)
313 if (childfd[i] != -1)
314 printf("%s ",testcases[childtest[i]].name);
315 printf("\n");
316 }
317 }
318 else
319 {
320 printf("Timeout\n");
321 kill_children(SIGKILL);
322 exit(EXIT_FAILURE);
323 }
324
325 if (nchildren==0)
326 goto end;
327
328 goto loop;
329
330end:
331
332 close(subunitfd);
333 return;
334}
335
336int main(int argc, char* argv[])
337{
338 const char* suitedir= "t/";
339 int njobs= 4;
340 int opt;
341 int nrcases;
342 struct testcase *testcases;
343 int timeout= 600;
344 const char* xbtarget= NULL;
345
346 struct sigaction sa;
347
348 sa.sa_flags= 0;
349 sigemptyset(&sa.sa_mask);
350 sa.sa_handler = kill_children;
351 sigaction(SIGHUP, &sa, NULL);
352 sigaction(SIGINT, &sa, NULL);
353 sigaction(SIGQUIT, &sa, NULL);
354
355#ifdef _SC_NPROCESSORS_ONLN
356 njobs= sysconf(_SC_NPROCESSORS_ONLN) /2;
357#endif
358
359#ifdef _SC_PHYS_PAGES
360 long nrpages= sysconf(_SC_PHYS_PAGES);
361 long pagesize= sysconf(_SC_PAGESIZE);
362 long pages_per_job= (128*(1 << 20)) / pagesize;
363 nrpages= nrpages/2;
364 if ((pages_per_job * njobs) > nrpages)
365 njobs= nrpages / pages_per_job;
366#endif
367
368 if (njobs == 0)
369 njobs= 1;
370
371 while ((opt = getopt(argc, argv, "j:s:t:c:")) != -1)
372 {
373 switch (opt) {
374 case 'c':
375 xbtarget= optarg;
376 break;
377 case 's':
378 suitedir= optarg;
379 break;
380 case 'j':
381 njobs= atoi(optarg);
382 break;
383 case 't':
384 timeout= atoi(optarg);
385 break;
386 default:
387 fprintf(stderr, "Usage: %s [-s suite] [-j parallel] [-t timeout]\n",
388 argv[0]);
389 exit(EXIT_FAILURE);
390 }
391 }
392
393 printf("%s running with: -s %s -j %d -t %d\n\n",
394 argv[0], suitedir,njobs, timeout);
395
396 nrcases= collect_testcases(suitedir, &testcases);
397
398 printf("Found %d testcases\n", nrcases);
399
400 run_testcases(testcases, nrcases, njobs, timeout, xbtarget);
401
402 free_testcases(testcases, nrcases);
403
404 return 0;
405}

Subscribers

People subscribed via source and target branches