diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /ctdb/tests/UNIT/eventscripts | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ctdb/tests/UNIT/eventscripts')
276 files changed, 8286 insertions, 0 deletions
diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.001.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.001.sh new file mode 100755 index 0000000..807f3ef --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool supports check" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="yes" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.002.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.002.sh new file mode 100755 index 0000000..7ff5385 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.002.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool does no support check" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="no" + +ok <<EOF +WARNING: The installed 'tdbtool' does not offer the 'check' subcommand. + Using 'tdbdump' for database checks. + Consider updating 'tdbtool' for better checks! +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.003.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.003.sh new file mode 100755 index 0000000..2d1fb0d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.003.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool supports check, good TDB" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="yes" + +touch "${CTDB_DBDIR}/foo.tdb.0" +FAKE_TDB_IS_OK="yes" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.004.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.004.sh new file mode 100755 index 0000000..196d7c2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.004.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool supports check, bad TDB" + +setup + +db="${CTDB_DBDIR}/foo.tdb.0" +touch "$db" +FAKE_TDB_IS_OK="no" + +ok <<EOF +WARNING: database ${db} is corrupted. + Moving to backup ${db}.DATE.TIME.corrupt for later analysis. +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.005.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.005.sh new file mode 100755 index 0000000..3f85de4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.005.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool does not support check, good TDB" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="no" + +touch "${CTDB_DBDIR}/foo.tdb.0" +FAKE_TDB_IS_OK="yes" + +ok <<EOF +WARNING: The installed 'tdbtool' does not offer the 'check' subcommand. + Using 'tdbdump' for database checks. + Consider updating 'tdbtool' for better checks! +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.006.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.006.sh new file mode 100755 index 0000000..29794d7 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.006.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool does not support check, bad TDB" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="no" + +db="${CTDB_DBDIR}/foo.tdb.0" +touch "$db" +FAKE_TDB_IS_OK="no" + +ok <<EOF +WARNING: The installed 'tdbtool' does not offer the 'check' subcommand. + Using 'tdbdump' for database checks. + Consider updating 'tdbtool' for better checks! +WARNING: database ${db} is corrupted. + Moving to backup ${db}.DATE.TIME.corrupt for later analysis. +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.007.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.007.sh new file mode 100755 index 0000000..5121513 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.007.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool supports check, good persistent TDB" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="yes" + +touch "${CTDB_DBDIR_PERSISTENT}/foo.tdb.0" +FAKE_TDB_IS_OK="yes" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.008.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.008.sh new file mode 100755 index 0000000..120aefc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.008.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, tdbtool supports check, bad persistent TDB" + +setup + +FAKE_TDBTOOL_SUPPORTS_CHECK="yes" + +db="${CTDB_DBDIR_PERSISTENT}/foo.tdb.0" +touch "$db" +FAKE_TDB_IS_OK="no" + +required_result 1 <<EOF +Persistent database ${db} is corrupted! CTDB will not start. +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/00.ctdb.init.009.sh b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.009.sh new file mode 100755 index 0000000..92a0e25 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/00.ctdb.init.009.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "TDB check, bad TDB multiple times" + +setup + +db="${CTDB_DBDIR}/foo.tdb.0" +FAKE_TDB_IS_OK="no" + +required_result_tdbcheck () +{ + ok <<EOF +WARNING: database ${db} is corrupted. + Moving to backup ${db}.DATE.TIME.corrupt for later analysis. +EOF +} + +# List the corrupt databases +test_num_corrupt () +{ + (cd "$CTDB_DBDIR" && ls foo.tdb.0.*.corrupt) +} + +# Required result is a list of up to 10 corrupt databases +required_result_num_corrupt () +{ + _num="$1" + + if [ "$_num" -gt 10 ] ; then + _num=10 + fi + + _t="" + for _x in $(seq 1 $_num) ; do + _t="${_t:+${_t} +}foo.tdb.0.DATE.TIME.corrupt" + done + + ok "$_t" +} + +for i in $(seq 1 15) ; do + FAKE_SLEEP_REALLY=yes sleep 1 + touch "$db" + required_result_tdbcheck + simple_test + required_result_num_corrupt "$i" + simple_test_command test_num_corrupt +done diff --git a/ctdb/tests/UNIT/eventscripts/01.reclock.init.001.sh b/ctdb/tests/UNIT/eventscripts/01.reclock.init.001.sh new file mode 100755 index 0000000..c495a47 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/01.reclock.init.001.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "unset, check no-op" + +setup "" + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/01.reclock.init.002.sh b/ctdb/tests/UNIT/eventscripts/01.reclock.init.002.sh new file mode 100755 index 0000000..1bd409c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/01.reclock.init.002.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "set to use helper, check no-op" + +setup "!/bin/false" + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/01.reclock.init.003.sh b/ctdb/tests/UNIT/eventscripts/01.reclock.init.003.sh new file mode 100755 index 0000000..a8b6abd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/01.reclock.init.003.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "set to default lock file, directory is created" + +setup + +dir=$(dirname "$CTDB_RECOVERY_LOCK") + +# Ensure directory doesn't exist before +required_result 1 "" +unit_test test -d "$dir" + +ok_null +simple_test + +# Ensure directory exists after +ok_null +unit_test test -d "$dir" diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.001.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.001.sh new file mode 100755 index 0000000..4171f3d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, error situation, default checks enabled" + +setup + +set_fs_usage 100 +ok <<EOF +WARNING: Filesystem ${CTDB_DBDIR_BASE} utilization 100% >= threshold 90% +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.002.sh new file mode 100755 index 0000000..4e78a56 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.002.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, good situation, 1 error check enabled" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var::80" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.003.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.003.sh new file mode 100755 index 0000000..41fd914 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.003.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, error situation, 1 error check enabled" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var::80" +EOF + +set_fs_usage 90 +required_result 1 <<EOF +ERROR: Filesystem /var utilization 90% >= threshold 80% +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.004.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.004.sh new file mode 100755 index 0000000..3400393 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.004.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, warn situation, only error check enabled" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var::80" +EOF + +set_fs_usage 70 +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.005.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.005.sh new file mode 100755 index 0000000..7e1a953 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.005.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, warn situation, both checks enabled" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var:80:90" +EOF + +set_fs_usage 85 +ok <<EOF +WARNING: Filesystem /var utilization 85% >= threshold 80% +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.006.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.006.sh new file mode 100755 index 0000000..48008d9 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.006.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, error situation, both checks enabled" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var:80:90" +EOF + +set_fs_usage 95 +required_result 1 <<EOF +ERROR: Filesystem /var utilization 95% >= threshold 90% +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.007.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.007.sh new file mode 100755 index 0000000..68b99cf --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.007.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Filesystem use check, good situation, both checks enabled, multiple filesystems" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_FILESYSTEM_USAGE="/var:80:90 /:90:95" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.011.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.011.sh new file mode 100755 index 0000000..6cd1dab --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.011.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (default), warning situation" + +setup + +set_mem_usage 100 100 +ok <<EOF +WARNING: System memory utilization 100% >= threshold 80% +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.012.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.012.sh new file mode 100755 index 0000000..9e84056 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.012.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (custom, both), good situation" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_MEMORY_USAGE="80:90" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.014.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.014.sh new file mode 100755 index 0000000..9e2b21c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.014.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (custom, warning only), warning situation" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_MEMORY_USAGE="85:" +EOF + +set_mem_usage 90 90 +ok <<EOF +WARNING: System memory utilization 90% >= threshold 85% +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.015.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.015.sh new file mode 100755 index 0000000..76b73a3 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.015.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (custom, error only), error situation" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_MEMORY_USAGE=":85" +EOF + +set_mem_usage 90 90 +required_result 1 <<EOF +ERROR: System memory utilization 90% >= threshold 85% +$FAKE_PROC_MEMINFO +$(ps auxfww) +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.017.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.017.sh new file mode 100755 index 0000000..b2e5029 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.017.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (custom, both), error situation" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_MEMORY_USAGE="70:80" +EOF + +set_mem_usage 87 87 +required_result 1 <<EOF +ERROR: System memory utilization 87% >= threshold 80% +$FAKE_PROC_MEMINFO +$(ps auxfww) +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/05.system.monitor.018.sh b/ctdb/tests/UNIT/eventscripts/05.system.monitor.018.sh new file mode 100755 index 0000000..427adc6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/05.system.monitor.018.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Memory check (custom, both), check throttling of warnings" + +setup + +setup_script_options <<EOF +CTDB_MONITOR_MEMORY_USAGE="70:80" +EOF + +# Below threshold, nothing logged +set_mem_usage 67 67 +ok_null +simple_test + +set_mem_usage 71 71 +ok "WARNING: System memory utilization 71% >= threshold 70%" +simple_test + +# 2nd time at same level, nothing logged +set_mem_usage 71 71 +ok_null +simple_test + +set_mem_usage 73 73 +ok "WARNING: System memory utilization 73% >= threshold 70%" +simple_test + +# 2nd time at same level, nothing logged +set_mem_usage 73 73 +ok_null +simple_test + +set_mem_usage 79 79 +ok "WARNING: System memory utilization 79% >= threshold 70%" +simple_test + +set_mem_usage 80 80 +required_result 1 <<EOF +ERROR: System memory utilization 80% >= threshold 80% +$FAKE_PROC_MEMINFO +$(ps auxfww) +EOF +simple_test + +# Fall back into warning at same level as last warning... should log +set_mem_usage 79 79 +ok "WARNING: System memory utilization 79% >= threshold 70%" +simple_test + +# Below threshold, notice +set_mem_usage 69 69 +ok <<EOF +NOTICE: System memory utilization 69% < threshold 70% +EOF +simple_test + +# Further reduction, nothing logged +set_mem_usage 68 68 +ok_null +simple_test + +# Back up into warning at same level as last warning... should log +set_mem_usage 79 79 +ok "WARNING: System memory utilization 79% >= threshold 70%" +simple_test + +# Back up above critical threshold... unhealthy +set_mem_usage 81 81 +required_result 1 <<EOF +ERROR: System memory utilization 81% >= threshold 80% +$FAKE_PROC_MEMINFO +$(ps auxfww) +EOF +simple_test + +# Straight back down to a good level... notice +set_mem_usage 65 65 +ok "NOTICE: System memory utilization 65% < threshold 70%" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.001.sh b/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.001.sh new file mode 100755 index 0000000..0546863 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.001.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout succeeds" + +setup + +setup_nfs_callout + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.002.sh b/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.002.sh new file mode 100755 index 0000000..dc44d2d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/06.nfs.releaseip.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes releaseip-pre to fail" + +setup + +setup_nfs_callout "releaseip-pre" + +required_result 1 "releaseip-pre" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.001.sh b/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.001.sh new file mode 100755 index 0000000..0546863 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.001.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout succeeds" + +setup + +setup_nfs_callout + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.002.sh b/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.002.sh new file mode 100755 index 0000000..c9f3db9 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/06.nfs.takeip.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes takeip-pre to fail" + +setup + +setup_nfs_callout "takeip-pre" + +required_result 1 "takeip-pre" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.010.sh b/ctdb/tests/UNIT/eventscripts/10.interface.010.sh new file mode 100755 index 0000000..171a697 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.010.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Release 1 IP, 10 connections killed OK" + +setup + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + count=10 + setup_tcp_connections $count \ + "$ip" 445 10.254.254.0 12300 + + ok <<EOF +Killed ${count}/${count} TCP connections to released IP $ip +EOF + + simple_test_event "releaseip" $dev $ip $bits +done diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.011.sh b/ctdb/tests/UNIT/eventscripts/10.interface.011.sh new file mode 100755 index 0000000..7f4302d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.011.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Release 1 IP, 10 connections killed, 1 fails" + +setup + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + count=10 + setup_tcp_connections $count \ + "$ip" 445 10.254.254.0 12300 + + setup_tcp_connections_unkillable 1 \ + "$ip" 445 10.254.254.0 43210 + + ok <<EOF +Killed 10/11 TCP connections to released IP ${ip} +Remaining connections: + ${ip}:445 10.254.254.1:43211 +EOF + + simple_test_event "releaseip" $dev $ip $bits +done diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.012.sh b/ctdb/tests/UNIT/eventscripts/10.interface.012.sh new file mode 100755 index 0000000..2ef0fe6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.012.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Release 1 IP, 10 connections killed, 3 fail" + +setup + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + count=10 + + setup_tcp_connections $count \ + "$ip" 445 10.254.254.0 12300 + + setup_tcp_connections_unkillable 3 \ + "$ip" 445 10.254.254.0 43210 + + ok <<EOF +Killed 10/13 TCP connections to released IP ${ip} +Remaining connections: + ${ip}:445 10.254.254.1:43211 + ${ip}:445 10.254.254.2:43212 + ${ip}:445 10.254.254.3:43213 +EOF + + simple_test_event "releaseip" $dev $ip $bits +done diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.013.sh b/ctdb/tests/UNIT/eventscripts/10.interface.013.sh new file mode 100755 index 0000000..e9a4c30 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.013.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Release 1 IP, all 10 connections kills fail" + +setup + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + setup_tcp_connections 0 + + count=10 + setup_tcp_connections_unkillable $count \ + "$ip" 445 10.254.254.0 43210 + + ok <<EOF +Killed 0/$count TCP connections to released IP ${ip} +Remaining connections: + ${ip}:445 10.254.254.1:43211 + ${ip}:445 10.254.254.2:43212 + ${ip}:445 10.254.254.3:43213 + ${ip}:445 10.254.254.4:43214 + ${ip}:445 10.254.254.5:43215 + ${ip}:445 10.254.254.6:43216 + ${ip}:445 10.254.254.7:43217 + ${ip}:445 10.254.254.8:43218 + ${ip}:445 10.254.254.9:43219 + ${ip}:445 10.254.254.10:43220 +EOF + + simple_test_event "releaseip" $dev $ip $bits +done diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.init.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.init.001.sh new file mode 100755 index 0000000..7f370b2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.init.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "no public addresses" + +setup + +rm -f "${CTDB_BASE}/public_addresses" + +ok "No public addresses file found" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.init.002.sh b/ctdb/tests/UNIT/eventscripts/10.interface.init.002.sh new file mode 100755 index 0000000..1862eac --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.init.002.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all interfaces up" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.init.021.sh b/ctdb/tests/UNIT/eventscripts/10.interface.init.021.sh new file mode 100755 index 0000000..fd89c87 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.init.021.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Check public IP dropping, none assigned" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.init.022.sh b/ctdb/tests/UNIT/eventscripts/10.interface.init.022.sh new file mode 100755 index 0000000..ee7fa14 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.init.022.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Check public IP dropping, 1 assigned" + +setup + +ctdb_get_1_public_address | +while read dev ip bits ; do + ip addr add "${ip}/${bits}" dev "$dev" + + ok <<EOF +Removing public address ${ip}/${bits} from device ${dev} +EOF + + simple_test +done diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.init.023.sh b/ctdb/tests/UNIT/eventscripts/10.interface.init.023.sh new file mode 100755 index 0000000..b39b67a --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.init.023.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Check public IP dropping, all assigned" + +setup + +nl=" +" +ctdb_get_my_public_addresses | { + out="" + while read dev ip bits ; do + ip addr add "${ip}/${bits}" dev "$dev" + + msg="Removing public address ${ip}/${bits} from device ${dev}" + out="${out}${out:+${nl}}${msg}" + done + + ok "$out" + + simple_test +} diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.001.sh new file mode 100755 index 0000000..c829efc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "no public addresses" + +setup + +rm -f "${CTDB_BASE}/public_addresses" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.002.sh new file mode 100755 index 0000000..1862eac --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.002.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all interfaces up" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.003.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.003.sh new file mode 100755 index 0000000..db1b2c6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.003.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 interface down" + +setup + +iface=$(ctdb_get_1_interface) + +ethtool_interfaces_down $iface + +required_result 1 "ERROR: No link on the public network interface $iface" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.004.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.004.sh new file mode 100755 index 0000000..3f20fdc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.004.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all interfaces up, 1 is a bond" + +setup + +iface=$(ctdb_get_1_interface) + +setup_bond $iface + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.005.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.005.sh new file mode 100755 index 0000000..1042d15 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.005.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 bond, no active slaves" + +setup + +iface=$(ctdb_get_1_interface) + +setup_bond $iface "None" + +required_result 1 "ERROR: No active slaves for bond device $iface" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.006.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.006.sh new file mode 100755 index 0000000..5facf08 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.006.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 bond, active slaves, link down" + +setup + +iface=$(ctdb_get_1_interface) + +setup_bond $iface "" "down" + +required_result 1 "ERROR: public network interface $iface is down" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.009.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.009.sh new file mode 100755 index 0000000..93ed68b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.009.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_PARTIALLY_ONLINE_INTERFACES, 1 down" + +setup + +iface=$(ctdb_get_1_interface) + +setup_script_options <<EOF +CTDB_PARTIALLY_ONLINE_INTERFACES=yes +EOF + +ethtool_interfaces_down "$iface" + +ok "ERROR: No link on the public network interface $iface" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.010.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.010.sh new file mode 100755 index 0000000..5287893 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.010.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_PARTIALLY_ONLINE_INTERFACES, all down" + +setup + +ifaces=$(ctdb_get_interfaces) + +setup_script_options <<EOF +CTDB_PARTIALLY_ONLINE_INTERFACES=yes +EOF + +ethtool_interfaces_down $ifaces + +msg=$( + for i in $ifaces ; do + echo "ERROR: No link on the public network interface $i" + done + ) + +required_result 1 "$msg" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.011.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.011.sh new file mode 100755 index 0000000..824bd32 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.011.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_PARTIALLY_ONLINE_INTERFACES, 1 bond down" + +setup + +iface=$(ctdb_get_1_interface) + +setup_bond $iface "None" + +setup_script_options <<EOF +CTDB_PARTIALLY_ONLINE_INTERFACES=yes +EOF + +ethtool_interfaces_down "$iface" + +ok "ERROR: No active slaves for bond device $iface" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.012.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.012.sh new file mode 100755 index 0000000..1315980 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.012.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_PARTIALLY_ONLINE_INTERFACES, 1 bond down" + +setup + +ifaces=$(ctdb_get_interfaces) + +for i in $ifaces ; do + setup_bond $i "None" +done + +setup_script_options <<EOF +CTDB_PARTIALLY_ONLINE_INTERFACES=yes +EOF + +ethtool_interfaces_down $ifaces + +msg=$( + for i in $ifaces ; do + echo "ERROR: No active slaves for bond device $i" + done + ) + +required_result 1 "$msg" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.013.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.013.sh new file mode 100755 index 0000000..2aa0a8e --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.013.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 bond, active slaves, link down" + +setup + +iface=$(ctdb_get_1_interface) + +setup_bond $iface "" "up" "down" + +required_result 1 "ERROR: No active slaves for 802.ad bond device $iface" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.014.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.014.sh new file mode 100755 index 0000000..1dd8ff0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.014.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "spurious addresses on interface, no action" + +setup + +iface=$(ctdb_get_1_interface) + +ip addr add 192.168.253.253/24 dev $iface +ip addr add 192.168.254.254/24 dev $iface + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.015.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.015.sh new file mode 100755 index 0000000..b7b4787 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.015.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Missing interface, fail" + +setup + +iface=$(ctdb_get_1_interface) +ip link delete "$iface" + +required_result 1 <<EOF +ERROR: Monitored interface dev123 does not exist +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.016.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.016.sh new file mode 100755 index 0000000..bd7f302 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.016.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Missing interface, CTDB_PARTIALLY_ONLINE_INTERFACES=yes, warn" + +setup + +setup_script_options <<EOF +CTDB_PARTIALLY_ONLINE_INTERFACES=yes +EOF + +iface=$(ctdb_get_1_interface) +ip link delete "$iface" + +ok <<EOF +ERROR: Monitored interface dev123 does not exist +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.017.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.017.sh new file mode 100755 index 0000000..bae0886 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.017.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 VLAN, link down" + +setup + +iface=$(ctdb_get_1_interface) + +ethtool_interfaces_down "$iface" + +# This just exercises the VLAN checking code, which will allow us to +# determine that real0 is not a bond. +realiface="real0" +ip link add link "$realiface" name "$iface" type vlan id 11 +ip link set "${iface}@${realiface}" up + +required_result 1 "ERROR: No link on the public network interface ${iface}" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.monitor.018.sh b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.018.sh new file mode 100755 index 0000000..8006d92 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.monitor.018.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "VLAN on bond, active slaves, link down" + +setup + +iface=$(ctdb_get_1_interface) + +bond="bond0" + +setup_bond "$bond" "" "down" + +ip link add link "$bond" name "$iface" type vlan id 11 +ip link set "${iface}@${bond}" up + +required_result 1 "ERROR: public network interface ${bond} is down" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.multi.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.multi.001.sh new file mode 100755 index 0000000..867cc24 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.multi.001.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "takeip, removeip" + +setup + +public_address=$(ctdb_get_1_public_address) + +ok_null + +simple_test_event "takeip" $public_address +simple_test_event "releaseip" $public_address diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.001.sh new file mode 100755 index 0000000..2ac0b86 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "error - no args given" + +setup + +iface=$(ctdb_get_1_interface) + +required_result 1 "ERROR: must supply interface, IP and maskbits" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.002.sh b/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.002.sh new file mode 100755 index 0000000..a60adbd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.releaseip.002.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "error - remove a non-existent ip" + +setup + +public_address=$(ctdb_get_1_public_address) +ip="${public_address% *}" ; ip="${ip#* }" + +required_result 1 "ERROR: Unable to determine interface for IP ${ip}" + +simple_test $public_address diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.startup.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.startup.001.sh new file mode 100755 index 0000000..c829efc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.startup.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "no public addresses" + +setup + +rm -f "${CTDB_BASE}/public_addresses" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.startup.002.sh b/ctdb/tests/UNIT/eventscripts/10.interface.startup.002.sh new file mode 100755 index 0000000..1862eac --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.startup.002.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all interfaces up" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.takeip.001.sh b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.001.sh new file mode 100755 index 0000000..2ac0b86 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "error - no args given" + +setup + +iface=$(ctdb_get_1_interface) + +required_result 1 "ERROR: must supply interface, IP and maskbits" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.takeip.002.sh b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.002.sh new file mode 100755 index 0000000..e267f16 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.002.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "add an ip" + +setup + +public_address=$(ctdb_get_1_public_address) + +ok_null + +simple_test $public_address diff --git a/ctdb/tests/UNIT/eventscripts/10.interface.takeip.003.sh b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.003.sh new file mode 100755 index 0000000..acb9b04 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/10.interface.takeip.003.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "error - add same IP twice" + +setup + +public_address=$(ctdb_get_1_public_address) +dev="${public_address%% *}" +t="${public_address#* }" +ip="${t% *}" +bits="${t#* }" + +ok_null +simple_test $public_address + +required_result 1 <<EOF +RTNETLINK answers: File exists +Failed to add $ip/$bits on dev $dev +EOF +simple_test $public_address diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.001.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.001.sh new file mode 100755 index 0000000..06b2cd3 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.001.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "not configured" + +setup + +ok_null +simple_test_event "ipreallocate" + +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.002.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.002.sh new file mode 100755 index 0000000..90b1399 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.002.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "missing config file" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +rm -f "$CTDB_NATGW_NODES" + +required_result 1 <<EOF +error: CTDB_NATGW_NODES=${CTDB_NATGW_NODES} unreadable +EOF + +for i in "startup" "ipreallocated" ; do + simple_test_event "$i" +done diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.003.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.003.sh new file mode 100755 index 0000000..370c10d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.003.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_NATGW_PUBLIC_IFACE unset, not follower-only" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_PUBLIC_IFACE="" +EOF + +required_result 1 "Invalid configuration: CTDB_NATGW_PUBLIC_IFACE not set" + +for i in "startup" "ipreallocated" ; do + simple_test_event "$i" +done diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.004.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.004.sh new file mode 100755 index 0000000..0f06be1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.004.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "CTDB_NATGW_PUBLIC_IP unset, not follower-only" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_PUBLIC_IP="" +EOF + +required_result 1 "Invalid configuration: CTDB_NATGW_PUBLIC_IP not set" + +for i in "startup" "ipreallocated" ; do + simple_test_event "$i" +done diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.011.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.011.sh new file mode 100755 index 0000000..407f049 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.011.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "leader node, basic configuration" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${CTDB_NATGW_DEFAULT_GATEWAY} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.012.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.012.sh new file mode 100755 index 0000000..fdec8ee --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.012.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower node, basic configuration" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.013.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.013.sh new file mode 100755 index 0000000..cb9af46 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.013.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "leader node, no gateway" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_DEFAULT_GATEWAY="" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_null +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.014.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.014.sh new file mode 100755 index 0000000..0fc3ccc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.014.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower node, no gateway" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_DEFAULT_GATEWAY="" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.015.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.015.sh new file mode 100755 index 0000000..84cc17b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.015.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "basic configuration, multiple transitions" + +setup + +echo "*** Leader node..." + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${CTDB_NATGW_DEFAULT_GATEWAY} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "*** Follower node..." + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "*** Leader node again..." + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${CTDB_NATGW_DEFAULT_GATEWAY} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.021.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.021.sh new file mode 100755 index 0000000..7d73c37 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.021.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "leader node, static routes" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options<<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.022.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.022.sh new file mode 100755 index 0000000..2a4dd47 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.022.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower node, static routes" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_follower_static_routes +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.023.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.023.sh new file mode 100755 index 0000000..9fdf734 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.023.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "leader node, static routes, custom gateway" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24@10.1.1.253" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.024.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.024.sh new file mode 100755 index 0000000..24f677d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.024.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower node, static routes, custom gateway" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24@10.1.1.253" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_follower_static_routes +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.025.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.025.sh new file mode 100755 index 0000000..d4221c2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.025.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "static routes, custom gateway, multiple transitions" + +setup + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24@10.1.1.253" +EOF + +echo "*** Leader node..." + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "*** Follower node..." + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_follower_static_routes +simple_test_command ip route show + +ok_natgw_follower_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "*** Leader node again..." + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.031.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.031.sh new file mode 100755 index 0000000..6a5bcad --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.031.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "leader node, static routes, custom gateway, config change" + +setup + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.1.0/24 10.1.2.0/24@10.1.1.253" +EOF + +echo "##################################################" +echo "Static routes..." + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "##################################################" +echo "Default routes..." + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="" +EOF + +ok "NAT gateway configuration has changed" +simple_test_event "ipreallocated" + +ok "default via ${CTDB_NATGW_DEFAULT_GATEWAY} dev ethXXX metric 10 " +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" + +echo "##################################################" +echo "Static routes again..." + +setup_script_options <<EOF +CTDB_NATGW_STATIC_ROUTES="10.1.3.0/24 10.1.4.4/32 10.1.2.0/24@10.1.1.252" +EOF + +ok "NAT gateway configuration has changed" +simple_test_event "ipreallocated" + +ok_natgw_leader_static_routes +simple_test_command ip route show + +ok_natgw_leader_ip_addr_show +simple_test_command ip addr show "$CTDB_NATGW_PUBLIC_IFACE" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.041.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.041.sh new file mode 100755 index 0000000..1cbe5b3 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.041.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower-only, CTDB_NATGW_PUBLIC_IFACE unset" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 follower-only +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_PUBLIC_IFACE="" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " +simple_test_command ip route show diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.042.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.042.sh new file mode 100755 index 0000000..b643fd3 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.042.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "follower-only, CTDB_NATGW_PUBLIC_IP unset" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 follower-only +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +setup_script_options <<EOF +CTDB_NATGW_PUBLIC_IFACE="" +CTDB_NATGW_PUBLIC_IP="" +EOF + +ok_null +simple_test_event "ipreallocated" + +ok "default via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " +simple_test_command ip route show diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.051.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.051.sh new file mode 100755 index 0000000..6c711c0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.051.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Monitor CTDB_NATGW_PUBLIC_IFACE, follower, up" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "monitor" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.052.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.052.sh new file mode 100755 index 0000000..ad02003 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.052.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Monitor CTDB_NATGW_PUBLIC_IFACE, follower, down" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 +192.168.1.22 leader +192.168.1.23 +192.168.1.24 +EOF + +ethtool_interfaces_down "$CTDB_NATGW_PUBLIC_IFACE" + +required_result 1 <<EOF +ERROR: No link on the public network interface ${CTDB_NATGW_PUBLIC_IFACE} +EOF +simple_test_event "monitor" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.053.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.053.sh new file mode 100755 index 0000000..e9bded1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.053.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Monitor CTDB_NATGW_PUBLIC_IFACE, leader, up" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ok_null +simple_test_event "monitor" diff --git a/ctdb/tests/UNIT/eventscripts/11.natgw.054.sh b/ctdb/tests/UNIT/eventscripts/11.natgw.054.sh new file mode 100755 index 0000000..2a79cde --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/11.natgw.054.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Monitor CTDB_NATGW_PUBLIC_IFACE, leader, down" + +setup + +setup_ctdb_natgw <<EOF +192.168.1.21 leader +192.168.1.22 +192.168.1.23 +192.168.1.24 +EOF + +ethtool_interfaces_down "$CTDB_NATGW_PUBLIC_IFACE" + +required_result 1 <<EOF +ERROR: No link on the public network interface ${CTDB_NATGW_PUBLIC_IFACE} +EOF +simple_test_event "monitor" diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.001.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.001.sh new file mode 100755 index 0000000..55c8c64 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.001.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "not configured" + +setup + +setup_script_options <<EOF +CTDB_PER_IP_ROUTING_CONF="" +EOF + +ok_null +simple_test_event "takeip" + +ok_null +simple_test_event "ipreallocate" + +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.002.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.002.sh new file mode 100755 index 0000000..6925983 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.002.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "missing config file" + +setup + +# Error because policy routing is configured but the configuration +# file is missing. +required_result 1 <<EOF +error: CTDB_PER_IP_ROUTING_CONF=${CTDB_BASE}/policy_routing file not found +EOF + +for i in "startup" "ipreallocated" "monitor" ; do + simple_test_event "$i" +done + diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.003.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.003.sh new file mode 100755 index 0000000..4eac963 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.003.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "empty config, ipreallocated" + +setup + +create_policy_routing_config 0 + +# ipreallocated should silently add any missing routes +ok_null +simple_test_event "ipreallocated" + +# empty configuration file should mean there are no routes +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.004.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.004.sh new file mode 100755 index 0000000..3724de0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.004.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "empty config, takeip" + +setup + +create_policy_routing_config 0 + +public_address=$(ctdb_get_1_public_address) + +ok_null +simple_test_event "takeip" $public_address + +# empty configuration file should mean there are no routes +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.005.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.005.sh new file mode 100755 index 0000000..baafbbb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.005.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, takeip" + +setup + +# Configuration for 1 IP +create_policy_routing_config 1 default + +# takeip should add routes for the given address +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits +done + +# Should have routes for 1 IP +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.006.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.006.sh new file mode 100755 index 0000000..6c4d686 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.006.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, takeip, releaseip" + +setup + +# create config for 1 IP +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +while read dev ip bits ; do + # takeip adds routes + ok_null + simple_test_event "takeip" $dev $ip $bits + + # releaseip removes routes + ok_null + simple_test_event "releaseip" $dev $ip $bits +done + +# should have no routes +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.007.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.007.sh new file mode 100755 index 0000000..4cf46e6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.007.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, ipreallocated" + +setup + +# create config for 1 IP +create_policy_routing_config 1 default + +# no takeip, but ipreallocated should add any missing routes +ok_null +simple_test_event "ipreallocated" + +# should have routes for 1 IP +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.008.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.008.sh new file mode 100755 index 0000000..889b4c4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.008.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, takeip twice" + +setup + +# create config for 1 IP +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + # 2nd takeip event for the same IP should be a no-op + ok_null + simple_test_event "takeip" $dev $ip $bits +done + +# should be routes for 1 IP +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.009.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.009.sh new file mode 100755 index 0000000..c887feb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.009.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "All IPs configured, takeip 1 address" + +setup + +# configure all addresses +create_policy_routing_config all default + +# add routes for all 1 IP +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits +done + +# for 1 IP +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.010.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.010.sh new file mode 100755 index 0000000..7297f96 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.010.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "All IPs configured, takeip on all nodes" + +setup + +# create config for all IPs +create_policy_routing_config all default + +ctdb_get_my_public_addresses | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits +done + +# should have routes for all IPs +check_routes all default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.011.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.011.sh new file mode 100755 index 0000000..8d96c8d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.011.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "__auto_link_local__, takeip all on node" + +setup + +# do link local fu instead of creating configuration +setup_script_options <<EOF +CTDB_PER_IP_ROUTING_CONF="__auto_link_local__" +EOF + +# add routes for all addresses +ctdb_get_my_public_addresses | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits +done + +check_routes all diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.012.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.012.sh new file mode 100755 index 0000000..48aab21 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.012.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, takeip, releaseip, ipreallocated" + +# This partly tests the test infrastructure. If the (stub) "ctdb +# moveip" doesn't do anything then the IP being released will still be +# on the node and the ipreallocated event will add the routes back. + +setup + +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + simple_test_event "takeip" $dev $ip $bits + + ok_null + ctdb moveip $ip 1 + simple_test_event "releaseip" $dev $ip $bits + + ok_null + simple_test_event "ipreallocated" +done + +# all routes should have been removed and not added back +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.013.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.013.sh new file mode 100755 index 0000000..2262083 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.013.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, releaseip of unassigned" + +setup + +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok <<EOF +WARNING: Failed to delete policy routing rule + Command "ip rule del from $ip pref $CTDB_PER_IP_ROUTING_RULE_PREF table ctdb.$ip" failed: + RTNETLINK answers: No such file or directory +EOF + + simple_test_event "releaseip" $dev $ip $bits +done + +# there should be no routes +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.014.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.014.sh new file mode 100755 index 0000000..a63e134 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.014.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, takeip, moveip, ipreallocated" + +# We move the IP to another node but don't run releaseip. +# ipreallocated should remove the bogus routes. + +setup + +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +while read dev ip bits ; do + ok_null + # Set up the routes for an IP that we have + simple_test_event "takeip" $dev $ip $bits + + # Now move that IPs but don't run the associated "releaseip" + ctdb moveip $ip 1 + + # This should handle removal of the routes + ok "Removing ip rule/routes for unhosted public address $ip" + simple_test_event "ipreallocated" +done + +# no routes left +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.015.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.015.sh new file mode 100755 index 0000000..742cfd4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.015.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, releaseip of unassigned" + +setup + +export IP_ROUTE_BAD_TABLE_ID=true + +create_policy_routing_config 1 default + +ctdb_get_1_public_address | +{ + read dev ip bits + + ok <<EOF +WARNING: Failed to delete policy routing rule + Command "ip rule del from $ip pref $CTDB_PER_IP_ROUTING_RULE_PREF table ctdb.$ip" failed: + Error: argument ctdb.$ip is wrong: invalid table ID + Error: argument ctdb.$ip is wrong: table id value is invalid +EOF + + simple_test_event "releaseip" $dev $ip $bits +} + + +# there should be no routes +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.016.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.016.sh new file mode 100755 index 0000000..4856ba5 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.016.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "empty config, reconfigure, NOOP" + +setup + +create_policy_routing_config 0 + +ok "Reconfiguring service \"${service_name}\"..." +simple_test_event "reconfigure" + +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.017.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.017.sh new file mode 100755 index 0000000..d26ab9c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.017.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, reconfigure" + +setup + +create_policy_routing_config 1 default + +# no takeip, but reconfigure should add any missing routes +ok "Reconfiguring service \"${service_name}\"..." +simple_test_event "reconfigure" + +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.018.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.018.sh new file mode 100755 index 0000000..4d89dc2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.018.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, ipreallocated, more routes, reconfigure" + +setup + +create_policy_routing_config 1 + +# no takeip, but ipreallocated should add any missing routes +ok_null +simple_test_event "ipreallocated" + +create_policy_routing_config 1 default + +# reconfigure should update routes even though rules are unchanged +ok "Reconfiguring service \"${service_name}\"..." +simple_test_event "reconfigure" + +check_routes 1 default diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.019.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.019.sh new file mode 100755 index 0000000..7575466 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.019.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, ipreallocated, less routes, reconfigure" + +setup + +create_policy_routing_config 1 default + +# no takeip, but ipreallocated should add any missing routes +ok_null +simple_test_event "ipreallocated" + +# rewrite the configuration to take out the default routes, as per the +# above change to $args +create_policy_routing_config 1 + +# reconfigure should update routes even though rules are unchanged +ok "Reconfiguring service \""${service_name}\""..." +simple_test_event "reconfigure" + +check_routes 1 diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.021.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.021.sh new file mode 100755 index 0000000..876b600 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.021.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Invalid table ID range - includes system tables" + +setup + +setup_script_options <<EOF +CTDB_PER_IP_ROUTING_TABLE_ID_LOW=100 +CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=500 +EOF + +required_result 1 "error: range CTDB_PER_IP_ROUTING_TABLE_ID_LOW[${CTDB_PER_IP_ROUTING_TABLE_ID_LOW}]..CTDB_PER_IP_ROUTING_TABLE_ID_HIGH[${CTDB_PER_IP_ROUTING_TABLE_ID_HIGH}] must not include 253-255" +simple_test_event "ipreallocated" diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.022.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.022.sh new file mode 100755 index 0000000..6f0638e --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.022.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Invalid table ID range - reversed" + +setup + +setup_script_options <<EOF +CTDB_PER_IP_ROUTING_TABLE_ID_LOW=9000 +CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=1000 +EOF + +required_result 1 "error: CTDB_PER_IP_ROUTING_TABLE_ID_LOW[${CTDB_PER_IP_ROUTING_TABLE_ID_LOW}] and/or CTDB_PER_IP_ROUTING_TABLE_ID_HIGH[${CTDB_PER_IP_ROUTING_TABLE_ID_HIGH}] improperly configured" +simple_test_event "ipreallocated" diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.023.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.023.sh new file mode 100755 index 0000000..a94b58b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.023.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "1 IP configured, broken configuration, takeip" + +setup + +# Configuration for 1 IP +create_policy_routing_config 1 default + +# takeip should add routes for the given address +ctdb_get_1_public_address | +while read dev ip bits ; do + # Now add configuration breakage by changing default route into a + # link local route with a gateway + net=$(ipv4_host_addr_to_net "$ip" "$bits") + sed -i -e "s@0\.0\.0\.0/0@${net}@" "$CTDB_PER_IP_ROUTING_CONF" + + ok <<EOF +RTNETLINK answers: File exists +add_routing_for_ip: failed to add route: ${net} via ${net%.*}.254 dev ${dev} table ctdb.${ip} +EOF + simple_test_event "takeip" $dev $ip $bits +done diff --git a/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.024.sh b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.024.sh new file mode 100755 index 0000000..7b1af37 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/13.per_ip_routing.024.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Single IP, restores original rt_tables" + +setup + +create_policy_routing_config 1 default + +_rt_tables="$CTDB_SYS_ETCDIR/iproute2/rt_tables" +_rt_orig=$(TMPDIR="$CTDB_TEST_TMP_DIR" mktemp) +cp "$_rt_tables" "$_rt_orig" + +ctdb_get_1_public_address | { + read dev ip bits + + ok_null + simple_test_event "takeip" $dev $ip $bits + + ok <<EOF +Removing ip rule for public address ${ip} for routing table ctdb.${ip} +EOF + simple_test_event "shutdown" +} + +ok_null +simple_test_command diff -u "$_rt_orig" "$_rt_tables" + +check_routes 0 diff --git a/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.001.sh b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.001.sh new file mode 100755 index 0000000..4991765 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.001.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "No multipath devices configure to check" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.002.sh new file mode 100755 index 0000000..f57f476 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.002.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "3 multipath devices configure to check, all up" + +setup "mpatha" "mpathb" "mpathc" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.003.sh b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.003.sh new file mode 100755 index 0000000..0d768a0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.003.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "3 multipath devices configure to check, one down" + +setup "mpatha" "!mpathb" "mpathc" + +required_result 1 <<EOF +ERROR: multipath device "mpathb" has no active paths +multipath monitoring failed +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.004.sh b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.004.sh new file mode 100755 index 0000000..a655b83 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/20.multipathd.monitor.004.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "3 multipath devices configure to check, multipath hangs" + +setup "mpatha" "!mpathb" "mpathc" +export FAKE_MULTIPATH_HANG="yes" + +required_result 1 <<EOF +ERROR: callout to multipath checks hung +multipath monitoring failed +EOF + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.002.sh new file mode 100755 index 0000000..48d3cbf --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.002.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Managed, clamd not listening" + +setup + +setup_script_options <<EOF +CTDB_CLAMD_SOCKET="/var/run/clamd.sock" +EOF + +required_result 1 <<EOF +ERROR: clamd not listening on $CTDB_CLAMD_SOCKET +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.003.sh b/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.003.sh new file mode 100755 index 0000000..f4e37d2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/31.clamd.monitor.003.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "Managed, clamd listening" + +setup + +setup_script_options <<EOF +CTDB_CLAMD_SOCKET="/var/run/clamd.sock" +EOF + +unix_socket_listening "$CTDB_CLAMD_SOCKET" + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/40.vsftpd.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/40.vsftpd.monitor.002.sh new file mode 100755 index 0000000..f825be4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/40.vsftpd.monitor.002.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "up once, down with recovery" + +setup "up" + +ok_null +simple_test + +setup "down" + +ok <<EOF +vsftpd not listening on TCP port 21 +WARNING: vsftpd listening on TCP port 21: fail count 1 >= threshold 1 +EOF +simple_test + +setup "up" + +ok <<EOF +NOTICE: vsftpd listening on TCP port 21: no longer failing +EOF +simple_test + +setup "down" + +ok <<EOF +vsftpd not listening on TCP port 21 +WARNING: vsftpd listening on TCP port 21: fail count 1 >= threshold 1 +EOF +simple_test + +required_result 1 <<EOF +vsftpd not listening on TCP port 21 +ERROR: vsftpd listening on TCP port 21: fail count 2 >= threshold 2 +EOF +simple_test + +required_result 1 <<EOF +vsftpd not listening on TCP port 21 +ERROR: vsftpd listening on TCP port 21: fail count 3 >= threshold 2 +EOF +simple_test + +setup "up" + +ok <<EOF +NOTICE: vsftpd listening on TCP port 21: no longer failing +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/40.vsftpd.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/40.vsftpd.shutdown.002.sh new file mode 100755 index 0000000..fe65278 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/40.vsftpd.shutdown.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "up" + +ok <<EOF +Stopping vsftpd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/40.vsftpd.startup.002.sh b/ctdb/tests/UNIT/eventscripts/40.vsftpd.startup.002.sh new file mode 100755 index 0000000..dd39860 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/40.vsftpd.startup.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "down" + +ok <<EOF +Starting vsftpd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/41.httpd.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/41.httpd.monitor.002.sh new file mode 100755 index 0000000..383040c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/41.httpd.monitor.002.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed, down - 5 times" + +setup "down" + +ok_null +simple_test + +ok <<EOF +HTTPD is not running. Trying to restart HTTPD. +service: can't stop httpd - not running +Starting httpd: OK +EOF +simple_test + +ok_null +simple_test + +ok_null +simple_test + +required_result 1 <<EOF +HTTPD is not running. Trying to restart HTTPD. +Stopping httpd: OK +Starting httpd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/41.httpd.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/41.httpd.shutdown.002.sh new file mode 100755 index 0000000..4e342fb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/41.httpd.shutdown.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "up" + +ok <<EOF +Stopping httpd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/41.httpd.startup.002.sh b/ctdb/tests/UNIT/eventscripts/41.httpd.startup.002.sh new file mode 100755 index 0000000..1722785 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/41.httpd.startup.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "down" + +ok <<EOF +Starting httpd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/48.netbios.shutdown.011.sh b/ctdb/tests/UNIT/eventscripts/48.netbios.shutdown.011.sh new file mode 100755 index 0000000..0649813 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/48.netbios.shutdown.011.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, Debian init style" + +setup + +export EVENTSCRIPT_TESTS_INIT_STYLE="debian" + +ok <<EOF +Stopping nmbd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/48.netbios.startup.011.sh b/ctdb/tests/UNIT/eventscripts/48.netbios.startup.011.sh new file mode 100755 index 0000000..40b90a1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/48.netbios.startup.011.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, Debian init style" + +setup + +export EVENTSCRIPT_TESTS_INIT_STYLE="debian" + +ok <<EOF +Starting nmbd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.101.sh b/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.101.sh new file mode 100755 index 0000000..3884a33 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.101.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all OK" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.102.sh b/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.102.sh new file mode 100755 index 0000000..24e4ed2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/49.winbind.monitor.102.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "winbind down" + +setup + +wbinfo_down + +required_result 1 "ERROR: wbinfo -p returned error" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/49.winbind.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/49.winbind.shutdown.002.sh new file mode 100755 index 0000000..dc6f160 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/49.winbind.shutdown.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "up" + +ok <<EOF +Stopping winbind: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/49.winbind.startup.002.sh b/ctdb/tests/UNIT/eventscripts/49.winbind.startup.002.sh new file mode 100755 index 0000000..dd0c1ad --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/49.winbind.startup.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "managed" + +setup "down" + +ok <<EOF +Starting winbind: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.101.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.101.sh new file mode 100755 index 0000000..3884a33 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.101.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all OK" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.103.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.103.sh new file mode 100755 index 0000000..e9232a6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.103.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "port 445 down" + +setup + +tcp_port_down 445 + +required_result 1 "samba not listening on TCP port 445" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.104.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.104.sh new file mode 100755 index 0000000..8e9d789 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.104.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "port 139 down" + +setup + +tcp_port_down 139 + +required_result 1 "samba not listening on TCP port 139" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.105.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.105.sh new file mode 100755 index 0000000..7208aca --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.105.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "non-existent share path" + +setup + +out=$(shares_missing "samba" 2) + +required_result 1 "$out" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.106.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.106.sh new file mode 100755 index 0000000..80bccef --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.106.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "non-existent share - not checked" + +setup + +setup_script_options <<EOF +CTDB_SAMBA_SKIP_SHARE_CHECK="yes" +EOF + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.110.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.110.sh new file mode 100755 index 0000000..9645c5a --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.110.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "testparm fails" + +setup + +export FAKE_TESTPARM_FAIL="yes" +required_result 1 <<EOF +ERROR: smb.conf cache create failed - testparm failed with: +Load smb config files from ${CTDB_SYS_ETCDIR}/samba/smb.conf +rlimit_max: increasing rlimit_max (2048) to minimum Windows limit (16384) +Processing section "[share1]" +Processing section "[share2]" +Processing section "[share3]" +Loaded services file OK. +WARNING: 'workgroup' and 'netbios name' must differ. +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.111.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.111.sh new file mode 100755 index 0000000..d72855f --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.111.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "testparm fails on 2nd time through" + +setup + +ok_null +simple_test + +export FAKE_TESTPARM_FAIL="yes" +ok <<EOF +WARNING: smb.conf cache update failed - using old cache file +Load smb config files from ${CTDB_SYS_ETCDIR}/samba/smb.conf +rlimit_max: increasing rlimit_max (2048) to minimum Windows limit (16384) +Processing section "[share1]" +Processing section "[share2]" +Processing section "[share3]" +Loaded services file OK. +WARNING: 'workgroup' and 'netbios name' must differ. +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.112.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.112.sh new file mode 100755 index 0000000..f714472 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.112.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "testparm times out" + +setup + +export FAKE_TIMEOUT="yes" +required_result 1 <<EOF +ERROR: smb.conf cache create failed - testparm command timed out +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.monitor.113.sh b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.113.sh new file mode 100755 index 0000000..faadda1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.monitor.113.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "testparm times out on 2nd time through" + +setup + +ok_null +simple_test + +export FAKE_TIMEOUT="yes" +ok <<EOF +WARNING: smb.conf cache update timed out - using old cache file +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.001.sh b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.001.sh new file mode 100755 index 0000000..76ac985 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.001.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, simple" + +setup + +ok <<EOF +Stopping smb: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.002.sh new file mode 100755 index 0000000..f692026 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.002.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, simple" + +setup + +samba_setup_fake_threads 1 2 3 4 5 6 + +ok <<EOF +Stopping smb: OK +$SAMBA_STACK_TRACES +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.011.sh b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.011.sh new file mode 100755 index 0000000..94867e0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.shutdown.011.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, Debian init style" + +setup + +export EVENTSCRIPT_TESTS_INIT_STYLE="debian" + +ok <<EOF +Stopping smbd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/50.samba.startup.011.sh b/ctdb/tests/UNIT/eventscripts/50.samba.startup.011.sh new file mode 100755 index 0000000..8c4699d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/50.samba.startup.011.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "shutdown, Debian init style" + +setup + +export EVENTSCRIPT_TESTS_INIT_STYLE="debian" + +ok <<EOF +Starting smbd: OK +EOF +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.101.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.101.sh new file mode 100755 index 0000000..293b724 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.101.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all services available" + +setup + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.102.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.102.sh new file mode 100755 index 0000000..2f83b2c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.102.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all services available, check nfsd thread count, count matches" + +setup + +RPCNFSDCOUNT=8 +nfs_setup_fake_threads "nfsd" 1 2 3 4 5 6 7 8 + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.103.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.103.sh new file mode 100755 index 0000000..c0bb305 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.103.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all services available, not enough nfsd threads" + +setup + +RPCNFSDCOUNT=8 +nfs_setup_fake_threads "nfsd" 1 2 3 4 5 + +ok "Attempting to correct number of nfsd threads from 5 to 8" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.104.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.104.sh new file mode 100755 index 0000000..d568892 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.104.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +# Add this extra test to catch a design change where we only ever +# increase the number of threads. That is, this test would need to be +# consciously removed. +define_test "all services available, check nfsd thread count, too many threads" + +setup + +RPCNFSDCOUNT=4 +nfs_setup_fake_threads "nfsd" 1 2 3 4 5 6 + +ok "Attempting to correct number of nfsd threads from 6 to 4" + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.105.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.105.sh new file mode 100755 index 0000000..e83ead8 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.105.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "all services available, 10 iterations with ok_null" + +setup + +ok_null +nfs_iterate_test 10 diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.106.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.106.sh new file mode 100755 index 0000000..43d6b2f --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.106.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "portmapper down, 2 iterations" + +setup + +rpc_services_down "portmapper" + +nfs_iterate_test 2 "portmapper" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.107.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.107.sh new file mode 100755 index 0000000..8bf0fa2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.107.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout is 'true'" + +setup + +setup_script_options <<EOF +CTDB_NFS_CALLOUT="true" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.108.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.108.sh new file mode 100755 index 0000000..39aba84 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.108.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes monitor-pre to fail" + +setup + +setup_nfs_callout "monitor-pre" + +required_result 1 "monitor-pre" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.109.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.109.sh new file mode 100755 index 0000000..36572e9 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.109.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes monitor-post to fail" + +setup + +setup_nfs_callout "monitor-post" + +required_result 1 "monitor-post" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.111.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.111.sh new file mode 100755 index 0000000..2bbda96 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.111.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "knfsd down, 1 iteration" + +setup + +rpc_services_down "nfs" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.112.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.112.sh new file mode 100755 index 0000000..4000b5d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.112.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "knfsd down, 10 iterations" + +# knfsd fails and attempts to restart it fail. + +setup + +rpc_services_down "nfs" + +nfs_iterate_test 10 "nfs" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.113.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.113.sh new file mode 100755 index 0000000..744966c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.113.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "knfsd down, 10 iterations, no hung threads" + +# knfsd fails and attempts to restart it fail. +setup + +rpc_services_down "nfs" + +nfs_setup_fake_threads "nfsd" + +nfs_iterate_test 10 "nfs" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.114.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.114.sh new file mode 100755 index 0000000..7170fff --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.114.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "knfsd down, 10 iterations, 3 hung threads" + +# knfsd fails and attempts to restart it fail. +setup + +rpc_services_down "nfs" + +nfs_setup_fake_threads "nfsd" 1001 1002 1003 + +nfs_iterate_test 10 "nfs" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.121.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.121.sh new file mode 100755 index 0000000..1cda276 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.121.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "lockd down, 7 iterations" + +# This simulates an ongoing failure in the eventscript's automated +# attempts to restart the service. That is, the eventscript is unable +# to restart the service. + +setup + +rpc_services_down "nlockmgr" + +nfs_iterate_test 7 "nlockmgr" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.122.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.122.sh new file mode 100755 index 0000000..eae7ca0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.122.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "lockd down, 7 iterations, back up after 2" + +# This simulates a success the eventscript's automated attempts to +# restart the service. + +setup + +rpc_services_down "nlockmgr" + +# Iteration 2 should try to restart rpc.lockd. However, our test +# stub rpc.lockd does nothing, so we have to explicitly flag it as up. + +nfs_iterate_test 7 "nlockmgr" \ + 3 "rpc_services_up nlockmgr" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.131.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.131.sh new file mode 100755 index 0000000..33e1cf4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.131.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "rquotad down, 7 iterations" + +setup + +rpc_services_down "rquotad" + +nfs_iterate_test 7 "rquotad" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.132.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.132.sh new file mode 100755 index 0000000..207d872 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.132.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "rquotad down, 7 iterations, back up after 2" + +# rquotad fails once but then comes back after restart after 2nd +# failure. + +setup + +rpc_services_down "rquotad" + +nfs_iterate_test 7 "rquotad" \ + 3 'rpc_services_up "rquotad"' diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.141.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.141.sh new file mode 100755 index 0000000..5a8c5ce --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.141.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "statd down, 7 iterations" + +# statd fails and attempts to restart it fail. + +setup + +rpc_services_down "status" + +nfs_iterate_test 7 "status" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.142.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.142.sh new file mode 100755 index 0000000..694bf92 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.142.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "statd down, 7 iterations, back up after 2" + +# statd fails and the first attempt to restart it succeeds. + +setup + +rpc_services_down "status" + +nfs_iterate_test 7 "status" \ + 3 'rpc_services_up "status"' diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.143.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.143.sh new file mode 100755 index 0000000..d17277e --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.143.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "statd down, 2 iterations, stuck process" + +# statd fails and the first attempt to restart it succeeds. + +setup + +rpc_services_down "status" +nfs_setup_fake_threads "rpc.status" 1001 + +nfs_iterate_test 2 "status" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.144.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.144.sh new file mode 100755 index 0000000..5a8c5ce --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.144.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "statd down, 7 iterations" + +# statd fails and attempts to restart it fail. + +setup + +rpc_services_down "status" + +nfs_iterate_test 7 "status" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.151.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.151.sh new file mode 100755 index 0000000..9ab1807 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.151.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "mountd down, 1 iteration" + +setup + +rpc_services_down "mountd" + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.152.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.152.sh new file mode 100755 index 0000000..c3a6b8b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.152.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "mountd down, 7 iterations" + +# This simulates an ongoing failure in the eventscript's automated +# attempts to restart the service. That is, the eventscript is unable +# to restart the service. + +setup + +rpc_services_down "mountd" + +nfs_iterate_test 7 "mountd" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.153.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.153.sh new file mode 100755 index 0000000..a09315b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.153.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "mountd down, 7 iterations, back up after 2" + +setup + +rpc_services_down "mountd" + +# Iteration 2 should try to restart rpc.mountd. However, our test +# stub rpc.mountd does nothing, so we have to explicitly flag it as +# up. +nfs_iterate_test 7 "mountd" \ + 3 "rpc_services_up mountd" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.161.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.161.sh new file mode 100755 index 0000000..1fa73bb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.161.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "2nd share missing" + +setup + +out=$(shares_missing "nfs" 2) + +required_result 1 "$out" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.162.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.162.sh new file mode 100755 index 0000000..9e3438f --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.monitor.162.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "2nd share missing, skipping share checks" + +setup + +setup_script_options <<EOF +CTDB_NFS_SKIP_SHARE_CHECK="yes" +EOF + +ok_null + +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.multi.001.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.multi.001.sh new file mode 100755 index 0000000..baa5701 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.multi.001.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "takeip, ipreallocated -> reconfigure" + +setup + +public_address=$(ctdb_get_1_public_address) + +ok_null + +simple_test_event "takeip" $public_address + +ok <<EOF +Reconfiguring service "nfs"... +EOF + +simple_test_event "ipreallocated" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.multi.002.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.multi.002.sh new file mode 100755 index 0000000..846380f --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.multi.002.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "takeip, monitor -> no reconfigure" + +setup + +public_address=$(ctdb_get_1_public_address) + +ok_null + +simple_test_event "takeip" $public_address + +ok_null + +simple_test_event "monitor" diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.001.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.001.sh new file mode 100755 index 0000000..8bf0fa2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.001.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout is 'true'" + +setup + +setup_script_options <<EOF +CTDB_NFS_CALLOUT="true" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.002.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.002.sh new file mode 100755 index 0000000..998c3ba --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.releaseip.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes releaseip to fail" + +setup + +setup_nfs_callout "releaseip" + +required_result 1 "releaseip" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.001.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.001.sh new file mode 100755 index 0000000..8bf0fa2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.001.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout is 'true'" + +setup + +setup_script_options <<EOF +CTDB_NFS_CALLOUT="true" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.002.sh new file mode 100755 index 0000000..9db0656 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.shutdown.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes shutdown to fail" + +setup + +setup_nfs_callout "shutdown" + +required_result 1 "shutdown" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.startup.001.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.startup.001.sh new file mode 100755 index 0000000..8bf0fa2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.startup.001.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout is 'true'" + +setup + +setup_script_options <<EOF +CTDB_NFS_CALLOUT="true" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.startup.002.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.startup.002.sh new file mode 100755 index 0000000..bf881d9 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.startup.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes startup to fail" + +setup + +setup_nfs_callout "startup" + +required_result 1 "startup" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.001.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.001.sh new file mode 100755 index 0000000..8bf0fa2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.001.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout is 'true'" + +setup + +setup_script_options <<EOF +CTDB_NFS_CALLOUT="true" +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.002.sh b/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.002.sh new file mode 100755 index 0000000..3f247ff --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/60.nfs.takeip.002.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "callout causes takeip to fail" + +setup + +setup_nfs_callout "takeip" + +required_result 1 "takeip" +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.001.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.001.sh new file mode 100755 index 0000000..9fc8d02 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.001.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "sanity check ipvsadm stub" + +setup<<EOF +EOF + +check_ipvsadm NULL + +ipvsadm -A -u 10.1.1.201 -s lc -p 1999999 +ipvsadm -a -u 10.1.1.201 -r 192.168.1.3 -g +ipvsadm -a -u 10.1.1.201 -r 192.168.1.1 -g +ipvsadm -a -u 10.1.1.201 -r 192.168.1.2:0 -g +ipvsadm -a -u 10.1.1.201 -r 127.0.0.1 + +check_ipvsadm <<EOF +UDP 10.1.1.201:0 lc persistent 1999999 + -> 127.0.0.1:0 Local 1 0 0 + -> 192.168.1.1:0 Route 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +EOF + +ipvsadm -A -t 10.1.1.201 -s lc -p 1999999 +ipvsadm -a -t 10.1.1.201 -r 192.168.1.3 -g +ipvsadm -a -t 10.1.1.201 -r 192.168.1.1 -g +ipvsadm -a -t 10.1.1.201 -r 192.168.1.2:0 -g + +check_ipvsadm <<EOF +TCP 10.1.1.201:0 lc persistent 1999999 + -> 192.168.1.1:0 Route 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +UDP 10.1.1.201:0 lc persistent 1999999 + -> 127.0.0.1:0 Local 1 0 0 + -> 192.168.1.1:0 Route 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +EOF + +ipvsadm -D -u 10.1.1.201 + +check_ipvsadm <<EOF +TCP 10.1.1.201:0 lc persistent 1999999 + -> 192.168.1.1:0 Route 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +EOF + +ipvsadm -D -t 10.1.1.201 + +check_ipvsadm NULL diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.011.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.011.sh new file mode 100755 index 0000000..6866047 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.011.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "configured, no nodes in config" + +setup "10.1.1.201" "eth0" <<EOF +EOF + +ok_null +simple_test + +check_ipvsadm NULL +check_lvs_ip host diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.012.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.012.sh new file mode 100755 index 0000000..15328ef --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.012.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "nodes in config, no leader (e.g. all inactive)" + +setup "10.1.1.201" "eth0" <<EOF +192.168.1.1 +192.168.1.2 +192.168.1.3 +EOF + +ok_null +simple_test + +check_ipvsadm NULL +check_lvs_ip host diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.013.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.013.sh new file mode 100755 index 0000000..918b18d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.013.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "nodes in config, other node is leader" + +setup "10.1.1.201" "eth0" <<EOF +192.168.1.1 +192.168.1.2 leader +192.168.1.3 +EOF + +ok_null +simple_test + +check_ipvsadm NULL +check_lvs_ip host diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.014.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.014.sh new file mode 100755 index 0000000..8af31d7 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.ipreallocated.014.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "nodes in config, this is leader" + +setup "10.1.1.201" "eth0" <<EOF +192.168.1.1 leader +192.168.1.2 +192.168.1.3 +EOF + +ok_null +simple_test + +check_ipvsadm <<EOF +TCP 10.1.1.201:0 lc persistent 1999999 + -> 127.0.0.1:0 Local 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +UDP 10.1.1.201:0 lc persistent 1999999 + -> 127.0.0.1:0 Local 1 0 0 + -> 192.168.1.2:0 Route 1 0 0 + -> 192.168.1.3:0 Route 1 0 0 +EOF + +check_lvs_ip global diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.001.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.001.sh new file mode 100755 index 0000000..42831fb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.001.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "not configured" + +setup <<EOF +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.002.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.002.sh new file mode 100755 index 0000000..a808017 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.002.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "configured, interface up" + +setup "10.1.1.201" "eth0" <<EOF +192.168.1.1 +192.168.1.2 +192.168.1.3 +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.003.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.003.sh new file mode 100755 index 0000000..89f443e --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.monitor.003.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "configured, interface up" + +setup "10.1.1.201" "eth0" <<EOF +192.168.1.1 +192.168.1.2 +192.168.1.3 +EOF + +ethtool_interfaces_down "$CTDB_LVS_PUBLIC_IFACE" + +required_result 1 <<EOF +ERROR: No link on the public network interface ${CTDB_LVS_PUBLIC_IFACE} +EOF +simple_test + diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.001.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.001.sh new file mode 100755 index 0000000..42831fb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.001.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "not configured" + +setup <<EOF +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.002.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.002.sh new file mode 100755 index 0000000..61c7f96 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.shutdown.002.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "configured" + +setup "10.1.1.201" "eth0" <<EOF +EOF + +ipvsadm -A -t "$CTDB_LVS_PUBLIC_IP" -s lc -p 1999999 +ipvsadm -A -u "$CTDB_LVS_PUBLIC_IP" -s lc -p 1999999 +ip addr add $CTDB_LVS_PUBLIC_IP/32 dev lo + +ok_null +simple_test + +check_ipvsadm NULL +check_lvs_ip NULL diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.startup.001.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.startup.001.sh new file mode 100755 index 0000000..42831fb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.startup.001.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "not configured" + +setup <<EOF +EOF + +ok_null +simple_test diff --git a/ctdb/tests/UNIT/eventscripts/91.lvs.startup.002.sh b/ctdb/tests/UNIT/eventscripts/91.lvs.startup.002.sh new file mode 100755 index 0000000..e4c5e8d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/91.lvs.startup.002.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "configured" + +setup "10.1.1.201" "eth0" <<EOF +EOF + +ok_null +simple_test + +check_ipvsadm NULL +check_lvs_ip "host" diff --git a/ctdb/tests/UNIT/eventscripts/README b/ctdb/tests/UNIT/eventscripts/README new file mode 100644 index 0000000..304cdba --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/README @@ -0,0 +1,46 @@ +eventscript unit tests +====================== + +This directory contains some eventscript unit tests for CTDB. These +tests can be run as a non-privileged user. There are a lot of stub +implementations of commands (located in stubs/) used to make the +eventscripts think they're running against a real system. + +Test case filenames look like: + + <eventscript>.<event>.NNN.sh + +The test helper functions will run <eventscript> with specified +options. If using the simple_test() helper function then the 1st +<event> argument is automatically passed. When simple_test_event() is +used the event name must be explicitly passed as the 1st argument - +this is more flexible and supports multiple events per test. + +Examples: + +* ../run_tests.sh . + + Run all tests, displaying minimal output. + +* ../run_tests.sh -s . + + Run all tests, displaying minimal output and a summary. + +* ../run_tests.sh -s ./10.interface.*.sh + + Run all the tests against the 10.interface eventscript. + +* ../run_tests.sh -v -s . + + Run all tests, displaying extra output and a summary. + +* ../run_tests.sh -sq . + + Run all tests, displaying only a summary. + +* ../run_tests.sh -X ./10.interface.startup.002.sh + + Run a test and have the eventscript itself run with "sh -x". This + will usually make a test fail because the (undesirable) trace output + will be included with the output of the eventscript. However, this + is useful for finding out why a test might be failing. diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.001.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.001.sh new file mode 100755 index 0000000..8f10200 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.001.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB S+ DB" + +setup + +do_test "DB" "S+" "DB" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.002.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.002.sh new file mode 100755 index 0000000..31ae3df --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.002.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB D. DB" + +setup + +do_test "DB" "D." "DB" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.003.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.003.sh new file mode 100755 index 0000000..89ab2f1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.003.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD S+ DB" + +setup + +do_test "RECORD" "S+" "DB" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.004.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.004.sh new file mode 100755 index 0000000..35500cb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.004.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD D. DB" + +setup + +do_test "RECORD" "D." "DB" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.005.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.005.sh new file mode 100755 index 0000000..10cbade --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.005.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB S+ RECORD" + +setup + +do_test "DB" "S+" "RECORD" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.006.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.006.sh new file mode 100755 index 0000000..c4988b7 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.006.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB D. RECORD" + +setup + +do_test "DB" "D." "RECORD" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.007.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.007.sh new file mode 100755 index 0000000..b186d20 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.007.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD S+ RECORD" + +setup + +do_test "RECORD" "S+" "RECORD" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.008.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.008.sh new file mode 100755 index 0000000..7b7ac9b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.008.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD D. RECORD" + +setup + +do_test "RECORD" "D." "RECORD" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.021.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.021.sh new file mode 100755 index 0000000..f324803 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.021.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB S+ DB MUTEX" + +setup + +do_test "DB" "S+" "DB" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.022.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.022.sh new file mode 100755 index 0000000..0e70771 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.022.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB D. DB MUTEX" + +setup + +do_test "DB" "D." "DB" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.023.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.023.sh new file mode 100755 index 0000000..de84c81 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.023.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD S+ DB MUTEX" + +setup + +do_test "RECORD" "S+" "DB" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.024.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.024.sh new file mode 100755 index 0000000..30ad6bd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.024.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD D. DB MUTEX" + +setup + +do_test "RECORD" "D." "DB" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.025.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.025.sh new file mode 100755 index 0000000..f259db5 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.025.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB S+ RECORD MUTEX" + +setup + +do_test "DB" "S+" "RECORD" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.026.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.026.sh new file mode 100755 index 0000000..9e057af --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.026.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "DB D. RECORD MUTEX" + +setup + +do_test "DB" "D." "RECORD" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.027.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.027.sh new file mode 100755 index 0000000..d70e7b7 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.027.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD S+ RECORD MUTEX" + +setup + +do_test "RECORD" "S+" "RECORD" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/debug_locks.sh.028.sh b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.028.sh new file mode 100755 index 0000000..7199035 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/debug_locks.sh.028.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "RECORD D. RECORD MUTEX" + +setup + +do_test "RECORD" "D." "RECORD" "MUTEX" diff --git a/ctdb/tests/UNIT/eventscripts/etc-ctdb/public_addresses b/ctdb/tests/UNIT/eventscripts/etc-ctdb/public_addresses new file mode 100644 index 0000000..cd2f6be --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc-ctdb/public_addresses @@ -0,0 +1,9 @@ +10.0.0.1/24 dev123 +10.0.0.2/24 dev123 +10.0.0.3/24 dev123 +10.0.0.4/24 dev123 +10.0.0.5/24 dev123 +10.0.0.6/24 dev123 +10.0.1.1/24 dev456 +10.0.1.2/24 dev456 +10.0.1.3/24 dev456 diff --git a/ctdb/tests/UNIT/eventscripts/etc-ctdb/rc.local b/ctdb/tests/UNIT/eventscripts/etc-ctdb/rc.local new file mode 100755 index 0000000..777aeaf --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc-ctdb/rc.local @@ -0,0 +1,56 @@ +# Hey Emacs, this is a -*- shell-script -*- !!! :-) + +# Always use stub version of service command +service () +{ + "${CTDB_HELPER_BINDIR}/service" "$@" +} + +nice_service () +{ + nice "${CTDB_HELPER_BINDIR}/service" "$@" +} + +# Always succeeds +set_proc () { : ; } +set_proc_maybe () { : ; } + +get_proc () +{ + case "$1" in + net/bonding/*) + cat "$FAKE_PROC_NET_BONDING/${1##*/}" + ;; + sys/net/ipv4/conf/all/arp_filter) + echo 1 + ;; + sys/net/ipv4/conf/all/promote_secondaries) + echo 1 + ;; + fs/nfsd/threads) + echo "$FAKE_NFSD_THREAD_PIDS" | wc -w + ;; + */stack) + echo "[<ffffffff87654321>] fake_stack_trace_for_pid_${1}+0x0/0xff" + ;; + meminfo) + echo "$FAKE_PROC_MEMINFO" + ;; + locks) + echo "$FAKE_PROC_LOCKS" + ;; + *) + echo "get_proc: \"$1\" not implemented" + exit 1 + esac +} + +# Do not actually background - we want to see the output +background_with_logging () +{ + "$@" 2>&1 </dev/null | sed -e 's@^@\&@' +} + +if [ -n "$EVENTSCRIPT_TESTS_INIT_STYLE" ]; then + CTDB_INIT_STYLE="$EVENTSCRIPT_TESTS_INIT_STYLE" +fi diff --git a/ctdb/tests/UNIT/eventscripts/etc/init.d/nfs b/ctdb/tests/UNIT/eventscripts/etc/init.d/nfs new file mode 100755 index 0000000..43eb308 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc/init.d/nfs @@ -0,0 +1,7 @@ +#!/bin/sh + +# This is not used. The fake "service" script is used instead. This +# is only needed to shut up functions like startstop_nfs(), which look +# for this script. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/etc/init.d/nfslock b/ctdb/tests/UNIT/eventscripts/etc/init.d/nfslock new file mode 100755 index 0000000..43eb308 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc/init.d/nfslock @@ -0,0 +1,7 @@ +#!/bin/sh + +# This is not used. The fake "service" script is used instead. This +# is only needed to shut up functions like startstop_nfs(), which look +# for this script. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/etc/os-release b/ctdb/tests/UNIT/eventscripts/etc/os-release new file mode 100644 index 0000000..f0057cc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc/os-release @@ -0,0 +1,2 @@ +ID="rocky" +ID_LIKE="rhel centos fedora" diff --git a/ctdb/tests/UNIT/eventscripts/etc/samba/smb.conf b/ctdb/tests/UNIT/eventscripts/etc/samba/smb.conf new file mode 100644 index 0000000..45976cd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc/samba/smb.conf @@ -0,0 +1,43 @@ +[global] + # enable clustering + clustering=yes + ctdb:registry.tdb=yes + + security = ADS + auth methods = guest sam winbind + + netbios name = cluster1 + workgroup = CLUSTER1 + realm = CLUSTER1.COM + server string = "Clustered Samba" + disable netbios = yes + disable spoolss = yes + fileid:mapping = fsname + use mmap = yes + gpfs:sharemodes = yes + gpfs:leases = yes + passdb backend = tdbsam + preferred master = no + kernel oplocks = yes + syslog = 1 + host msdfs = no + notify:inotify = no + vfs objects = shadow_copy2 syncops gpfs fileid + shadow:snapdir = .snapshots + shadow:fixinodes = yes + wide links = no + smbd:backgroundqueue = False + read only = no + use sendfile = yes + strict locking = yes + posix locking = yes + large readwrite = yes + force unknown acl user = yes + nfs4:mode = special + nfs4:chown = yes + nfs4:acedup = merge + nfs4:sidmap = /etc/samba/sidmap.tdb + map readonly = no + ea support = yes + dmapi support = no + smb ports = 445 139 diff --git a/ctdb/tests/UNIT/eventscripts/etc/sysconfig/nfs b/ctdb/tests/UNIT/eventscripts/etc/sysconfig/nfs new file mode 100644 index 0000000..090d786 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/etc/sysconfig/nfs @@ -0,0 +1,2 @@ +NFS_HOSTNAME="cluster1" +STATD_HOSTNAME="$NFS_HOSTNAME -H /etc/ctdb/statd-callout " diff --git a/ctdb/tests/UNIT/eventscripts/scripts/00.ctdb.sh b/ctdb/tests/UNIT/eventscripts/scripts/00.ctdb.sh new file mode 100644 index 0000000..a192e05 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/00.ctdb.sh @@ -0,0 +1,24 @@ +setup() +{ + setup_dbdir + setup_date + + export FAKE_TDBTOOL_SUPPORTS_CHECK="yes" + export FAKE_TDB_IS_OK="yes" + + export FAKE_CTDB_TUNABLES_OK=" + MonitorInterval + DatabaseHashSize + " + export FAKE_CTDB_TUNABLES_OBSOLETE=" + EventScriptUnhealthyOnTimeout + " +} + +result_filter() +{ + _date="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" + _time="[0-9][0-9][0-9][0-9][0-9][0-9]" + _date_time="${_date}\.${_time}" + sed -e "s|\.${_date_time}\.|.DATE.TIME.|" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/01.reclock.sh b/ctdb/tests/UNIT/eventscripts/scripts/01.reclock.sh new file mode 100644 index 0000000..7365dd8 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/01.reclock.sh @@ -0,0 +1,16 @@ +setup() +{ + if [ $# -eq 1 ]; then + reclock="$1" + else + reclock="${CTDB_TEST_TMP_DIR}/reclock_subdir/rec.lock" + fi + CTDB_RECOVERY_LOCK="$reclock" + + if [ -n "$CTDB_RECOVERY_LOCK" ]; then + cat >>"${CTDB_BASE}/ctdb.conf" <<EOF +[cluster] + recovery lock = $CTDB_RECOVERY_LOCK +EOF + fi +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/05.system.sh b/ctdb/tests/UNIT/eventscripts/scripts/05.system.sh new file mode 100644 index 0000000..0191e55 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/05.system.sh @@ -0,0 +1,48 @@ +# shellcheck disable=SC2120 +# Arguments used in testcases +set_mem_usage() +{ + _mem_usage="${1:-10}" # Default is 10% + _swap_usage="${2:-0}" # Default is 0% + + _swap_total=5857276 + _swap_free=$(((100 - _swap_usage) * _swap_total / 100)) + + _mem_total=3940712 + _mem_free=225268 + _mem_buffers=146120 + _mem_cached=$((_mem_total * (100 - _mem_usage) / 100 - \ + _mem_free - _mem_buffers)) + + export FAKE_PROC_MEMINFO="\ +MemTotal: ${_mem_total} kB +MemFree: ${_mem_free} kB +Buffers: ${_mem_buffers} kB +Cached: ${_mem_cached} kB +SwapCached: 56016 kB +Active: 2422104 kB +Inactive: 1019928 kB +Active(anon): 1917580 kB +Inactive(anon): 523080 kB +Active(file): 504524 kB +Inactive(file): 496848 kB +Unevictable: 4844 kB +Mlocked: 4844 kB +SwapTotal: ${_swap_total} kB +SwapFree: ${_swap_free} kB +..." +} + +set_fs_usage() +{ + export FAKE_FS_USE="${1:-10}" # Default is 10% usage +} + +setup() +{ + setup_dbdir + + # Tests use default unless explicitly set + set_mem_usage + set_fs_usage +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/06.nfs.sh b/ctdb/tests/UNIT/eventscripts/scripts/06.nfs.sh new file mode 100644 index 0000000..5912a4b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/06.nfs.sh @@ -0,0 +1,4 @@ +setup() +{ + : +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/10.interface.sh b/ctdb/tests/UNIT/eventscripts/scripts/10.interface.sh new file mode 100644 index 0000000..579f3ee --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/10.interface.sh @@ -0,0 +1,72 @@ +setup() +{ + setup_public_addresses +} + +_tcp_connections() +{ + _count="$1" + _sip="$2" + _sport="$3" + _cip_base="$4" + _cport_base="$5" + + _cip_prefix="${_cip_base%.*}" + _cip_suffix="${_cip_base##*.}" + + for _i in $(seq 1 "$_count"); do + _cip_last=$((_cip_suffix + _i)) + _cip="${_cip_prefix}.${_cip_last}" + _cport=$((_cport_base + _i)) + echo "${_sip}:${_sport} ${_cip}:${_cport}" + done +} + +setup_tcp_connections() +{ + _t="${FAKE_NETWORK_STATE}/tcp-established" + export FAKE_NETSTAT_TCP_ESTABLISHED_FILE="$_t" + _tcp_connections "$@" >"$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" +} + +setup_tcp_connections_unkillable() +{ + # These connections are listed by the "ss" stub but are not + # killed by the "ctdb killtcp" stub. So killing these + # connections will never succeed... and will look like a time + # out. + _t=$(_tcp_connections "$@" | sed -e 's/ /|/g') + export FAKE_NETSTAT_TCP_ESTABLISHED="$_t" +} + +# Setup some fake /proc/net/bonding files with just enough info for +# the eventscripts. + +# arg1 is interface name, arg2 is currently active slave (use "None" +# if none), arg3 is MII status ("up" or "down"). +setup_bond() +{ + _iface="$1" + _slave="${2:-${_iface}_sl_0}" + _mii_s="${3:-up}" + _mii_subs="${4:-${_mii_s:-up}}" + + cat <<EOF +Setting $_iface to be a bond with active slave $_slave and MII status $_mii_s +EOF + + _t="${FAKE_NETWORK_STATE}/proc-net-bonding" + export FAKE_PROC_NET_BONDING="$_t" + mkdir -p "$FAKE_PROC_NET_BONDING" + + cat >"${FAKE_PROC_NET_BONDING}/$_iface" <<EOF +Bonding Mode: IEEE 802.3ad Dynamic link aggregation +Currently Active Slave: $_slave +# Status of the bond +MII Status: $_mii_s +# Status of 1st pretend adapter +MII Status: $_mii_subs +# Status of 2nd pretend adapter +MII Status: $_mii_subs +EOF +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/11.natgw.sh b/ctdb/tests/UNIT/eventscripts/scripts/11.natgw.sh new file mode 100644 index 0000000..3b19895 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/11.natgw.sh @@ -0,0 +1,120 @@ +setup() +{ + debug "Setting up NAT gateway" + + natgw_nodes="${CTDB_BASE}/natgw_nodes" + + ctdb_set_pnn +} + +# A separate function for this makes sense because it can be done +# multiple times per test +setup_ctdb_natgw() +{ + # Read from stdin + while read -r _ip _opts; do + case "$_opts" in + leader) + export FAKE_CTDB_NATGW_LEADER="$_ip" + echo "$_ip" + ;; + follower-only) + printf "%s\tfollower-only\n" "$_ip" + ;; + *) + echo "$_ip" + ;; + esac + done >"$natgw_nodes" + + # Assume all of the nodes are on a /24 network and have IPv4 + # addresses: + read -r _ip <"$natgw_nodes" + + setup_script_options <<EOF +CTDB_NATGW_NODES="$natgw_nodes" +CTDB_NATGW_PRIVATE_NETWORK="${_ip%.*}.0/24" +# These are fixed. Probably don't use the same network for the +# private node IPs. To unset the default gateway just set it to +# "". :-) +CTDB_NATGW_PUBLIC_IP="10.1.1.121/24" +CTDB_NATGW_PUBLIC_IFACE="eth1" +CTDB_NATGW_DEFAULT_GATEWAY="10.1.1.254" +EOF +} + +ok_natgw_leader_ip_addr_show() +{ + _mac=$(echo "$CTDB_NATGW_PUBLIC_IFACE" | + cksum | + sed -r -e 's@(..)(..)(..).*@fe:fe:fe:\1:\2:\3@') + + # This is based on CTDB_NATGW_PUBLIC_IP + _brd="10.1.1.255" + + ok <<EOF +1: ${CTDB_NATGW_PUBLIC_IFACE}: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 + link/ether ${_mac} brd ff:ff:ff:ff:ff:ff + inet ${CTDB_NATGW_PUBLIC_IP} brd ${_brd} scope global ${CTDB_NATGW_PUBLIC_IFACE} + valid_lft forever preferred_lft forever +EOF +} + +ok_natgw_follower_ip_addr_show() +{ + _mac=$(echo "$CTDB_NATGW_PUBLIC_IFACE" | + cksum | + sed -r -e 's@(..)(..)(..).*@fe:fe:fe:\1:\2:\3@') + + ok <<EOF +1: ${CTDB_NATGW_PUBLIC_IFACE}: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 + link/ether ${_mac} brd ff:ff:ff:ff:ff:ff +EOF +} + +ok_natgw_leader_static_routes() +{ + _nl=" +" + _t="" + for _i in $CTDB_NATGW_STATIC_ROUTES; do + # This is intentionally different to the code in 11.natgw ;-) + case "$_i" in + *@*) + _net=$(echo "$_i" | sed -e 's|@.*||') + _gw=$(echo "$_i" | sed -e 's|.*@||') + ;; + *) + _net="$_i" + _gw="$CTDB_NATGW_DEFAULT_GATEWAY" + ;; + esac + + [ -n "$_gw" ] || continue + _t="${_t}${_t:+${_nl}}" + _t="${_t}${_net} via ${_gw} dev ethXXX metric 10 " + done + _t=$(echo "$_t" | sort) + ok "$_t" +} + +ok_natgw_follower_static_routes() +{ + _nl=" +" + _t="" + for _i in $CTDB_NATGW_STATIC_ROUTES; do + # This is intentionally different to the code in 11.natgw ;-) + _net=$(echo "$_i" | sed -e 's|@.*||') + + # The interface for the private network isn't + # specified as part of the NATGW configuration and + # isn't part of the command to add the route. It is + # implicitly added by "ip route" but our stub doesn't + # do this and adds "ethXXX". + _t="${_t}${_t:+${_nl}}" + _t="${_t}${_net} via ${FAKE_CTDB_NATGW_LEADER} dev ethXXX metric 10 " + done + _t=$(echo "$_t" | sort) + ok "$_t" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/13.per_ip_routing.sh b/ctdb/tests/UNIT/eventscripts/scripts/13.per_ip_routing.sh new file mode 100644 index 0000000..aac2c3d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/13.per_ip_routing.sh @@ -0,0 +1,47 @@ +setup() +{ + setup_public_addresses + + # shellcheck disable=SC2034 + # Used in expected output + service_name="per_ip_routing" + + setup_script_options <<EOF +CTDB_PER_IP_ROUTING_CONF="${CTDB_BASE}/policy_routing" +CTDB_PER_IP_ROUTING_RULE_PREF=100 +CTDB_PER_IP_ROUTING_TABLE_ID_LOW=1000 +CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=2000 +EOF + + # Tests need to create and populate this file + rm -f "$CTDB_PER_IP_ROUTING_CONF" +} + +# Create policy routing configuration in $CTDB_PER_IP_ROUTING_CONF. +# $1 is the number of assigned IPs to use (<num>, all), defaulting to +# 1. If $2 is "default" then a default route is also added. +create_policy_routing_config() +{ + _num_ips="${1:-1}" + _should_add_default="$2" + + ctdb_get_my_public_addresses | + if [ "$_num_ips" = "all" ]; then + cat + else + { + head -n "$_num_ips" + cat >/dev/null + } + fi | + while read -r _dev _ip _bits; do + _net=$(ipv4_host_addr_to_net "$_ip" "$_bits") + _gw="${_net%.*}.254" # a dumb, calculated default + + echo "$_ip $_net" + + if [ "$_should_add_default" = "default" ]; then + echo "$_ip 0.0.0.0/0 $_gw" + fi + done >"$CTDB_PER_IP_ROUTING_CONF" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/20.multipathd.sh b/ctdb/tests/UNIT/eventscripts/scripts/20.multipathd.sh new file mode 100644 index 0000000..9add0bc --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/20.multipathd.sh @@ -0,0 +1,25 @@ +setup() +{ + _failures="" + _devices="" + for i; do + case "$i" in + \!*) + _t="${i#!}" + echo "Marking ${_t} as having no active paths" + _failures="${_failures}${_failures:+ }${_t}" + ;; + *) + _t="$i" + ;; + esac + _devices="${_devices}${_devices:+ }${_t}" + done + + setup_script_options <<EOF +CTDB_MONITOR_MPDEVICES="$_devices" +EOF + + export FAKE_MULTIPATH_FAILURES="$_failures" + export FAKE_SLEEP_FORCE=0.1 +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/31.clamd.sh b/ctdb/tests/UNIT/eventscripts/scripts/31.clamd.sh new file mode 100644 index 0000000..27016cb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/31.clamd.sh @@ -0,0 +1,8 @@ +setup() +{ + setup_script_options <<EOF +CTDB_CLAMD_SOCKET="/var/run/clamd.sock" +EOF + + setup_unix_listen +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/40.vsftpd.sh b/ctdb/tests/UNIT/eventscripts/scripts/40.vsftpd.sh new file mode 100644 index 0000000..236d130 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/40.vsftpd.sh @@ -0,0 +1,14 @@ +setup() +{ + debug "Setting up VSFTPD environment: service $1, not managed by CTDB" + + _service_name="vsftpd" + + if [ "$1" != "down" ]; then + service "$_service_name" start + setup_tcp_listen 21 + else + service "$_service_name" force-stopped + setup_tcp_listen "" + fi +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/41.httpd.sh b/ctdb/tests/UNIT/eventscripts/scripts/41.httpd.sh new file mode 100644 index 0000000..3fac4f0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/41.httpd.sh @@ -0,0 +1,14 @@ +setup() +{ + debug "Setting up HTTPD environment: service $1, not managed by CTDB" + + if [ "$1" != "down" ]; then + for _service_name in "apache2" "httpd"; do + service "$_service_name" start + done + else + for _service_name in "apache2" "httpd"; do + service "$_service_name" force-stopped + done + fi +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/48.netbios.sh b/ctdb/tests/UNIT/eventscripts/scripts/48.netbios.sh new file mode 100644 index 0000000..6efcd8a --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/48.netbios.sh @@ -0,0 +1,23 @@ +setup() +{ + # shellcheck disable=SC2034 + # Used in expected output + service_name="netbios" + + if [ "$1" != "down" ]; then + + debug "Marking Netbios name services as up, listening and managed by CTDB" + + # All possible service names for all known distros. + for i in "nmb" "nmbd"; do + service "$i" force-started + done + else + debug "Marking Netbios name services as down, not listening and not managed by CTDB" + + # All possible service names for all known distros. + for i in "nmb" "nmbd"; do + service "$i" force-stopped + done + fi +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/49.winbind.sh b/ctdb/tests/UNIT/eventscripts/scripts/49.winbind.sh new file mode 100644 index 0000000..bbe1de2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/49.winbind.sh @@ -0,0 +1,28 @@ +setup() +{ + # shellcheck disable=SC2034 + # Used in expected output + service_name="winbind" + + if [ "$1" != "down" ]; then + + debug "Marking Winbind service as up and managed by CTDB" + + service "winbind" force-started + + export FAKE_WBINFO_FAIL="no" + + else + debug "Marking Winbind service as down and not managed by CTDB" + + service "winbind" force-stopped + + export FAKE_WBINFO_FAIL="yes" + fi +} + +wbinfo_down() +{ + debug "Making wbinfo commands fail" + FAKE_WBINFO_FAIL="yes" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/50.samba.sh b/ctdb/tests/UNIT/eventscripts/scripts/50.samba.sh new file mode 100644 index 0000000..88af69b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/50.samba.sh @@ -0,0 +1,58 @@ +setup() +{ + # shellcheck disable=SC2034 + # Used in expected output + service_name="samba" + + if [ "$1" != "down" ]; then + + debug "Marking Samba services as up, listening and managed by CTDB" + + # All possible service names for all known distros. + for i in "smb" "samba" "smbd"; do + service "$i" force-started + done + + setup_tcp_listen 445 139 + + # Some things in 50.samba are backgrounded and waited + # for. If we don't sleep at all then timeouts can + # happen. This avoids that... :-) + export FAKE_SLEEP_FORCE=0.1 + else + debug "Marking Samba services as down, not listening and not managed by CTDB" + + # All possible service names for all known distros. + for i in "smb" "samba" "smbd"; do + service "$i" force-stopped + done + + setup_tcp_listen + fi + + setup_script_options <<EOF +CTDB_SAMBA_SKIP_SHARE_CHECK="no" +EOF + + setup_shares + +} + +samba_setup_fake_threads() +{ + export FAKE_SMBD_THREAD_PIDS="$*" + + _nl=" +" + _out="" + _count=0 + for _pid; do + [ "$_count" -lt 5 ] || break + _t=$(program_stack_trace "smbd" "$_pid") + _out="${_out:+${_out}${_nl}}${_t}" + _count=$((_count + 1)) + done + # shellcheck disable=SC2034 + # Used in expected output + SAMBA_STACK_TRACES="$_out" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/60.nfs.sh b/ctdb/tests/UNIT/eventscripts/scripts/60.nfs.sh new file mode 100644 index 0000000..9c614c7 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/60.nfs.sh @@ -0,0 +1,435 @@ +setup() +{ + setup_public_addresses + setup_shares + + # shellcheck disable=SC2034 + # Used in expected output + service_name="nfs" + + if [ -z "$CTDB_NFS_DISTRO_STYLE" ]; then + # Currently supported: sysvinit-redhat, systemd-redhat + CTDB_NFS_DISTRO_STYLE="systemd-redhat" + fi + + export FAKE_RPCINFO_SERVICES="" + + setup_script_options <<EOF +CTDB_NFS_SKIP_SHARE_CHECK="no" +# This doesn't even need to exist +CTDB_NFS_EXPORTS_FILE="${CTDB_TEST_TMP_DIR}/etc-exports" +EOF + + export RPCNFSDCOUNT + + if [ "$1" != "down" ]; then + debug <<EOF +Setting up NFS environment: all RPC services up, NFS managed by CTDB +EOF + + case "$CTDB_NFS_DISTRO_STYLE" in + sysvinit-*) + service "nfs" force-started + service "nfslock" force-started + ;; + systemd-*) + service "nfs-service" force-started + service "nfs-mountd" force-started + service "rpc-rquotad" force-started + service "rpc-statd" force-started + ;; + esac + + rpc_services_up \ + "portmapper" "nfs" "mountd" "rquotad" \ + "nlockmgr" "status" + + nfs_setup_fake_threads "nfsd" + nfs_setup_fake_threads "rpc.foobar" # Set the variable to empty + else + debug <<EOF +Setting up NFS environment: all RPC services down, NFS not managed by CTDB +EOF + + case "$CTDB_NFS_DISTRO_STYLE" in + sysvinit-*) + service "nfs" force-stopped + service "nfslock" force-stopped + service "nfs-kernel-server" force-stopped + ;; + systemd-*) + service "nfs-server" force-stopped + service "nfs-mountd" force-stopped + service "rpc-quotad" force-stopped + service "rpc-statd" force-stopped + ;; + esac + fi + + # This is really nasty. However, when we test NFS we don't + # actually test statd-callout. If we leave it there then left + # over, backgrounded instances of statd-callout will do + # horrible things with the "ctdb ip" stub and cause the actual + # statd-callout tests that follow to fail. + rm "${CTDB_BASE}/statd-callout" +} + +rpc_services_down() +{ + _out="" + for _s in $FAKE_RPCINFO_SERVICES; do + for _i; do + if [ "$_i" = "${_s%%:*}" ]; then + debug "Marking RPC service \"${_i}\" as UNAVAILABLE" + continue 2 + fi + done + _out="${_out}${_out:+ }${_s}" + done + FAKE_RPCINFO_SERVICES="$_out" +} + +rpc_services_up() +{ + _out="$FAKE_RPCINFO_SERVICES" + for _i; do + debug "Marking RPC service \"${_i}\" as available" + case "$_i" in + portmapper) _t="2:4" ;; + nfs) _t="2:3" ;; + mountd) _t="1:3" ;; + rquotad) _t="1:2" ;; + nlockmgr) _t="3:4" ;; + status) _t="1:1" ;; + *) die "Internal error - unsupported RPC service \"${_i}\"" ;; + esac + + _out="${_out}${_out:+ }${_i}:${_t}" + done + export FAKE_RPCINFO_SERVICES="$_out" +} + +nfs_setup_fake_threads() +{ + _prog="$1" + shift + + case "$_prog" in + nfsd) + export PROCFS_PATH="${CTDB_TEST_TMP_DIR}/proc" + _threads="${PROCFS_PATH}/fs/nfsd/threads" + mkdir -p "$(dirname "$_threads")" + echo $# >"$_threads" + export FAKE_NFSD_THREAD_PIDS="$*" + ;; + *) + export FAKE_RPC_THREAD_PIDS="$*" + ;; + esac +} + +guess_output() +{ + case "$1" in + "${CTDB_NFS_CALLOUT} start nlockmgr") + case "$CTDB_NFS_DISTRO_STYLE" in + sysvinit-redhat) + echo "&Starting nfslock: OK" + ;; + sysvinit-debian) + cat <<EOF +&Starting nfs-kernel-server: OK +EOF + ;; + systemd-*) + echo "&Starting rpc-statd: OK" + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} start nfs") + case "$CTDB_NFS_DISTRO_STYLE" in + sysvinit-redhat) + cat <<EOF +&Starting nfslock: OK +&Starting nfs: OK +EOF + ;; + sysvinit-debian) + cat <<EOF +&Starting nfs-kernel-server: OK +EOF + ;; + systemd-redhat) + cat <<EOF +&Starting rpc-statd: OK +&Starting nfs-server: OK +&Starting rpc-rquotad: OK +EOF + ;; + systemd-debian) + cat <<EOF +&Starting rpc-statd: OK +&Starting nfs-server: OK +&Starting quotarpc: OK +EOF + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} stop mountd") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-*) + echo "Stopping nfs-mountd: OK" + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} stop rquotad") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-redhat) + echo "Stopping rpc-rquotad: OK" + ;; + systemd-debian) + if service "quotarpc" status >/dev/null; then + echo "Stopping quotarpc: OK" + else + echo "service: can't stop quotarpc - not running" + fi + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} stop status") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-*) + echo "Stopping rpc-statd: OK" + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} start mountd") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-*) + echo "&Starting nfs-mountd: OK" + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} start rquotad") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-redhat) + echo "&Starting rpc-rquotad: OK" + ;; + systemd-debian) + echo "&Starting quotarpc: OK" + ;; + esac + ;; + "${CTDB_NFS_CALLOUT} start status") + case "$CTDB_NFS_DISTRO_STYLE" in + systemd-*) + echo "&Starting rpc-statd: OK" + ;; + esac + ;; + *) + : # Nothing + ;; + esac +} + +# Set the required result for a particular RPC program having failed +# for a certain number of iterations. This is probably still a work +# in progress. Note that we could hook aggressively +# nfs_check_rpc_service() to try to implement this but we're better +# off testing nfs_check_rpc_service() using independent code... even +# if it is incomplete and hacky. So, if the 60.nfs eventscript +# changes and the tests start to fail then it may be due to this +# function being incomplete. +rpc_set_service_failure_response() +{ + _rpc_service="$1" + _numfails="${2:-1}" # default 1 + + # Default + ok_null + if [ "$_numfails" -eq 0 ]; then + return + fi + + nfs_load_config + + # A handy newline. :-) + _nl=" +" + + _dir="${CTDB_NFS_CHECKS_DIR:-${CTDB_BASE}/nfs-checks.d}" + + _file=$(ls "$_dir"/[0-9][0-9]."${_rpc_service}.check") + [ -r "$_file" ] || + die "RPC check file \"$_file\" does not exist or is not unique" + + _out="${CTDB_TEST_TMP_DIR}/rpc_failure_output" + : >"$_out" + _rc_file="${CTDB_TEST_TMP_DIR}/rpc_result" + + ( + # Subshell to restrict scope variables... + + # Defaults + # shellcheck disable=SC2034 + # Unused, but for completeness, possible future use + family="tcp" + version="" + unhealthy_after=1 + restart_every=0 + service_stop_cmd="" + service_start_cmd="" + # shellcheck disable=SC2034 + # Unused, but for completeness, possible future use + service_check_cmd="" + service_debug_cmd="" + + # Don't bother syntax checking, eventscript does that... + . "$_file" + + # Just use the first version, or use default. This is + # dumb but handles all the cases that we care about + # now... + if [ -n "$version" ]; then + _ver="${version%% *}" + else + case "$_rpc_service" in + portmapper) _ver="" ;; + *) _ver=1 ;; + esac + fi + _rpc_check_out="\ +$_rpc_service failed RPC check: +rpcinfo: RPC: Program not registered +program $_rpc_service${_ver:+ version }${_ver} is not available" + + if [ $unhealthy_after -gt 0 ] && + [ "$_numfails" -ge $unhealthy_after ]; then + _unhealthy=true + echo 1 >"$_rc_file" + echo "ERROR: ${_rpc_check_out}" >>"$_out" + else + _unhealthy=false + echo 0 >"$_rc_file" + fi + + if [ $restart_every -gt 0 ] && + [ $((_numfails % restart_every)) -eq 0 ]; then + if ! $_unhealthy; then + echo "WARNING: ${_rpc_check_out}" >>"$_out" + fi + + echo "Trying to restart service \"${_rpc_service}\"..." \ + >>"$_out" + + guess_output "$service_stop_cmd" >>"$_out" + + if [ -n "$service_debug_cmd" ]; then + $service_debug_cmd >>"$_out" 2>&1 + fi + + guess_output "$service_start_cmd" >>"$_out" + fi + ) + + read -r _rc <"$_rc_file" + required_result "$_rc" <"$_out" + + rm -f "$_out" "$_rc_file" +} + +program_stack_traces() +{ + _prog="$1" + _max="${2:-1}" + + _count=1 + if [ "$_prog" = "nfsd" ]; then + _pids="$FAKE_NFSD_THREAD_PIDS" + else + _pids="$FAKE_RPC_THREAD_PIDS" + fi + for _pid in $_pids; do + [ $_count -le "$_max" ] || break + + program_stack_trace "$_prog" "$_pid" + _count=$((_count + 1)) + done +} + +# Run an NFS eventscript iteratively. +# +# - 1st argument is the number of iterations. +# +# - 2nd argument is the NFS/RPC service being tested +# +# rpcinfo is used on each iteration to test the availability of the +# service +# +# If this is not set or null then no RPC service is checked and the +# required output is not reset on each iteration. This is useful in +# baseline tests to confirm that the eventscript and test +# infrastructure is working correctly. +# +# - Subsequent arguments come in pairs: an iteration number and +# something to eval before that iteration. Each time an iteration +# number is matched the associated argument is given to eval after +# the default setup is done. The iteration numbers need to be given +# in ascending order. +# +# These arguments can allow a service to be started or stopped +# before a particular iteration. +# +nfs_iterate_test() +{ + _repeats="$1" + _rpc_service="$2" + if [ -n "$2" ]; then + shift 2 + else + shift + fi + + # shellcheck disable=SC2154 + # Variables defined in define_test() + echo "Running $_repeats iterations of \"$script $event\" $args" + + _iterate_failcount=0 + for _iteration in $(seq 1 "$_repeats"); do + # This is not a numerical comparison because $1 will + # often not be set. + if [ "$_iteration" = "$1" ]; then + debug <<EOF +################################################## +EOF + eval "$2" + debug <<EOF +################################################## +EOF + shift 2 + fi + if [ -n "$_rpc_service" ]; then + if rpcinfo -T tcp localhost "$_rpc_service" \ + >/dev/null 2>&1 ; then + _iterate_failcount=0 + else + _iterate_failcount=$((_iterate_failcount + 1)) + fi + rpc_set_service_failure_response \ + "$_rpc_service" $_iterate_failcount + fi + _out=$(simple_test 2>&1) + _ret=$? + if "$CTDB_TEST_VERBOSE" || [ $_ret -ne 0 ]; then + cat <<EOF +################################################## +Iteration ${_iteration}: +$_out +EOF + fi + if [ $_ret -ne 0 ]; then + exit $_ret + fi + done +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/91.lvs.sh b/ctdb/tests/UNIT/eventscripts/scripts/91.lvs.sh new file mode 100644 index 0000000..1e307c5 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/91.lvs.sh @@ -0,0 +1,76 @@ +setup() +{ + _ip="$1" + _iface="$2" + + export FAKE_LVS_STATE_DIR="${FAKE_NETWORK_STATE}/lvs" + mkdir -p "$FAKE_LVS_STATE_DIR" + + lvs_header=$(ipvsadm -l -n) + + [ -n "$_ip" ] || return 0 + [ -n "$_iface" ] || return 0 + + setup_script_options <<EOF +CTDB_LVS_NODES="${CTDB_BASE}/lvs_nodes" +CTDB_LVS_PUBLIC_IP="$_ip" +CTDB_LVS_PUBLIC_IFACE="$_iface" +EOF + + export FAKE_CTDB_LVS_LEADER="" + + # Read from stdin + _pnn=0 + while read -r _ip _opts; do + case "$_opts" in + leader) + FAKE_CTDB_LVS_LEADER="$_pnn" + echo "$_ip" + ;; + follower-only) + printf "%s\tfollower-only\n" "$_ip" + ;; + *) + echo "$_ip" + ;; + esac + _pnn=$((_pnn + 1)) + done >"$CTDB_LVS_NODES" +} + +check_ipvsadm() +{ + if [ "$1" = "NULL" ]; then + required_result 0 <<EOF +$lvs_header +EOF + else + required_result 0 <<EOF +$lvs_header +$(cat) +EOF + fi + + simple_test_command ipvsadm -l -n +} + +check_lvs_ip() +{ + _scope="$1" + + if [ "$_scope" = "NULL" ]; then + required_result 0 <<EOF +1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 +EOF + else + required_result 0 <<EOF +1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet ${CTDB_LVS_PUBLIC_IP}/32 scope ${_scope} lo + valid_lft forever preferred_lft forever +EOF + fi + + simple_test_command ip addr show dev lo +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/debug_locks.sh b/ctdb/tests/UNIT/eventscripts/scripts/debug_locks.sh new file mode 100644 index 0000000..b0cd039 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/debug_locks.sh @@ -0,0 +1,272 @@ +setup() +{ + setup_dbdir +} + +result_filter() +{ + sed -e 's|\( of debug locks PID=\)[0-9]*|\1PID|' +} + +tdb_path() +{ + echo "${CTDB_DBDIR}/${1}.${FAKE_CTDB_PNN}" +} + +fake_file_id() +{ + _path="$1" + + echo "$FAKE_FILE_ID_MAP" | + awk -v path="$_path" '$1 == path { print $2 }' +} + +fake_stack_trace() +{ + _pid="$1" + _command="${2:-smbd}" + _state="$3" + + echo "----- Stack trace for PID=${_pid} -----" + + case "$_state" in + D*) + cat <<EOF +----- Process in D state, printing kernel stack only +[<ffffffff87654321>] fake_stack_trace_for_pid_${_pid}/stack+0x0/0xff +EOF + ;; + *) + cat <<EOF +Thread 1 (Thread 0x7f688fbfb180 (LWP ${_pid}) "${_command}"): +#0 0x00007f688ff7a076 in open (FAKE ARGS...) at FAKE PLACE +.... +#3 0x000055cd368ead72 in main (argc=<optimized out>, argv=<optimized out>) at ${_command}.c +EOF + ;; + esac +} + +do_test() +{ + _holder_scope="$1" + _holder_state="$2" + _helper_scope="$3" + _lock_type="${4:-FCNTL}" + + _lock_helper_pid="4132032" + + FAKE_PS_MAP=$( + cat <<EOF +1234567 ctdbd S +2345678 smbd S +4131931 smbd ${_holder_state} +${_lock_helper_pid} ctdb_lock_helpe S+ +EOF + ) + export FAKE_PS_MAP + + FAKE_FILE_ID_MAP="" + _tdbs="locking.tdb brlock.tdb test.tdb foo.tdb" + _n=1 + for _t in $_tdbs; do + _path=$(tdb_path "$_t") + _inode=$((19690818 + _n)) + FAKE_FILE_ID_MAP=$( + cat <<EOF +${FAKE_FILE_ID_MAP} +${_path} 103:04:${_inode} +EOF + ) + rm -f "$_path" + touch "$_path" + _n=$((_n + 1)) + done + export FAKE_FILE_ID_MAP + + _path=$(tdb_path "locking.tdb") + _locking_tdb_id=$(fake_file_id "$_path") + + _t=$( + cat <<EOF +POSIX ADVISORY WRITE 3769740 103:04:24380821 1073741826 1073742335 +FLOCK ADVISORY WRITE 3632524 103:02:1059266 0 EOF +FLOCK ADVISORY WRITE 4060231 00:17:17184 0 EOF +POSIX ADVISORY READ 1234567 ${_locking_tdb_id} 4 4 +POSIX ADVISORY WRITE 59178 103:04:24380821 1073741826 1073742335 +POSIX ADVISORY READ 4427 103:04:22152234 1073741826 1073742335 +POSIX ADVISORY WRITE 4427 103:04:22152494 0 EOF +POSIX ADVISORY READ 4427 103:04:22152702 1073741826 1073742335 +EOF + ) + + _holder_lock="" + if [ "$_holder_scope" = "DB" ]; then + if [ "$_lock_type" = "FCNTL" ]; then + _holder_lock=$( + cat <<EOF +POSIX ADVISORY WRITE 4131931 ${_locking_tdb_id} 168 EOF +EOF + ) + elif [ "$_lock_type" = "MUTEX" ]; then + _holder_lock=$( + cat <<EOF +POSIX ADVISORY WRITE 4131931 ${_locking_tdb_id} 400172 EOF +EOF + ) + fi + elif [ "$_holder_scope" = "RECORD" ] && + [ "$_lock_type" = "FCNTL" ]; then + _holder_lock=$( + cat <<EOF +POSIX ADVISORY WRITE 2345678 ${_locking_tdb_id} 112736 112736 +POSIX ADVISORY WRITE 4131931 ${_locking_tdb_id} 225472 225472 +EOF + ) + fi + + _t=$( + cat <<EOF +$_t +$_holder_lock +EOF + ) + + _helper_lock="" + if [ "$_helper_scope" = "DB" ] && + [ "$_lock_type" = "FCNTL" ]; then + _helper_lock=$( + cat <<EOF +-> POSIX ADVISORY WRITE ${_lock_helper_pid} ${_locking_tdb_id} 168 170 +EOF + ) + elif [ "$_helper_scope" = "RECORD" ] && + [ "$_lock_type" = "FCNTL" ]; then + _helper_lock=$( + cat <<EOF +-> POSIX ADVISORY WRITE ${_lock_helper_pid} ${_locking_tdb_id} 112736 112736 +EOF + ) + fi + _t=$( + cat <<EOF +$_t +$_helper_lock +EOF + ) + + if [ "$_holder_scope" = "DB" ]; then + _t=$( + cat <<EOF +$_t +POSIX ADVISORY READ 4131931 ${_locking_tdb_id} 4 4 +EOF + ) + elif [ "$_holder_scope" = "RECORD" ] && + [ "$_lock_type" = "FCNTL" ]; then + _t=$( + cat <<EOF +$_t +POSIX ADVISORY READ 2345678 ${_locking_tdb_id} 4 4 +POSIX ADVISORY READ 4131931 ${_locking_tdb_id} 4 4 +EOF + ) + fi + + _t=$( + cat <<EOF +$_t +POSIX ADVISORY READ 3769740 103:04:24390149 1073741826 1073742335 +POSIX ADVISORY WRITE 3769740 103:04:24380839 1073741826 1073742335 +FLOCK ADVISORY WRITE 3769302 103:02:1180313 0 EOF +FLOCK ADVISORY WRITE 3769302 103:02:1177487 0 EOF +FLOCK ADVISORY WRITE 3769302 103:02:1180308 0 EOF +OFDLCK ADVISORY READ -1 00:05:6 0 EOF +EOF + ) + + FAKE_PROC_LOCKS=$(echo "$_t" | awk '{ printf "%d: %s\n", NR, $0 }') + export FAKE_PROC_LOCKS + + _holder_mutex_lock="" + if [ "$_lock_type" = "MUTEX" ]; then + if [ "$_holder_scope" = "RECORD" ]; then + _holder_mutex_lock=$( + cat <<EOF +2345678 28142 +4131931 56284 +EOF + ) + fi + fi + + FAKE_TDB_MUTEX_CHECK="$_holder_mutex_lock" + export FAKE_TDB_MUTEX_CHECK + + _out='' + _nl=' +' + _db="locking.tdb.${FAKE_CTDB_PNN}" + + if [ -n "$_helper_lock" ]; then + read -r _ _ _ _ _pid _ _start _end <<EOF +$_helper_lock +EOF + _out="Waiter:${_nl}" + _out="${_out}${_pid} ctdb_lock_helpe ${_db} ${_start} ${_end}" + fi + + # fake lock info + _pids='' + _out="${_out:+${_out}${_nl}}Lock holders:" + if [ -n "$_holder_mutex_lock" ]; then + while read -r _pid _chain; do + _comm="smbd" + _out="${_out}${_nl}" + _out="${_out}${_pid} smbd ${_db} ${_chain}" + _pids="${_pids:+${_pids} }${_pid}" + done <<EOF +$_holder_mutex_lock +EOF + else + while read -r _ _ _ _pid _ _start _end; do + _comm="smbd" + _out="${_out}${_nl}" + _out="${_out}${_pid} smbd ${_db} ${_start} ${_end}" + _pids="${_pids:+${_pids} }${_pid}" + done <<EOF +$_holder_lock +EOF + fi + + # fake stack traces + for _pid in $_pids; do + _comm="smbd" + if [ "$_pid" = "4131931" ]; then + _state="$_holder_state" + else + _state="S" + fi + _out=$( + cat <<EOF +$_out +$(fake_stack_trace "$_pid" "$_comm" "$_state") +EOF + ) + done + + ok <<EOF +===== Start of debug locks PID=PID ===== +$_out +===== End of debug locks PID=PID ===== +EOF + + # shellcheck disable=SC2154 + # script_dir and script set in define_test() + script_test "${script_dir}/${script}" \ + "$_lock_helper_pid" \ + "$_helper_scope" \ + "$_path" \ + "$_lock_type" + +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/local.sh b/ctdb/tests/UNIT/eventscripts/scripts/local.sh new file mode 100644 index 0000000..3c28181 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/local.sh @@ -0,0 +1,568 @@ +# Hey Emacs, this is a -*- shell-script -*- !!! :-) + +# +# Augment PATH with relevant stubs/ directories. +# + +stubs_dir="${CTDB_TEST_SUITE_DIR}/stubs" +[ -d "${stubs_dir}" ] || die "Failed to locate stubs/ subdirectory" + +# Make the path absolute for tests that change directory +case "$stubs_dir" in +/*) : ;; +*) stubs_dir="${PWD}/${stubs_dir}" ;; +esac + +# Use stubs as helpers +export CTDB_HELPER_BINDIR="$stubs_dir" + +PATH="${stubs_dir}:${PATH}" + +export CTDB="ctdb" + +# Force this to be absolute - event scripts can change directory +CTDB_TEST_TMP_DIR=$(cd "$CTDB_TEST_TMP_DIR" && echo "$PWD") + +export CTDB_LOGGING="file:" + +if [ -d "${CTDB_TEST_SUITE_DIR}/etc" ]; then + cp -a "${CTDB_TEST_SUITE_DIR}/etc" "$CTDB_TEST_TMP_DIR" + export CTDB_SYS_ETCDIR="${CTDB_TEST_TMP_DIR}/etc" +else + die "Unable to setup \$CTDB_SYS_ETCDIR" +fi + +setup_ctdb_base "$CTDB_TEST_TMP_DIR" "etc-ctdb" \ + debug_locks.sh \ + functions \ + nfs-checks.d \ + nfs-linux-kernel-callout \ + statd-callout + +export FAKE_CTDB_STATE="${CTDB_TEST_TMP_DIR}/fake-ctdb" +mkdir -p "$FAKE_CTDB_STATE" + +export FAKE_NETWORK_STATE="${CTDB_TEST_TMP_DIR}/fake-network-state" +mkdir -p "$FAKE_NETWORK_STATE" + +###################################################################### + +if "$CTDB_TEST_VERBOSE"; then + debug() + { + if [ -n "$1" ]; then + echo "$@" >&2 + else + cat >&2 + fi + } +else + debug() + { + : + } +fi + +###################################################################### + +# General setup fakery + +# Default is to use script name with ".options" appended. With +# arguments, this can specify an alternate script name (and +# component). +setup_script_options() +{ + if [ $# -eq 2 ]; then + _script="$2" + elif [ $# -eq 0 ]; then + _script="" + else + die "usage: setup_script_options [ component script ]" + fi + + if [ -n "$_script" ]; then + _options="${CTDB_BASE}/events/legacy/${_script}.options" + else + _options="${script_dir}/${script%.script}.options" + fi + + cat >>"$_options" + + # Source the options so that tests can use the variables + . "$_options" +} + +setup_dbdir() +{ + export CTDB_DBDIR_BASE="${CTDB_TEST_TMP_DIR}/db" + CTDB_DBDIR="${CTDB_DBDIR_BASE}/volatile" + CTDB_DBDIR_PERSISTENT="${CTDB_DBDIR_BASE}/persistent" + CTDB_DBDIR_STATE="${CTDB_DBDIR_BASE}/state" + cat >>"${CTDB_BASE}/ctdb.conf" <<EOF +[database] + volatile database directory = ${CTDB_DBDIR} + persistent database directory = ${CTDB_DBDIR_PERSISTENT} + state database directory = ${CTDB_DBDIR_STATE} +EOF + mkdir -p "$CTDB_DBDIR" + mkdir -p "$CTDB_DBDIR_PERSISTENT" + mkdir -p "$CTDB_DBDIR_STATE" +} + +setup_date() +{ + export FAKE_DATE_OUTPUT="$1" +} + +setup_tcp_listen() +{ + export FAKE_TCP_LISTEN="$*" +} + +tcp_port_listening() +{ + for _i; do + FAKE_TCP_LISTEN="${FAKE_TCP_LISTEN} ${_i}" + done +} + +tcp_port_down() +{ + _port="$1" + debug "Marking TCP port \"${_port}\" as not listening" + + _t="" + for _i in $FAKE_TCP_LISTEN; do + if [ "$_i" = "$_port" ]; then + continue + fi + _t="${_t} ${_i}" + done + + FAKE_TCP_LISTEN="$_t" +} + +setup_unix_listen() +{ + export FAKE_NETSTAT_UNIX_LISTEN="$*" +} + +unix_socket_listening() +{ + _s="$1" + + FAKE_NETSTAT_UNIX_LISTEN="${FAKE_NETSTAT_UNIX_LISTEN} ${_s}" +} + +setup_shares() +{ + debug "Setting up shares (3 existing shares)" + # Create 3 fake shares/exports. + export FAKE_SHARES="" + for i in $(seq 1 3); do + _s="${CTDB_TEST_TMP_DIR}/shares/share${i}" + mkdir -p "$_s" + FAKE_SHARES="${FAKE_SHARES}${FAKE_SHARES:+ }${_s}" + done +} + +shares_missing() +{ + # Mark some shares as non-existent + _type="$1" + shift + + _out="" + _nl=" +" + + _n=1 + for _i in $FAKE_SHARES; do + for _j; do + if [ $_n -ne "$_j" ]; then + continue + fi + + debug "Mark share $_n as missing share \"$_i\"" + rmdir "$_i" + _t=$(printf "ERROR: %s directory \"%s\" not available" \ + "$_type" "${_i}") + _out="${_out}${_out:+${_nl}}${_t}" + done + _n=$((_n + 1)) + done + + echo "$_out" +} + +_ethtool_setup() +{ + FAKE_ETHTOOL_LINK_DOWN="${FAKE_NETWORK_STATE}/ethtool-link-down" + export FAKE_ETHTOOL_LINK_DOWN + mkdir -p "$FAKE_ETHTOOL_LINK_DOWN" +} + +ethtool_interfaces_down() +{ + _ethtool_setup + + for _i; do + echo "Marking interface $_i DOWN for ethtool" + touch "${FAKE_ETHTOOL_LINK_DOWN}/${_i}" + done +} + +ethtool_interfaces_up() +{ + _ethtool_setup + + for _i; do + echo "Marking interface $_i UP for ethtool" + rm -f "${FAKE_ETHTOOL_LINK_DOWN}/${_i}" + done +} + +dump_routes() +{ + echo "# ip rule show" + ip rule show + + ip rule show | + while read -r _p _ _i _ _t; do + # Remove trailing colon after priority/preference. + _p="${_p%:}" + # Only remove rules that match our priority/preference. + [ "$CTDB_PER_IP_ROUTING_RULE_PREF" = "$_p" ] || continue + + echo "# ip route show table $_t" + ip route show table "$_t" + done +} + +# Copied from 13.per_ip_routing for now... so this is lazy testing :-( +ipv4_host_addr_to_net() +{ + _host="$1" + _maskbits="$2" + + # Convert the host address to an unsigned long by splitting out + # the octets and doing the math. + _host_ul=0 + for _o in $( + export IFS="." + # shellcheck disable=SC2086 + # Intentional word splitting + echo $_host + ); do + _host_ul=$(((_host_ul << 8) + _o)) # work around Emacs color bug + done + + # Calculate the mask and apply it. + _mask_ul=$((0xffffffff << (32 - _maskbits))) + _net_ul=$((_host_ul & _mask_ul)) + + # Now convert to a network address one byte at a time. + _net="" + for _o in $(seq 1 4); do + _net="$((_net_ul & 255))${_net:+.}${_net}" + _net_ul=$((_net_ul >> 8)) + done + + echo "${_net}/${_maskbits}" +} + +###################################################################### + +# CTDB fakery + +# shellcheck disable=SC2120 +# Argument can be used in testcases +setup_numnodes() +{ + export FAKE_CTDB_NUMNODES="${1:-3}" + echo "Setting up CTDB with ${FAKE_CTDB_NUMNODES} fake nodes" +} + +# For now this creates the same public addresses each time. However, +# it could be made more flexible. +setup_public_addresses() +{ + _f="${CTDB_BASE}/public_addresses" + + echo "Setting up public addresses in ${_f}" + cat >"$_f" <<EOF +# This is a comment +10.0.0.1/24 dev123 +10.0.0.2/24 dev123 +10.0.0.3/24 dev123 +10.0.0.4/24 dev123 +10.0.0.5/24 dev123 +10.0.0.6/24 dev123 +10.0.1.1/24 dev456 +10.0.1.2/24 dev456 +10.0.1.3/24 dev456 +EOF + + # Needed for IP allocation + setup_numnodes +} + +# Need to cope with ctdb_get_pnn(). If a test changes PNN then it +# needs to be using a different state directory, otherwise the wrong +# PNN can already be cached in the state directory. +ctdb_set_pnn() +{ + export FAKE_CTDB_PNN="$1" + echo "Setting up PNN ${FAKE_CTDB_PNN}" + + CTDB_SCRIPT_VARDIR="${CTDB_TEST_TMP_DIR}/scripts/${FAKE_CTDB_PNN}" + export CTDB_SCRIPT_VARDIR + mkdir -p "$CTDB_SCRIPT_VARDIR" +} + +ctdb_get_interfaces() +{ + ctdb ifaces -X | awk -F'|' 'FNR > 1 {print $2}' | xargs +} + +ctdb_get_1_interface() +{ + _t=$(ctdb_get_interfaces) + echo "${_t%% *}" +} + +# Print public addresses on this node as: interface IP maskbits +# Each line is suitable for passing to takeip/releaseip +ctdb_get_my_public_addresses() +{ + ctdb ip -v -X | { + read -r _ # skip header line + + while IFS="|" read -r _ _ip _ _iface _; do + [ -n "$_iface" ] || continue + while IFS="/$IFS" read -r _i _maskbits _; do + if [ "$_ip" = "$_i" ]; then + echo "$_iface $_ip $_maskbits" + break + fi + done <"${CTDB_BASE}/public_addresses" + done + } +} + +# Prints the 1st public address as: interface IP maskbits +# This is suitable for passing to takeip/releaseip +ctdb_get_1_public_address() +{ + ctdb_get_my_public_addresses | { + head -n 1 + cat >/dev/null + } +} + +# Check the routes against those that are expected. $1 is the number +# of assigned IPs to use (<num>, all), defaulting to 1. If $2 is +# "default" then expect default routes to have been added. +check_routes() +{ + _num_ips="${1:-1}" + _should_add_default="$2" + + _policy_rules="" + _policy_routes="" + + ctdb_get_my_public_addresses | + if [ "$_num_ips" = "all" ]; then + cat + else + { + head -n "$_num_ips" + cat >/dev/null + } + fi | { + while read -r _dev _ip _bits; do + _net=$(ipv4_host_addr_to_net "$_ip" "$_bits") + _gw="${_net%.*}.254" # a dumb, calculated default + + _policy_rules="${_policy_rules} +${CTDB_PER_IP_ROUTING_RULE_PREF}: from $_ip lookup ctdb.$_ip " + _policy_routes="${_policy_routes} +# ip route show table ctdb.$_ip +$_net dev $_dev scope link " + + if [ "$_should_add_default" = "default" ]; then + _policy_routes="${_policy_routes} +default via $_gw dev $_dev " + fi + done + + ok <<EOF +# ip rule show +0: from all lookup local ${_policy_rules} +32766: from all lookup main +32767: from all lookup default ${_policy_routes} +EOF + + simple_test_command dump_routes + } || test_fail +} + +###################################################################### + +nfs_load_config() +{ + _etc="$CTDB_SYS_ETCDIR" # shortcut for readability + for _c in "$_etc/sysconfig/nfs" "$_etc/default/nfs" "$_etc/ctdb/sysconfig/nfs"; do + if [ -r "$_c" ]; then + . "$_c" + break + fi + done +} + +setup_nfs_callout() +{ + export CTDB_NFS_CALLOUT="${CTDB_HELPER_BINDIR}/nfs-fake-callout" + export NFS_FAKE_CALLOUT_MAGIC="$1" +} + +program_stack_trace() +{ + _prog="$1" + _pid="$2" + + cat <<EOF +Stack trace for ${_prog}[${_pid}]: +[<ffffffff87654321>] fake_stack_trace_for_pid_${_pid}/stack+0x0/0xff +EOF +} + +###################################################################### + +# Result and test functions + +############################################################ + +setup() +{ + die "setup() is not defined" +} + +# Set some globals and print the summary. +define_test() +{ + desc="$1" + + _f=$(basename "$0" ".sh") + + # Remaining format should be NN.script.event.NUM or + # NN.script.NUM or script.NUM: + _num="${_f##*.}" + _f="${_f%.*}" + + case "$_f" in + [0-9][0-9].*) + case "$_f" in + [0-9][0-9].*.*) + script="${_f%.*}.script" + event="${_f##*.}" + ;; + [0-9][0-9].*) + script="${_f}.script" + unset event + ;; + esac + # "Enable" the script + _subdir="events/legacy" + script_dir="${CTDB_BASE}/${_subdir}" + # Symlink target needs to be absolute + case "$CTDB_SCRIPTS_DATA_DIR" in + /*) _data_dir="${CTDB_SCRIPTS_DATA_DIR}/${_subdir}" ;; + *) _data_dir="${PWD}/${CTDB_SCRIPTS_DATA_DIR}/${_subdir}" ;; + esac + mkdir -p "$script_dir" + ln -s "${_data_dir}/${script}" "$script_dir" + ;; + *) + script="${_f%.*}" + script="$_f" + unset event + script_dir="${CTDB_BASE}" + ;; + esac + + _s="${script_dir}/${script}" + [ -r "$_s" ] || + die "Internal error - unable to find script \"${_s}\"" + + case "$script" in + *.script) script_short="${script%.script}" ;; + *.sh) script_short="${script%.sh}" ;; + *) script_short="$script" ;; + esac + + printf "%-17s %-10s %-4s - %s\n\n" \ + "$script_short" "$event" "$_num" "$desc" + + _f="${CTDB_TEST_SUITE_DIR}/scripts/${script_short}.sh" + if [ -r "$_f" ]; then + . "$_f" + fi + + ctdb_set_pnn 0 +} + +# Run an eventscript once. The test passes if the return code and +# output match those required. + +# Any args are passed to the eventscript. + +simple_test() +{ + [ -n "$event" ] || die 'simple_test: event not set' + + args="$*" + + # shellcheck disable=SC2317 + # used in unit_test(), etc. + test_header() + { + echo "Running script \"$script $event${args:+ }$args\"" + } + + # shellcheck disable=SC2317 + # used in unit_test(), etc. + extra_header() + { + cat <<EOF + +################################################## +CTDB_BASE="$CTDB_BASE" +CTDB_SYS_ETCDIR="$CTDB_SYS_ETCDIR" +ctdb client is "$(which ctdb)" +ip command is "$(which ip)" +EOF + } + + script_test "${script_dir}/${script}" "$event" "$@" + + reset_test_header + reset_extra_header +} + +simple_test_event() +{ + # If something has previously failed then don't continue. + : "${_passed:=true}" + $_passed || return 1 + + event="$1" + shift + echo "==================================================" + simple_test "$@" +} + +simple_test_command() +{ + unit_test_notrace "$@" +} diff --git a/ctdb/tests/UNIT/eventscripts/scripts/statd-callout.sh b/ctdb/tests/UNIT/eventscripts/scripts/statd-callout.sh new file mode 100644 index 0000000..e966cb4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/scripts/statd-callout.sh @@ -0,0 +1,65 @@ +setup() +{ + ctdb_set_pnn + setup_public_addresses + setup_date "123456789" +} + +ctdb_catdb_format_pairs() +{ + _count=0 + + while read -r _k _v; do + _kn=$(printf '%s' "$_k" | wc -c) + _vn=$(printf '%s' "$_v" | wc -c) + cat <<EOF +key(${_kn}) = "${_k}" +dmaster: 0 +rsn: 1 +data(${_vn}) = "${_v}" + +EOF + _count=$((_count + 1)) + done + + echo "Dumped ${_count} records" +} + +check_ctdb_tdb_statd_state() +{ + ctdb_get_my_public_addresses | + while read -r _ _sip _; do + for _cip; do + cat <<EOF +statd-state@${_sip}@${_cip} $(date) +EOF + done + done | + ctdb_catdb_format_pairs | { + ok + simple_test_command ctdb catdb ctdb.tdb + } || exit $? +} + +check_statd_callout_smnotify() +{ + _state_even=$(( $(date '+%s') / 2 * 2)) + _state_odd=$((_state_even + 1)) + + nfs_load_config + + ctdb_get_my_public_addresses | + while read -r _ _sip _; do + for _cip; do + cat <<EOF +SM_NOTIFY: ${_sip} -> ${_cip}, MON_NAME=${_sip}, STATE=${_state_even} +SM_NOTIFY: ${_sip} -> ${_cip}, MON_NAME=${NFS_HOSTNAME}, STATE=${_state_even} +SM_NOTIFY: ${_sip} -> ${_cip}, MON_NAME=${_sip}, STATE=${_state_odd} +SM_NOTIFY: ${_sip} -> ${_cip}, MON_NAME=${NFS_HOSTNAME}, STATE=${_state_odd} +EOF + done + done | { + ok + simple_test_event "notify" + } || exit $? +} diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.001.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.001.sh new file mode 100755 index 0000000..7293390 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.001.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "single add-client" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "update" + +check_ctdb_tdb_statd_state "192.168.123.45" diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.002.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.002.sh new file mode 100755 index 0000000..ce9f139 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.002.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "2 x add-client, update" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "add-client" "192.168.123.46" +simple_test_event "update" + +check_ctdb_tdb_statd_state "192.168.123.45" "192.168.123.46" diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.003.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.003.sh new file mode 100755 index 0000000..25bec29 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.003.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "add-client, update, del-client, update" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "update" + +simple_test_event "del-client" "192.168.123.45" +simple_test_event "update" + +check_ctdb_tdb_statd_state diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.004.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.004.sh new file mode 100755 index 0000000..dc2156b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.004.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "single add-client, notify" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "update" + +check_ctdb_tdb_statd_state "192.168.123.45" + +check_statd_callout_smnotify "192.168.123.45" + +check_ctdb_tdb_statd_state diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.005.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.005.sh new file mode 100755 index 0000000..1f802a2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.005.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "2 x add-client to different nodes, notify on 1" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "update" + +ctdb_set_pnn 1 + +ok_null +simple_test_event "add-client" "192.168.123.46" +simple_test_event "update" + +ctdb_set_pnn 0 + +check_statd_callout_smnotify "192.168.123.45" + +ctdb_set_pnn 1 + +check_ctdb_tdb_statd_state "192.168.123.46" diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.006.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.006.sh new file mode 100755 index 0000000..8ecba5c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.006.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "2 x add-client to different nodes, notify on both" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "update" + +ctdb_set_pnn 1 + +ok_null +simple_test_event "add-client" "192.168.123.46" +simple_test_event "update" + +ctdb_set_pnn 0 + +check_statd_callout_smnotify "192.168.123.45" + +ctdb_set_pnn 1 + +check_statd_callout_smnotify "192.168.123.46" + +check_ctdb_tdb_statd_state diff --git a/ctdb/tests/UNIT/eventscripts/statd-callout.007.sh b/ctdb/tests/UNIT/eventscripts/statd-callout.007.sh new file mode 100755 index 0000000..4445fff --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/statd-callout.007.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "add-client, del-client, update" + +setup + +ok_null +simple_test_event "add-client" "192.168.123.45" +simple_test_event "del-client" "192.168.123.45" +simple_test_event "update" + +check_ctdb_tdb_statd_state diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb b/ctdb/tests/UNIT/eventscripts/stubs/ctdb new file mode 100755 index 0000000..20135eb --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb @@ -0,0 +1,481 @@ +#!/bin/sh + +prog="ctdb" + +# Print a message and exit. +die() +{ + echo "$1" >&2 + exit "${2:-1}" +} + +not_implemented_exit_code=1 + +usage() +{ + cat >&2 <<EOF +Usage: $prog [-X] cmd + +A fake CTDB stub that prints items depending on the variables +FAKE_CTDB_PNN (default 0) depending on command-line options. +EOF + exit 1 +} + +not_implemented() +{ + echo "${prog}: command \"$1\" not implemented in stub" >&2 + exit $not_implemented_exit_code +} + +verbose=false +machine_readable=false +nodespec="" + +args="" + +# Options and command argument can appear in any order, so when +# getopts thinks it is done, process any non-option arguments and go +# around again. +while [ $# -gt 0 ]; do + while getopts "Xvhn:?" opt; do + case "$opt" in + X) machine_readable=true ;; + v) verbose=true ;; + n) nodespec="$OPTARG" ;; + \? | *) usage ;; + esac + done + shift $((OPTIND - 1)) + + # Anything left over must be a non-option arg + if [ $# -gt 0 ]; then + args="${args}${args:+ }${1}" + shift + fi +done + +[ -n "$args" ] || usage +# Want word splitting +# shellcheck disable=SC2086 +set -- $args + +setup_tickles() +{ + # Make sure tickles file exists. + tickles_file="${CTDB_TEST_TMP_DIR}/fake-ctdb/tickles" + mkdir -p "$(dirname "$tickles_file")" + touch "$tickles_file" +} + +ctdb_gettickles() +{ + _ip="$1" + _port="$2" + + setup_tickles + + echo "|source ip|port|destination ip|port|" + while read -r _src _dst; do + if [ -z "$_ip" ] || [ "$_ip" = "${_dst%:*}" ]; then + if [ -z "$_port" ] || [ "$_port" = "${_dst##*:}" ]; then + echo "|${_src%:*}|${_src##*:}|${_dst%:*}|${_dst##*:}|" + fi + fi + done <"$tickles_file" +} + +ctdb_addtickle() +{ + _src="$1" + _dst="$2" + + setup_tickles + + if [ -n "$_dst" ]; then + echo "${_src} ${_dst}" >>"$tickles_file" + else + cat >>"$tickles_file" + fi +} + +ctdb_deltickle() +{ + _src="$1" + _dst="$2" + + setup_tickles + + if [ -n "$_dst" ]; then + _t=$(grep -F -v "${_src} $${_dst}" "$tickles_file") + else + _t=$(cat "$tickles_file") + while read -r _src _dst; do + _t=$(echo "$_t" | grep -F -v "${_src} ${_dst}") + done + fi + echo "$_t" >"$tickles_file" +} + +parse_nodespec() +{ + if [ "$nodespec" = "all" ]; then + nodes="$(seq 0 $((FAKE_CTDB_NUMNODES - 1)))" + elif [ -n "$nodespec" ]; then + nodes="$(echo "$nodespec" | sed -e 's@,@ @g')" + else + nodes=$(ctdb_pnn) + fi +} + +# For testing backward compatibility... +for i in $CTDB_NOT_IMPLEMENTED; do + if [ "$i" = "$1" ]; then + not_implemented "$i" + fi +done + +ctdb_pnn() +{ + # Defaults to 0 + echo "${FAKE_CTDB_PNN:-0}" +} + +###################################################################### + +FAKE_CTDB_NODE_STATE="$FAKE_CTDB_STATE/node-state" +FAKE_CTDB_NODES_DISABLED="$FAKE_CTDB_NODE_STATE/0x4" + +###################################################################### + +# NOTE: all nodes share public addresses file + +FAKE_CTDB_IP_LAYOUT="$FAKE_CTDB_STATE/ip-layout" + +ip_reallocate() +{ + touch "$FAKE_CTDB_IP_LAYOUT" + + # ShellCheck doesn't understand this flock pattern + # shellcheck disable=SC2094 + ( + flock 0 + + _pa="${CTDB_BASE}/public_addresses" + + if [ ! -s "$FAKE_CTDB_IP_LAYOUT" ]; then + sed -n -e 's@^\([^#][^/]*\)/.*@\1 -1@p' \ + "$_pa" >"$FAKE_CTDB_IP_LAYOUT" + fi + + _t="${FAKE_CTDB_IP_LAYOUT}.new" + + _flags="" + for _i in $(seq 0 $((FAKE_CTDB_NUMNODES - 1))); do + if ls "$FAKE_CTDB_STATE/node-state/"*"/$_i" >/dev/null 2>&1; then + # Have non-zero flags + _this=0 + for _j in "$FAKE_CTDB_STATE/node-state/"*"/$_i"; do + _tf="${_j%/*}" # dirname + _f="${_tf##*/}" # basename + _this=$((_this | _f)) + done + else + _this="0" + fi + _flags="${_flags}${_flags:+,}${_this}" + done + CTDB_TEST_LOGLEVEL=NOTICE \ + "ctdb_takeover_tests" \ + "ipalloc" "$_flags" <"$FAKE_CTDB_IP_LAYOUT" | + sort >"$_t" + mv "$_t" "$FAKE_CTDB_IP_LAYOUT" + ) <"$FAKE_CTDB_IP_LAYOUT" +} + +ctdb_ip() +{ + # If nobody has done any IP-fu then generate a layout. + [ -f "$FAKE_CTDB_IP_LAYOUT" ] || ip_reallocate + + _mypnn=$(ctdb_pnn) + + if $machine_readable; then + if $verbose; then + echo "|Public IP|Node|ActiveInterface|AvailableInterfaces|ConfiguredInterfaces|" + else + echo "|Public IP|Node|" + fi + else + echo "Public IPs on node ${_mypnn}" + fi + + # Join public addresses file with $FAKE_CTDB_IP_LAYOUT, and + # process output line by line... + _pa="${CTDB_BASE}/public_addresses" + sed -e 's@/@ @' "$_pa" | sort | join - "$FAKE_CTDB_IP_LAYOUT" | + while read -r _ip _ _ifaces _pnn; do + if $verbose; then + # If more than 1 interface, assume all addresses are on the 1st. + _first_iface="${_ifaces%%,*}" + # Only show interface if address is on this node. + _my_iface="" + if [ "$_pnn" = "$_mypnn" ]; then + _my_iface="$_first_iface" + fi + if $machine_readable; then + echo "|${_ip}|${_pnn}|${_my_iface}|${_first_iface}|${_ifaces}|" + else + echo "${_ip} node[${_pnn}] active[${_my_iface}] available[${_first_iface}] configured[[${_ifaces}]" + fi + else + if $machine_readable; then + echo "|${_ip}|${_pnn}|" + else + echo "${_ip} ${_pnn}" + fi + fi + done +} + +ctdb_moveip() +{ + _ip="$1" + _target="$2" + + ip_reallocate # should be harmless and ensures we have good state + + # ShellCheck doesn't understand this flock pattern + # shellcheck disable=SC2094 + ( + flock 0 + + _t="${FAKE_CTDB_IP_LAYOUT}.new" + + while read -r _i _pnn; do + if [ "$_ip" = "$_i" ]; then + echo "$_i $_target" + else + echo "$_i $_pnn" + fi + done | sort >"$_t" + mv "$_t" "$FAKE_CTDB_IP_LAYOUT" + ) <"$FAKE_CTDB_IP_LAYOUT" +} + +###################################################################### + +ctdb_enable() +{ + parse_nodespec + + for _i in $nodes; do + rm -f "${FAKE_CTDB_NODES_DISABLED}/${_i}" + done + + ip_reallocate +} + +ctdb_disable() +{ + parse_nodespec + + for _i in $nodes; do + mkdir -p "$FAKE_CTDB_NODES_DISABLED" + touch "${FAKE_CTDB_NODES_DISABLED}/${_i}" + done + + ip_reallocate +} + +###################################################################### + +ctdb_shutdown() +{ + echo "CTDB says BYE!" +} + +###################################################################### + +# This is only used by the NAT and LVS gateway code at the moment, so +# use a hack. Assume that $CTDB_NATGW_NODES or $CTDB_LVS_NODES +# contains all nodes in the cluster (which is what current tests +# assume). Use the PNN to find the address from this file. The NAT +# gateway code only used the address, so just mark the node healthy. +ctdb_nodestatus() +{ + echo '|Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode|' + _line=$((FAKE_CTDB_PNN + 1)) + _ip=$(sed -e "${_line}p" "${CTDB_NATGW_NODES:-${CTDB_LVS_NODES}}") + echo "|${FAKE_CTDB_PNN}|${_ip}|0|0|0|0|0|0|0|Y|" +} + +###################################################################### + +_t_setup() +{ + _t_dir="${CTDB_TEST_TMP_DIR}/fake-ctdb/fake-tdb/$1" + mkdir -p "$_t_dir" +} + +_t_put() +{ + echo "$2" >"${_t_dir}/$1" +} + +_t_get() +{ + cat "${_t_dir}/$1" +} + +_t_del() +{ + rm -f "${_t_dir}/$1" +} + +ctdb_pstore() +{ + _t_setup "$1" + _t_put "$2" "$3" +} + +ctdb_pdelete() +{ + _t_setup "$1" + _t_del "$2" +} + +ctdb_pfetch() +{ + _t_setup "$1" + _t_get "$2" >"$3" 2>/dev/null +} + +ctdb_ptrans() +{ + _t_setup "$1" + + while IFS="" read -r _line; do + _k=$(echo "$_line" | sed -n -e 's@^"\([^"]*\)" "[^"]*"$@\1@p') + _v=$(echo "$_line" | sed -e 's@^"[^"]*" "\([^"]*\)"$@\1@') + [ -n "$_k" ] || die "ctdb ptrans: bad line \"${_line}\"" + if [ -n "$_v" ]; then + _t_put "$_k" "$_v" + else + _t_del "$_k" + fi + done +} + +ctdb_catdb() +{ + _t_setup "$1" + + # This will break on keys with spaces but we don't have any of + # those yet. + _count=0 + for _i in "${_t_dir}/"*; do + [ -r "$_i" ] || continue + _k="${_i##*/}" # basename + _v=$(_t_get "$_k") + _kn=$(printf '%s' "$_k" | wc -c) + _vn=$(printf '%s' "$_v" | wc -c) + cat <<EOF +key(${_kn}) = "${_k}" +dmaster: 0 +rsn: 1 +data(${_vn}) = "${_v}" + +EOF + _count=$((_count + 1)) + done + + echo "Dumped ${_count} records" +} + +###################################################################### + +FAKE_CTDB_IFACES_DOWN="${FAKE_CTDB_STATE}/ifaces-down" +rm -f "${FAKE_CTDB_IFACES_DOWN}"/* + +ctdb_ifaces() +{ + _f="${CTDB_BASE}/public_addresses" + + if [ ! -f "$_f" ]; then + die "Public addresses file \"${_f}\" not found" + fi + + # Assume -Y. + echo "|Name|LinkStatus|References|" + while read -r _ip _iface; do + case "$_ip" in + \#*) : ;; + *) + _status=1 + # For now assume _iface contains only 1. + if [ -f "{FAKE_CTDB_IFACES_DOWN}/${_iface}" ]; then + _status=0 + fi + # Nobody looks at references + echo "|${_iface}|${_status}|0|" + ;; + esac + done <"$_f" | + sort -u +} + +ctdb_setifacelink() +{ + _iface="$1" + _state="$2" + + mkdir -p "$FAKE_CTDB_IFACES_DOWN" + + # Existence of file means CTDB thinks interface is down. + _f="${FAKE_CTDB_IFACES_DOWN}/${_iface}" + + case "$_state" in + up) rm -f "$_f" ;; + down) touch "$_f" ;; + *) die "ctdb setifacelink: unsupported interface status ${_state}" ;; + esac +} + +###################################################################### + +ctdb_checktcpport() +{ + _port="$1" + + for _i in $FAKE_TCP_LISTEN; do + if [ "$_port" = "$_i" ]; then + exit 98 + fi + done + + exit 0 +} + +ctdb_gratarp() +{ + # Do nothing for now + : +} + +###################################################################### + +cmd="$1" +shift + +func="ctdb_${cmd}" + +# This could inadvertently run an external function instead of a local +# function. However, this can only happen if testing a script +# containing a new ctdb command that is not implemented, so this is +# unlikely to do harm. +if type "$func" >/dev/null 2>&1; then + "$func" "$@" +else + not_implemented "$cmd" +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb-config b/ctdb/tests/UNIT/eventscripts/stubs/ctdb-config new file mode 100755 index 0000000..818e3db --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb-config @@ -0,0 +1,2 @@ +#!/bin/sh +exec $VALGRIND "${CTDB_SCRIPTS_HELPER_BINDIR}/ctdb-config" "$@" diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb_killtcp b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_killtcp new file mode 100755 index 0000000..2a4bac4 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_killtcp @@ -0,0 +1,10 @@ +#!/bin/sh + +# Only supports reading from stdin + +# shellcheck disable=SC2034 +iface="$1" # ignored + +while read -r src dst; do + sed -i -e "/^${dst} ${src}\$/d" "$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" +done diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb_lvs b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_lvs new file mode 100755 index 0000000..31f56e8 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_lvs @@ -0,0 +1,53 @@ +#!/bin/sh + +prog="ctdb_lvs" + +# Print a message and exit. +die() +{ + echo "$1" >&2 + exit "${2:-1}" +} + +not_implemented_exit_code=1 + +usage() +{ + cat >&2 <<EOF +Usage: $prog { leader | list } +EOF + exit 1 +} + +not_implemented() +{ + echo "${prog}: command \"$1\" not implemented in stub" >&2 + exit $not_implemented_exit_code +} + +ctdb_lvs_leader() +{ + if [ -n "$FAKE_CTDB_LVS_LEADER" ]; then + echo "$FAKE_CTDB_LVS_LEADER" + return 0 + else + return 255 + fi +} + +ctdb_lvs_list() +{ + _pnn=0 + while read -r _ip _; do + echo "${_pnn} ${_ip}" + _pnn=$((_pnn + 1)) + done <"$CTDB_LVS_NODES" +} + +###################################################################### + +case "$1" in +leader) ctdb_lvs_leader "$@" ;; +list) ctdb_lvs_list "$@" ;; +*) not_implemented "$1" ;; +esac diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb_natgw b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_natgw new file mode 100755 index 0000000..22a2191 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb_natgw @@ -0,0 +1,34 @@ +#!/bin/sh + +prog="ctdb_natgw" + +not_implemented_exit_code=1 + +not_implemented() +{ + echo "${prog}: command \"$1\" not implemented in stub" >&2 + exit $not_implemented_exit_code +} + +ctdb_natgw_leader() +{ + [ -r "$CTDB_NATGW_NODES" ] || + die "error: missing CTDB_NATGW_NODES=${CTDB_NATGW_NODES}" + + # Determine the leader node + _leader="-1 0.0.0.0" + _pnn=0 + while read -r _ip; do + if [ "$FAKE_CTDB_NATGW_LEADER" = "$_ip" ]; then + _leader="${_pnn} ${_ip}" + break + fi + _pnn=$((_pnn + 1)) + done <"$CTDB_NATGW_NODES" + echo "$_leader" +} + +case "$1" in +leader) ctdb_natgw_leader "$@" ;; +*) not_implemented "$1" ;; +esac diff --git a/ctdb/tests/UNIT/eventscripts/stubs/date b/ctdb/tests/UNIT/eventscripts/stubs/date new file mode 100755 index 0000000..8319c9c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/date @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$FAKE_DATE_OUTPUT" ]; then + echo "$FAKE_DATE_OUTPUT" +else + /bin/date "$@" +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/df b/ctdb/tests/UNIT/eventscripts/stubs/df new file mode 100755 index 0000000..858f0ef --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/df @@ -0,0 +1,38 @@ +#!/bin/sh + +usage() +{ + echo "usage: df [-kP] [<mount-point>]" + exit 1 +} + +if [ "$1" = "-kP" ]; then + shift +fi + +case "$1" in +-*) usage ;; +esac + +fs="${1:-/}" + +# Anything starting with CTDB_DBDIR_BASE gets canonicalised to +# CTDB_DBDIR_BASE. This helps with the setting of defaults for the +# filesystem checks. +if [ "${fs#"${CTDB_DBDIR_BASE}"}" != "$fs" ]; then + fs="$CTDB_DBDIR_BASE" +fi + +# A default, for tests that don't initialise this... +if [ -z "$FAKE_FS_USE" ]; then + FAKE_FS_USE=10 +fi + +echo "Filesystem 1024-blocks Used Available Capacity Mounted on" + +blocks="1000000" +used=$((blocks * FAKE_FS_USE / 100)) +available=$((blocks - used)) + +printf "%-36s %10d %10d %10d %10d%% %s\n" \ + "/dev/sda1" "$blocks" "$used" "$available" "$FAKE_FS_USE" "$fs" diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ethtool b/ctdb/tests/UNIT/eventscripts/stubs/ethtool new file mode 100755 index 0000000..3d4b889 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ethtool @@ -0,0 +1,12 @@ +#!/bin/sh + +link="yes" + +if [ -f "${FAKE_ETHTOOL_LINK_DOWN}/${1}" ]; then + link="no" +fi + +# Expect to add more fields later. +cat <<EOF + Link detected: ${link} +EOF diff --git a/ctdb/tests/UNIT/eventscripts/stubs/exportfs b/ctdb/tests/UNIT/eventscripts/stubs/exportfs new file mode 100755 index 0000000..e0970c5 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/exportfs @@ -0,0 +1,13 @@ +#!/bin/sh + +opts="10.0.0.0/16(rw,async,insecure,no_root_squash,no_subtree_check)" + +for i in $FAKE_SHARES; do + # Directories longer than 15 characters are printed on their own + # line. + if [ ${#i} -ge 15 ]; then + printf '%s\n\t\t%s\n' "$i" "$opts" + else + printf '%s\t%s\n' "$i" "$opts" + fi +done diff --git a/ctdb/tests/UNIT/eventscripts/stubs/gstack b/ctdb/tests/UNIT/eventscripts/stubs/gstack new file mode 100755 index 0000000..1dec235 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/gstack @@ -0,0 +1,19 @@ +#!/bin/sh + +pid="$1" + +if [ -n "$FAKE_PS_MAP" ]; then + command=$(echo "$FAKE_PS_MAP" | + awk -v pid="$pid" '$1 == pid { print $2 }') +fi + +if [ -z "$command" ]; then + command="smbd" +fi + +cat <<EOF +Thread 1 (Thread 0x7f688fbfb180 (LWP ${pid}) "${command}"): +#0 0x00007f688ff7a076 in open (FAKE ARGS...) at FAKE PLACE +.... +#3 0x000055cd368ead72 in main (argc=<optimized out>, argv=<optimized out>) at ${command}.c +EOF diff --git a/ctdb/tests/UNIT/eventscripts/stubs/id b/ctdb/tests/UNIT/eventscripts/stubs/id new file mode 100755 index 0000000..1ecd2f8 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/id @@ -0,0 +1,3 @@ +#!/bin/sh +# Make statd-callout happy +echo 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ip b/ctdb/tests/UNIT/eventscripts/stubs/ip new file mode 100755 index 0000000..090afae --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ip @@ -0,0 +1,833 @@ +#!/bin/sh + +FAKE_IP_STATE="${FAKE_NETWORK_STATE}/ip-state" +mkdir -p "$FAKE_IP_STATE" + +promote_secondaries=true + +not_implemented() +{ + echo "ip stub command: \"$1\" not implemented" + exit 127 +} + +###################################################################### + +ip_link() +{ + case "$1" in + set) + shift + # iface="$1" + case "$2" in + up) ip_link_set_up "$1" ;; + down) ip_link_down_up "$1" ;; + *) not_implemented "\"$2\" in \"$orig_args\"" ;; + esac + ;; + show) + shift + ip_link_show "$@" + ;; + add*) + shift + ip_link_add "$@" + ;; + del*) + shift + ip_link_delete "$@" + ;; + *) not_implemented "$*" ;; + esac +} + +ip_link_add() +{ + _link="" + _name="" + _type="" + + while [ -n "$1" ]; do + case "$1" in + link) + _link="$2" + shift 2 + ;; + name) + _name="$2" + shift 2 + ;; + type) + if [ "$2" != "vlan" ]; then + not_implemented "link type $1" + fi + _type="$2" + shift 2 + ;; + id) shift 2 ;; + *) not_implemented "$1" ;; + esac + done + + case "$_type" in + vlan) + if [ -z "$_name" ] || [ -z "$_link" ]; then + not_implemented "ip link add with null name or link" + fi + + mkdir -p "${FAKE_IP_STATE}/interfaces-vlan" + echo "$_link" >"${FAKE_IP_STATE}/interfaces-vlan/${_name}" + ip_link_set_down "$_name" + ;; + esac +} + +ip_link_delete() +{ + mkdir -p "${FAKE_IP_STATE}/interfaces-deleted" + touch "${FAKE_IP_STATE}/interfaces-deleted/$1" + rm -f "${FAKE_IP_STATE}/interfaces-vlan/$1" +} + +ip_link_set_up() +{ + rm -f "${FAKE_IP_STATE}/interfaces-down/$1" + rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1" +} + +ip_link_set_down() +{ + rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1" + mkdir -p "${FAKE_IP_STATE}/interfaces-down" + touch "${FAKE_IP_STATE}/interfaces-down/$1" +} + +ip_link_show() +{ + dev="$1" + if [ "$dev" = "dev" ] && [ -n "$2" ]; then + dev="$2" + fi + + if [ -e "${FAKE_IP_STATE}/interfaces-deleted/$dev" ]; then + echo "Device \"${dev}\" does not exist." >&2 + exit 255 + fi + + if [ -r "${FAKE_IP_STATE}/interfaces-vlan/${dev}" ]; then + read -r _link <"${FAKE_IP_STATE}/interfaces-vlan/${dev}" + dev="${dev}@${_link}" + fi + + _state="UP" + _flags=",UP,LOWER_UP" + if [ -e "${FAKE_IP_STATE}/interfaces-down/$dev" ]; then + _state="DOWN" + _flags="" + fi + case "$dev" in + lo) + _mac="00:00:00:00:00:00" + _brd="00:00:00:00:00:00" + _type="loopback" + _state="UNKNOWN" + _status="<LOOPBACK${_flags}>" + _opts="mtu 65536 qdisc noqueue state ${_state}" + ;; + *) + _mac=$(echo "$dev" | cksum | sed -r -e 's@(..)(..)(..).*@fe:fe:fe:\1:\2:\3@') + _brd="ff:ff:ff:ff:ff:ff" + _type="ether" + _status="<BROADCAST,MULTICAST${_flags}>" + _opts="mtu 1500 qdisc pfifo_fast state ${_state} qlen 1000" + ;; + esac + + if $brief; then + printf '%-16s %-14s %-17s %s\n' \ + "$dev" "$_status" "$_mac" "$_status" + else + echo "${n:-42}: ${dev}: ${_status} ${_opts}" + echo " link/${_type} ${_mac} brd ${_brd}" + fi +} + +# This is incomplete because it doesn't actually look up table ids in +# /etc/iproute2/rt_tables. The rules/routes are actually associated +# with the name instead of the number. However, we include a variable +# to fake a bad table id. +[ -n "$IP_ROUTE_BAD_TABLE_ID" ] || IP_ROUTE_BAD_TABLE_ID=false + +ip_check_table() +{ + _cmd="$1" + + if [ "$_cmd" = "route" ] && [ -z "$_table" ]; then + _table="main" + fi + + [ -n "$_table" ] || not_implemented "ip rule/route without \"table\"" + + # Only allow tables names from 13.per_ip_routing and "main". This + # is a cheap way of avoiding implementing the default/local + # tables. + case "$_table" in + ctdb.* | main) + if $IP_ROUTE_BAD_TABLE_ID; then + # Ouch. Simulate inconsistent errors from ip. :-( + case "$_cmd" in + route) + echo "Error: argument \"${_table}\" is wrong: table id value is invalid" >&2 + + ;; + *) + echo "Error: argument \"${_table}\" is wrong: invalid table ID" >&2 + ;; + esac + exit 255 + fi + ;; + *) not_implemented "table=${_table} ${orig_args}" ;; + esac +} + +###################################################################### + +ip_addr() +{ + case "$1" in + show | list | "") + shift + ip_addr_show "$@" + ;; + add*) + shift + ip_addr_add "$@" + ;; + del*) + shift + ip_addr_del "$@" + ;; + *) not_implemented "\"$1\" in \"$orig_args\"" ;; + esac +} + +ip_addr_show() +{ + dev="" + primary=true + secondary=true + _to="" + + if $brief; then + not_implemented "ip -br addr show in \"$orig_args\"" + fi + + while [ -n "$1" ]; do + case "$1" in + dev) + dev="$2" + shift 2 + ;; + # Do stupid things and stupid things will happen! + primary) + primary=true + secondary=false + shift + ;; + secondary) + secondary=true + primary=false + shift + ;; + to) + _to="$2" + shift 2 + ;; + *) + # Assume an interface name + dev="$1" + shift 1 + ;; + esac + done + devices="$dev" + if [ -z "$devices" ]; then + # No device specified? Get all the primaries... + devices=$(find "${FAKE_IP_STATE}/addresses" -name "*-primary" | + sed -e 's@.*/@@' -e 's@-.*-primary$@@' | + sort -u) + fi + calc_brd() + { + case "${local#*/}" in + 24) brd="${local%.*}.255" ;; + 32) brd="" ;; + *) not_implemented "list ... fake bits other than 24/32: ${local#*/}" ;; + esac + } + show_iface() + { + ip_link_show "$dev" + + nets=$(find "${FAKE_IP_STATE}/addresses" -name "${dev}-*-primary" | + sed -e 's@.*/@@' -e "s@${dev}-\(.*\)-primary\$@\1@") + + for net in $nets; do + pf="${FAKE_IP_STATE}/addresses/${dev}-${net}-primary" + sf="${FAKE_IP_STATE}/addresses/${dev}-${net}-secondary" + if $primary && [ -r "$pf" ]; then + read -r local scope <"$pf" + if [ -z "$_to" ] || [ "${_to%/*}" = "${local%/*}" ]; then + calc_brd + echo " inet ${local} ${brd:+brd ${brd} }scope ${scope} ${dev}" + fi + fi + if $secondary && [ -r "$sf" ]; then + while read -r local scope; do + if [ -z "$_to" ] || [ "${_to%/*}" = "${local%/*}" ]; then + calc_brd + echo " inet ${local} ${brd:+brd }${brd} scope ${scope} secondary ${dev}" + fi + done <"$sf" + fi + if [ -z "$_to" ]; then + echo " valid_lft forever preferred_lft forever" + fi + done + } + n=1 + for dev in $devices; do + if [ -z "$_to" ] || + grep -F "${_to%/*}/" "${FAKE_IP_STATE}/addresses/${dev}-"* >/dev/null; then + show_iface + fi + n=$((n + 1)) + done +} + +# Copied from 13.per_ip_routing for now... so this is lazy testing :-( +ipv4_host_addr_to_net() +{ + _addr="$1" + + _host="${_addr%/*}" + _maskbits="${_addr#*/}" + + # Convert the host address to an unsigned long by splitting out + # the octets and doing the math. + _host_ul=0 + # Want word splitting here + # shellcheck disable=SC2086 + for _o in $( + export IFS="." + echo $_host + ); do + _host_ul=$(((_host_ul << 8) + _o)) # work around Emacs color bug + done + + # Calculate the mask and apply it. + _mask_ul=$((0xffffffff << (32 - _maskbits))) + _net_ul=$((_host_ul & _mask_ul)) + + # Now convert to a network address one byte at a time. + _net="" + for _o in $(seq 1 4); do + _net="$((_net_ul & 255))${_net:+.}${_net}" + _net_ul=$((_net_ul >> 8)) + done + + echo "${_net}/${_maskbits}" +} + +ip_addr_add() +{ + local="" + dev="" + brd="" + scope="global" + while [ -n "$1" ]; do + case "$1" in + *.*.*.*/*) + local="$1" + shift + ;; + local) + local="$2" + shift 2 + ;; + broadcast | brd) + # For now assume this is always '+'. + if [ "$2" != "+" ]; then + not_implemented "addr add ... brd $2 ..." + fi + shift 2 + ;; + dev) + dev="$2" + shift 2 + ;; + scope) + scope="$2" + shift 2 + ;; + *) + not_implemented "$@" + ;; + esac + done + if [ -z "$dev" ]; then + not_implemented "addr add (without dev)" + fi + mkdir -p "${FAKE_IP_STATE}/addresses" + net_str=$(ipv4_host_addr_to_net "$local") + net_str=$(echo "$net_str" | sed -e 's@/@_@') + pf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-primary" + sf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-secondary" + # We could lock here... but we should be the only ones playing + # around here with these stubs. + if [ ! -f "$pf" ]; then + echo "$local $scope" >"$pf" + elif grep -Fq "$local" "$pf"; then + echo "RTNETLINK answers: File exists" >&2 + exit 254 + elif [ -f "$sf" ] && grep -Fq "$local" "$sf"; then + echo "RTNETLINK answers: File exists" >&2 + exit 254 + else + echo "$local $scope" >>"$sf" + fi +} + +ip_addr_del() +{ + local="" + dev="" + while [ -n "$1" ]; do + case "$1" in + *.*.*.*/*) + local="$1" + shift + ;; + local) + local="$2" + shift 2 + ;; + dev) + dev="$2" + shift 2 + ;; + *) + not_implemented "addr del ... $1 ..." + ;; + esac + done + if [ -z "$dev" ]; then + not_implemented "addr del (without dev)" + fi + mkdir -p "${FAKE_IP_STATE}/addresses" + net_str=$(ipv4_host_addr_to_net "$local") + net_str=$(echo "$net_str" | sed -e 's@/@_@') + pf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-primary" + sf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-secondary" + # We could lock here... but we should be the only ones playing + # around here with these stubs. + if [ ! -f "$pf" ]; then + echo "RTNETLINK answers: Cannot assign requested address" >&2 + exit 254 + elif grep -Fq "$local" "$pf"; then + if $promote_secondaries && [ -s "$sf" ]; then + head -n 1 "$sf" >"$pf" + sed -i -e '1d' "$sf" + else + # Remove primaries AND SECONDARIES. + rm -f "$pf" "$sf" + fi + elif [ -f "$sf" ] && grep -Fq "$local" "$sf"; then + grep -Fv "$local" "$sf" >"${sf}.new" + mv "${sf}.new" "$sf" + else + echo "RTNETLINK answers: Cannot assign requested address" >&2 + exit 254 + fi +} + +###################################################################### + +ip_rule() +{ + case "$1" in + show | list | "") + shift + ip_rule_show "$@" + ;; + add) + shift + ip_rule_add "$@" + ;; + del*) + shift + ip_rule_del "$@" + ;; + *) not_implemented "$1 in \"$orig_args\"" ;; + esac + +} + +# All non-default rules are in $FAKE_IP_STATE_RULES/rules. As with +# the real version, rules can be repeated. Deleting just deletes the +# 1st match. + +ip_rule_show() +{ + if $brief; then + not_implemented "ip -br rule show in \"$orig_args\"" + fi + + ip_rule_show_1() + { + _pre="$1" + _table="$2" + _selectors="$3" + # potentially more options + + printf "%d:\t%s lookup %s \n" "$_pre" "$_selectors" "$_table" + } + + ip_rule_show_some() + { + _min="$1" + _max="$2" + + [ -f "${FAKE_IP_STATE}/rules" ] || return + + while read -r _pre _table _selectors; do + # Only print those in range + if [ "$_min" -le "$_pre" ] && + [ "$_pre" -le "$_max" ]; then + ip_rule_show_1 "$_pre" "$_table" "$_selectors" + fi + done <"${FAKE_IP_STATE}/rules" + } + + ip_rule_show_1 0 "local" "from all" + + ip_rule_show_some 1 32765 + + ip_rule_show_1 32766 "main" "from all" + ip_rule_show_1 32767 "default" "from all" + + ip_rule_show_some 32768 2147483648 +} + +ip_rule_common() +{ + _from="" + _pre="" + _table="" + while [ -n "$1" ]; do + case "$1" in + from) + _from="$2" + shift 2 + ;; + pref) + _pre="$2" + shift 2 + ;; + table) + _table="$2" + shift 2 + ;; + *) not_implemented "$1 in \"$orig_args\"" ;; + esac + done + + [ -n "$_pre" ] || not_implemented "ip rule without \"pref\"" + ip_check_table "rule" + # Relax this if more selectors added later... + [ -n "$_from" ] || not_implemented "ip rule without \"from\"" +} + +ip_rule_add() +{ + ip_rule_common "$@" + + _f="${FAKE_IP_STATE}/rules" + touch "$_f" + ( + flock 0 + # Filter order must be consistent with the comparison in ip_rule_del() + echo "$_pre $_table${_from:+ from }$_from" >>"$_f" + ) <"$_f" +} + +ip_rule_del() +{ + ip_rule_common "$@" + + _f="${FAKE_IP_STATE}/rules" + touch "$_f" + # ShellCheck doesn't understand this flock pattern + # shellcheck disable=SC2094 + ( + flock 0 + _tmp="${_f}.new" + : >"$_tmp" + _found=false + while read -r _p _t _s; do + if ! $_found && + [ "$_p" = "$_pre" ] && [ "$_t" = "$_table" ] && + [ "$_s" = "${_from:+from }$_from" ]; then + # Found. Skip this one but not future ones. + _found=true + else + echo "$_p $_t $_s" >>"$_tmp" + fi + done + if cmp -s "$_tmp" "$_f"; then + # No changes, must not have found what we wanted to delete + echo "RTNETLINK answers: No such file or directory" >&2 + rm -f "$_tmp" + exit 2 + else + mv "$_tmp" "$_f" + fi + ) <"$_f" || exit $? +} + +###################################################################### + +ip_route() +{ + case "$1" in + show | list) + shift + ip_route_show "$@" + ;; + flush) + shift + ip_route_flush "$@" + ;; + add) + shift + ip_route_add "$@" + ;; + del*) + shift + ip_route_del "$@" + ;; + *) not_implemented "$1 in \"ip route\"" ;; + esac +} + +ip_route_common() +{ + if [ "$1" = table ]; then + _table="$2" + shift 2 + fi + + ip_check_table "route" +} + +# Routes are in a file per table in the directory +# $FAKE_IP_STATE/routes. These routes just use the table ID +# that is passed and don't do any lookup. This could be "improved" if +# necessary. + +ip_route_show() +{ + ip_route_common "$@" + + # Missing file is just an empty table + sort "$FAKE_IP_STATE/routes/${_table}" 2>/dev/null || true +} + +ip_route_flush() +{ + ip_route_common "$@" + + rm -f "$FAKE_IP_STATE/routes/${_table}" +} + +ip_route_add() +{ + _prefix="" + _dev="" + _gw="" + _table="" + _metric="" + + while [ -n "$1" ]; do + case "$1" in + *.*.*.*/* | *.*.*.*) + _prefix="$1" + shift 1 + ;; + local) + _prefix="$2" + shift 2 + ;; + dev) + _dev="$2" + shift 2 + ;; + via) + _gw="$2" + shift 2 + ;; + table) + _table="$2" + shift 2 + ;; + metric) + _metric="$2" + shift 2 + ;; + *) not_implemented "$1 in \"$orig_args\"" ;; + esac + done + + ip_check_table "route" + [ -n "$_prefix" ] || not_implemented "ip route without inet prefix in \"$orig_args\"" + # This can't be easily deduced, so print some garbage. + [ -n "$_dev" ] || _dev="ethXXX" + + # Alias or add missing bits + case "$_prefix" in + 0.0.0.0/0) _prefix="default" ;; + */*) : ;; + *) _prefix="${_prefix}/32" ;; + esac + + _f="$FAKE_IP_STATE/routes/${_table}" + mkdir -p "$FAKE_IP_STATE/routes" + touch "$_f" + + # Check for duplicate + _prefix_regexp=$(echo "^${_prefix}" | sed -e 's@\.@\\.@g') + if [ -n "$_metric" ]; then + _prefix_regexp="${_prefix_regexp} .*metric ${_metric} " + fi + if grep -q "$_prefix_regexp" "$_f"; then + echo "RTNETLINK answers: File exists" >&2 + exit 1 + fi + + ( + flock 0 + + _out="${_prefix} " + [ -z "$_gw" ] || _out="${_out}via ${_gw} " + [ -z "$_dev" ] || _out="${_out}dev ${_dev} " + [ -n "$_gw" ] || _out="${_out} scope link " + [ -z "$_metric" ] || _out="${_out} metric ${_metric} " + echo "$_out" >>"$_f" + ) <"$_f" +} + +ip_route_del() +{ + _prefix="" + _dev="" + _gw="" + _table="" + _metric="" + + while [ -n "$1" ]; do + case "$1" in + *.*.*.*/* | *.*.*.*) + _prefix="$1" + shift 1 + ;; + local) + _prefix="$2" + shift 2 + ;; + dev) + _dev="$2" + shift 2 + ;; + via) + _gw="$2" + shift 2 + ;; + table) + _table="$2" + shift 2 + ;; + metric) + _metric="$2" + shift 2 + ;; + *) not_implemented "$1 in \"$orig_args\"" ;; + esac + done + + ip_check_table "route" + [ -n "$_prefix" ] || not_implemented "ip route without inet prefix in \"$orig_args\"" + # This can't be easily deduced, so print some garbage. + [ -n "$_dev" ] || _dev="ethXXX" + + # Alias or add missing bits + case "$_prefix" in + 0.0.0.0/0) _prefix="default" ;; + */*) : ;; + *) _prefix="${_prefix}/32" ;; + esac + + _f="$FAKE_IP_STATE/routes/${_table}" + mkdir -p "$FAKE_IP_STATE/routes" + touch "$_f" + + # ShellCheck doesn't understand this flock pattern + # shellcheck disable=SC2094 + ( + flock 0 + + # Escape some dots + [ -z "$_gw" ] || _gw=$(echo "$_gw" | sed -e 's@\.@\\.@g') + _prefix=$(echo "$_prefix" | sed -e 's@\.@\\.@g' -e 's@/@\\/@') + + _re="^${_prefix}\>.*" + [ -z "$_gw" ] || _re="${_re}\<via ${_gw}\>.*" + [ -z "$_dev" ] || _re="${_re}\<dev ${_dev}\>.*" + [ -z "$_metric" ] || _re="${_re}.*\<metric ${_metric}\>.*" + sed -i -e "/${_re}/d" "$_f" + ) <"$_f" +} + +###################################################################### + +orig_args="$*" + +brief=false +case "$1" in +-br*) + brief=true + shift + ;; +esac + +case "$1" in +link) + shift + ip_link "$@" + ;; +addr*) + shift + ip_addr "$@" + ;; +rule) + shift + ip_rule "$@" + ;; +route) + shift + ip_route "$@" + ;; +*) not_implemented "$1" ;; +esac + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ip6tables b/ctdb/tests/UNIT/eventscripts/stubs/ip6tables new file mode 100755 index 0000000..2c65f7b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ip6tables @@ -0,0 +1,5 @@ +#!/bin/sh + +# Always succeed. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/iptables b/ctdb/tests/UNIT/eventscripts/stubs/iptables new file mode 100755 index 0000000..2c65f7b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/iptables @@ -0,0 +1,5 @@ +#!/bin/sh + +# Always succeed. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ipvsadm b/ctdb/tests/UNIT/eventscripts/stubs/ipvsadm new file mode 100755 index 0000000..31bdf2c --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ipvsadm @@ -0,0 +1,154 @@ +#!/bin/sh + +die() +{ + echo "$1" >&2 + exit "${2:-1}" +} + +[ -n "$FAKE_LVS_STATE_DIR" ] || die "FAKE_LVS_STATE_DIR not set" + +service_address="" +scheduling_method="wlc" +persistent_timeout="" +real_server="" +forwarding_method="Route" + +set_service_address() +{ + [ -z "$service_address" ] || + die "multiple 'service-address' options specified" 2 + case "$2" in + *:*) service_address="${1} ${2}" ;; + *) service_address="${1} ${2}:0" ;; + esac +} + +set_real_server() +{ + [ -z "$real_server" ] || + die "multiple 'real-server' options specified" 2 + case "$1" in + *\]:*) real_server="${1}" ;; + *\]) real_server="${1}:0" ;; + *:*) real_server="${1}" ;; + *) real_server="${1}:0" ;; + esac + + case "$real_server" in + 127.0.0.1:* | \[::1\]:*) forwarding_method="Local" ;; + esac +} + +case "$1" in +-A) + shift + while [ -n "$1" ]; do + case "$1" in + -t) + set_service_address "TCP" "$2" + shift 2 + ;; + -u) + set_service_address "UDP" "$2" + shift 2 + ;; + -s) + scheduling_method="$2" + shift 2 + ;; + -p) + persistent_timeout="persistent $2" + shift 2 + ;; + *) die "Unsupported -A option $1" ;; + esac + done + [ -n "$service_address" ] || + die "You need to supply the 'service-address' option for the 'add-service' command" 2 + d="${FAKE_LVS_STATE_DIR}/${service_address}" + mkdir "$d" 2>/dev/null || die "Service already exists" 255 + t="${scheduling_method}${persistent_timeout:+ }${persistent_timeout}" + echo "$t" >"${d}/.info" + ;; +-D) + shift + while [ -n "$1" ]; do + case "$1" in + -t) + set_service_address "TCP" "$2" + shift 2 + ;; + -u) + set_service_address "UDP" "$2" + shift 2 + ;; + *) die "Unsupported -D option $1" ;; + esac + done + [ -n "$service_address" ] || + die "You need to supply the 'service-address' option for the 'delete-service' command" 2 + d="${FAKE_LVS_STATE_DIR}/${service_address}" + rm -f "${d}/"* + rm -f "${d}/.info" + rmdir "$d" 2>/dev/null || die "No such service" 255 + ;; +-a) + shift + while [ -n "$1" ]; do + case "$1" in + -t) + set_service_address "TCP" "$2" + shift 2 + ;; + -u) + set_service_address "UDP" "$2" + shift 2 + ;; + -r) + set_real_server "$2" + shift 2 + ;; + -g) + forwarding_method="Route" + shift 1 + ;; + *) die "Unsupported -A option $1" ;; + esac + done + [ -n "$service_address" ] || + die "You need to supply the 'service-address' option for the 'delete-service' command" 2 + d="${FAKE_LVS_STATE_DIR}/${service_address}" + [ -d "$d" ] || die "Service not defined" 255 + [ -n "$real_server" ] || + die "You need to supply the 'real-server' option for the 'add-server' command" 2 + f="${d}/${real_server}" + echo "$forwarding_method" >"$f" + ;; +-l) + cat <<EOF +IP Virtual Server version 1.2.1 (size=4096) +Prot LocalAddress:Port Scheduler Flags + -> RemoteAddress:Port Forward Weight ActiveConn InActConn +EOF + cd "$FAKE_LVS_STATE_DIR" || exit 0 + ( + for d in *; do + [ -d "$d" ] || continue + printf '%s ' "$d" + cat "${d}/.info" + for f in "${d}/"*; do + [ -f "$f" ] || continue + read -r forwarding_method <"$f" + printf " -> %-28s %-7s %-6s %-10s %-10s\n" \ + "${f##*/}" "$forwarding_method" 1 0 0 + done + done + ) + ;; +*) + die "Unknown option $1" + ;; +esac + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/kill b/ctdb/tests/UNIT/eventscripts/stubs/kill new file mode 100755 index 0000000..b69e3e6 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/kill @@ -0,0 +1,7 @@ +#!/bin/sh + +# Always succeed. This means that kill -0 will always find a +# process and anything else will successfully kill. This should +# exercise a good avriety of code paths. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/killall b/ctdb/tests/UNIT/eventscripts/stubs/killall new file mode 100755 index 0000000..1e182e1 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/killall @@ -0,0 +1,7 @@ +#!/bin/sh + +# Always succeed. This means that killall -0 will always find a +# process and anything else will successfully kill. This should +# exercise a good avriety of code paths. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/multipath b/ctdb/tests/UNIT/eventscripts/stubs/multipath new file mode 100755 index 0000000..319b734 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/multipath @@ -0,0 +1,36 @@ +#!/bin/sh + +usage() +{ + die "usage: ${0} -ll device" +} + +[ "$1" = "-ll" ] || usage +shift +[ $# -eq 1 ] || usage + +device="$1" + +if [ -n "$FAKE_MULTIPATH_HANG" ]; then + FAKE_SLEEP_REALLY="yes" sleep 999 +fi + +path1_state="active" +path2_state="enabled" + +for i in $FAKE_MULTIPATH_FAILURES; do + if [ "$device" = "$i" ]; then + path1_state="inactive" + path2_state="inactive" + break + fi +done + +cat <<EOF +${device} (AUTO-01234567) dm-0 , +size=10G features='0' hwhandler='0' wp=rw +|-+- policy='round-robin 0' prio=1 status=${path1_state} +| \`- #:#:#:# vda 252:0 active ready running +\`-+- policy='round-robin 0' prio=1 status=${path2_state} + \`- #:#:#:# vdb 252:16 active ready running +EOF diff --git a/ctdb/tests/UNIT/eventscripts/stubs/net b/ctdb/tests/UNIT/eventscripts/stubs/net new file mode 100755 index 0000000..3f96413 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/net @@ -0,0 +1,5 @@ +#!/bin/sh + +# Always succeed for now... + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/nfs-fake-callout b/ctdb/tests/UNIT/eventscripts/stubs/nfs-fake-callout new file mode 100755 index 0000000..a4d43d0 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/nfs-fake-callout @@ -0,0 +1,15 @@ +#!/bin/sh + +case "$1" in +register) + echo "ALL" + exit + ;; +esac + +if [ "$NFS_FAKE_CALLOUT_MAGIC" = "$1" ]; then + echo "$1" + exit 1 +fi + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/nfsconf b/ctdb/tests/UNIT/eventscripts/stubs/nfsconf new file mode 100755 index 0000000..84dd9ea --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/nfsconf @@ -0,0 +1,5 @@ +#!/bin/sh + +# This always fails for now, since there are no tests that expect to +# use it. +exit 1 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/pidof b/ctdb/tests/UNIT/eventscripts/stubs/pidof new file mode 100755 index 0000000..6a25395 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/pidof @@ -0,0 +1,17 @@ +#!/bin/sh + +case "$1" in +nfsd) + echo "$FAKE_NFSD_THREAD_PIDS" + ;; +rpc.statd | rpc.rquotad | rpc.mountd) + echo "$FAKE_RPC_THREAD_PIDS" + ;; +smbd) + echo "$FAKE_SMBD_THREAD_PIDS" + ;; +*) + echo "pidof: \"$1\" not implemented" + exit 1 + ;; +esac diff --git a/ctdb/tests/UNIT/eventscripts/stubs/pkill b/ctdb/tests/UNIT/eventscripts/stubs/pkill new file mode 100755 index 0000000..b3f1de5 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/pkill @@ -0,0 +1,7 @@ +#!/bin/sh + +# Always succeed. This means that pkill -0 will always find a +# process and anything else will successfully kill. This should +# exercise a good avriety of code paths. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ps b/ctdb/tests/UNIT/eventscripts/stubs/ps new file mode 100755 index 0000000..0d33203 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ps @@ -0,0 +1,48 @@ +#!/bin/sh + +usage() +{ + echo "ps [ -p PID | -o FORMAT | aufxww ]" + exit 1 +} + +while getopts "o:p:h:?" opt; do + case "$opt" in + o) format="$OPTARG" ;; + p) pid="$OPTARG" ;; + \? | h) usage ;; + esac +done +shift $((OPTIND - 1)) + +if [ -n "$pid" ] && [ -n "$FAKE_PS_MAP" ]; then + # shellcheck disable=SC1001 + case "$format" in + comm\=) + echo "$FAKE_PS_MAP" | + awk -v pid="$pid" '$1 == pid { print $2 }' + ;; + state\=) + echo "$FAKE_PS_MAP" | + awk -v pid="$pid" '$1 == pid { print $3 }' + ;; + esac + + exit +fi + +if [ "$1" != "auxfww" ]; then + echo "option $1 not supported" + usage +fi + +cat <<EOF +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 2 0.0 0.0 0 0 ? S Aug28 0:00 [kthreadd] +root 3 0.0 0.0 0 0 ? S Aug28 0:43 \_ [ksoftirqd/0] +... +root 1 0.0 0.0 2976 624 ? Ss Aug28 0:07 init [2] +root 495 0.0 0.0 3888 1640 ? Ss Aug28 0:00 udevd --daemon +... +[MORE FAKE ps OUTPUT] +EOF diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rm b/ctdb/tests/UNIT/eventscripts/stubs/rm new file mode 100755 index 0000000..6034d75 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rm @@ -0,0 +1,6 @@ +#!/bin/sh +# Make statd-callout happy +case "$*" in +*/var/lib/nfs/statd/sm*) : ;; +*) exec /bin/rm "$@" ;; +esac diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rpc.lockd b/ctdb/tests/UNIT/eventscripts/stubs/rpc.lockd new file mode 100755 index 0000000..e71f6cd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rpc.lockd @@ -0,0 +1,6 @@ +#!/bin/sh + +# Restart always "works". However, the test infrastructure may +# continue to mark the service as down, so that's what matters. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rpc.mountd b/ctdb/tests/UNIT/eventscripts/stubs/rpc.mountd new file mode 100755 index 0000000..e71f6cd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rpc.mountd @@ -0,0 +1,6 @@ +#!/bin/sh + +# Restart always "works". However, the test infrastructure may +# continue to mark the service as down, so that's what matters. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rpc.rquotad b/ctdb/tests/UNIT/eventscripts/stubs/rpc.rquotad new file mode 100755 index 0000000..e71f6cd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rpc.rquotad @@ -0,0 +1,6 @@ +#!/bin/sh + +# Restart always "works". However, the test infrastructure may +# continue to mark the service as down, so that's what matters. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rpc.statd b/ctdb/tests/UNIT/eventscripts/stubs/rpc.statd new file mode 100755 index 0000000..e71f6cd --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rpc.statd @@ -0,0 +1,6 @@ +#!/bin/sh + +# Restart always "works". However, the test infrastructure may +# continue to mark the service as down, so that's what matters. + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/rpcinfo b/ctdb/tests/UNIT/eventscripts/stubs/rpcinfo new file mode 100755 index 0000000..8732751 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/rpcinfo @@ -0,0 +1,78 @@ +#!/bin/sh + +prog="rpcinfo" + +usage() +{ + cat >&2 <<EOF +Usage: $prog -T tcp host program [version] + +A fake rpcinfo stub that succeeds for items in FAKE_RPCINFO_SERVICES, +depending on command-line options. + +EOF + exit 1 +} + +parse_options() +{ + while getopts "T:h?" opt; do + case "$opt" in + T) netid="$OPTARG" ;; + \? | h) usage ;; + esac + done + shift $((OPTIND - 1)) + + [ "$netid" = "tcp" ] || usage + + host="$1" + shift + [ "$host" = "localhost" ] || [ "$host" = "127.0.0.1" ] || usage + + if [ $# -lt 1 ] || [ $# -gt 2 ]; then + usage + fi + + p="$1" + v="$2" +} + +parse_options "$@" + +for i in ${FAKE_RPCINFO_SERVICES}; do + # This is stupidly cumulative, but needs to happen after the + # initial split of the list above. + IFS="${IFS}:" + # Want glob expansion + # shellcheck disable=SC2086 + set -- $i + # $1 = program, $2 = low version, $3 = high version + + if [ "$1" = "$p" ]; then + if [ -n "$v" ]; then + if [ "$2" -le "$v" ] && [ "$v" -le "$3" ]; then + echo "program ${p} version ${v} ready and waiting" + exit 0 + else + echo "rpcinfo: RPC: Program/version mismatch; low version = ${2}, high version = ${3}" >&2 + echo "program ${p} version ${v} is not available" + exit 1 + fi + else + for j in $(seq "$2" "$3"); do + echo "program ${p} version ${j} ready and waiting" + done + exit 0 + fi + fi +done + +echo "rpcinfo: RPC: Program not registered" >&2 +if [ -n "$v" ]; then + echo "program ${p} version ${v} is not available" +else + echo "program ${p} is not available" +fi + +exit 1 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/service b/ctdb/tests/UNIT/eventscripts/stubs/service new file mode 100755 index 0000000..d706280 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/service @@ -0,0 +1,65 @@ +#!/bin/sh + +service_status_dir="${CTDB_TEST_TMP_DIR}/service_fake_status" +mkdir -p "$service_status_dir" + +service="$1" +flag="${service_status_dir}/${service}" + +start() +{ + if [ -f "$flag" ]; then + echo "service: can't start ${service} - already running" + exit 1 + else + touch "$flag" + echo "Starting ${service}: OK" + fi +} + +stop() +{ + if [ -f "$flag" ]; then + echo "Stopping ${service}: OK" + rm -f "$flag" + else + echo "service: can't stop ${service} - not running" + exit 1 + fi +} + +case "$2" in +start) + start + ;; +stop) + stop + ;; +restart | reload) + stop + start + ;; +status) + if [ -f "$flag" ]; then + echo "$service running" + exit 0 + else + echo "$service not running" + exit 3 + fi + ;; +force-started) + # For test setup... + touch "$flag" + ;; +force-stopped) + # For test setup... + rm -f "$flag" + ;; +*) + echo "service $service $2 not supported" + exit 1 + ;; +esac + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/sleep b/ctdb/tests/UNIT/eventscripts/stubs/sleep new file mode 100755 index 0000000..0d0e82b --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/sleep @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ "$FAKE_SLEEP_REALLY" = "yes" ]; then + /bin/sleep "$@" +elif [ -n "$FAKE_SLEEP_FORCE" ]; then + /bin/sleep "$FAKE_SLEEP_FORCE" +else + : +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/smnotify b/ctdb/tests/UNIT/eventscripts/stubs/smnotify new file mode 100755 index 0000000..5606b3d --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/smnotify @@ -0,0 +1,65 @@ +#!/bin/sh + +usage() +{ + _prog="${0##*/}" # basename + cat <<EOF +Usage: ${_prog} --client=CLIENT --ip=IP --server=SERVER --stateval=STATEVAL +EOF + exit 1 +} + +cip="" +sip="" +mon_name="" +state="" + +while [ $# -gt 0 ]; do + case "$1" in + --client) + cip="$2" + shift 2 + ;; + --client=*) + cip="${1#*=}" + shift + ;; + --ip) + sip="$2" + shift 2 + ;; + --ip=*) + sip="${1#*=}" + shift + ;; + --server) + mon_name="$2" + shift 2 + ;; + --server=*) + mon_name="${1#*=}" + shift + ;; + --stateval) + state="$2" + shift 2 + ;; + --stateval=*) + state="${1#*=}" + shift + ;; + --) + shift + break + ;; + -*) usage ;; + *) break ;; + esac +done +[ $# -eq 0 ] || usage + +if [ -z "$cip" ] || [ -z "$sip" ] || [ -z "$mon_name" ] || [ -z "$state" ]; then + usage +fi + +echo "SM_NOTIFY: ${sip} -> ${cip}, MON_NAME=${mon_name}, STATE=${state}" diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ss b/ctdb/tests/UNIT/eventscripts/stubs/ss new file mode 100755 index 0000000..c1199fe --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/ss @@ -0,0 +1,206 @@ +#!/bin/sh + +prog="ss" + +usage() +{ + cat >&2 <<EOF +Usage: $prog { -t|--tcp | -x|--unix } [options] [ FILTER ] + +A fake ss stub that prints items depending on the variables +FAKE_NETSTAT_TCP_ESTABLISHED, FAKE_TCP_LISTEN, +FAKE_NETSTAT_UNIX_LISTEN, depending on command-line options. + +Note that -n is ignored. + +EOF + exit 1 +} + +not_supported() +{ + echo "Options not supported in stub: $*" >&2 + usage +} + +############################################################ + +# +parse_filter() +{ + # Very limited implementation: + # We only expect to find || inside parentheses + # We don't expect to see && - it is implied by juxtaposition + # Operator for port comparison is ignored and assumed to be == + + # Build lists of source ports and source IP addresses where + # each entry is surrounded by '|' characters. These lists can + # be easily "searched" using the POSIX prefix and suffix + # removal operators. + in_parens=false + sports="|" + srcs="|" + + while [ -n "$1" ]; do + case "$1" in + \() + in_parens=true + shift + ;; + \)) + in_parens=false + shift + ;; + \|\|) + if ! $in_parens; then + not_supported "|| in parentheses" + fi + shift + ;; + sport) + p="${3#:}" + sports="${sports}${p}|" + shift 3 + ;; + src) + ip="${2#\[}" + ip="${ip%\]}" + srcs="${srcs}${ip}|" + shift 2 + ;; + *) + usage + ;; + esac + done +} + +# Check if socket has matches in both ok_ips and ok_ports +filter_socket() +{ + ok_ips="$1" + ok_ports="$2" + socket="$3" + + ip="${socket%:*}" + port="${socket##*:}" + + if [ "$ok_ports" != "|" ] && + [ "${ok_ports#*|"${port}"|}" = "$ok_ports" ]; then + return 1 + fi + if [ "$ok_ips" != "|" ] && [ "${ok_ips#*|"${ip}"|}" = "$ok_ips" ]; then + return 1 + fi + + return 0 +} + +ss_tcp_established() +{ + if $header; then + echo "Recv-Q Send-Q Local Address:Port Peer Address:Port" + fi + + # Yes, lose the quoting so we can do a hacky parsing job + # shellcheck disable=SC2048,SC2086 + parse_filter $* + + for i in $FAKE_NETSTAT_TCP_ESTABLISHED; do + src="${i%|*}" + dst="${i#*|}" + if filter_socket "$srcs" "$sports" "$src"; then + echo 0 0 "$src" "$dst" + fi + done + + if [ -z "$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" ]; then + return + fi + while read -r src dst; do + if filter_socket "$srcs" "$sports" "$src"; then + echo 0 0 "$src" "$dst" + fi + done <"$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" +} + +############################################################ + +unix_listen() +{ + if $header; then + cat <<EOF +Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port" +EOF + fi + + # Yes, lose the quoting so we can do a hacky parsing job + # shellcheck disable=SC2048,SC2086 + parse_filter $* + + _n=12345 + for _s in $FAKE_NETSTAT_UNIX_LISTEN; do + # ss matches Unix domain sockets as either src or + # sport. + if filter_socket "$srcs" "$sports" "${_s}:" || + filter_socket "$srcs" "$sports" ":${_s}"; then + printf "u_str LISTEN 0 128 %s %d * 0\n" "$_s" "$_n" + _n=$((_n + 1)) + fi + done +} + +############################################################ + +# Defaults. +tcp=false +unix=false +all=false +listen=false +header=true + +orig="$*" + +while getopts "txnalHh?" opt; do + case "$opt" in + t) tcp=true ;; + x) unix=true ;; + l) listen=true ;; + a) all=true ;; + H) header=false ;; + n) : ;; + \? | h) usage ;; + esac +done +shift $((OPTIND - 1)) + +$tcp || $unix || not_supported "$*" +if [ -z "$all" ]; then + nosupported "$*" +fi + +if $tcp; then + if [ "$1" != "state" ] || [ "$2" != "established" ] || $listen; then + usage + fi + + shift 2 + + # Yes, lose the quoting so we can do a hacky parsing job + # shellcheck disable=SC2048,SC2086 + ss_tcp_established $* + + exit +fi + +if $unix; then + if ! $listen; then + not_supported "$orig" + fi + + # Yes, lose the quoting so we can do a hacky parsing job + # shellcheck disable=SC2048,SC2086 + unix_listen $* + + exit +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/stat b/ctdb/tests/UNIT/eventscripts/stubs/stat new file mode 100755 index 0000000..840265f --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/stat @@ -0,0 +1,71 @@ +#!/bin/sh + +usage() +{ + echo "stat -c FMT FILE ..." + exit 1 +} + +format="" + +while getopts "c:h:?" opt; do + case "$opt" in + c) format="$OPTARG" ;; + \? | h) usage ;; + esac +done +shift $((OPTIND - 1)) + +fake_device_id() +{ + _path="$1" + + _t=$(echo "$FAKE_FILE_ID_MAP" | + awk -v path="${_path}" '$1 == path { print $2 }') + _major_minor="${_t%:*}" + _major="0x${_major_minor%:*}" + _minor="0x${_major_minor#*:}" + _device_id=$((_major * 256 + _minor)) + echo "$_device_id" +} + +fake_inode() +{ + _path="$1" + + _t=$(echo "$FAKE_FILE_ID_MAP" | + awk -v path="${_path}" '$1 == path { print $2 }') + echo "${_t##*:}" +} + +if [ -n "$format" ]; then + for f; do + if [ ! -e "$f" ]; then + continue + fi + case "$f" in + /*) path="$f" ;; + *) path="${PWD}/${f}" ;; + esac + + case "$format" in + "s#[0-9a-f]*:[0-9a-f]*:%i #%n #") + inode=$(fake_inode "$path") + echo "s#[0-9a-f]*:[0-9a-f]*:${inode} #${f} #" + ;; + "%d:%i") + device_id=$(fake_device_id "$path") + inode=$(fake_inode "$path") + echo "${device_id}:${inode}" + ;; + *) + echo "Unsupported format \"${format}\"" + usage + ;; + esac + done + + exit +fi + +usage diff --git a/ctdb/tests/UNIT/eventscripts/stubs/tdb_mutex_check b/ctdb/tests/UNIT/eventscripts/stubs/tdb_mutex_check new file mode 100755 index 0000000..6cc7572 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/tdb_mutex_check @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ -z "$FAKE_TDB_MUTEX_CHECK" ]; then + exit +fi + +echo "$FAKE_TDB_MUTEX_CHECK" | + while read -r pid chain; do + echo "[${chain}] pid=${pid}" + done diff --git a/ctdb/tests/UNIT/eventscripts/stubs/tdbdump b/ctdb/tests/UNIT/eventscripts/stubs/tdbdump new file mode 100755 index 0000000..92dcb8e --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/tdbdump @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ "$FAKE_TDB_IS_OK" = "yes" ]; then + echo "TDB good" + exit 0 +else + echo "TDB busted" + exit 1 +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/tdbtool b/ctdb/tests/UNIT/eventscripts/stubs/tdbtool new file mode 100755 index 0000000..df83160 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/tdbtool @@ -0,0 +1,36 @@ +#!/bin/sh + +do_help() +{ + if [ "$FAKE_TDBTOOL_SUPPORTS_CHECK" = "yes" ]; then + echo "check" + fi + exit 0 +} + +do_check() +{ + if [ "$FAKE_TDB_IS_OK" = "yes" ]; then + echo "Database integrity is OK" + else + echo "Database is busted" + fi + exit 0 +} + +do_cmd() +{ + case "$*" in + *check) do_check ;; + help) do_help ;; + "") read -r tdb_cmd && [ -n "$tdb_cmd" ] && do_cmd "$tdb_cmd" ;; + *) + echo "$0: Not implemented: $*" + exit 1 + ;; + esac +} + +do_cmd "$@" + +exit 0 diff --git a/ctdb/tests/UNIT/eventscripts/stubs/testparm b/ctdb/tests/UNIT/eventscripts/stubs/testparm new file mode 100755 index 0000000..3a97e91 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/testparm @@ -0,0 +1,84 @@ +#!/bin/sh + +not_implemented() +{ + echo "testparm: option \"$1\" not implemented in stub" >&2 + exit 2 +} + +error() +{ + cat >&2 <<EOF +Load smb config files from ${CTDB_SYS_ETCDIR}/samba/smb.conf +rlimit_max: increasing rlimit_max (2048) to minimum Windows limit (16384) +EOF + + for i in $FAKE_SHARES; do + bi=$(basename "$i") + echo "Processing section \"[${bi}]\"" + done >&2 + + cat >&2 <<EOF +Loaded services file OK. +WARNING: 'workgroup' and 'netbios name' must differ. + +EOF + + exit 1 +} + +timeout() +{ + echo "$0: INTERNAL ERROR - timeout stub should avoid this" >&2 +} + +if [ -n "$FAKE_TESTPARM_FAIL" ]; then + error +fi + +if [ -n "$FAKE_TIMEOUT" ]; then + timeout +fi + +# Ensure that testparm always uses our canned configuration instead of +# the global one, unless some other file is specified. + +file="" +param="" +for i; do + case "$i" in + --parameter-name=*) param="${i#--parameter-name=}" ;; + -*) : ;; + *) file="$i" ;; + esac +done + +# Parse out parameter request +if [ -n "$param" ]; then + sed -n \ + -e "s|^[[:space:]]*${param}[[:space:]]*=[[:space:]]\(..*\)|\1|p" \ + "${file:-"${CTDB_SYS_ETCDIR}/samba/smb.conf"}" + exit 0 +fi + +if [ -n "$file" ]; then + # This should include the shares, since this is used when the + # samba eventscript caches the output. + cat "$file" +else + # We force our own smb.conf and add the shares. + cat "${CTDB_SYS_ETCDIR}/samba/smb.conf" + + for i in $FAKE_SHARES; do + bi=$(basename "$i") + cat <<EOF + +[${bi}] + path = $i + comment = fake share $bi + guest ok = no + read only = no + browsable = yes +EOF + done +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/timeout b/ctdb/tests/UNIT/eventscripts/stubs/timeout new file mode 100755 index 0000000..26132ee --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/timeout @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ -n "$FAKE_TIMEOUT" ]; then + exit 124 +else + shift 1 + exec "$@" +fi diff --git a/ctdb/tests/UNIT/eventscripts/stubs/wbinfo b/ctdb/tests/UNIT/eventscripts/stubs/wbinfo new file mode 100755 index 0000000..b4bd9f2 --- /dev/null +++ b/ctdb/tests/UNIT/eventscripts/stubs/wbinfo @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$FAKE_WBINFO_FAIL" = "yes" ]; then + exit 1 +fi + +exit 0 |