Monikop cleaned up.
[monikop.git] / test / test.sh
blobb97d9c8d663eebe31c480bd152e0c4feca97dbef
1 #! /bin/bash
3 # Caveats: - kills all killable rsyncs
4 # - don't disturb test timing by putting too much (extra) load
5 # on the machine
7 killall --quiet rsync
9 TESTDIR=/tmp/monikop-test
10 DEV=$TESTDIR/dev
11 MNT=$TESTDIR/mnt
12 LOG=$TESTDIR/log
13 RSYNC=$TESTDIR/rsync
14 MONIKOP_1="../monikop ../test/monikop.config.test.1"
15 MONIKOP_2="../monikop ../test/monikop.config.test.2"
16 MONIKOP_3="../monikop ../test/monikop.config.test.3"
17 POKINOM="../pokinom ../test/pokinom.config.test"
18 TEST_COUNT=0
19 FAIL_COUNT=0
20 FAILED_TESTS=""
22 function kill_rsyncd {
23 kill `cat $TESTDIR/rsync/rsyncd.pid`
26 function start_rsyncd {
27 kill_rsyncd 2> /dev/null
28 rm -f $RSYNC/rsyncd.pid 2> /dev/null
29 chmod o-rwx ../test/rsyncd.secrets.test
30 rsync --daemon --config=../test/rsyncd.conf.test
33 # make_test_drive <name> <size>
34 function make_test_drive {
35 mkdir -p $MNT/$1
36 dd if=/dev/zero of=$DEV/$1 bs=1024 count=$2 2> /dev/null
37 /sbin/mkfs.ext3 -m 0 -Fq $DEV/$1
38 if ! mount $MNT/$1 2> /dev/null; then
39 echo "# Can't mount $DEV/$1 to $MNT/$1."
40 echo "# Redo from start after adding the following line to your /etc/fstab:"
41 echo
42 echo " $DEV/$1 $MNT/$1 ext3 loop,user,noauto 0 0"
43 echo
44 return 1
48 # make_test_file <name> <size> <date>
49 function make_test_file {
50 mkdir -p `dirname "$1"`
51 dd if=/dev/zero of="$1" bs=1024 count=$2 2> /dev/null
52 echo "++++++++++++++++++++++++++$RANDOM***$3---$1" >> "$1"
53 touch -t $3 $1
56 # find_and_compare <origin_dir> <origin_dir> ... :: <copy_dir> <copy_dir> ...
57 function find_and_compare {
58 ORIGIN_DIRS=$1; shift;
59 until [[ $1 == "::" ]]; do
60 ORIGIN_DIRS="$ORIGIN_DIRS $1"; shift;
61 done
62 shift
63 COPY_DIRS=$@
64 MISSING=""
65 DIVERGING=""
66 DIVERGING_MTIME=""
67 RETURN_VALUE=0
68 for ORIGIN_DIR in $ORIGIN_DIRS; do
69 while read -r -d $'\0' ORIGIN_FILE; do
70 ORIGIN_FILE_ESCAPED=${ORIGIN_FILE//\\/\\\\}
71 ORIGIN_FILE_ESCAPED=${ORIGIN_FILE_ESCAPED//\[/\\[}
72 for COPY_DIR in $COPY_DIRS; do
73 FOUND=`find $COPY_DIR -path "$COPY_DIR/${ORIGIN_FILE_ESCAPED#$ORIGIN_DIR/}" -print0 2> /dev/null`
74 if [[ -n "$FOUND" ]] ; then
75 break
77 done
78 if [[ -z "$FOUND" ]] ; then
79 MISSING="$MISSING $ORIGIN_FILE";
80 elif ! cmp --quiet "$ORIGIN_FILE" "$FOUND"; then
81 DIVERGING="$DIVERGING $ORIGIN_FILE"
82 elif [[ `stat --printf="%Y" "$ORIGIN_FILE"` != `stat --printf="%Y" "$FOUND"` ]]; then
83 DIVERGING_MTIME="$DIVERGING_MTIME $ORIGIN_FILE"
85 done < <(find $ORIGIN_DIR -type f -print0 2> /dev/null)
86 done
87 if [[ -n $MISSING ]]; then
88 RETURN_VALUE=1
89 echo "MISSING: $MISSING"
91 if [[ -n $DIVERGING ]]; then
92 RETURN_VALUE=$((return_value + 2))
93 echo "DIVERGING: $DIVERGING"
95 if [[ -n $DIVERGING_MTIME ]]; then
96 RETURN_VALUE=$((return_value + 4))
97 echo "DIVERGING MTIME: $DIVERGING_MTIME"
99 return $RETURN_VALUE
102 # run_test <return_value> <test> <documentation>
103 function run_test {
104 sleep 4
105 killall monikop pokinom 2> /dev/null
106 sleep 2
107 killall -KILL monikop pokinom 2> /dev/null
108 sleep 2
109 echo "RUNNING $2 [$3]"
110 TEST_COUNT=$(( TEST_COUNT + 1 ))
112 RETURN_VALUE=$?
113 if [[ $RETURN_VALUE -ne $1 ]]; then
114 FAIL_COUNT=$(( FAIL_COUNT + 1 ))
115 FAILED_TESTS="$FAILED_TESTS$2($1? $RETURN_VALUE!) [$3]\n"
116 echo "$2 should have returned $1 but returned $RETURN_VALUE instead."
118 sleep 2
121 # Create and mount test drives:
122 umount $MNT/* #2> /dev/null
123 rm -rf $DEV $MNT $LOG
124 mkdir -p $DEV $MNT $RSYNC
126 for i in 01 02 03 04; do
127 make_test_drive $i 102400
128 if [[ $? == 1 ]]; then
129 MOUNTING_PROBLEM=1
131 done
132 make_test_drive 05 307200
133 if [[ $? == 1 ]]; then
134 MOUNTING_PROBLEM=1
136 if [[ $MOUNTING_PROBLEM == 1 ]]; then exit; fi
138 function fill_sources_with_big_files {
139 for i in f1 f2 f3; do
140 make_test_file $MNT/01/data/$i 25000 200703250845.33
141 done
142 for i in f10 f11 f12; do
143 make_test_file $MNT/02/data/$i 25000 200703250845.33
144 done
145 for i in f4 f5 f6; do
146 make_test_file $MNT/01/data/d1/$i 2000 200703250845.33
147 make_test_file $MNT/01/data/d1/d2/$i 2000 200703250845.33
148 done
149 for i in f7 f8 f9; do
150 make_test_file $MNT/02/data/d1/$i 2000 200703250845.33
151 make_test_file $MNT/02/data/d1/d2/$i 2000 200703250845.33
152 done
155 function fill_sources_with_hidden_files {
156 for i in 01 02; do
157 make_test_file $MNT/$i/data/.hidden_dir_$i/.hidden_file 20 200804250955.10
158 done
161 function fill_destinations_with_few_small_files {
162 for i in 03 04; do
163 for j in file_one file_two file_three; do
164 make_test_file $MNT/$i/measuring_data/$i/$j 20 200004250955.10
165 done
166 done
169 # Check how fast we are:
170 fill_sources_with_big_files
171 T1=`/usr/bin/time --format="%e" rsync --recursive --times $MNT/01/data/ $MNT/03/ 2>&1 &`
172 T2=`/usr/bin/time --format="%e" rsync --recursive --times $MNT/02/data/ $MNT/04/ 2>&1 &`
173 INTERRUPTION_TIME_0=`echo "($T1 + $T2) * 3" | bc`
174 INTERRUPTION_TIME_1=`echo "($T1 + $T2) * .08" | bc`
175 INTERRUPTION_TIME_2=`echo "($T1 + $T2) * .82" | bc`
176 echo "One run of a testee takes about $INTERRUPTION_TIME_0 seconds."
177 rm -rf $MNT/0{1,2,3,4}/*
179 ######################################################################
180 # Define tests:
181 ######################################################################
183 function test_monikop_simple {
184 sleep 4
185 $MONIKOP_1 & sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
186 sleep 2
187 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4}/measuring_data
190 function test_monikop_simple_late_sources {
191 kill_rsyncd
192 $MONIKOP_1 & sleep $INTERRUPTION_TIME_2; start_rsyncd; sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
193 sleep 2
194 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4}/measuring_data
197 function test_monikop_short {
198 $MONIKOP_1 & sleep $INTERRUPTION_TIME_1; /bin/kill -TERM $!
199 sleep 2
200 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4}/measuring_data
203 function test_monikop_short_2 {
204 $MONIKOP_2 & sleep $INTERRUPTION_TIME_1; /bin/kill -TERM $!
205 sleep 2
206 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4,5}/measuring_data
209 function test_monikop_short_kill_rsync_first {
210 $MONIKOP_2 & sleep $INTERRUPTION_TIME_1; /usr/bin/killall -KILL rsync; sleep 1; /bin/kill -TERM $!
211 sleep 2
212 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4,5}/measuring_data
213 RETURN=$?
214 start_rsyncd
215 sleep 2
216 return $RETURN
219 function test_monikop_short_cut_sources {
220 $MONIKOP_2 & sleep $INTERRUPTION_TIME_1; kill_rsyncd; sleep 1; /bin/kill -TERM $!
221 sleep 2
222 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4,5}/measuring_data
223 RETURN=$?
224 start_rsyncd
225 sleep 2
226 return $RETURN
229 function test_monikop_simple_2 {
230 $MONIKOP_2 & sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
231 sleep 2
232 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4,5}/measuring_data
235 function test_monikop_simple_3 {
236 $MONIKOP_3 & sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
237 sleep 2
238 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4}/measuring_data/dir_0{1,2}
241 function test_monikop_overflow {
242 # Stuff one of the destinations a bit:
243 make_test_file $MNT/03/stuffing 25000 199903250845
244 $MONIKOP_1 & sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
245 sleep 2
246 find_and_compare $MNT/0{1,2}/data :: $MNT/0{3,4}/measuring_data
249 function test_monikop_no_destination {
250 # We test basically if there is something to kill.
251 umount $MNT/{03,04}
252 $MONIKOP_1 & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
253 RETURN=$?
254 mount $MNT/03
255 mount $MNT/04
256 return $RETURN
259 function test_monikop_no_source {
260 # We test basically if there is something to kill.
261 kill_rsyncd
262 $MONIKOP_1 & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
263 RETURN=$?
264 start_rsyncd
265 return $RETURN
268 function test_pokinom_clean_finish {
269 $POKINOM & sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
270 sleep 2
271 find_and_compare $MNT/0{1,2}/data :: $MNT/05/NEW_DATA
274 function test_pokinom_short {
275 $POKINOM & sleep $INTERRUPTION_TIME_1; /bin/kill -TERM $!
276 sleep 2
277 find_and_compare $MNT/0{1,2}/data :: $MNT/05/NEW_DATA
280 function test_pokinom_late_destination {
281 kill_rsyncd
282 $POKINOM & sleep $INTERRUPTION_TIME_2; start_rsyncd; sleep $INTERRUPTION_TIME_0; /bin/kill -TERM $!
283 sleep 2
284 find_and_compare $MNT/0{1,2}/data :: $MNT/05/NEW_DATA
287 function test_dirs_backed_up {
288 test -d $MNT/03/backed_up && test -d $MNT/04/backed_up
291 function test_monikop_deletes_being_deleted_dir {
292 mkdir -p $MNT/0{3,4}/{being_deleted,backed_up}
293 touch $MNT/0{3,4}/{being_deleted,backed_up}/some_file
294 touch $MNT/0{3,4}/{being_deleted,backed_up}/.some_hidden_file
295 $MONIKOP_1 & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
296 test -d $MNT/03/being_deleted || test -d $MNT/04/being_deleted
299 function test_pokinom_deletes_being_deleted_dir {
300 mkdir -p $MNT/0{3,4}/being_deleted
301 touch $MNT/0{3,4}/being_deleted/some_file
302 touch $MNT/0{3,4}/being_deleted/.some_hidden_file
303 $POKINOM & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
304 test -d $MNT/03/being_deleted || test -d $MNT/04/being_deleted
307 function test_pokinom_newer_files_win {
308 fill_destinations_with_few_small_files
309 $POKINOM & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
310 for i in 03 04; do
311 mv $MNT/$i/backed_up $MNT/$i/measuring_data
312 touch $MNT/$i/measuring_data/$i/*
313 done
314 $POKINOM & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
315 sleep 2
316 find_and_compare $MNT/0{3,4}/backed_up :: $MNT/05/NEW_DATA
319 function test_pokinom_older_files_lose {
320 fill_destinations_with_few_small_files
321 $POKINOM & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
322 for i in 03 04; do
323 mv $MNT/$i/backed_up $MNT/$i/measuring_data
324 done
325 touch -t 198001011200.00 $MNT/03/measuring_data/03/file_one
326 $POKINOM & sleep $INTERRUPTION_TIME_2; /bin/kill -TERM $!
327 sleep 2
328 find_and_compare $MNT/0{3,4}/backed_up :: $MNT/05/NEW_DATA
331 ######################################################################
332 # Run the tests:
333 ######################################################################
334 start_rsyncd
336 ##########################
337 ### Run tests: Monikop
338 ##########################
340 fill_sources_with_big_files
342 run_test 1 test_monikop_deletes_being_deleted_dir "Monikop deletes left-over directory named being_deleted."
344 rm -rf $MNT/0{3,4}/* $LOG
346 chmod a-w,a-x $MNT/0{3,4}
347 run_test 1 test_monikop_simple "Unwritable destination"
348 chmod a+w,a+x $MNT/0{3,4}
349 run_test 0 test_monikop_simple "Unwritable destination"
351 rm -rf $MNT/0{3,4}/* $LOG
353 run_test 0 test_monikop_simple_3 "Source-specific directories on disks"
355 rm -rf $MNT/0{3,4}/* $LOG
357 run_test 0 test_monikop_simple_late_sources "Simple run, sources coming up late."
359 mv $MNT/03/measuring_data $MNT/03/backed_up
360 mv $MNT/04/measuring_data $MNT/04/backed_up
361 rm -rf $LOG
363 run_test 0 test_monikop_simple "Simple run, deletion."
365 rm -rf $MNT/0{3,4}/* $LOG
367 run_test 1 test_monikop_short "Interruption, finished.* or finished.*.bak deleted."
368 rm -f $LOG/finished.rsync___localhost_2000_test_01_data $LOG/finished.rsync___localhost_2000_test_02_data.bak
369 run_test 0 test_monikop_simple "Recovery after interruption, finished.* or finished.*.bak deleted."
371 rm -rf $MNT/0{3,4}/* $LOG
373 run_test 1 test_monikop_short "Interruption, finished.* and/or log.* deleted."
374 rm -f $LOG/finished.rsync___localhost_2000_test_01_data $LOG/log.rsync___localhost_2000_test_01_data
375 rm -f $LOG/rm log.rsync___localhost_2000_test_02_data
376 run_test 0 test_monikop_simple "Recovery after interruption, finished.* and/or log.* deleted."
378 rm -rf $MNT/0{3,4}/* $LOG
380 run_test 1 test_monikop_short_2 "Repeated interruption."
381 run_test 1 test_monikop_short_2 "Repeated interruption (may pass unexpectedly due to test timing)."
382 run_test 0 test_monikop_simple_2 "Repeated interruption."
384 mv $MNT/03/measuring_data $MNT/03/backed_up
385 mv $MNT/04/measuring_data $MNT/04/backed_up
386 mv $MNT/05/measuring_data $MNT/05/backed_up
387 rm -rf $LOG
389 run_test 1 test_monikop_short_2 "Repeated interruption, deletion."
390 run_test 1 test_monikop_short_2 "Repeated interruption, deletion (may pass unexpectedly due to test timing)."
391 run_test 0 test_monikop_simple_2 "Repeated interruption, deletion."
393 rm -rf $MNT/0{3,4,5}/* $LOG
395 run_test 0 test_monikop_no_destination "No destination available."
396 run_test 0 test_monikop_no_source "No destination available."
398 rm -rf $MNT/0{3,4}/* $LOG
400 run_test 1 test_monikop_short_kill_rsync_first "Rsync killed."
401 ps aux | grep rsync
402 run_test 0 test_monikop_simple_2 "Rsync killed."
404 rm -rf $MNT/0{3,4,5}/* $LOG
406 run_test 1 test_monikop_short_cut_sources "Connection to source destroyed."
407 run_test 0 test_monikop_simple_2 "Connection to source destroyed."
409 rm -rf $MNT/0{3,4,5}/* $LOG
411 ##############################
412 # Run tests: Pokinom
413 ##############################
415 run_test 1 test_pokinom_deletes_being_deleted_dir "Pokinom deletes left-over directory named being_deleted."
417 rm -rf $MNT/0{3,4,5}/*
419 run_test 0 test_pokinom_newer_files_win "Pokinom overwrites older files in Destination."
421 run_test 4 test_pokinom_older_files_lose "Pokinom discards older files on removable disk."
423 ##################################################
424 # Run tests: Monikop and Pokinom together
425 ##################################################
427 rm -rf $MNT/0{1,2,3,4,5}/*
428 fill_sources_with_hidden_files
430 run_test 0 test_monikop_simple "Preparation for simple Pokinom test, hidden files."
431 run_test 0 test_pokinom_clean_finish "Simple Pokinom test, hidden files."
432 run_test 0 test_dirs_backed_up "Simple Pokinom test, hidden files."
433 run_test 1 test_monikop_short "After test with hidden files, this one should do nothing but delete backed_up."
434 run_test 1 test_dirs_backed_up "Deletion of backed_up with hidden files."
436 rm -rf $MNT/0{1,2,3,4,5}/*
437 fill_sources_with_big_files
439 run_test 0 test_monikop_simple "Simple run in preparation for simple Pokinom test."
440 run_test 0 test_pokinom_clean_finish "Simple Pokinom test."
441 run_test 0 test_dirs_backed_up "Simple Pokinom test: directories renamed?."
443 rm -rf $MNT/05/* $LOG
445 run_test 0 test_monikop_simple "Preparation for Pokinom's destination overfull."
446 # Stuff destination:
447 make_test_file $MNT/05/stuffing 200000 199903250845
448 run_test 1 test_pokinom_clean_finish "Pokinom's destination overfull."
449 rm $MNT/05/stuffing
450 run_test 0 test_pokinom_clean_finish "Pokinom's destination no longer overfull: recovering."
452 rm -rf $MNT/05/* $LOG
454 run_test 0 test_monikop_simple "Simple run in preparation for Pokinom, late destination."
455 run_test 0 test_pokinom_late_destination "Pokinom, late destination."
457 rm -rf $MNT/05/* $LOG
459 run_test 0 test_monikop_simple "Simple run in preparation for Pokinom stopped early."
460 run_test 1 test_pokinom_short "Pokinom stopped early."
461 run_test 0 test_monikop_simple "Simple run after Pokinom having been stopped early."
462 run_test 0 test_pokinom_clean_finish "Simple run after Pokinom having been stopped early."
464 rm -rf $MNT/05/* $LOG
466 run_test 0 test_monikop_simple "Simple run in preparation for \"file grown too large\""
467 rm $MNT/01/data/f3
468 cat $MNT/01/data/f1 >> $MNT/01/data/f2
469 run_test 2 test_monikop_simple "Repeated run, file grown too large."
470 run_test 2 test_pokinom_clean_finish "Repeated run, file grown too large."
471 run_test 1 test_monikop_simple "Repeated run, file grown too large."
472 run_test 0 test_pokinom_clean_finish "Repeated run, file grown too large."
474 rm -rf $MNT/05/* $LOG
476 run_test 1 test_monikop_overflow "Initially, too little room on disks."
477 run_test 1 test_pokinom_clean_finish "Initially, too little room on disks."
478 run_test 1 test_monikop_overflow "Previously, too little room on disks."
479 run_test 0 test_pokinom_clean_finish "Previously, too little room on disks."
481 rm -rf $MNT/0{3,4,5}/* $LOG
483 run_test 1 test_monikop_short "Unfinished by Monikop, then another full cycle."
484 run_test 1 test_pokinom_clean_finish "Unfinished by Monikop, then another full cycle (Outcome unpredictable)."
485 run_test 1 test_monikop_simple "Previously unfinished by Monikop, now another full cycle (Outcome unpredictable)."
486 run_test 0 test_pokinom_clean_finish "Previously unfinished by Monikop, now another full cycle."
488 rm -rf $MNT/0{1,2,3,4,5}/* $LOG
490 make_test_file $MNT/01/data/d1/f1 10 200703250845.33
491 make_test_file $MNT/01/data/d2/f3 10 200703250845.33
492 make_test_file $MNT/01/data/f4 10 200703250845.33
493 make_test_file $MNT/01/data/f5 10 200703250845.33
494 make_test_file $MNT/01/data/f6 10 200703250845.33
495 make_test_file $MNT/01/data/f7 10 200703250845.33
496 make_test_file $MNT/01/data/f8 10 200703250845.33
497 make_test_file $MNT/01/data/f9 10 200703250845.33
498 make_test_file $MNT/01/data/f10 10 200703250845.33
499 make_test_file $MNT/01/data/.f11 10 200703250845.33
500 make_test_file $MNT/01/data/d3/d4/f4 10 200703250845.33
501 mv $MNT/01/data/d1/f1 "$MNT/01/data/d1/Große Datei"
502 mv $MNT/01/data/d1 "$MNT/01/data/Schönes Verzeichnis"
503 mv $MNT/01/data/f4 "$MNT/01/data/[square brackets]"
504 mv $MNT/01/data/f5 "$MNT/01/data/\`backquotes\`"
505 mv $MNT/01/data/f6 "$MNT/01/data/'single quotes'"
506 mv $MNT/01/data/f7 "$MNT/01/data/\"double quotes\""
507 mv $MNT/01/data/f8 "$MNT/01/data/b\\a\\ckslashes"
508 mv $MNT/01/data/f9 "`echo -e "$MNT/01/data/newlines\nin\nname"`";
509 ## Won't work:
510 #mv $MNT/01/data/d2 $MNT/01/data/.rsync_partial
511 #mv $MNT/01/data/d3/d4 $MNT/01/data/d3/.rsync_partial
512 run_test 0 test_monikop_simple "Weird file names."
513 run_test 0 test_pokinom_clean_finish "Weird file names."
514 run_test 1 test_monikop_short "Weird file names, second run: nothing to do."
516 ########################################
517 # End of tests
518 ########################################
519 kill_rsyncd
521 echo "TOTAL NUMBER OF TESTS: $TEST_COUNT"
522 echo "NUMBER OF FAILED TESTS: $FAIL_COUNT"
523 echo "FAILED TESTS:"
524 echo -e "$FAILED_TESTS"
526 exit $FAIL_COUNT