2 # This script is uses ShUnit to test packaging/common/*. Currently
3 # it only tests the functions as they perform for rpm and deb building.
4 # As support is added for other styles of package, these tests should be
7 #######################
8 # If EXECUTING WITH ROOT ACCESS SCRIPT DELETES AND CREATES USERS.
9 # EXECUTE WITH CAUTION.
10 #######################
14 # Note on conflicting variable names:
15 # SHUNIT_* and SHU_* are shunit2 variables
16 # test_* should only be used by test functions.
17 # All other variables will probably be used by pre/post/common functions.
19 # shunit2 assumes _inc is, but we might run from a separate builddir. So try to
20 # use srcdir, as defined by automake, or otherwise `pwd`.
21 SHUNIT_INC="${srcdir=`pwd`}/packaging/common"; export SHUNIT_INC
23 TMPDIR=`pwd`/shunit-test; export TMPDIR
24 amanda_user=test_amandabackup; export amanda_user
25 amanda_group=test_disk; export amanda_group
26 AMANDAHOMEDIR=$TMPDIR/amanda; export AMANDAHOMEDIR
27 AMANDATES=$AMANDAHOMEDIR/amandates; export AMANDATES
29 dist=Fedora; export dist
30 SYSCONFDIR=$TMPDIR/etc; export SYSCONFDIR
31 SBINDIR=$TMPDIR/sbin; export SBINDIR
32 # Don't potentially conflict with a real value...
33 deb_uid=63000; export deb_uid
36 # Append stuff to this when you make temp files if they are outside TMPDIR
37 test_cleanup_files="$TMPDIR"; export sh_cleanup_files
39 # This can't be part of one-time setup, because TMPDIR must exist before
41 mkdir -p ${TMPDIR} || exit 1
44 (umask 077 && mktemp "$TMPDIR/test-log.XXXX") 2> /dev/null
48 LOGFILE=$TMPDIR/test-log.$$.$RANDOM
49 (umask 077 && touch "$LOGFILE")
51 echo "Unable to create log file!"
57 msg_prefix="oneTimeSetUp: "
58 if [ "$IAmRoot" ]; then
59 # Delete an existing user.
60 echo "$msg_prefix attempting to delete an existing user."
61 userdel -f -r ${amanda_user}
62 # If the user exists, our tests will act wrong, so exit
63 grep "${amanda_user}" ${SYSCONFDIR}/passwd &> /dev/null || { \
64 echo "$msg_prefix ${amanda_user} still exists, or no ${SYSCONFDIR}/passwd.";
67 echo "Not root, cleanup skipped"
69 # Make all directories which might be needed.
70 mkdir -p ${AMANDAHOMEDIR}/example
71 if [ ! "$IAmRoot" ]; then
72 mkdir -p ${SYSCONFDIR}/xinetd.d
73 mkdir -p ${SYSCONFDIR}/init.d
78 if [ ${__shunit_assertsFailed} -eq 0 ]; then
79 rm -rf $test_cleanup_files
81 echo "Check ${test_cleanup_files} for logs and error info."
85 test_cleanup_files="$LOGFILE ${test_cleanup_files}"
87 # errors before the tests are run.
88 . ${SHUNIT_INC}/common_functions.sh
89 . ${SHUNIT_INC}/pre_inst_functions.sh
90 . ${SHUNIT_INC}/post_inst_functions.sh
91 . ${SHUNIT_INC}/post_rm_functions.sh
93 # Use this to skip root requiring tests.
94 # id -u is not portable to solaris.
95 tester_id=`id | sed 's/gid=\([0-9]*\).*/\1/'`
96 if [ "$tester_id" = "0" ]; then
97 # Same as SHUNIT_TRUE, but we can't use that yet...
102 # A list of flag files that must be present to avoid spurious output.
103 # Each mock util gets one whether it is used or not.
105 # CAUTION: using real values if we are root.
106 if [ "$IAmRoot" ]; then
107 amanda_group=disk; export amanda_group
108 SYSCONFDIR=/etc; export SYSCONFDIR
109 SBINDDIR=/sbin; export SBINDDIR
112 # Source our mock utils.
113 . ${SHUNIT_INC}/mock_utils.sh
114 ######################################
117 # shUnit reorders tests alphabetically. We need the logger and cleanup tests
120 # Write a line to the log, test that it got there.
121 TEST_MSG="Test01_logger message"
122 LOG_LINE="`date +'%b %e %Y %T'`: ${TEST_MSG}"
123 # It's important for the log messages to be quoted, or funny stuff happens.
125 assertEquals "logger() return code" 0 $?
126 LOG_TAIL=`tail -1 ${LOGFILE}`
127 assertEquals "logger() did not write <${LOG_LINE}> " \
128 "${LOG_LINE}" "${LOG_TAIL}"
129 # Leave this outside the unit test framework. if the logger is
130 # broken we must exit.
131 if [ ! `grep -c "${LOG_LINE}" ${LOGFILE}` = "1" ]; then
132 echo "error: logger(): Incorrect content in ${LOGFILE}: " `cat ${LOGFILE}`
137 test__log_output_of() {
138 # Use log_output_of to append to the log
139 TEST_MSG="Test02_log_output_of message"
140 log_output_of echo "${TEST_MSG}"
141 assertEquals "log_output_of()" 0 $?
142 COUNT=`grep -c "${TEST_MSG}" ${LOGFILE}`
143 assertEquals "log_output_of(): incorrect content in log" \
145 # Leave this outside the unit test framework. if the logger is
146 # broken we must exit.
147 if [ ! ${COUNT} = '1' ]; then
148 echo "error: log_output_of(): Incorrect content in ${LOGFILE}: " `cat ${LOGFILE}`
154 # NOTE: check_xinetd and check_inetd tests end up simply duplicating the
155 # code of the function itself
158 logger "test_check_smf"
159 [ "$os" = "SunOS" ] || { startSkipping; echo "test_check_smf: skipped"; }
160 # Test existing service
161 touch ${MOCKDIR}/prexisting_service
163 assertEquals "check_smf preexisting services" 0 $?
164 rm ${MOCKDIR}/prexisting_service
166 assertEquals "check_smf no amanda service" 1 $?
169 test_check_superserver_running() {
170 logger "test_check_superserver_running"
171 [ "$IAmRoot" ] && { startSkipping; echo "test_check_superserver_running: skipped"; }
172 # Test the positive cases
173 # running changes the output of mocked ps
174 touch ${MOCKDIR}/running
175 check_superserver_running inetd
176 assertEquals "check_superserver_running inetd" 0 $?
177 assertSame "ps args: -e" "`cat $mock_ps_flags`"
178 if [ `uname` = 'Darwin' ]; then
179 [ "$IAmRoot" ] && startSkipping
180 check_superserver_running launchd
181 assertEquals "check_superserver_running launchd" 0 $?
182 assertSame "ps args: aux" "`cat $mock_ps_flags`"
186 check_superserver_running launchd
189 # Test the negative case, skip if root
190 [ "$IAmRoot" ] && startSkipping
191 rm ${MOCKDIR}/running
192 check_superserver_running inetd
193 assertEquals "check_superserver_running inetd returned 0 when inetd was not running" 1 $?
194 assertSame "ps args: -e" "`cat $mock_ps_flags`"
195 check_superserver_running xinetd
196 assertNotEquals "check_superserver_running xinetd incorrectly returned 0" \
198 assertSame "ps args: -e" "`cat $mock_ps_flags`"
201 test_backup_xinetd() {
202 logger "test_backup_xinetd"
203 touch ${SYSCONFDIR}/xinetd.d/amandaserver
204 backup_xinetd "amandaserver"
205 assertEquals "backup_xinetd returns 0" 0 $?
206 assertTrue "[ -f ${AMANDAHOMEDIR}/example/*.amandaserver.orig ]"
209 test_backup_inetd() {
210 logger "test_backup_inetd"
212 SunOS) inetd_dir=${SYSCONFDIR}/inet ;;
213 *) inetd_dir=${SYSCONFDIR} ;;
215 [ -d "${inetd_dir}" ] || mkdir -p ${inetd_dir}
216 touch ${inetd_dir}/inetd.conf
217 echo "amanda foo/bar/baz amandad" >> ${inetd_dir}/inetd.conf
219 assertEquals "backup_inetd returns 0" 0 $?
220 assertTrue "[ -f ${AMANDAHOMEDIR}/example/inetd.orig ]"
224 logger "test_backup_smf"
226 # TODO: how to mock this?
229 test_install_xinetd() {
230 logger "test_install_xinetd"
231 if [ "$os" = "SunOS" ] ; then
232 # Solaris has install_xinetd_sol
234 echo "test_install_xinetd: skipped"
238 touch ${MOCKDIR}/success
239 touch ${AMANDAHOMEDIR}/example/xinetd.amandaserver
240 install_xinetd "amandaserver"
241 assertEquals "install_xinetd returns 0" 0 $?
242 # Test "install" failure
243 rm ${MOCKDIR}/success
244 install_xinetd "amandaserver"
245 assertEquals "install_xinetd returns 1" 1 $?
248 test_install_inetd() {
249 logger "test_install_inetd"
251 SunOS) inetd_dir=${BASEDIR}/${SYSCONFDIR}/inet ;;
252 *) inetd_dir=${SYSCONFDIR} ;;
254 [ -f ${inetd_dir}/inetd.conf ] || touch ${inetd_dir}/inetd.conf
255 test_inetd_entry='amanda foo/bar/baz amandad'
256 if [ ! -f ${AMANDAHOMEDIR}/example/inetd.conf ]; then
257 echo "${test_inetd_entry}" > ${AMANDAHOMEDIR}/example/inetd.conf.amandaserver
259 install_inetd amandaserver
260 assertEquals "install_inetd returns 0" 0 $?
261 assertSame "${test_inetd_entry}" "`tail -1 ${inetd_dir}/inetd.conf`"
264 # TODO: test_install_smf() {
265 # Needs mocks for: inetconv, inetadm, svcadm.
267 test_reload_xinetd() {
268 logger "test_reload_xinetd"
269 # Might need init script.
270 if [ "$IAmRoot" ]; then
272 echo "test_install_smf: skipped"
274 elif [ ! -f "${SYSCONFDIR}/init.d/xinetd" ]; then
275 mv ${MOCKDIR}/xinetd ${SYSCONFDIR}/init.d
279 assertEquals "reload_xinetd should reject argument 'foo'" 1 $?
281 touch ${MOCKDIR}/success
282 reload_xinetd "reload"
283 assertEquals "reload_xinetd" 0 $?
285 rm ${MOCKDIR}/success
286 reload_xinetd "reload"
287 assertEquals "reload_xinetd" 1 $?
288 tail -4 ${LOGFILE}|grep "\<xinetd.*Attempting restart"
289 assertEquals "reload_xinetd should try to restart." 0 $?
290 reload_xinetd "restart"
291 assertEquals "restart should fail." 1 $?
292 tail -3 ${LOGFILE}|grep "Restarting xinetd"
293 assertEquals "Should log attempt to restart" 0 $?
296 test_reload_inetd() {
297 logger "test_reload_inetd"
299 # Might need init script.
300 if [ ! "$IAmRoot" ]; then
301 if [ ! -f "${SYSCONFDIR}/init.d/inetd" ]; then
302 mv ${MOCKDIR}/inetd ${SYSCONFDIR}/init.d
307 assertEquals "reload_inetd should reject argument 'foo' (return 1):" 1 $?
309 touch ${MOCKDIR}/success
311 assertEquals "reload_inetd" 0 $?
313 rm ${MOCKDIR}/success
314 reload_inetd "reload"
315 assertEquals "reload_inetd" 1 $?
316 tail -4 ${LOGFILE}|grep "\<inetd.*Attempting restart"
317 assertEquals "reload_inetd should try to restart." 0 $?
318 reload_inetd "restart"
319 assertEquals "restart should fail." 1 $?
320 tail -3 ${LOGFILE}|grep "Restarting inetd"
321 assertEquals "Should log attempt to restart" 0 $?
325 ######################################
326 # pre_install_functions
328 test_check_user_crazy_input() {
329 logger "test_check_user_crazy_input"
330 # Case 1: not enough params.
332 assertEquals "'check_user bar'" 2 $?
334 # Case 2: bad first param.
335 check_user "bar" "bell"
336 assertEquals "'check_user bar bell'" 2 $?
339 test_check_user_group_missing() {
340 logger "test_check_user_group_missing"
341 touch ${SYSCONFDIR}/group
342 check_user "group" "abracadabra"
343 assertNotEquals "'check_user group abracadabra' should not be found:" 0 $?
346 # passwd file entry for Linux systems, maybe others. UID is correct
347 # for Debian as well.
348 good_passwd_entry="${amanda_user}:x:${mock_deb_uid}:6::${AMANDAHOMEDIR}:/bin/bash"
349 export good_passwd_entry
351 logger "test_create_user"
352 if [ ! "$IAmRoot" ]; then
354 echo "test_create_user: Creating mock passwd file."
355 echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
356 echo "test_create_user: tests skipped."
360 # Case 1: create_user should succeed.
362 assertEquals "create_user()" 0 $?
365 good_group_entry="${amanda_group}:x:100:${amanda_user}"
366 export good_group_entry
367 test_check_user_group() {
368 logger "test_check_user_group"
369 touch ${SYSCONFDIR}/group
370 # Non-root adds and entry to the mock group file
371 [ ! "$IAmRoot" ] && echo $good_group_entry > ${SYSCONFDIR}/group
373 # Case 1: Amanda_user is correct.
374 touch ${MOCKDIR}/is_member
375 check_user "group" "${amanda_group}"
376 assertEquals "'check_user group ${amanda_group}': id returns member" \
379 # Case 2: Amanda_user is not a member of the the correct group.
380 rm ${MOCKDIR}/is_member
381 check_user "group" "${amanda_group}"
382 assertEquals "'check_user group ${amanda_group}' when not a member" 1 $?
385 test_check_user_shell() {
386 logger "test_check_user_shell"
387 if [ ! "$IAmRoot" ]; then
388 echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
390 # Case 1: Provide a matching shell
391 check_user "shell" "/bin/bash"
392 assertEquals "check_user shell /bin/bash (matching)" 0 $?
393 # Case 2: Provid a non-matching shell.
394 check_user "shell" "/bin/sh"
395 assertEquals "check_user shell /bin/ksh (not matching)" 1 $?
398 test_check_user_homedir() {
399 logger 'test_check_user_homedir'
400 if [ ! "$IAmRoot" ]; then
401 echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
403 # Case 1: Assume amanda_user is correct.
404 check_user "homedir" "${AMANDAHOMEDIR}"
405 assertEquals "check_user homedir ${AMANDAHOMEDIR}" 0 $?
406 # Case 2: Provide an incorrect homedir
407 check_user "homedir" "/tmp"
408 assertEquals "check_user homedir /tmp" 1 $?
411 test_check_homedir_dir_missing() {
412 logger "test_check_homedir_dir_missing"
413 # First make sure the dir is missing
414 rm -rf ${AMANDAHOMEDIR}
416 assertNotEquals "check_homedir returned 0, but homedir did not exist" 0 $?
419 test_create_homedir() {
420 logger "test_create_homedir"
421 rm -rf ${AMANDAHOMEDIR}
423 assertEquals "create_homedir returns 0" 0 $?
424 assertTrue "${AMANDAHOMEDIR} did not get created" "[ -d ${AMANDAHOMEDIR} ]"
425 if [ "$IAmRoot" ]; then
427 real_owner=`ls -ld $AMANDAHOMEDIR | awk '{ print $3":"$4; }'`
428 assertSame "${amanda_user}:${amanda_group}" "$real_owner"
431 "chown args: -R ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}" \
432 "`cat $mock_chown_flags`"
434 # A second run should succeed too.
436 assertEquals "When homedir exists, create_homedir returns 0:" 0 $?
437 # Later tests use ${AMANDAHOMEDIR}, so leave the dir there.
440 test_check_homedir_dir_existing() {
441 logger "test_check_homedir_dir_existing"
442 # Create the dir (example needed for other tests), then check again.
443 mkdir -p ${AMANDAHOMEDIR}/example
445 assertEquals "Homedir exists; check_homedir" 0 $?
448 test_create_logdir() {
449 logger "test_create_logdir"
450 # The logdir variable for the shell libs, not shunit2.
451 LOGDIR=$TMPDIR/amanda_log; export LOGDIR
453 rm -rf ${LOGDIR}.save
455 assertEquals "create_logdir clean system" 0 $?
456 if [ -n "$IAmRoot" ]; then
457 real_owner=`ls -ld $LOGDIR | awk '{ print $3":"$4; }'`
458 assertSame "${amanda_user}:${amanda_group}" "$real_owner"
461 "chown args: -R ${amanda_user}:${amanda_group} ${LOGDIR}"\
462 "`cat $mock_chown_flags`"
464 assertTrue "${LOGDIR} exists" "[ -d ${LOGDIR} ]"
465 # What happens if logdir is a file?
469 assertEquals "create_logdir" 0 $?
470 assertTrue "${LOGDIR} exists" "[ -d ${LOGDIR} ]"
471 assertTrue "${LOGDIR}/amanda_log.save backup exists" \
472 "[ -f ${LOGDIR}/amanda_log.save ]"
475 test_create_amandates() {
476 logger "test_create_amandates"
479 assertEquals "create_amandates" 0 $?
480 assertTrue "[ -f ${AMANDATES} ]"
483 test_check_amandates() {
484 logger "test_check_amandates"
485 touch $mock_chown_flags
486 touch $mock_chmod_flags
488 assertEquals "check_amandates" 0 $?
489 [ "$IAmRoot" ] && { startSkipping; echo "test_check_amandates: skipped"; }
491 "chown args: ${amanda_user}:${amanda_group} ${AMANDATES}" \
492 "`cat $mock_chown_flags`"
494 "chmod args: 0640 ${AMANDATES}" \
495 "`cat $mock_chmod_flags`"
498 test_create_gnupg() {
499 logger "test_create_gnupg"
501 assertEquals "create_gnupg" 0 $?
502 assertTrue "[ -d ${AMANDAHOMEDIR}/.gnupg ]"
506 logger "test_check_gnupg"
508 assertEquals "check_gnupg" 0 $?
509 [ "$IAmRoot" ] && { startSkipping; echo "test_check_gnupg: skipped"; }
511 "chown args: ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.gnupg" \
512 "`cat $mock_chown_flags`"
514 "chmod args: 700 ${AMANDAHOMEDIR}/.gnupg" \
515 "`cat $mock_chmod_flags`"
518 test_create_amandahosts() {
519 logger "test_create_amandahosts"
521 assertEquals "create_amandahosts:" 0 $?
522 assertEquals "${AMANDAHOMEDIR}/.amandahosts exists:" 0 $?
523 assertEquals "create_amandahosts" 0 $?
524 assertTrue "[ -f ${AMANDAHOMEDIR}/.amandahosts ]"
527 test_check_amandahosts_entry() {
528 logger "test_check_amandahosts_entry"
529 if [ -f ${AMANDAHOMEDIR}/.amandahosts ]; then
530 check_amandahosts_entry root amindexd amidxtaped
531 assertEquals "check_amandahosts_entry root amindexd amidxtaped" \
534 echo "test_check_amandahosts_entry: ${AMANDAHOMEDIR}/.amandahosts missing. test skipped"
539 test_check_amandahosts_perm() {
540 logger "test_check_amandahosts_perm"
541 check_amandahosts_perms
542 assertEquals "check_amandahosts_perms" 0 $?
543 [ "$IAmRoot" ] && { startSkipping; echo "test_check_amandahosts_perm: skipped"; }
545 "chown args: ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.amandahosts" \
546 "`cat $mock_chown_flags`"
548 "chmod args: 0600 ${AMANDAHOMEDIR}/.amandahosts" \
549 "`cat $mock_chmod_flags`"
552 test_create_ssh_key() {
553 logger "test_create_ssh_key"
554 keydir=${AMANDAHOMEDIR}/.ssh
556 create_ssh_key server
557 assertEquals "create_ssh_key" 0 $?
558 assertTrue "[ -f ${keydir}/id_rsa_amdump ]"
559 [ "$IAmRoot" ] && { startSkipping; echo "test_create_ssh_key: skipped"; }
561 "chown args: ${amanda_user}:${amanda_group} ${keydir} ${keydir}/id_rsa_amdump ${keydir}/id_rsa_amdump.pub" \
562 "`cat $mock_chown_flags`"
563 # Chmod is called twice, but we only get the 2nd invocation.
565 "chmod args: 0600 ${keydir}/id_rsa_amdump ${keydir}/id_rsa_amdump.pub" \
566 "`cat $mock_chmod_flags`"
570 # What happens if .ssh is a file?
571 touch ${AMANDAHOMEDIR}/.ssh
572 create_ssh_key client
573 assertEquals "create_ssh_key" 0 $?
574 assertTrue "[ -f ${keydir}.save ]"
575 assertTrue "[ -f ${keydir}/id_rsa_amrecover ]"
578 test_create_profile() {
579 logger "test_create_profile"
580 rm -f ${AMANDAHOMEDIR}/.profile
582 assertEquals "create_profile" 0 $?
583 assertTrue "[ -f ${AMANDAHOMEDIR}/.profile ]"
586 test_check_profile() {
587 logger "test_check_profile"
588 [ -f "${AMANDAHOMEDIR}/.profile" ] || touch ${AMANDAHOMEDIR}/.profile
590 assertEquals "check_profile" 0 $?
591 assertTrue "[ -s ${AMANDAHOMEDIR}/.profile ]"
592 [ "$IAmRoot" ] && { startSkipping; echo "test_check_profile: skipped"; }
594 "chown args: ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.profile" \
595 "`cat $mock_chown_flags`"
597 "chmod args: 0640 ${AMANDAHOMEDIR}/.profile" \
598 "`cat $mock_chmod_flags`"
601 test_install_client_conf() {
602 logger "test_install_client_conf"
604 touch ${MOCKDIR}/success
606 assertEquals "install_client_conf" 0 $?
607 prefix="install args:"
608 inst_files="${AMANDAHOMEDIR}/example/amanda-client.conf ${SYSCONFDIR}/amanda/"
611 "`cat $mock_install_flags`" \
612 "${prefix} -m 0600 -u ${amanda_user} -g ${amanda_group} ${inst_files}"
615 "`cat $mock_install_flags`" \
616 "${prefix} -m 0600 -o ${amanda_user} -g ${amanda_group} ${inst_files}"
620 #TODO: create_ampassphrase, create_amtmp
622 ######################################
623 #TODO: post_rm_functions
625 # Run a single test, or let shunit run all tests
626 if [ $# -gt 0 ]; then
630 __shunit_suite="test___logger"
631 __shunit_suite="$__shunit_suite test__log_output_of"
632 __shunit_suite="$__shunit_suite $SPECIFIC_TESTS"
633 # Set the test total including the 3 base tests.
634 __shunit_testsTotal=`expr 2 + $#`
635 suite_addTest test___logger
639 # Importing shunit2 triggers test enumeration, so must happen after
640 # all tests are defined.
641 . ${SHUNIT_INC}/shunit2
643 echo "shunit2 log is: ${LOGFILE}"
644 echo "mockdir is: ${MOCKDIR}"