diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:52:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:52:36 +0000 |
commit | 7de03e4e519705301265c0415b3c0af85263a7ac (patch) | |
tree | 29d819c5227e3619d18a67d2a5dde963b3229dbe /tools/ocft | |
parent | Initial commit. (diff) | |
download | resource-agents-7de03e4e519705301265c0415b3c0af85263a7ac.tar.xz resource-agents-7de03e4e519705301265c0415b3c0af85263a7ac.zip |
Adding upstream version 1:4.13.0.upstream/1%4.13.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools/ocft')
39 files changed, 4960 insertions, 0 deletions
diff --git a/tools/ocft/ChangeLog b/tools/ocft/ChangeLog new file mode 100644 index 0000000..8b00210 --- /dev/null +++ b/tools/ocft/ChangeLog @@ -0,0 +1,57 @@ +0.43: + - Add an option 'Agent' in 'CONFIG' + - Fix a bug about remote shell. + - Add top level option 'VARIABLE'. + - Add top level option 'CLEANUP-AGENT'. + - Rename Var & Unvar to Env & Unenv. + - Fix a bug about agent installation. + - Modified configs of agent according the new syntax. +0.42: + - Fix a bug about agent installation. + - The tests stop early if the basic functionality it not there. + - Fix a bug about 'config parser'. + - Keep the resource stat between the runs to avoid there are multiple stop/start per run. + - Add a function with warning output. + - Adjust the sequence of cases running. + - Change the default timeout. + - Replace the crm_master command in Agent scripts, it is no use in testing, + because the agent runs in local when test. + - Support drbd testing if the configuration is correct. + - Fix a 'Include' bug. + - Fix a bug about configuration of 'mysql'. +0.41: + - Fixed a remote shell bug. + - Improved 'Include' option, now it supports remote shell, invoked just like 'Include@ip_address'. + - Show line number, if syntax error occurs in config file. + - Add a 'AgentRoot' sub-option. + - Fix a bug with config parsing. + - Rename ACTION "run" to "test". + - Add a simple output mode for "test" ACTION. + - Add a verbose ouput mode for "help" ACTION. + - The output will be recorded to log file. + - Add double stop and double start to tests. + - Exit with 1 if test script failed. + - The output of agents will be exposed if the test fails. + - Run zypper with -q + - Use 127.0.0.x(and lo for interface) for agents IP* +0.4: + - Add a 'CASE-BLOCK' top option, it can be included by 'CASE' + - Add a 'SETUP-AGENT' top option, you can initialize agents before testing. + - Add a 'Include' sub-option. + - Add a 'Unvar' sub-option. + - Rename 'GLOBAL' to 'CONFIG'. + - Modify a part of syntax. + - Imporve the 'InstallPackage' option, now it supports SUSE, Redhat and Debian. + - Add README & README.zh_CN. +0.3: + - All statements in CASE can be executed by remote shell. +0.2: + - Implement options: BashAtExit, GLOBAL, HangTimeout, InstallPackage. + - Delete option: Name. + - Modify a part of syntax. + - Fix some bugs. + - Print testing message in human readable format. + - Improve 'make' and 'run' option. + - Add 'clean' option. +0.1: + - Implement options: CASE, Bash, Run, Var, Name. diff --git a/tools/ocft/Filesystem b/tools/ocft/Filesystem new file mode 100644 index 0000000..2b22d1b --- /dev/null +++ b/tools/ocft/Filesystem @@ -0,0 +1,105 @@ +# Filesystem +# by dejan@suse.de on +# Tue Feb 15 18:50:04 CET 2011 +# +CONFIG + Agent Filesystem + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +VARIABLE + OCFT_rundir="`get_rundir`" + OCFT_fs="$OCFT_rundir/resource-agents/ocft-Filesystem-fs" + OCFT_dir="$OCFT_rundir/resource-agents/ocft-Filesystem-mnt" + OCFT_loop="`loopbackeddev make $OCFT_fs 16M`" + +SETUP-AGENT + mke2fs -j -Fq -m 0 $OCFT_loop + +CLEANUP-AGENT + loopbackeddev unmake $OCFT_fs + rmdir $OCFT_dir + +CASE-BLOCK required_args + Env OCF_RESKEY_device=$OCFT_loop + Env OCF_RESKEY_fstype=ext3 + Env OCF_RESKEY_directory=$OCFT_dir + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_device'" + Include prepare + Env OCF_RESKEY_device=/dev/no_such_device + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: unset 'OCF_RESKEY_device'" + Include prepare + Unenv OCF_RESKEY_device + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "monitor depth 10 when running" + Include prepare + AgentRun start + Env OCF_CHECK_LEVEL=10 + AgentRun monitor OCF_SUCCESS + +CASE "monitor depth 20 with running" + Include prepare + AgentRun start + Env OCF_CHECK_LEVEL=20 + AgentRun monitor OCF_SUCCESS + +CASE "start insert failure (remove device)" + Include prepare + Bash losetup -d $OCFT_loop + BashAtExit losetup $OCFT_loop $OCFT_fs + AgentRun start OCF_ERR_GENERIC + +CASE "monitor depth 20 insert failure (r/o fs)" + Include prepare + AgentRun start + Bash mount -o remount,ro $OCFT_dir + BashAtExit mount -o remount,rw $OCFT_dir + Env OCF_CHECK_LEVEL=20 + AgentRun monitor OCF_ERR_GENERIC + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/IPaddr2 b/tools/ocft/IPaddr2 new file mode 100644 index 0000000..04698a0 --- /dev/null +++ b/tools/ocft/IPaddr2 @@ -0,0 +1,137 @@ +# IPaddr2 + +CONFIG + Agent IPaddr2 + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +SETUP-AGENT + ip addr add 192.168.144.1/24 dev eth0 brd 192.168.144.255 + +CLEANUP-AGENT + ip addr del 192.168.144.1/24 dev eth0 + +CASE-BLOCK required_args + Env OCF_RESKEY_ip=192.168.144.2 + +CASE-BLOCK check_iflabel_assigned + Bash ip -4 -o addr show eth0 | grep -w 192.168.144.2/24 | grep -w eth0:iflabel >/dev/null # checking iflabel was assigned correctly + +CASE-BLOCK check_iflabel_removed + Bash ! ip -4 -o addr show eth0 | grep -w 192.168.144.2/24 | grep -w eth0:iflabel >/dev/null # checking iflabel was removed correctly + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_ip'" + Include prepare + Unenv OCF_RESKEY_ip + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set invalid 'OCF_RESKEY_ip'" + Include prepare + Env OCF_RESKEY_ip=not_ip_address + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set 'OCF_RESKEY_cidr_netmask'" + Include prepare + Env OCF_RESKEY_cidr_netmask=24 + AgentRun start OCF_SUCCESS + +CASE "check base env: set invalid 'OCF_RESKEY_cidr_netmask'" + Include prepare + Env OCF_RESKEY_cidr_netmask=not_netmask + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set 'OCF_RESKEY_broadcast'" + Include prepare + Env OCF_RESKEY_broadcast=192.168.144.255 + AgentRun start OCF_SUCCESS + +CASE "check base env: set invalid 'OCF_RESKEY_broadcast'" + Include prepare + Env OCF_RESKEY_broadcast=not_broadcast + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set 'OCF_RESKEY_nic'" + Include prepare + Env OCF_RESKEY_nic=eth0 + AgentRun start OCF_SUCCESS + +CASE "check base env: set invalid 'OCF_RESKEY_nic'" + Include prepare + Env OCF_RESKEY_nic=not_nic + AgentRun start OCF_ERR_CONFIGURED + AgentRun validate-all OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "Attachment to loopback interface" + Env OCF_RESKEY_ip=127.0.0.3 + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + +CASE "check additional env: set 'OCF_RESKEY_iflabel'" + Include prepare + Env OCF_RESKEY_nic=eth0 + Env OCF_RESKEY_iflabel=iflabel + AgentRun start OCF_SUCCESS + Include check_iflabel_assigned + AgentRun stop OCF_SUCCESS + Include check_iflabel_removed + +# This is deprecated but still supported for the compatibility. +CASE "check additional env: specify iflabel in 'OCF_RESKEY_nic'" + Include prepare + Env OCF_RESKEY_nic=eth0:iflabel + AgentRun start OCF_SUCCESS + Include check_iflabel_assigned + AgentRun stop OCF_SUCCESS + Include check_iflabel_removed + +# monitor should return OCF_ERR_GENERIC rather than OCF_ERR_CONFIGURED +# when the specified OCF_RESKEY_nic is vanished by a failure. +# This has been changed as of 3.9.6. +CASE "monitor failure when 'OCF_RESKEY_nic' is vanished" + Include prepare + Env OCF_RESKEY_nic=ethVanished + Env OCF_RESKEY_CRM_meta_interval=10 # not in probe + AgentRun monitor OCF_ERR_GENERIC diff --git a/tools/ocft/IPaddr2v4 b/tools/ocft/IPaddr2v4 new file mode 100644 index 0000000..4d37168 --- /dev/null +++ b/tools/ocft/IPaddr2v4 @@ -0,0 +1,323 @@ +# IPaddr2v4 + +# Note: This test case uses two NICs(eth0, eth1) and +# a IPv4 address prefix (192.168.144.0/24). +# Adjust them according to your environment at VARIABLE section if needed. + +CONFIG + Agent IPaddr2 + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +VARIABLE + OCFT_target_ip=192.168.144.2 + OCFT_target_nic=eth0 + OCFT_target_prefix=24 + OCFT_target_netaddr=192.168.144.1/$OCFT_target_prefix + OCFT_target_brd=192.168.144.255 + OCFT_wrong_ip=192.168.120.1 + OCFT_force_nic=eth1 + OCFT_force_prefix=16 + OCFT_force_prefix2=28 + OCFT_force_brd=192.168.255.255 + +SETUP-AGENT + ip addr add $OCFT_target_netaddr dev $OCFT_target_nic brd $OCFT_target_brd + +CLEANUP-AGENT + ip addr del $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK required_args + Env OCF_RESKEY_ip=$OCFT_target_ip + Env OCFT_check_ip=$OCFT_target_ip + Env OCFT_check_prefix=$OCFT_target_prefix + Env OCFT_check_nic=$OCFT_target_nic + +CASE-BLOCK check_ip_assigned + Bash ip -4 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ip/$OCFT_check_prefix >/dev/null # checking if the IPv4 address was assigned correctly + +CASE-BLOCK check_ip_removed + Bash ! ip -4 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ip/$OCFT_check_prefix >/dev/null # checking if the IPv4 address was removed correctly + +CASE-BLOCK base_ip_assigned + Bash ip addr add $OCFT_target_netaddr dev $OCFT_target_nic brd $OCFT_target_brd + +CASE-BLOCK base_ip_removed + Bash ip addr del $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +# CASE No.0 +# +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + Include check_ip_assigned + +# CASE No.1 +# +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.2 +# +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +# CASE No.3 +# +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +# CASE No.4 +# +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +# CASE No.5 +# +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +# CASE No.6 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 succeeds if the ip matched based on the netmask of the subnet +# or fails if it did not match to any. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 was using a wrong subnet mask (constant of 32) in this case. +# +CASE "params with nic, no cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.7 +# +CASE "params with nic, cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.8 +# +CASE "error params with wrong ip" + Include prepare + Env OCF_RESKEY_ip=$OCFT_wrong_ip + AgentRun start OCF_ERR_GENERIC + +# CASE No.9 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 fails when it could not determine the correct subnet mask. +# When it could not get base ip, it becomes the error. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 was using a wrong subnet mask (constant of 32) in this case. +# +CASE "params with force nic" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCFT_check_nic=$OCFT_force_nic + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + Unenv OCF_RESKEY_nic + +# CASE No.10 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 fails when it could not determine the broadcast. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 succeeded but it's considered ambiguous. +# +CASE "params with force cidr_netmask (base netmask > assigned netmask)" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + +# CASE No.11 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 succeeds but the broadcast is not set. +# This is because findif.sh can not calculate a broadcast from a netmask. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 succeeded with using a calculated broadcast. +# +CASE "force to use the specified nic and cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + Unenv OCF_RESKEY_cidr_netmask + + +# CASE No.12 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 fails when it could not determine the correct subnet mask. +# When it could not get base ip, it becomes the error. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 was using a wrong subnet mask (constant of 32) in this case. +# +CASE "error params with wrong ip and nic (not exist base_ip)" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCFT_check_nic=$OCFT_target_nic + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + Include base_ip_assigned + +# CASE No.13 +# +CASE "params with cidr_netmask" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.14 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 does not override the broadcast by cidr_netmask. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 overrode the broadcast calculated by cidr_netmask. +# +CASE "params with force cidr_netmask (base netmask < assigned netmask)" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_prefix=$OCFT_force_prefix2 + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.15 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 fails when it could not determine the broadcast. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 succeeded but it's considered ambiguous. +# +CASE "error params with wrong ip and cidr_netmask (not exist base_ip)" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + AgentRun start OCF_ERR_GENERIC + Include base_ip_assigned + +# CASE No.16 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 succeeds but the broadcast is not set. +# This is because findif.sh can not calculate a broadcast from a netmask. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 succeeded with using a calculated broadcast. +# +CASE "force to use the specified nic and cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_prefix=$OCFT_force_prefix2 + Env OCFT_check_nic=$OCFT_force_nic + AgentRun start OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.17 +# Note: this result is different from IPaddr2 in 3.9.3. +# IPaddr2 succeeds but the broadcast is not set. +# This is because findif.sh can not calculate a broadcast from a netmask. +# Recommended to always specify both nic, cidr_netmask, and broadcast when you needed. +# IPaddr2 in 3.9.3 succeeded with using a calculated broadcast. +# +CASE "force to use the specified nic and cidr_netmask (not exist base_ip)" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_prefix=$OCFT_force_prefix2 + Env OCFT_check_nic=$OCFT_force_nic + AgentRun start OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Unenv OCF_RESKEY_nic + Unenv OCF_RESKEY_cidr_netmask + Include base_ip_assigned + +# CASE No.18 +# +CASE "params with broadcast, no nic, no cidr_netmask" + Include prepare + Env OCF_RESKEY_broadcast=$OCFT_force_brd + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.19 +# +CASE "params with broadcast, no nic, no cidr_netmask" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_broadcast=$OCFT_force_brd + AgentRun start OCF_ERR_GENERIC + Include base_ip_assigned + +# CASE No.20 +# +CASE "force to use the specified nic and cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCF_RESKEY_broadcast=$OCFT_force_brd + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + Unenv OCF_RESKEY_cidr_netmask + +# CASE No.21 +# +CASE "force to use the specified nic and cidr_netmask" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCF_RESKEY_broadcast=$OCFT_target_brd + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix2 + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + Include base_ip_assigned + diff --git a/tools/ocft/IPaddr2v6 b/tools/ocft/IPaddr2v6 new file mode 100644 index 0000000..d24d890 --- /dev/null +++ b/tools/ocft/IPaddr2v6 @@ -0,0 +1,250 @@ +# IPaddr2v6 + +# Note: This test case uses two NICs(eth0, eth1) and +# a IPv6 address prefix (2001:db8::/32, RFC3849). +# Adjust them according to your environment at VARIABLE section if needed. + +CONFIG + Agent IPaddr2 + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +VARIABLE + OCFT_target_ip=2001:db8:1234::2 + OCFT_target_nic=eth0 + OCFT_target_prefix=64 + OCFT_target_netaddr=2001:db8:1234::1/$OCFT_target_prefix + OCFT_target_linklocal=fe80::2 + OCFT_wrong_ip=2001:db8:5678::2 + OCFT_force_nic=eth1 + OCFT_force_prefix=80 + OCFT_force_prefix2=48 + +SETUP-AGENT + ip addr add $OCFT_target_netaddr dev $OCFT_target_nic + +CLEANUP-AGENT + ip addr del $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK required_args + Env OCF_RESKEY_ip=$OCFT_target_ip + Env OCFT_check_ip=$OCFT_target_ip + Env OCFT_check_prefix=$OCFT_target_prefix + Env OCFT_check_nic=$OCFT_target_nic + +CASE-BLOCK check_ip_assigned + Bash ip -6 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ip/$OCFT_check_prefix >/dev/null # checking if the IPv6 address was assigned correctly + +CASE-BLOCK check_ip_removed + Bash ! ip -6 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ip/$OCFT_check_prefix >/dev/null # checking if the IPv6 address was removed correctly + +CASE-BLOCK base_ip_assigned + Bash ip addr add $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK base_ip_removed + Bash ip addr del $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +# CASE No.0 +# +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + Include check_ip_assigned + +# CASE No.1 +# +CASE "normal stop" + Include prepare + AgentRun start OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.2 +# +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +# CASE No.3 +# +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +# CASE No.4 +# +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +# CASE No.5 +# +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +# CASE No.6 +# +CASE "error params with wrong ip" + Include prepare + Env OCF_RESKEY_ip=$OCFT_wrong_ip + AgentRun start OCF_ERR_GENERIC + +# CASE No.7 +# +CASE "error params with no nic for a link-local IPv6 address" + Include prepare + Env OCF_RESKEY_ip=$OCFT_target_linklocal + Env OCFT_check_ip=$OCFT_target_linklocal + # nic is mandatory for a link-local address + AgentRun start OCF_ERR_CONFIGURED + +# CASE No.8 +# +CASE "params with nic, no cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.9 +# +CASE "normal usage for a link-local IPv6 address, params with nic" + Include prepare + Env OCF_RESKEY_ip=$OCFT_target_linklocal + Env OCFT_check_ip=$OCFT_target_linklocal + # nic is mandatory for a link-local address + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCFT_check_nic=$OCFT_target_nic + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.10 +# +CASE "error params with wrong ip and nic (not exist base_ip)" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCFT_check_nic=$OCFT_target_nic + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + Include base_ip_assigned + +# CASE No.11 +# +CASE "params with force nic" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCFT_check_nic=$OCFT_force_nic + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + Unenv OCF_RESKEY_nic + +# CASE No.12 +# +CASE "params with force cidr_netmask" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + Env OCFT_check_prefix=$OCFT_target_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.13 +# +CASE "params with force cidr_netmask (base netmask < assigned netmask)" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + +# CASE No.14 +# +CASE "params with force cidr_netmask (base netmask > assigned netmask)" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_prefix=$OCFT_force_prefix2 + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + +# CASE No.15 +# +CASE "params with cidr_netmask" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + Env OCFT_check_prefix=$OCFT_target_prefix + AgentRun start OCF_ERR_GENERIC + Include base_ip_assigned + +# CASE No.16 +# +CASE "params with nic, cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + Env OCFT_check_nic=$OCFT_target_nic + Env OCFT_check_prefix=$OCFT_target_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.17 +# +CASE "force to use the specified nic and cidr_netmask (base netmask < assigned netmask)" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.18 +# This use case is now valid. It was not allowed until v3.9.2. +# +CASE "force to use the specified nic and cidr_netmask (base netmask > assigned netmask)" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix2 + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +# CASE No.19 +# +CASE "force to use the specified nic and cidr_netmask (base netmask > assigned netmask)" + Include prepare + Include base_ip_removed + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix2 + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix2 + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun stop OCF_SUCCESS + Include check_ip_removed + Include base_ip_assigned + diff --git a/tools/ocft/IPsrcaddr b/tools/ocft/IPsrcaddr new file mode 100644 index 0000000..d95142e --- /dev/null +++ b/tools/ocft/IPsrcaddr @@ -0,0 +1,63 @@ +# IPsrcaddr + +CONFIG + Agent IPsrcaddr + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage iproute2 + HangTimeout 20 + +CASE-BLOCK required_args + Env OCF_RESKEY_ipaddress= # put here your IP + Env OCF_RESKEY_cidr_netmask= # and the netmask + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_ipaddress'" + Include prepare + Unenv OCF_RESKEY_ipaddress + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set invalid 'OCF_RESKEY_ipaddress'" + Include prepare + Env OCF_RESKEY_ipaddress=not_ip_address + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/IPv6addr b/tools/ocft/IPv6addr new file mode 100644 index 0000000..36a9642 --- /dev/null +++ b/tools/ocft/IPv6addr @@ -0,0 +1,150 @@ +# IPv6addr + +# Note: This test case uses two NICs(eth0, eth1) and +# a IPv6 address prefix (2001:db8::/32, RFC3849). +# Adjust them according to your environment at VARIABLE section if needed. + +CONFIG + Agent IPv6addr + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +VARIABLE + OCFT_target_ipv6addr=2001:db8:1234::2 + OCFT_target_nic=eth0 + OCFT_target_prefix=64 + OCFT_target_netaddr=2001:db8:1234::1/$OCFT_target_prefix + OCFT_target_linklocal=fe80::2 + OCFT_wrong_ipv6addr=2001:db8:5678::2 + OCFT_force_nic=eth1 + OCFT_force_prefix=80 + +SETUP-AGENT + ip addr add $OCFT_target_netaddr dev $OCFT_target_nic + +CLEANUP-AGENT + ip addr del $OCFT_target_netaddr dev $OCFT_target_nic + +CASE-BLOCK required_args + Env OCF_RESKEY_ipv6addr=$OCFT_target_ipv6addr + Env OCFT_check_ipv6addr=$OCFT_target_ipv6addr + Env OCFT_check_prefix=$OCFT_target_prefix + Env OCFT_check_nic=$OCFT_target_nic + +CASE-BLOCK check_ip_assigned + Bash ip -6 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ipv6addr/$OCFT_check_prefix >/dev/null # checking if the IPv6 address was assigned correctly + +CASE-BLOCK check_ip_removed + Bash ! ip -6 -o addr show $OCFT_check_nic | grep -w $OCFT_check_ipv6addr/$OCFT_check_prefix >/dev/null # checking if the IPv6 address was removed correctly + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + Include check_ip_assigned + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "params with nic, no cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +CASE "params with nic, cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_target_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_target_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +CASE "normal usage for a link-local IPv6 address" + Include prepare + Env OCF_RESKEY_ipv6addr=$OCFT_target_linklocal + Env OCFT_check_ipv6addr=$OCFT_target_linklocal + # nic is mandatory for a link-local address + Env OCF_RESKEY_nic=$OCFT_target_nic + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed + +CASE "error start for a link-local IPv6 address when no nic" + Include prepare + Env OCF_RESKEY_ipv6addr=$OCFT_target_linklocal + # nic is mandatory for a link-local address + Unenv OCF_RESKEY_nic + AgentRun start OCF_ERR_GENERIC + Include check_ip_removed + +CASE "error params with wrong ipv6addr" + Include prepare + Env OCF_RESKEY_ipv6addr=$OCFT_wrong_ipv6addr + AgentRun start OCF_ERR_GENERIC + +# Note: this result is different from IPaddr2/findif +# IPaddr2 succeeds if the ip matched based on the netmask of the subnet +# or fails if it did not match to any. +# Recommended to always specify both nic and cidr_netmask when you needed. +CASE "error params with wrong cidr_netmask" + Include prepare + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + AgentRun start OCF_ERR_GENERIC + +# Note: this result is different from IPaddr2/findif +# IPaddr2 succeeds but it uses /32 as a guessed cidr_netmask which +# does not seem to be expected. +# Recommended to always specify both nic and cidr_netmask when you needed. +CASE "error params with wrong nic" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + AgentRun start OCF_ERR_GENERIC + +# Note: This use case is now valid. It was not allowed until v3.9.2. +CASE "force to use the specified nic and cidr_netmask" + Include prepare + Env OCF_RESKEY_nic=$OCFT_force_nic + Env OCF_RESKEY_cidr_netmask=$OCFT_force_prefix + Env OCFT_check_nic=$OCFT_force_nic + Env OCFT_check_prefix=$OCFT_force_prefix + AgentRun start OCF_SUCCESS + Include check_ip_assigned + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + Include check_ip_removed diff --git a/tools/ocft/LVM b/tools/ocft/LVM new file mode 100644 index 0000000..00b69ee --- /dev/null +++ b/tools/ocft/LVM @@ -0,0 +1,83 @@ +# LVM +# by dejan@suse.de on +# Wed Feb 16 13:15:01 CET 2011 + +CONFIG + Agent LVM + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +VARIABLE + OCFT_rundir="`get_rundir`" + OCFT_pv=$OCFT_rundir/resource-agents/ocft-LVM-pv + OCFT_vg=ocft-vg + OCFT_lv=ocft-lv + OCFT_loop="`loopbackeddev make $OCFT_pv 16M`" + +SETUP-AGENT + pvcreate $OCFT_loop + vgcreate -s 4K $OCFT_vg $OCFT_loop + lvcreate -n $OCFT_lv -L 600K $OCFT_vg + +CLEANUP-AGENT + vgchange -an $OCFT_vg + lvremove -f /dev/$OCFT_vg/$OCFT_lv + vgremove -f $OCFT_vg + pvremove $OCFT_loop + loopbackeddev unmake $OCFT_pv + +CASE-BLOCK required_args + Env OCF_RESKEY_volgrpname=$OCFT_vg + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_volgrpname'" + Include prepare + Env OCF_RESKEY_volgrpname=/dev/no_such_device + AgentRun start OCF_ERR_GENERIC + +CASE "check base env: unset 'OCF_RESKEY_volgrpname'" + Include prepare + Unenv OCF_RESKEY_volgrpname + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/MailTo b/tools/ocft/MailTo new file mode 100644 index 0000000..8754035 --- /dev/null +++ b/tools/ocft/MailTo @@ -0,0 +1,57 @@ +# MailTo + +CONFIG + Agent MailTo + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage mailx + HangTimeout 20 + +CASE-BLOCK required_args + Env OCF_RESKEY_email=root@localhost + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_email'" + Include prepare + Unenv OCF_RESKEY_email + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/Makefile.am b/tools/ocft/Makefile.am new file mode 100644 index 0000000..69c59ee --- /dev/null +++ b/tools/ocft/Makefile.am @@ -0,0 +1,63 @@ +# Author: John Shi +# jshi@suse.de +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = $(ocftcfgs_DATA) $(ocft_DATA) $(ocft_SCRIPTS) + +sbin_SCRIPTS = ocft + +ocftcfgsdir = $(datadir)/$(PACKAGE_NAME)/ocft/configs +ocftcfgs_DATA = apache \ + IPaddr2 \ + IPaddr2v4 \ + IPaddr2v6 \ + IPv6addr \ + Filesystem \ + LVM \ + Raid1 \ + IPsrcaddr \ + MailTo \ + jboss \ + mysql \ + mysql-proxy \ + pgsql \ + db2 \ + oracle \ + drbd.linbit \ + exportfs \ + exportfs-multidir \ + nfsserver \ + portblock \ + iscsi \ + named \ + postfix \ + sg_persist \ + tomcat \ + Xinetd \ + Xen \ + VirtualDomain \ + SendArp + +ocftdir = $(datadir)/$(PACKAGE_NAME)/ocft +ocft_DATA = README \ + README.zh_CN \ + caselib \ + helpers.sh \ + runocft.prereq +ocft_SCRIPTS = runocft + diff --git a/tools/ocft/README.in b/tools/ocft/README.in new file mode 100644 index 0000000..1c4ae12 --- /dev/null +++ b/tools/ocft/README.in @@ -0,0 +1,147 @@ +INTRODUCTION & DESIGN +~~~~~~~~~~~~~~~~~~~~~ + + - Ocft is a testing tool for resource agents. Instead of the policy of HA, + it mainly concerns whether resource agents run correct locally. It can + design types of complicated environments to test the reliability of + resource agents. Precisely, it is to display whether resource agents can + return to correct or expected value. The advantage of the tool provides + us with competence to design conditions which can be recorded or reproduced. + Hence it is useful to debuggers. + +* Components + ** Test case generator (@sbindir@/ocft) + - Turning configuration files of test case to executable scripts. + + ** Configuration file (@datadir@/@PACKAGE_NAME@/ocft/configs/) + - Every configuration file directs only one resource agent and share the same + name with resource agent but contains more test cases. + + ** The testing script (/var/lib/@PACKAGE_NAME@/ocft/cases/) + - After the generator reads configuration files and generates many testing + scripts and the script is underway, the test begins. + +* How to customize the environment of testing + - Ocft designs the running conditions through two ways, one is changing the + environment variables of resource agents (it is the interface left by OCF itself), + the other is modifying the OS environment of resource agents, such as altering + the permission of some key file or IP address of the machine. + +* How to test + - Firstly, you need to sketch the all complex and uncommon environments against + a certain resource agent and keep in mind what consequences may be caused by + these uncommon environments. + Secondly, write the designed conditions and foreknown consequences into + configuration files, and then run the generator to translate the test case to + executable scripts. + Finally, you need running these scripts to observe the output and learn + the running status of each test case, which will compares the predicated result + with the actual one. If they differ, you will be able to find the bugs of the + resource agent. + - All of the output with test will be recorded into the log files, you can find them + in /var/lib/@PACKAGE_NAME@/ocft/cases/logs. + + +HOW TO WRITE CONFIGURATION FILE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + - There are only 6 top level options that are all spelled by capital letters and "-". + Every top level option contains sub-options that they are initials. + +* 'CONFIG' (top level option) + - Grammar: CONFIG + - The design in this option is global and influences every test case. + + ** 'Agent' (sub-option) + - Grammar: Agent AGENT_NAME + - The agent name you want to test. + + ** 'AgentRoot' (sub-option) + - Grammar: AgentRoot /usr/lib/ocf/resource.d/xxx + - A few agents will go to "linbit" or "pacemaker" directory, if you define this option, + ocft will use it to replace the default directory "heartbeat". + + ** 'InstallPackage' (sub-option) + - Grammar: InstallPackage package [package2 [...]] + - It will test whether the system have installed the service of the resource agent. + If not, it will download from Internet and have it installed automatically. + + ** 'HangTimeout' (sub-option) + - Grammar: HangTimeout secs + - If you alter some key options, some resource agents will get puzzled and stop, + which will influence the running of the following test case. Hence timeout setting is + needed, if the resource agent stops timeout, the scripts will kill this resource agent. + +* 'VARIABLE' (top level option) + - Grammar: + VARIABLE + VAR1=value1 + VAR2=value2 + ... + - Define the global variable here, the variables can be visited everywhere, they can be referenced + using $VAR_NAME. Note, the variables in VARIABLE are different from 'Env VAR1=value1', 'Env' can + affect the activity of agent, but the variables in VARIABLE just be shared with top level option. + +* 'SETUP-AGENT' (top level option) + - Grammar: + SETUP-AGENT + bash scripts... + ... + - Some of Agents may need to be initialized before testing, you can do it here with bash script. + +* 'CLEANUP-AGENT' (top level option) + - Grammar: + CLEANUP-AGENT + bash scripts... + ... + - If SETUP-AGENT set, usually you might be use this option do some cleaning work after test. + +* 'CASE' & 'CASE-BLOCK' (top level option) + - Grammar: CASE "description" & CASE-BLOCK macro_name + - Usually, the conditions you designed are more than one and a few 'CASE "..."' will + appear in configuration file. It is worth noting that the following sub-options + have 2 spellings: + One is general, where shell affects the local environment; the other is special, + where each options added "@ipaddr". It can remotely execute shell codes. In other words, + it is to execute the shell codes from a remote host, which is meaningful when a resource + agent needs 2 hosts. This remote shell is not a remote execution only through "ssh", but + running a remote shell in the background while the test case is running. The remote shell + runs in the background till the end and saves the results during the process. That is to + say, you can alternatively carry out local and remote shell code segments. + The "CASE-BLOCK" option is a macro definer, the statements in "CASE-BLOCK" will be inserted + into "CASE" if you "Include" the "macro_name". + + ** 'Env' (sub-option) + - Grammar: Env VARIABLE=value + - It is to set up an environment variable of the resource agent. They usually appear to + be OCF_RESKEY_xxx. One point is to be noted is there is no blank by both sides of "=". + + ** 'Unenv' (sub-option) + - Grammar: Unenv VARIABLE [VARIABLE2 [...]] + - Remove the environment variable. + + ** 'Include' (sub-option) + - Grammar: Include macro_name + - It will be replaced by statements in 'macro_name', of course, you should define the + content of 'macro_name' with 'CASE-BLOCK' first. + + ** 'Bash' (sub-option) + - Grammar: Bash bash_codes + - This option is to set up the environment of OS, where you can insert BASH code to + customize the system randomly. Note, do not cause unrecoverable consequences to the + system. + + ** 'BashAtExit' (sub-option) + - Grammar: BashAtExit bash_codes + - This option is to recover the OS environment in order to run another test case + correctly. Of cause you can use 'Bash' option to recover it. However, if mistakes occur + in the process, the script will quit directly instead of running your recovery codes. + If it happens, you ought to use BashAtExit which can restore the system environment + before you quit. + + ** 'AgentRun' (sub-option) + - Grammar: AgentRun cmd [ret_value] + - This option is to run resource agent. "cmd" is the parameter of the resource agent, + such as "start, status, stop ...". The second parameter is optional. It will compare the + actual returned value with the expected value when the script has run recourse agent. + If differs, bugs will be found. diff --git a/tools/ocft/README.zh_CN.in b/tools/ocft/README.zh_CN.in new file mode 100644 index 0000000..5138cf1 --- /dev/null +++ b/tools/ocft/README.zh_CN.in @@ -0,0 +1,124 @@ +1 介绍和设计 +ocft是一个测试resource agents的工具。它并不关注HA的策略,而是关注resource agents +是否正常运行在本机。他能对resource agents设计各种复杂环境,来考验resource agnets +是否能正常应对,也就是看resouce agents是否能返回正确的或者说我们所期望的值。 +这个工具给我们带来的好处就是我们可以集中的批量的来设计环境,而且这种环境是可被我们 +记录、重现的,对Debug人员来说是很有用的。 + +1.1 组成 +1.1.1 解释器 (@sbindir@/ocft) +将test case配置文件转换成可执行的测试脚本。 + +1.1.2 配置文件 (@datadir@/@PACKAGE_NAME@/ocft/configs/) +每一个configuration file只针对一个resouce agent,配置文件名与resouce agent名相同, +但是它可以容纳很多test case。 + +1.1.3 测试脚本 (/var/lib/@PACKAGE_NAME@/ocft/cases/) +由generator读取configuration file生成测试脚本,直接运行此脚本就可以开始测试了。 + +1.2 如何定制环境 +ocft 通过两种手段来设计resouce agents的运行环境,一是更改resouce agents的环境变量, +当然这是ocf本身就留给我们的接口。二是更改resource agents所处的系统环境, +比如更改某个关键文件的权限,更改本机ip地址等等... + +1.3 如何进行测试 +首先你需要针对某个resource agent在脑中勾画各种复杂且异常的环境,并且你能清楚预知 +这些异常环境会给resource agent带来什么结果,然后将这些设计好的环境和你预知的结果 +都写入配置文件,然后运行generator,将你刚写的test case转换成可执行的脚本。最后运行 +这些脚本,观察它们的输出,你可以清楚看到每个test case运行状况,他会比较你的预知结 +果和resource agent的实际结果,如果不一样,说明你找到resource agent的bug了。 +所有的测试输出都会被记录到日志文件中,你可以在 /var/lib/@PACKAGE_NAME@/ocft/cases/logs +中找到他们. + +2 配置 +只有6个top level option,它们是由大写字母和'-'构成的,每个top level option都有若干sub-option, +它们是首字母大写。 + +2.1 'CONFIG' 选项 +语法:CONFIG +此option中的设计是全局的,对每个test case都有所影响。 + +2.1.1 'Agent' 选项 +语法:Agent AGENT_NAME +你要测试的Agent的名字。 + +2.1.2 'AgentRoot' 选项 +语法:AgentRoot /usr/lib/ocf/resource.d/xxx +一些agent将会被移到 "pacemaker" 或 "linbit" 目录,如果你定义了这个选项,ocft将会用它来 +替代默认的目录"heartbeat"。 + +2.1.3 'InstallPackage' 选项 +语法:InstallPackage package [package2 [...]] +他会检测系统是否安装了此resource agent的service,如果没有安装,会自动从网络进行安装。 +package_name是某个resouce agent在操作系统中必须安装的包。 + +2.1.4 'HangTimeout' 选项 +语法:HangTimeout secs +如果你更改了一些很关键的东西,有些resouce agent会不知所措,停在那里不动,那么就会影响 +到后面test case的运行,所以你需要设定超时,如果一旦resouce agent停在那超时了,脚本会 +杀死这个resouce agent。 + +2.2 'VARIABLE' 选项 +语法: +VARIABLE + VAR1=value1 + VAR2=value2 + ... +在此定义全局变量,这些变量可以用于配置文件中的任何地方,引用时在变量名前加上$。请注意,这些 +变量不同于Env定义的变量,Env是定义环境变量,可以改变agent的行为,而这些变量只是用于配置文件中 +共享。 + +2.3 'SETUP-AGENT' 选项 +语法: +SETUP-AGENT + bash scripts... + ... +一些Agent在测试前可能需要初始化,你可以用bash脚本在这初始化。 + +2.4 'CLEANUP-AGENT' 选项 +语法: +CLEANUP-AGENT + bash scripts... + ... +如果之前定义了SETUP-AGENT, 你可能还需要此选项在测试完后来作一些清除。 + +2.5 'CASE' & 'CASE-BLOCK' 选项 +语法:CASE "description" & CASE-BLOCK macro_name +通常你设计的环境不止一个,那么配置文件中应该会出现许多 'CASE "..."',值得注意的是,以下子 +选项每个都有两种写法,一是普通写法,产生的shell代码对本地产生作用,二是特殊写法,就是在每 +个选项后加上 "@ipaddr",他可以远程执行shell代码,也就是控制远程机器执行你给的shell代码, +这对需要两台机器以上的resouce agent很有用的,这个远程shell并非简单的用ssh去远程执行,而是在 +test case生存期内,后台运行一个远程shell,他始终在后台运行并且保存你的中间结果,也就是说你 +可以交替执行本地shell代码段和远程shell代码段。 +'CASE-BLOCK'选项是一个宏定义器,它定义的内容将会被插入到"CASE"内容中。 + +2.5.1 'Env' 选项 +语法:Env VARIABLE=value +这是设置resouce agent的环境变量,他们通常是OCF_RESKEY_xxx,注意=号两边不要有空格。 + +2.5.2 'Unenv' 选项 +语法:Unenv VARIABLE +此选项用于删除环境变量。 + +2.5.3 'Include' 选项 +语法:Include macro_name +此选项将会被宏"macro_name"的内容所替代,当然,你得预先用"CASE-BLOCK"来定义宏"macro_name" +的内容。 + +2.5.4 'Bash' 选项 +语法:Bash bash_codes +此选项是用来设置os的环境,你可以嵌入bash代码来对系统作任意设置,不过要注意不要对系统造成 +不可恢复的后果就行了。 + +2.5.5 'BashAtExit' 选项 +语法:BashAtExit bash_codes +此选项是用来恢复os的环境,以便另一个test case能正常运行,当然你也可以直接用'Bash'选项来 +恢复,但是如果脚本在执行过程中产生某些错误,那么脚本会直接退出,而不会去执行你的恢复代码, +那么你就要用到BashAtExit,他能在你退出前去恢复系统环境。 + +2.5.6 'AgentRun' 选项 +语法:AgentRun cmd [ret_value] +此option会去运行resouce agent,'cmd' 就是resouce agent的参数,如 start,status,stop ... +第二个参数是可选的,它是你对系统环境作出特殊设定以后,你预计resouce agent会返回的值, +如果给出此参数,那么脚本会在运行resouce agent后,会比较此时的返回值和你预期的返回值, +如果不一致,那么说明找到bug了。 diff --git a/tools/ocft/Raid1 b/tools/ocft/Raid1 new file mode 100644 index 0000000..462b9b9 --- /dev/null +++ b/tools/ocft/Raid1 @@ -0,0 +1,134 @@ +# Raid1 +# by dejan@suse.de on +# Fri Aug 24 17:01:40 CEST 2012 + +CONFIG + Agent Raid1 + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage mdadm + HangTimeout 20 + +VARIABLE + OCFT_rundir="`get_rundir`" + OCFT_disk0=$OCFT_rundir/resource-agents/ocft-Raid1-disk0 + OCFT_disk1=$OCFT_rundir/resource-agents/ocft-Raid1-disk1 + OCFT_disk2=$OCFT_rundir/resource-agents/ocft-Raid1-disk2 + OCFT_disk3=$OCFT_rundir/resource-agents/ocft-Raid1-disk3 + OCFT_raidconf=$OCFT_rundir/resource-agents/ocft-mdadm.conf + OCFT_raiddev=/dev/md8 + OCFT_raiddev2=/dev/md9 + OCFT_loop0="`loopbackeddev make $OCFT_disk0 16M`" + OCFT_loop1="`loopbackeddev make $OCFT_disk1 16M`" + OCFT_loop2="`loopbackeddev make $OCFT_disk2 16M`" + OCFT_loop3="`loopbackeddev make $OCFT_disk3 16M`" + +SETUP-AGENT + mdadm --create $OCFT_raiddev -l 0 --raid-devices=2 $OCFT_loop0 $OCFT_loop1 + mdadm --create $OCFT_raiddev2 -l 0 --raid-devices=2 $OCFT_loop2 $OCFT_loop3 + echo DEVICE $OCFT_loop0 $OCFT_loop1 > $OCFT_raidconf + echo DEVICE $OCFT_loop2 $OCFT_loop3 >> $OCFT_raidconf + echo ARRAY $OCFT_raiddev devices=$OCFT_loop0,$OCFT_loop1 >> $OCFT_raidconf + echo ARRAY $OCFT_raiddev2 devices=$OCFT_loop2,$OCFT_loop3 >> $OCFT_raidconf + +CLEANUP-AGENT + mdadm --zero-superblock $OCFT_loop0 + mdadm --zero-superblock $OCFT_loop1 + mdadm --zero-superblock $OCFT_loop2 + mdadm --zero-superblock $OCFT_loop3 + mdadm --remove $OCFT_raiddev 2>/dev/null + mdadm --remove $OCFT_raiddev2 2>/dev/null + loopbackeddev unmake $OCFT_disk0 + loopbackeddev unmake $OCFT_disk1 + loopbackeddev unmake $OCFT_disk2 + loopbackeddev unmake $OCFT_disk3 + rm -f $OCFT_raidconf + +CASE-BLOCK required_args + Env OCF_RESKEY_raidconf=$OCFT_raidconf + Env OCF_RESKEY_raiddev=$OCFT_raiddev + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE-BLOCK prepare_auto + Include required_args + Env OCF_RESKEY_raiddev="auto" + Include default_status + +CASE-BLOCK prepare_multiple + Include required_args + Env OCF_RESKEY_raiddev="$OCFT_raiddev $OCFT_raiddev2" + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_raiddev'" + Include prepare + Env OCF_RESKEY_raiddev=/dev/no_such_device + AgentRun start OCF_ERR_GENERIC + +CASE "check base env: unset 'OCF_RESKEY_raiddev'" + Include prepare + Unenv OCF_RESKEY_raiddev + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "normal start (auto)" + Include prepare_auto + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + +CASE "normal stop (auto)" + Include prepare_auto + AgentRun start + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + +CASE "normal start (multiple)" + Include prepare + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + +CASE "normal stop (multiple)" + Include prepare + Env OCF_RESKEY_raiddev="$OCFT_raiddev $OCFT_raiddev2" + AgentRun start + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/SendArp b/tools/ocft/SendArp new file mode 100644 index 0000000..7880388 --- /dev/null +++ b/tools/ocft/SendArp @@ -0,0 +1,74 @@ +# SendArp + +CONFIG + Agent SendArp + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage resource-agents + HangTimeout 15 + +CASE-BLOCK required_args + Env OCF_RESKEY_ip=127.0.0.1 + Env OCF_RESKEY_nic=lo + Env OCF_RESKEY_background=false + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_ip'" + Include prepare + Unenv OCF_RESKEY_ip + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set invalid 'OCF_RESKEY_ip'" + Include prepare + Env OCF_RESKEY_ip=not_ip_address + AgentRun start OCF_ERR_GENERIC + +CASE "check base env: unset 'OCF_RESKEY_nic'" + Include prepare + Unenv OCF_RESKEY_nic + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: set invalid 'OCF_RESKEY_nic'" + Include prepare + Env OCF_RESKEY_nic=not_nic + AgentRun start OCF_ERR_GENERIC + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/VirtualDomain b/tools/ocft/VirtualDomain new file mode 100644 index 0000000..3a44f20 --- /dev/null +++ b/tools/ocft/VirtualDomain @@ -0,0 +1,71 @@ +# VirtualDomain +# by dejan@suse.de on +# Tue Jul 8 12:48:03 CEST 2014 + +CONFIG + Agent VirtualDomain + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +# set OCFT_config to the libvirt configuration file +# the guest is going to be stopped and started +VARIABLE + OCFT_config=/etc/libvirt/qemu/sle11-sp3.xml + +CASE-BLOCK required_args + Env OCF_RESKEY_config=$OCFT_config + +CASE-BLOCK unset_utilization + Env OCF_RESKEY_autoset_utilization_host_memory=false + Env OCF_RESKEY_autoset_utilization_hv_memory=false + Env OCF_RESKEY_autoset_utilization_cpu=false + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include unset_utilization + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_config'" + Include prepare + Env OCF_RESKEY_config=/no_such_file + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: unset 'OCF_RESKEY_config'" + Include prepare + Unenv OCF_RESKEY_config + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/Xen b/tools/ocft/Xen new file mode 100644 index 0000000..731564b --- /dev/null +++ b/tools/ocft/Xen @@ -0,0 +1,65 @@ +# Xen +# by dejan@suse.de on +# Tue Jul 8 12:20:23 CEST 2014 + +CONFIG + Agent Xen + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 20 + +# set OCFT_xmfile to the xen-xm format file +# the guest is going to be stopped and started +VARIABLE + OCFT_xmfile=/etc/xen/vm/xen-f + +CASE-BLOCK required_args + Env OCF_RESKEY_xmfile=$OCFT_xmfile + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_xmfile'" + Include prepare + Env OCF_RESKEY_xmfile=/no_such_file + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: unset 'OCF_RESKEY_xmfile'" + Include prepare + Unenv OCF_RESKEY_xmfile + AgentRun start OCF_ERR_INSTALLED + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/Xinetd b/tools/ocft/Xinetd new file mode 100644 index 0000000..53f4f65 --- /dev/null +++ b/tools/ocft/Xinetd @@ -0,0 +1,64 @@ +# Xinetd + +CONFIG + Agent Xinetd + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage xinetd + +SETUP-AGENT + sed -i /disable/s/yes/no/ /etc/xinetd.d/echo + if which /etc/init.d/xinetd >/dev/null 2>&1; then + /etc/init.d/xinetd start + elif systemctl list-unit-files | grep -qs xinetd; then + systemctl start xinetd + fi + +CASE-BLOCK required_args + Env OCF_RESKEY_service=discard + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_protocol'" + Include prepare + Unenv OCF_RESKEY_service + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/apache b/tools/ocft/apache new file mode 100644 index 0000000..fe4f193 --- /dev/null +++ b/tools/ocft/apache @@ -0,0 +1,68 @@ +# apache +# make sure that your apache configuration loads mod_status + +CONFIG + Agent apache + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage apache2 + HangTimeout 20 + +SETUP-AGENT + if systemctl list-unit-files 2>/dev/null | fgrep -q apache2.service; then + systemctl start apache2.service + systemctl stop apache2.service + else + /etc/init.d/apache2 start + /etc/init.d/apache2 stop + fi + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: set non-existing OCF_RESKEY_statusurl" + Include prepare + Env OCF_RESKEY_statusurl="yoyoyoyo" + AgentRun start OCF_ERR_GENERIC + +CASE "check base env: set non-existing OCF_RESKEY_configfile" + Include prepare + Env OCF_RESKEY_configfile="/yoyoyoyo/nosuchfile" + AgentRun start OCF_ERR_INSTALLED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/caselib.in b/tools/ocft/caselib.in new file mode 100644 index 0000000..44165d6 --- /dev/null +++ b/tools/ocft/caselib.in @@ -0,0 +1,299 @@ +# +# Copyright (c) 2010-2011 Novell Inc, John Shi +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + + +quit() +{ + local ret + ret="$1" + + while [ $__OCFT__atexit_num -gt 0 ]; do + atexit$__OCFT__atexit_num + let __OCFT__atexit_num-- + done + + rm -rf $__OCFT__fakebin + + exit $ret +} + +agent_install() +{ + local pkg + + if [ $# -eq 0 ]; then + return 0 + fi + + for pkg in "$@"; do + if [ -e /etc/SuSE-release ]; then + if ! zypper -q install -y "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + elif [ -e /etc/debian_version ]; then + if ! apt-get -y install "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + elif [ -e /etc/redhat-release ]; then + if ! yum -y install "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + else + echo "${__OCFT__showhost}ERROR: Cannot detect your OS type." + quit 2 + fi + done +} + +set_ocf_env() +{ + export OCF_RA_VERSION_MAJOR=1 + export OCF_RA_VERSION_MINOR=0 + export OCF_RESOURCE_TYPE=$1 + export OCF_RESOURCE_INSTANCE=${OCF_RESOURCE_INSTANCE:-"ocft"} +} + +agent_run() +{ + local agent cmd timeout pid i ret aroot + agent="$1" + cmd="$2" + timeout="$3" + + set_ocf_env $agent + + export OCF_RESKEY_CRM_meta_timeout + : ${OCF_RESKEY_CRM_meta_timeout:=$((timeout*1000))} + + aroot=${__OCFT__MYROOT:-$__OCFT__AGENT_ROOT} + + setsid $aroot/$agent $cmd >${HA_RSCTMP}/.ocft_runlog 2>&1 & + pid=$! + + i=0 + while [ $i -lt $timeout ]; do + if [ ! -e /proc/$pid ]; then + break + fi + sleep 1 + let i++ + done + + if [ $i -ge $timeout ]; then + kill -SIGTERM -$pid >/dev/null 2>&1 + sleep 3 + kill -SIGKILL -$pid >/dev/null 2>&1 + echo -n "${__OCFT__showhost}ERROR: The agent was hanging, killed it, " + echo "maybe you damaged the agent or system's environment, see details below:" + cat ${HA_RSCTMP}/.ocft_runlog + echo + quit 1 + fi + + wait $pid +} + +check_success() +{ + local ret msg + ret="$1" + msg="$2" + + if [ $ret -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: '${msg}' failed, the return code is ${ret}." + quit 1 + fi +} + +__maxfd() +{ + (echo 0; ls -1 /proc/$$/fd) | sort -rn | head -1 +} + +__getfd() +{ + local host rw fd file + host="$1" + rw="$2" + + for fd in /proc/$$/fd/*; do + file=$(basename "$(readlink $fd)") + if [ "$file" = "${host}_$rw" ]; then + basename $fd + break + fi + done +} + +backbash_start() +{ + local host fd rfd wfd + host="$1" + + if [ ! -d "$__OCFT__CASES_DIR" ]; then + echo "${__OCFT__showhost}ERROR: Could not found Directory: ${__OCFT__CASES_DIR}." + quit 1 + fi + + if lsof $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w >/dev/null 2>&1; then + echo "${__OCFT__showhost}ERROR: Connection exist with $host." + quit 1 + fi + if [ ! -p "$__OCFT__CASES_DIR/${host}_r" ] || [ ! -p "$__OCFT__CASES_DIR/${host}_w" ]; then + rm -f $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w + if ! mkfifo $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w >/dev/null 2>&1; then + echo "${__OCFT__showhost}ERROR: Could not create pipe file: $__OCFT__CASES_DIR/${host}_*." + quit 1 + fi + fi + + ssh root@$host '@BASH_SHELL@ 2>&1 + sed "s/00/001/g" ${HA_RSCTMP}/.backbash-log + echo 000 + echo 1' >$__OCFT__CASES_DIR/${host}_r <$__OCFT__CASES_DIR/${host}_w & + + fd=$(__maxfd) + rfd=$(expr $fd + 1) + wfd=$(expr $fd + 2) + eval "exec ${rfd}<$__OCFT__CASES_DIR/${host}_r ${wfd}>$__OCFT__CASES_DIR/${host}_w" +} + +backbash() +{ + local host rfd wfd ret + host="$1" + + rfd=$(__getfd $host r) + wfd=$(__getfd $host w) + + if [ -z "$rfd" -o -z "$wfd" ]; then + echo "${__OCFT__showhost}ERROR: Could not found connection with $host." + fi + + cat >&$wfd <<EOF +{ +true +EOF + cat >&$wfd + cat >&$wfd <<EOF + +} >&${HA_RSCTMP}/.backbash-log +sed 's/00/001/g' ${HA_RSCTMP}/.backbash-log +echo 000 +echo 0 +EOF + if [ $? -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: Broken connection with $host." + quit 1 + fi + + awk -vlive=2 '{ + if (sub(/000$/, "")) { + if ($0 != "") { + gsub("001", "00"); + printf("%s", $0); + } + getline live; + exit; + } + gsub("001", "00"); + print; + } END { + exit(live); + }' <&$rfd + case $? in + 1) + quit 1 + ;; + 2) + echo "${__OCFT__showhost}ERROR: Broken connection with $host." + quit 1 + ;; + esac +} + +backbash_stop() +{ + local host rfd wfd + host="$1" + + wfd=$(__getfd $host w) + if [ -n "$wfd" ]; then + cat >&$wfd <<<'quit 0' + fi + rm -f $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w +} + + +export OCF_ROOT=@OCF_ROOT_DIR@ +export OCF_LIB=@OCF_LIB_DIR@/heartbeat +__OCFT__AGENT_ROOT=@OCF_RA_DIR@/heartbeat +__OCFT__CASES_DIR=/var/lib/@PACKAGE_NAME@/ocft/cases +OCFT_DIR=@datadir@/@PACKAGE_NAME@/ocft + +. $OCFT_DIR/helpers.sh + +__OCFT__atexit_num=0 + +if [ $EUID -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: '$0' needs to be run by root." + quit 3 +fi + +__OCFT__fakebin=./fakebin + +mkdir -p $__OCFT__fakebin >/dev/null 2>&1 && +ln -sf /bin/true $__OCFT__fakebin/crm_master >/dev/null 2>&1 && +ln -sf /bin/true $__OCFT__fakebin/crm_mon >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: initialize 'fakebin' failed." + quit 3 +fi +export HA_SBIN_DIR=$__OCFT__fakebin + +. $OCF_LIB/ocf-returncodes || { + echo "${__OCFT__showhost}ERROR: $OCF_LIB/ocf-returncodes not found." + quit 3 +} + +. $OCF_LIB/ocf-directories || { + echo "${__OCFT__showhost}ERROR: $OCF_LIB/ocf-directories not found." + quit 3 +} + +while read __OCFT__line; do + if [ -n "$__OCFT__line" ]; then + __OCFT__retn=${__OCFT__line%%=*} + __OCFT__reti=$(eval echo \$$__OCFT__retn) + __OCFT__retval[__OCFT__reti]=$__OCFT__retn + fi +done <<<"$(sed 's/#.*//' $OCF_LIB/ocf-returncodes)" + + +# vim:ts=2:sw=2:et: diff --git a/tools/ocft/db2 b/tools/ocft/db2 new file mode 100644 index 0000000..5c4d6ea --- /dev/null +++ b/tools/ocft/db2 @@ -0,0 +1,164 @@ +# db2 +# +# This test assumes a db2 ESE instance with two partitions and a database. +# Default is instance=db2inst1, database=ocft +# adapt this in set_testenv below +# +# Simple steps to generate a test environment (if you don't have one): +# +# A virtual machine with 1200MB RAM is sufficient +# +# - download an eval version of DB2 server from IBM +# - create an user "db2inst1" in group "db2inst1" +# +# As root +# - install DB2 software in some location +# - create instance +# cd <this_location>/instance +# ./db2icrt -s ese -u db2inst1 db2inst1 +# - adapt profile of db2inst1 as instructed by db2icrt +# +# As db2inst1 +# # allow to run with small memory footprint +# db2set DB2_FCM_SETTINGS=FCM_MAXIMIZE_SET_SIZE:FALSE +# db2start +# db2start dbpartitionnum 1 add dbpartitionnum hostname $(uname -n) port 1 without tablespaces +# db2stop +# db2start +# db2 create database ocft +# Done +# In order to install a real cluster refer to http://www.linux-ha.org/wiki/db2_(resource_agent) + +CONFIG + Agent db2 + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 40 + +SETUP-AGENT + # nothing + +CASE-BLOCK set_testenv + Env OCFT_instance=db2inst1 + Env OCFT_db=ocft + +CASE-BLOCK crm_setting + Env OCF_RESKEY_instance=$OCFT_instance + Env OCF_RESKEY_CRM_meta_timeout=30000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include set_testenv + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_instance'" + Include prepare + Env OCF_RESKEY_instance=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "invalid instance config" + Include prepare + Bash eval mv ~$OCFT_instance/sqllib ~$OCFT_instance/sqllib- + BashAtExit eval mv ~$OCFT_instance/sqllib- ~$OCFT_instance/sqllib + AgentRun start OCF_ERR_INSTALLED + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "started: monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not started: monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "killed instance: monitor" + Include prepare + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + BashAtExit rm /tmp/ocft-helper1 + Bash echo "su $OCFT_instance -c '. ~$OCFT_instance/sqllib/db2profile; db2nkill 0 >/dev/null 2>&1'" > /tmp/ocft-helper1 + Bash sh -x /tmp/ocft-helper1 + AgentRun monitor OCF_NOT_RUNNING + +CASE "overload param instance by admin" + Include prepare + Env OCF_RESKEY_instance=no_such + Env OCF_RESKEY_admin=$OCFT_instance + AgentRun start OCF_SUCCESS + +CASE "check start really activates db" + Include prepare + AgentRun start OCF_SUCCESS + + BashAtExit rm /tmp/ocft-helper2 + Bash echo "su $OCFT_instance -c '. ~$OCFT_instance/sqllib/db2profile; db2 get snapshot for database on $OCFT_db>/dev/null'" > /tmp/ocft-helper2 + Bash sh -x /tmp/ocft-helper2 + +CASE "multipartion test" + Include prepare + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + + # start does not start partion 1 + Env OCF_RESKEY_dbpartitionnum=1 + AgentRun monitor OCF_NOT_RUNNING + + # now start 1 + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + + # now stop 1 + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + + # does not affect 0 + Env OCF_RESKEY_dbpartitionnum=0 + AgentRun monitor OCF_SUCCESS + +# fault injection does not work on the 1.0.4 client due to a hardcoded path +CASE "simulate hanging db2stop (not meaningful for 1.0.4 agent)" + Include prepare + AgentRun start OCF_SUCCESS + Bash [ ! -f /usr/local/bin/db2stop ] + BashAtExit rm /usr/local/bin/db2stop + Bash echo -e "#!/bin/sh\necho fake db2stop\nsleep 10000" > /usr/local/bin/db2stop + Bash chmod +x /usr/local/bin/db2stop + AgentRun stop OCF_SUCCESS + +# fault injection does not work on the 1.0.4 client due to a hardcoded path +CASE "simulate not stopping db2stop (not meaningful for 1.0.4 agent)" + Include prepare + AgentRun start OCF_SUCCESS + Bash [ ! -f /usr/local/bin/db2stop ] + BashAtExit rm /usr/local/bin/db2stop + Bash echo -e "#!/bin/sh\necho fake db2stop\nexit 0" > /usr/local/bin/db2stop + Bash chmod +x /usr/local/bin/db2stop + AgentRun stop OCF_SUCCESS diff --git a/tools/ocft/drbd.linbit b/tools/ocft/drbd.linbit new file mode 100644 index 0000000..57fa088 --- /dev/null +++ b/tools/ocft/drbd.linbit @@ -0,0 +1,183 @@ +# linbit: drbd + +CONFIG + Agent drbd + AgentRoot /usr/lib/ocf/resource.d/linbit + InstallPackage drbd + HangTimeout 20 + +VARIABLE + DRBDCONF=${HA_RSCTMP}/ocft_drbd_tmp.conf + + # should be this machine's hostname/ip, please modify it by yourself. + NAME_1=HOSTNAME1 + IP_1=IP_ADDRESS1 + + # the block device just for test, please modify it by yourself. + DISK_1=/dev/DEVICE1 + + PORT_1=5735 + DEVICE_1=/dev/drbd0 + + #################################################################### + + # please modify it by yourself. + NAME_2=HOSTNAME2 + IP_2=IP_ADDRESS2 + + # the block device just for test, please modify it by yourself. + DISK_2=/dev/DEVICE2 + + PORT_2=5735 + DEVICE_2=/dev/drbd0 + + + +SETUP-AGENT + cat >$DRBDCONF <<EOF + global { + usage-count no; + } + + resource ocft0 { + protocol C; + disk { + on-io-error detach; + } + on $NAME_1 { + device $DEVICE_1; + address $IP_1:$PORT_1; + meta-disk internal; + disk $DISK_1; + } + on $NAME_2 { + device $DEVICE_2; + address $IP_2:$PORT_2; + meta-disk internal; + disk $DISK_2; + } + } +EOF + HOST=$(uname -n) + DRBDADM="drbdadm -c $DRBDCONF" + + # prepare + modprobe drbd $(drbdadm sh-mod-parms) + $DRBDADM down ocft0 + + # create meta data block if necessary + $DRBDADM dump-md ocft0 >/dev/null 2>&1 + if [ $? -eq 255 ]; then + $DRBDADM create-md ocft0 + fi + + # start drbd + $DRBDADM up ocft0 + + # UpToDate + if [ "$HOST" = "$NAME_1" ]; then + $DRBDADM wait-connect ocft0 + echo "drbd Syncing .." + $DRBDADM primary --force ocft0 + while true; do + CSTATE=$($DRBDADM cstate ocft0) + DSTATE=$($DRBDADM dstate ocft0) + if [ "$CSTATE" = "Connected" -a "$DSTATE" = "UpToDate/UpToDate" ]; then + break + else + sleep 3 + fi + done + echo "done" + fi + +CLEANUP-AGENT + drbdadm -c $DRBDCONF down ocft0 + rm -f $DRBDCONF + +CASE-BLOCK required_args + Env OCF_RESKEY_drbdconf=$DRBDCONF + Env OCF_RESKEY_drbd_resource=ocft0 + Env OCF_RESKEY_CRM_meta_notify=true + Env OCF_RESKEY_CRM_meta_clone_max=2 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include required_args + AgentRun validate-all OCF_SUCCESS + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "wrong path of config file" + Include prepare + Env OCF_RESKEY_drbdconf=no_such_file + AgentRun start OCF_ERR_INSTALLED + +CASE "wrong resource name" + Include prepare + Env OCF_RESKEY_drbd_resource=no_such_src + # OCF_RESKEY_drbd_resource is a required parameter in agent meta-data, + # if wrong, I think the agent should return OCF_ERR_CONFIGURED. + AgentRun start OCF_ERR_CONFIGURED + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "Primary/Secondary monitor" + Include prepare + AgentRun start + AgentRun promote + AgentRun monitor OCF_RUNNING_MASTER + AgentRun demote + AgentRun monitor OCF_SUCCESS + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "try to 'promote' in single-primary mode" + Include prepare + Include@$IP_2 prepare + + # start drbd + AgentRun start + AgentRun@$IP_2 start + + # promote local drbd first + AgentRun promote OCF_SUCCESS + + # demote local drbd prepare for remote drbd promote + AgentRun demote + # remote drbd promote + AgentRun@$IP_2 promote OCF_SUCCESS + + # promote fails, because remote drbd promote first. + AgentRun promote OCF_ERR_GENERIC diff --git a/tools/ocft/exportfs b/tools/ocft/exportfs new file mode 100644 index 0000000..285a4b8 --- /dev/null +++ b/tools/ocft/exportfs @@ -0,0 +1,80 @@ +# exportfs +# +# + +CONFIG + Agent exportfs + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage nfs-kernel-server + HangTimeout 40 + +SETUP-AGENT + # nothing + +CASE-BLOCK set_testenv + Env OCF_RESKEY_directory=/usr + Env OCF_RESKEY_fsid=105 + Env OCF_RESKEY_clientspec="*" + Env OCF_RESKEY_CRM_meta_timeout=30000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include set_testenv + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: no 'OCF_RESKEY_fsid'" + Include prepare + Env OCF_RESKEY_fsid= + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: invalid 'OCF_RESKEY_directory'" + Include prepare + Env OCF_RESKEY_directory=/no_such + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: non-decimal 'OCF_RESKEY_fsid'" + Include prepare + Env OCF_RESKEY_fsid="4f838db14f838db14f838db14f838db1" + AgentRun start OCF_SUCCESS + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "stop with no env" + Include prepare + Env OCF_RESKEY_directory=/no_such + AgentRun stop OCF_SUCCESS + +CASE "started: monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not started: monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING diff --git a/tools/ocft/exportfs-multidir b/tools/ocft/exportfs-multidir new file mode 100644 index 0000000..00e41f0 --- /dev/null +++ b/tools/ocft/exportfs-multidir @@ -0,0 +1,80 @@ +# exportfs +# +# + +CONFIG + Agent exportfs + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage nfs-kernel-server + HangTimeout 40 + +SETUP-AGENT + # nothing + +CASE-BLOCK set_testenv + Env OCF_RESKEY_directory="/usr /var" + Env OCF_RESKEY_fsid=105 + Env OCF_RESKEY_clientspec="*" + Env OCF_RESKEY_CRM_meta_timeout=30000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include set_testenv + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: no 'OCF_RESKEY_fsid'" + Include prepare + Env OCF_RESKEY_fsid= + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: invalid 'OCF_RESKEY_directory'" + Include prepare + Env OCF_RESKEY_directory=/no_such + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: invalid 'OCF_RESKEY_fsid'" + Include prepare + Env OCF_RESKEY_fsid=root + AgentRun start OCF_ERR_CONFIGURED + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "stop with no env" + Include prepare + Env OCF_RESKEY_directory="/usr /no_such" + AgentRun stop OCF_SUCCESS + +CASE "started: monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not started: monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING diff --git a/tools/ocft/helpers.sh b/tools/ocft/helpers.sh new file mode 100644 index 0000000..9848934 --- /dev/null +++ b/tools/ocft/helpers.sh @@ -0,0 +1,43 @@ +get_rundir() { + local rundir + rundir="`mount | grep '/run ' | awk '{print $3}'`" + echo ${rundir:-"/var/run"} +} + +loopbackeddev() { + local action file size ctlfile + + action="$1" + file="$2" + size="$3" + ctlfile=$HA_RSCTMP/`echo $file | tr / _` + + case "$action" in + start|setup|make) + if [ ! -f "$ctlfile" ]; then + if [ -z "$size" ]; then + echo "usage: $0 action file size" >&2 + exit 1 + fi + loopdev=`losetup -f` + if ! dd if=/dev/zero of=$file bs=1 count=0 seek=$size 2>/dev/null; then + echo "$0: dd failed" >&2 + exit 1 + fi + if ! losetup $loopdev $file; then + echo "$0: losetup failed" >&2 + exit 1 + fi + echo $loopdev | tee $ctlfile + else + cat $ctlfile + fi + ;; + stop|undo|unmake) + if [ -f "$ctlfile" ]; then + losetup -d `cat $ctlfile` + rm -f $file $ctlfile + fi + ;; + esac +} diff --git a/tools/ocft/iscsi b/tools/ocft/iscsi new file mode 100644 index 0000000..3c5d524 --- /dev/null +++ b/tools/ocft/iscsi @@ -0,0 +1,108 @@ +# iscsi + +CONFIG + Agent iscsi + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage open-iscsi targetcli + HangTimeout 20 + +VARIABLE + OCFT_rundir="`get_rundir`" + OCFT_disk="$OCFT_rundir/resource-agents/ocft-iscsi" + OCFT_target="iqn.2003-01.org.linux-iscsi:ocft" + OCFT_portal="127.0.0.1:3260" + OCFT_loop="`loopbackeddev make $OCFT_disk 16M`" + OCF_RESKEY_iqn=$OCFT_target + OCF_RESKEY_portals=$OCFT_portal + OCF_RESKEY_target_iqn=$OCFT_target + OCF_RESKEY_path=$OCFT_loop + OCF_RESKEY_lun=1 + +SETUP-AGENT + if systemctl list-unit-files 2>/dev/null | fgrep -q iscsid.service; then + systemctl start iscsid.service + else + /etc/init.d/open-iscsi start + fi + if systemctl list-unit-files 2>/dev/null | fgrep -q target.service; then + systemctl start target.service + else + /etc/init.d/target start + fi + export OCF_RESKEY_iqn=$OCFT_target + export OCF_RESKEY_portals=$OCFT_portal + export OCF_RESKEY_target_iqn=$OCFT_target + export OCF_RESKEY_path=$OCFT_loop + export OCF_RESKEY_lun=1 + /usr/lib/ocf/resource.d/heartbeat/iSCSITarget start + /usr/lib/ocf/resource.d/heartbeat/iSCSILogicalUnit start + +CLEANUP-AGENT + export OCF_RESKEY_iqn=$OCFT_target + export OCF_RESKEY_portals=$OCFT_portal + export OCF_RESKEY_target_iqn=$OCFT_target + export OCF_RESKEY_path=$OCFT_loop + export OCF_RESKEY_lun=1 + /usr/lib/ocf/resource.d/heartbeat/iSCSILogicalUnit stop + /usr/lib/ocf/resource.d/heartbeat/iSCSITarget stop + if systemctl list-unit-files 2>/dev/null | fgrep -q target.service; then + systemctl stop target.service + fi + loopbackeddev unmake $OCFT_disk + +CASE-BLOCK required_args + Env OCF_RESKEY_portal=$OCFT_portal + Env OCF_RESKEY_target=$OCFT_target + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_portal'" + Include prepare + Unenv OCF_RESKEY_portal + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: unset 'OCF_RESKEY_target'" + Include prepare + Unenv OCF_RESKEY_target + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + diff --git a/tools/ocft/jboss b/tools/ocft/jboss new file mode 100644 index 0000000..bc99d8f --- /dev/null +++ b/tools/ocft/jboss @@ -0,0 +1,83 @@ +# jboss +# +# NOTE: Clean up $jboss_home/standalone/log before running this test +# otherwise creating the pid/log files may fail +# in the test case with a different user. + +CONFIG + Agent jboss + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 120 + +# Note : Change setting by a version of JBoss. +# +VARIABLE + # JBoss5 Environment require +# jboss_version=5 +# jboss_home=/opt/jboss5/current +# java_home=/usr/lib/jvm/java-1.6.0-openjdk.x86_64 +# user=jboss5 + # JBoss6 Environment require + jboss_version=6 + jboss_home=/opt/jboss6/current + java_home=/usr/lib/jvm/java-1.7.0-openjdk.x86_64 + user=jboss6 + +CASE-BLOCK required_args_jboss + Env OCF_RESKEY_jboss_home=${jboss_home} + Env OCF_RESKEY_java_home=${java_home} + Env OCF_RESKEY_jboss_version=${jboss_version} + Env OCF_RESKEY_user=${user} + +CASE-BLOCK args_clear + Unenv OCF_RESKEY_jboss_home + Unenv OCF_RESKEY_java_home + Unenv OCF_RESKEY_jboss_version + Unenv OCF_RESKEY_user + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare_jboss + Include required_args_jboss + Include default_status + +# Test CASE +# +CASE "normal start jboss require_args (user:user)" + Include prepare_jboss + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + +CASE "normal start jboss require_args (user:root)" + Include prepare_jboss + Unenv OCF_RESKEY_user + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + +CASE "error start jboss no jboss_home" + Include prepare_jboss + Unenv OCF_RESKEY_jboss_home + AgentRun start OCF_ERR_INSTALLED + Include args_clear + +CASE "error start jboss no java_home" + Include prepare_jboss + Unenv OCF_RESKEY_java_home + AgentRun start OCF_ERR_INSTALLED + Include args_clear + +CASE "error start jboss no java command" + Include prepare_jboss + Env OCF_RESKEY_java_home=/var + AgentRun start OCF_ERR_INSTALLED + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + diff --git a/tools/ocft/mysql b/tools/ocft/mysql new file mode 100644 index 0000000..305a900 --- /dev/null +++ b/tools/ocft/mysql @@ -0,0 +1,82 @@ +# mysql + +CONFIG + Agent mysql + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage mysql + HangTimeout 20 + +SETUP-AGENT + if systemctl list-unit-files 2>/dev/null | fgrep -q mysql.service; then + systemctl start mysql.service + systemctl stop mysql.service + else + /etc/init.d/mysql start + /etc/init.d/mysql stop + fi + +CASE-BLOCK crm_setting + Env OCF_RESKEY_CRM_meta_timeout=15000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_binary'" + Include prepare + Env OCF_RESKEY_binary=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "check lib file" + Include prepare + Bash chmod u-w /var/lib/mysql + BashAtExit chmod u+w /var/lib/mysql + AgentRun start OCF_ERR_PERM + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "non-existent user" + Include prepare + Env OCF_RESKEY_user=no_user + AgentRun start OCF_ERR_INSTALLED + +CASE "invalid user" + Include prepare + Env OCF_RESKEY_user=nobody + AgentRun start OCF_ERR_PERM diff --git a/tools/ocft/mysql-proxy b/tools/ocft/mysql-proxy new file mode 100644 index 0000000..e16d52b --- /dev/null +++ b/tools/ocft/mysql-proxy @@ -0,0 +1,83 @@ +# mysql-proxy +# by r.bhatia@ipax.at +# +# test cases (to implement): +# +# * /usr/sbin/ocf-tester -n mp -o binary="/usr/sbin/mysql-proxy" -o defaults_file="" -o parameters="--proxy-skip-profiling" \ +# -o admin_address="127.0.0.1:4041" -o admin_username="root" -o admin_password="la" -o admin_lua_script="/usr/lib/mysql-proxy/lua/admin.lua" \ +# -o proxy_backend_addresses="192.168.100.200:42006" -o proxy_address="/var/run/mysqld/mysqld.sock" /usr/lib/ocf/resource.d/heartbeat/mysql-proxy +# +# * OCF_CHECK_LEVEL 20 check + +CONFIG + Agent mysql-proxy + AgentRoot /usr/lib/ocf/resource.d/heartbeat/ + InstallPackage mysql-proxy + HangTimeout 20 + +SETUP-AGENT + # nothing + +CASE-BLOCK crm_setting + Env OCF_RESKEY_CRM_meta_timeout=15000 + Env OCF_RESKEY_binary=/tmp/mysql-proxy + Env OCF_RESKEY_admin_username=root + Env OCF_RESKEY_admin_password=test123 + Env OCF_RESKEY_admin_lua_script=/usr/lib/mysql-proxy/lua/admin.lua + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Bash [ ! -x /tmp/mysql-proxy ] && ln -s `which mysql-proxy` /tmp/mysql-proxy || true + Include crm_setting + +CASE-BLOCK teardown + AgentRun stop + BashAtExit rm -f /tmp/mysql-proxy + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + Include teardown + +CASE "check base env: invalid 'OCF_RESKEY_binary'" + Include prepare + Env OCF_RESKEY_binary=no_such + AgentRun start OCF_ERR_INSTALLED + BashAtExit rm -f /tmp/mysql-proxy + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + Include teardown + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + Include teardown + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + Include teardown + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + Include teardown + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/named b/tools/ocft/named new file mode 100644 index 0000000..90a4351 --- /dev/null +++ b/tools/ocft/named @@ -0,0 +1,69 @@ +#named + +# To work properly this test requires that standard bind and bin-utils +# packages installed. + +CONFIG + Agent named + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage bind + InstallPackage bind-utils + +SETUP-AGENT + /etc/init.d/named start + /etc/init.d/named stop + +CASE-BLOCK crm_setting + Env OCF_RESKEY_CRM_meta_timeout=15000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_named'" + Include prepare + Env OCF_RESKEY_named=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "non-existent user" + Include prepare + Env OCF_RESKEY_named_user=no_user + AgentRun start OCF_ERR_INSTALLED diff --git a/tools/ocft/nfsserver b/tools/ocft/nfsserver new file mode 100644 index 0000000..cf2ac89 --- /dev/null +++ b/tools/ocft/nfsserver @@ -0,0 +1,69 @@ +# nfsserver + +CONFIG + Agent nfsserver + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage nfs-kernel-server + HangTimeout 20 + +SETUP-AGENT + INITSCRIPT="" + if test -f /etc/init.d/nfsserver; then + INITSCRIPT="/etc/init.d/nfsserver" + fi + true + +CASE-BLOCK required_args + Env OCF_RESKEY_nfs_init_script=$INITSCRIPT + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_nfs_init_script'" + Include prepare + Env OCF_RESKEY_nfs_init_script=no_such_script + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: invalid 'OCF_RESKEY_nfs_notify_cmd'" + Include prepare + Env OCF_RESKEY_nfs_notify_cmd=no_such_program + AgentRun start OCF_ERR_INSTALLED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/ocft.in b/tools/ocft/ocft.in new file mode 100644 index 0000000..0d7f645 --- /dev/null +++ b/tools/ocft/ocft.in @@ -0,0 +1,893 @@ +#!@BASH_SHELL@ + +# Copyright (c) 2010-2013 Novell Inc, John Shi +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + +die() +{ + local str + str="$1" + + echo "ERROR: $str" >&2 + exit 1 +} + +warn() +{ + local str + str="$1" + + echo "WARNING: $str" >&2 +} + +parse_die() +{ + local str + str="$1" + + agent_parse_finish + die "${agent}: line ${line_num}: ${str}" +} + +# add quotes to string for Here Documents +add_quotes() +{ + local typ str a b + typ="$1" + str="$2" + + case "$typ" in + 1) a=\'; b=\";; + 2) a=\"; b=\';; + esac + + echo "$str" | sed "s/$a/$a$b$a$b$a/g; 1 s/^/$a/; $ s/$/$a/" +} + +# split strings +explode() +{ + local str + str="$1" + + echo "$str" | awk -F'"' '{ + if (NF > 0 && NF%2 == 0) + exit(1); + for (i=1; i<=NF; i++) { + if (i%2 == 0) + print $i; + else { + len = split($i, str, /[ \t]+/); + for (j=1; j<=len; j++) { + sb = sub(/#.*/, "", str[j]); + if (str[j] != "") + print str[j]; + if (sb) + exit(0); + } + } + } + }' +} + +# phase 1: parse the string to 'command' and 'argument collection'. +line2trunk() +{ + trunk[0]="${line%%[[:blank:]]*}" + trunk[1]="${line#*[[:blank:]]}" +} + +# phase 2: split the argument collection. +trunk2branch() +{ + local IFS + + # Some of statements need one parameter at least. + if [ "$line" = "${trunk[0]}" ]; then + parse_die "missing parameter." + fi + + IFS=$'\n' + branch=($(explode "${trunk[1]}")) + if [ $? -ne 0 ]; then + parse_die "missing '\"'." + fi +} + +preparse_cfg() +{ + local agent line trunk branch macro num host + agent="$1" + + if [ ! -r "$opt_cfgsdir/$agent" ]; then + die "${agent}: configuration file not found." + fi + + line_num=0 + while read -r line; do + let line_num++ + num=" $line_num" + + case "$line" in + ""|\#*) continue;; + esac + + line2trunk + case "${trunk[0]}" in + CASE-BLOCK) + trunk2branch + macro="$CASES_DIR/${agent}_macro.${branch[0]}" + continue + ;; + Include|Include@*) + host=$(echo "${trunk[0]}" | awk -F@ '{print $2}') + trunk2branch + if [ ! -r "$CASES_DIR/${agent}_macro.${branch[0]}" ]; then + parse_die "Macro '${branch[0]}' not found." + fi + if [ -n "$host" ]; then + line="$(sed -e 's/^\([^[:blank:]]*\)@[^[:blank:]]*/\1/' -e "s/^[^[:blank:]]*/&@$host/" "$CASES_DIR/${agent}_macro.${branch[0]}")" + else + line="$(<"$CASES_DIR/${agent}_macro.${branch[0]}")" + fi + num= + ;; + *[!A-Z-]*) + : + ;; + *) + macro= + ;; + esac + + if [ -n "$macro" ]; then + echo "$line$num" >>"$macro" + else + echo "$line$num" >>"$CASES_DIR/${agent}_preparse" + fi + done <"$opt_cfgsdir/$agent" +} + +case_parse_finish() +{ + local host + + if [ -n "$sh" ]; then + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo +fi +# Cleanup and exit +EOF + for host in $hosts; do + echo "backbash_stop $host" >>$sh + done + echo "quit 0" >>$sh + fi + + atexit_num=0 + hosts= + sh= +} + +init_cfg_vars() +{ + cfg_agent= + cfg_agent_root= + cfg_install_package=() + cfg_hang_timeout=20 +} + +agent_parse_finish() +{ + local suf + + for suf in preparse setup cleanup var hosts; do + rm -f $CASES_DIR/${agent}_$suf + done + rm -f $CASES_DIR/${agent}_macro.* + init_cfg_vars +} + +need_make() +{ + local src_time obj_time + + if [ ! -f "$CASES_DIR/0_${agent}.sh" ]; then + return 0 + fi + + src_time=$(stat -c '%Y' "$opt_cfgsdir/$agent") + obj_time=$(stat -c '%Y' "$CASES_DIR/0_${agent}.sh") + + test $src_time -ge $obj_time +} + +parse_cfg() +{ + local agents i line stat sh trunk branch atexit_num host hosts + + if [ $# -eq 0 ]; then + agents=($opt_cfgsdir/*) + else + agents=("$@") + fi + + for agent in "${agents[@]}"; do + agent="$(basename "$agent")" + + if ! need_make; then + continue + fi + + agent_obj_clean $agent + agent_parse_finish + + i=0 + + echo "Making '$agent': " + preparse_cfg "$agent" + while read -r line; do + line_num="${line##* }" + line="${line% *}" + line2trunk + + # state switch + case "${trunk[0]}" in + CONFIG) + case_parse_finish + stat=1 + continue + ;; + VARIABLE) + case_parse_finish + stat=2 + continue + ;; + SETUP-AGENT) + case_parse_finish + stat=3 + continue + ;; + CLEANUP-AGENT) + case_parse_finish + stat=4 + continue + ;; + CASE) + case_parse_finish + trunk2branch + echo " - case ${i}: ${branch[0]}" + sh="$CASES_DIR/${i}_${agent}.sh" + cat >$sh <<EOF +#!@BASH_SHELL@ + +# Agent: $cfg_agent +# Summary: ${branch[0]} + +. $OCFT_DIR/caselib || { + echo "ERROR: '$OCFT_DIR/caselib' not found." + exit 2 +} + +$(test -r $CASES_DIR/${agent}_var && cat $CASES_DIR/${agent}_var) + +__OCFT__MYROOT="$cfg_agent_root" + +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") + +if [ -n "\$__OCFT__VERBOSE" ]; then + echo -e $(add_quotes 1 "Starting '\\033[33m${agent}\\033[0m' case $i '\\033[33m${branch[0]}\\033[0m':") +else + echo -n "${agent}: ${branch[0]} - " +fi +EOF + chmod a+x $sh + + let i++ + stat=5 + continue + ;; + esac + + case "$stat" in + 1) + case "${trunk[0]}" in + Agent) + trunk2branch + cfg_agent="${branch[0]}" + ;; + AgentRoot) + trunk2branch + cfg_agent_root="${branch[0]}" + ;; + InstallPackage) + trunk2branch + cfg_install_package=(${cfg_install_package[@]} ${branch[@]}) + ;; + HangTimeout) + trunk2branch + if ! echo "${branch[0]}" | grep -qxE '[0-9]+'; then + parse_die "numeric argument required." + fi + cfg_hang_timeout="${branch[0]}" + ;; + *) + parse_die "unimplemented statement: ${trunk[0]}" + ;; + esac + ;; + 2) + if echo "$line" | grep -q '^__OCFT__'; then + parse_die "reserved key word '__OCFT__'." + fi + echo "declare $line" >>$CASES_DIR/${agent}_var + ;; + 3) + echo "$line" >>$CASES_DIR/${agent}_setup + ;; + 4) + echo "$line" >>$CASES_DIR/${agent}_cleanup + ;; + 5) + host=$(echo ${trunk[0]} | awk -F@ '{print $2}') + if [ -n "$host" ]; then + if ! echo "$hosts" | grep -q "$host"; then + echo "$host" >>$CASES_DIR/${agent}_hosts + hosts=$hosts$'\n'$host + cat >>$sh <<EOF +# Initialize remote shell +backbash_start $host +backbash $host <<CMD +__OCFT__VERBOSE=\$__OCFT__VERBOSE +CMD +backbash $host <$OCFT_DIR/caselib +backbash $host <<'CMD' +$(test -r $CASES_DIR/${agent}_var && cat $CASES_DIR/${agent}_var) + +__OCFT__MYROOT="$cfg_agent_root" +__OCFT__showhost="${host}: " + +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") +CMD +EOF + fi + fi + + echo " +# CASE statement: $line" >>$sh + + if [ -n "$host" ]; then + echo "backbash $host <<'CMD'" >>$sh + fi + + case "${trunk[0]}" in + Env|Env@*) + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Setting agent environment: export ${trunk[1]}") +fi +export ${trunk[1]} +check_success \$? $(add_quotes 1 "export ${trunk[1]}") +EOF + ;; + Unenv|Unenv@*) + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Removing agent environment: unset ${trunk[1]}") +fi +unset ${trunk[1]} +check_success \$? $(add_quotes 1 "unset ${trunk[1]}") +EOF + ;; + AgentRun|AgentRun@*) + trunk2branch + if [ -z "${branch[1]}" ]; then + if [ "${branch[0]}" = "start" ]; then + cat >>$sh <<EOF +agent_run $(add_quotes 1 "$cfg_agent") monitor $cfg_hang_timeout +__OCFT__rc=\$? + +if [ \$__OCFT__rc -eq \$OCF_SUCCESS -o \$__OCFT__rc -eq \$OCF_RUNNING_MASTER ]; then + : #The status I want, so I can do nothing. +elif [ \$__OCFT__rc -eq \$OCF_NOT_RUNNING ]; then + if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Running agent: ./$cfg_agent ${branch[0]}") + fi + agent_run $(add_quotes 1 "$cfg_agent") start $cfg_hang_timeout + check_success \$? $(add_quotes 1 "./$cfg_agent ${branch[0]}") +else + check_success \$__OCFT__rc $(add_quotes 1 "./$cfg_agent monitor") +fi +EOF + elif [ "${branch[0]}" = "stop" ]; then + cat >>$sh <<EOF +agent_run $(add_quotes 1 "$cfg_agent") monitor $cfg_hang_timeout +__OCFT__rc=\$? + +if [ \$__OCFT__rc -eq \$OCF_NOT_RUNNING ]; then + : #The status I want, so I can do nothing. +elif [ \$__OCFT__rc -eq \$OCF_SUCCESS -o \$__OCFT__rc -eq \$OCF_RUNNING_MASTER ]; then + if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Running agent: ./$cfg_agent ${branch[0]}") + fi + agent_run $(add_quotes 1 "$cfg_agent") stop $cfg_hang_timeout + check_success \$? $(add_quotes 1 "./$cfg_agent ${branch[0]}") +else + check_success \$__OCFT__rc $(add_quotes 1 "./$cfg_agent monitor") +fi +EOF + elif [ "${branch[0]}" = "monitor" ]; then + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Running agent: ./$cfg_agent ${branch[0]}") +fi +agent_run $(add_quotes 1 "$cfg_agent") $(add_quotes 1 "${branch[0]}") $cfg_hang_timeout +EOF + else + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Running agent: ./$cfg_agent ${branch[0]}") +fi +agent_run $(add_quotes 1 "$cfg_agent") $(add_quotes 1 "${branch[0]}") $cfg_hang_timeout +check_success \$? $(add_quotes 1 "./$cfg_agent ${branch[0]}") +EOF + fi + else + cat >>$sh <<EOF +test -n $(add_quotes 2 "\$${branch[1]}") +check_success \$? $(add_quotes 1 "test -n \"\$${branch[1]}\"") +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Running agent: ./$cfg_agent ${branch[0]}") +fi +agent_run $(add_quotes 1 "$cfg_agent") $(add_quotes 1 "${branch[0]}") $cfg_hang_timeout +__OCFT__ret=\$? +if [ -n "\$__OCFT__VERBOSE" ]; then + echo -n " \${__OCFT__showhost}Checking return value:" +fi +if [ -n "\${__OCFT__retval[__OCFT__ret]}" ]; then + __OCFT__retstr="\${__OCFT__retval[__OCFT__ret]}" +else + __OCFT__retstr=\$__OCFT__ret +fi +if [ \$__OCFT__ret -eq \$${branch[1]} ]; then + if [ -n "\$__OCFT__VERBOSE" ]; then + echo -e $(add_quotes 2 " \\033[32mOK\\033[0m. The return value '\\033[34m\$__OCFT__retstr\\033[0m' == '\\033[34m${branch[1]}\\033[0m'") + else + echo -e "\\033[32mOK\\033[0m." + fi +else + if [ -n "\$__OCFT__VERBOSE" ]; then + echo -en $(add_quotes 2 " \\033[31mFAILED\\033[0m. The return value '\\033[34m\$__OCFT__retstr\\033[0m' != '\\033[34m${branch[1]}\\033[0m'. ") + else + echo -en "\\033[31mFAILED\\033[0m. Agent returns unexpected value: '\$__OCFT__retstr'. " + fi + echo "See details below:" + cat /tmp/.ocft_runlog + echo + quit 1 +fi +EOF + fi + ;; + Bash|Bash@*) + cat >>$sh <<EOF +if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Setting system environment: ${trunk[1]}") +fi +${trunk[1]} +check_success \$? $(add_quotes 1 "${trunk[1]}") +EOF + ;; + BashAtExit|BashAtExit@*) + let atexit_num++ + cat >>$sh <<EOF +atexit${atexit_num}() +{ + if [ -n "\$__OCFT__VERBOSE" ]; then + echo $(add_quotes 2 " \${__OCFT__showhost}Setting system environment: ${trunk[1]}") + fi + ${trunk[1]} +} +let __OCFT__atexit_num++ +EOF + ;; + *) + parse_die "unimplemented statement: ${trunk[0]}" + ;; + esac + if [ -n "$host" ]; then + echo 'CMD' >>$sh + fi + ;; + *) + parse_die "unimplemented statement: ${trunk[0]}" + ;; + esac + done <$CASES_DIR/${agent}_preparse + + if [ -r "$CASES_DIR/${agent}_setup" ]; then + cat >$CASES_DIR/setup_${agent}.sh <<EOF +#!@BASH_SHELL@ + +# Agent: $cfg_agent +# Summary: SETUP before test + +echo "Initializing '$cfg_agent' ..." + +. $OCFT_DIR/caselib || { + echo "ERROR: '$OCFT_DIR/caselib' not found." + exit 2 +} + +$(test -r "$CASES_DIR/${agent}_var" && cat $CASES_DIR/${agent}_var) +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") + +EOF + for host in $(test -r $CASES_DIR/${agent}_hosts && cat $CASES_DIR/${agent}_hosts); do + cat >>$CASES_DIR/setup_${agent}.sh <<EOF +# Initialize remote shell +backbash_start $host +backbash $host <<CMD +__OCFT__VERBOSE=\$__OCFT__VERBOSE +CMD +backbash $host <$OCFT_DIR/caselib +backbash $host <<'CMD' +$(test -r "$CASES_DIR/${agent}_var" && cat $CASES_DIR/${agent}_var) + +__OCFT__MYROOT="$cfg_agent_root" +__OCFT__showhost="${host}: " + +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") + +$(cat $CASES_DIR/${agent}_setup) +check_success \$? "SETUP-AGENT" +CMD +backbash_stop $host +EOF + done + cat >>$CASES_DIR/setup_${agent}.sh <<EOF +$(cat $CASES_DIR/${agent}_setup) +check_success \$? "SETUP-AGENT" + +echo "Done." +echo +quit 0 +EOF + chmod a+x $CASES_DIR/setup_${agent}.sh + fi + + if [ -r "$CASES_DIR/${agent}_cleanup" ]; then + cat >$CASES_DIR/cleanup_${agent}.sh <<EOF +#!@BASH_SHELL@ + +# Agent: $cfg_agent +# Summary: CLEANUP after test + +echo "Cleaning '$cfg_agent' ..." + +. $OCFT_DIR/caselib || { + echo "ERROR: '$OCFT_DIR/caselib' not found." + exit 2 +} + +$(test -r "$CASES_DIR/${agent}_var" && cat $CASES_DIR/${agent}_var) +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") + +$(cat $CASES_DIR/${agent}_cleanup) +check_success \$? "CLEANUP-AGENT" + +EOF + for host in $(test -r $CASES_DIR/${agent}_hosts && cat $CASES_DIR/${agent}_hosts); do + cat >>$CASES_DIR/cleanup_${agent}.sh <<EOF +# Initialize remote shell +backbash_start $host +backbash $host <<CMD +__OCFT__VERBOSE=\$__OCFT__VERBOSE +CMD +backbash $host <$OCFT_DIR/caselib +backbash $host <<'CMD' +$(test -r "$CASES_DIR/${agent}_var" && cat $CASES_DIR/${agent}_var) + +__OCFT__MYROOT="$cfg_agent_root" +__OCFT__showhost="${host}: " + +$(test -n "$cfg_install_package" && echo "agent_install ${cfg_install_package[@]}") + +$(cat $CASES_DIR/${agent}_cleanup) +check_success \$? "CLEANUP-AGENT" +CMD +backbash_stop $host +EOF + done + cat >>$CASES_DIR/cleanup_${agent}.sh <<EOF +echo "Done." +echo +quit 0 +EOF + chmod a+x $CASES_DIR/cleanup_${agent}.sh + fi + case_parse_finish + agent_parse_finish + + done +} + +start_test() +{ + local sh shs testsh agents line ret + local rc=0 + local varlib + local rc_f + + if ! cd $CASES_DIR >/dev/null 2>&1; then + die "cases directory not found." + fi + + if [ ! -d logs ]; then + mkdir logs + fi + + export __OCFT__VERBOSE=$opt_verbose + + if [ $# -eq 0 ]; then + agents=($(ls -1 *.sh 2>/dev/null | sed 's/.*_\([^_]*\)\.sh$/\1/' | sort | uniq)) + else + agents=("$@") + fi + + for shs in "${agents[@]}"; do + if [ -z "$opt_incremental" ]; then + testsh="setup_${shs}.sh + $(ls -1 [0-9]*_${shs}.sh 2>/dev/null | sort -n) + cleanup_${shs}.sh" + else + testsh="setup_${shs}.sh + $(ls -1 [0-9]*_${shs}.retest 2>/dev/null | sed 's/retest$/sh/' | sort -n) + cleanup_${shs}.sh" + fi + + if [ -n "$opt_trace_ra" ]; then + varlib=${HA_VARLIB:="/var/lib/heartbeat"} + export OCF_RESKEY_trace_ra=1 + echo "RA trace on, output in $varlib/trace_ra" + fi + + rc_f=`mktemp` + (for sh in $testsh; do + if [ -r "$sh" ]; then + if [ -n "$opt_trace_ra" ]; then + export OCF_RESOURCE_INSTANCE="`echo $sh | sed 's/_.*//'`" + fi + ./$sh + ret=$? + + case "$sh" in + setup*) + rc=$((rc|ret)) + if [ $ret -ne 0 ]; then + warn "SETUP failed, break all tests of '$shs'." + break + fi + ;; + cleanup*) + if [ $ret -ne 0 ]; then + warn "CLEANUP failed." + fi + ;; + [0-9]*) + case $ret in + 3) die "core function failed, break all tests." ;; + 2) warn "core function failed, break all tests of '$shs'."; break ;; + 1) touch ${sh%.*}.retest ;; + 0) rm -f ${sh%.*}.retest ;; + esac + rc=$((rc|ret)) + ;; + esac + fi + done 2>&1; echo $rc > $rc_f) | while read -r line; do + echo "$line" + echo "$(date '+%F %T'): $line" | cat -A | + sed -r 's/\^\[\[[0-9]+m|\^I|.$//g' >>logs/$shs.log + done + done + rc=`cat $rc_f` + rm -f $rc_f + return $rc +} + +agent_clean() +{ + local typ ra + typ=$1 + + shift + + if [ $# -eq 0 ]; then + rm -f $CASES_DIR/*.$typ + else + for ra in "$@"; do + rm -f $CASES_DIR/*_${ra}.$typ + done + fi +} + +agent_retest_clean() +{ + agent_clean retest "$@" +} + +agent_obj_clean() +{ + agent_clean sh "$@" +} + +usage() +{ + cat <<EOF +$0 ACTION [OPTION] [agent1 [agent2] [...]] +ACTIONs include: + make [-d dir] Generate the testing shell scripts. + -d The directory that contains + configuration of cases. + test [-v|-i|-X] Execute the testing shell scripts. + -v Verbose output mode. + -i Incremental mode, skip case + which succeeded. If cleaning + the status of incremental mode + is needed, try to '$0 clean RA_NAME'. + -X Trace the RA + clean Delete the testing shell scripts. + help [-v] Show this help and exit. + -v Show HOWTO and exit. +Version 0.44 +See '$OCFT_DIR/README' for detail. +EOF +} + +howto() +{ + cat <<EOF +HOW TO USE THIS TOOL + + - Ocft is a testing tool for resource agents. Instead of the policy of HA, + it mainly concerns whether resource agents run correct locally. It can + design types of complicated environments to test the reliability of + resource agents. Precisely, it is to display whether resource agents can + return to correct or expected value. The advantage of the tool provides + us with competence to design conditions which can be recorded or reproduced. + Hence it is useful to debuggers. + +* Components + ** Test case generator (/usr/sbin/ocft) + - Turning configuration files of test case to executable scripts. + + ** Configuration file ($CONFIGS_DIR/) + - Every configuration file directs only one resource agent and share the same + name with resource agent but contains more test cases. + + ** The testing script ($CASES_DIR/) + - After the generator reads configuration files and generates many testing + scripts and the script is underway, the test begins. + +* How to customize the environment of testing + - Ocft designs the running conditions through two ways, one is changing the + environment variables of resource agents (it is the interface left by OCF itself), + the other is modifying the OS environment of resource agents, such as altering + the permission of some key file or IP address of the machine. + +* How to test + - Firstly, you need to sketch the all complex and uncommon environments against + a certain resource agent and keep in mind what consequences may be caused by + these uncommon environments. + Secondly, write the designed conditions and foreknown consequences into + configuration files, and then run the generator to translate the test case to + executable scripts. + Finally, you need running these scripts to observe the output and learn + the running status of each test case, which will compares the predicated result + with the actual one. If they differ, you will be able to find the bugs of the + resource agent. + - All of the output with test will be recorded into the log files, you can find them + in $CASES_DIR/logs. +EOF +} + + +export LANG=C + +# system variable +OCFT_DIR=@datadir@/@PACKAGE_NAME@/ocft +CONFIGS_DIR=@datadir@/@PACKAGE_NAME@/ocft/configs +CASES_DIR=/var/lib/@PACKAGE_NAME@/ocft/cases + +# global variable +agent= +line_num= + +# default configuration +init_cfg_vars + +# default option +opt_verbose= +opt_incremental= +opt_cfgsdir=$CONFIGS_DIR + +command="$1" +shift + +case "$command" in + make) + if [ "$1" = "-d" ]; then + if [ ! -d "$2" ]; then + usage + exit 1 + fi + opt_cfgsdir="$2" + shift 2 + fi + if [ ! -d "$CASES_DIR" ]; then + mkdir -p "$CASES_DIR" || die "Can not create directory: ${CASES_DIR}." + fi + parse_cfg "$@" + ;; + test) + for v in 1 2 3; do + case "$1" in + -v) + opt_verbose=1 + shift + ;; + -X) + opt_trace_ra=1 + shift + ;; + -i) + opt_incremental=1 + shift + ;; + -*) + die "bad option $1" + ;; + esac + done + start_test "$@" + ;; + clean) + agent_obj_clean "$@" + agent_retest_clean "$@" + ;; + help) + if [ "$1" = "-v" ]; then + howto + else + usage + fi + exit 0 + ;; + *) + usage + exit 1 + ;; +esac + +# vim:ts=2:sw=2:et: diff --git a/tools/ocft/oracle b/tools/ocft/oracle new file mode 100644 index 0000000..6f145c7 --- /dev/null +++ b/tools/ocft/oracle @@ -0,0 +1,81 @@ +# oracle +# (based on db2) +# +# Created on an SLE11SP2 running oracle 11g +# database sid is orcl +# adapt this in set_testenv below +# TODO: need oracle expert to break it, then test it +# + +CONFIG + Agent oracle + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 40 + +SETUP-AGENT + # nothing + +CASE-BLOCK set_testenv + Env OCFT_sid=orcl + +CASE-BLOCK crm_setting + Env OCF_RESKEY_sid=$OCFT_sid + Env OCF_RESKEY_CRM_meta_timeout=30000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include set_testenv + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: no 'OCF_RESKEY_sid'" + Include prepare + Env OCF_RESKEY_sid= + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: invalid 'OCF_RESKEY_home'" + Include prepare + Env OCF_RESKEY_home=/no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "started: monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not started: monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "try different ipcrm method" + Include prepare + Env OCF_RESKEY_ipcrm=none + AgentRun start OCF_SUCCESS diff --git a/tools/ocft/pgsql b/tools/ocft/pgsql new file mode 100644 index 0000000..9944b09 --- /dev/null +++ b/tools/ocft/pgsql @@ -0,0 +1,71 @@ +# pgsql + +CONFIG + Agent pgsql + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage postgresql-server + HangTimeout 20 + +SETUP-AGENT + /etc/init.d/postgresql start + /etc/init.d/postgresql stop + +CASE-BLOCK crm_setting + Env OCF_RESKEY_CRM_meta_timeout=15000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_pgctl'" + Include prepare + Env OCF_RESKEY_pgctl=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "running monitor" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "not running monitor" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED + +CASE "non-existent user" + Include prepare + Env OCF_RESKEY_pgdba=no_user + AgentRun start OCF_ERR_INSTALLED + +CASE "invalid user" + Include prepare + Env OCF_RESKEY_pgdba=nobody + AgentRun start OCF_ERR_PERM diff --git a/tools/ocft/portblock b/tools/ocft/portblock new file mode 100644 index 0000000..3475c63 --- /dev/null +++ b/tools/ocft/portblock @@ -0,0 +1,69 @@ +# portblock + +CONFIG + Agent portblock + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage iptables + HangTimeout 15 + +CASE-BLOCK required_args + Env OCF_RESKEY_protocol=tcp + Env OCF_RESKEY_portno=80 + Env OCF_RESKEY_action=block + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_protocol'" + Include prepare + Unenv OCF_RESKEY_protocol + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: unset 'OCF_RESKEY_portno'" + Include prepare + Unenv OCF_RESKEY_portno + AgentRun start OCF_ERR_CONFIGURED + +CASE "check base env: unset 'OCF_RESKEY_action'" + Include prepare + Unenv OCF_RESKEY_action + AgentRun start OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor with running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor with not running" + Include prepare + AgentRun monitor OCF_NOT_RUNNING + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/postfix b/tools/ocft/postfix new file mode 100644 index 0000000..f17e968 --- /dev/null +++ b/tools/ocft/postfix @@ -0,0 +1,102 @@ +# postfix +# by r.bhatia@ipax.at +# +# test cases (to implement): +# +# * /usr/sbin/ocf-tester -n post1 /usr/lib/ocf/resource.d/heartbeat/postfix; echo $? -> DONE +# * /usr/sbin/ocf-tester -n post2 -o binary="/usr/sbin/postfix" \ +# -o config_dir="" /usr/lib/ocf/resource.d/heartbeat/postfix; echo $? -> DONE +# * /usr/sbin/ocf-tester -n post3 -o binary="/usr/sbin/postfix" \ +# -o config_dir="/etc/postfix" /usr/lib/ocf/resource.d/heartbeat/postfix; echo $? -> DONE +# * /usr/sbin/ocf-tester -n post4 -o binary="/usr/sbin/postfix" \ +# -o config_dir="/root/postfix/" /usr/lib/ocf/resource.d/heartbeat/postfix; echo $? + +CONFIG + Agent postfix + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage postfix + HangTimeout 20 + +SETUP-AGENT + # nothing + +CASE-BLOCK crm_setting + Env OCF_RESKEY_CRM_meta_timeout=15000 + Env OCF_RESKEY_CRM_meta_interval=10000 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include crm_setting + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: invalid 'OCF_RESKEY_binary'" + Include prepare + Env OCF_RESKEY_binary=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: invalid 'OCF_RESKEY_config_dir'" + Include prepare + Env OCF_RESKEY_config_dir=no_such + AgentRun start OCF_ERR_INSTALLED + +CASE "check base env: 'OCF_RESKEY_binary'" + Include prepare + Env OCF_RESKEY_binary=/usr/sbin/postfix + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "check base env: 'OCF_RESKEY_config_dir' without trailing slash" + Include prepare + Env OCF_RESKEY_config_dir="/etc/postfix" + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "check base env: 'OCF_RESKEY_config_dir' with trailing slash" + Include prepare + Env OCF_RESKEY_config_dir="/etc/postfix/" + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop OCF_SUCCESS + +CASE "monitor a running resource" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "(initial) probe a stopped resource" + Include prepare + Env OCF_RESKEY_CRM_meta_interval=0 + AgentRun monitor OCF_NOT_RUNNING + +CASE "(re-)probe a running resource" + Include prepare + Env OCF_RESKEY_CRM_meta_interval=0 + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "unimplemented command" + Include prepare + AgentRun no_cmd OCF_ERR_UNIMPLEMENTED diff --git a/tools/ocft/runocft b/tools/ocft/runocft new file mode 100755 index 0000000..d269a6b --- /dev/null +++ b/tools/ocft/runocft @@ -0,0 +1,38 @@ +#!/bin/sh +OCFTDIR=/usr/share/resource-agents/ocft +CONFDIR=$OCFTDIR/configs + +prereq_run() { + eval "$@" +} +prereq_prog() { + which $@ +} + +test_prereq() { + local tp arg + tp=`echo $prereq|sed 's/:.*//'` + arg=`echo $prereq|sed 's/[a-z]*://'` + prereq_$tp $arg >/dev/null 2>&1 +} + +rm -f ocft.FAILED +rc=0 +while read f prereq; do + if [ -n "$prereq" ] && ! test_prereq; then + echo "$f: prerequisite not fulfilled, skipping" + continue + fi + ocft make $f + if ! ocft test $f; then + echo $f >> ocft.FAILED + rc=1 + fi +done < $OCFTDIR/runocft.prereq + +if [ -f ocft.FAILED ]; then + echo "The following ocft tests failed:" + cat ocft.FAILED +fi + +exit $rc diff --git a/tools/ocft/runocft.prereq b/tools/ocft/runocft.prereq new file mode 100644 index 0000000..3bc222c --- /dev/null +++ b/tools/ocft/runocft.prereq @@ -0,0 +1,30 @@ +apache +db2 prog:~db2inst1/sqllib/bin/db2 +drbd.linbit run:false +exportfs +exportfs-multidir +Filesystem +IPaddr2 run:ip addr show dev eth0 +IPaddr2v4 run:ip addr show dev eth0 && ip addr show dev eth1 +IPaddr2v6 run:ip addr show dev eth0 && ip addr show dev eth1 +IPsrcaddr run:false +IPv6addr run:ip addr show dev eth0 && ip addr show dev eth1 +iscsi +jboss run:false +LVM +MailTo +mysql +mysql-proxy run:false +named +nfsserver +oracle prog:sqlplus +pgsql +portblock +postfix +Raid1 +SendArp +sg_persist run:false +tomcat run:false +VirtualDomain run:false +Xen run:false +Xinetd diff --git a/tools/ocft/sg_persist b/tools/ocft/sg_persist new file mode 100644 index 0000000..f11d36d --- /dev/null +++ b/tools/ocft/sg_persist @@ -0,0 +1,225 @@ +# sg_persist +# Before use sg_persist ocft test case you have to prepare to make pacemaker +# can be started successfully because sg_persist RA needs to use the result of +# `crm_node -i` as sg_persist register key. + +CONFIG + Agent sg_persist + AgentRoot /usr/lib/ocf/resource.d/heartbeat + InstallPackage sg3_utils + HangTimeout 20 + +VARIABLE + + # Please set the disk you want to test + #OCFT_DEVS="/dev/disk/by-id/scsi-14945540000000000844965720e6e555176b19461345d68d5" + OCFT_DEVS= + + # please set the IP addrees of the other server. + IP_2= + +SETUP-AGENT + # start pacemaker to get node_id through crm_node -i + systemctl start pacemaker + +CLEANUP-AGENT + +CASE-BLOCK required_args + Env HA_SBIN_DIR="" + Env OCF_RESKEY_devs="$OCFT_DEVS" + Env OCF_RESKEY_reservation_type=1 + Env OCF_RESKEY_CRM_meta_notify=true + Env OCF_RESKEY_CRM_meta_master_max=1 + +CASE-BLOCK required_args_error + Env HA_SBIN_DIR="" + Env OCF_RESKEY_devs="$OCFT_DEVS" + Env OCF_RESKEY_reservation_type=1 + Env OCF_RESKEY_CRM_meta_notify=true + Env OCF_RESKEY_CRM_meta_master_max=2 + +CASE-BLOCK required_args_type_5 + Env HA_SBIN_DIR="" + Env OCF_RESKEY_devs="$OCFT_DEVS" + Env OCF_RESKEY_reservation_type=5 + Env OCF_RESKEY_CRM_meta_notify=true + Env OCF_RESKEY_CRM_meta_master_max=1 + +CASE-BLOCK required_args_type_7 + Env HA_SBIN_DIR="" + Env OCF_RESKEY_devs="$OCFT_DEVS" + Env OCF_RESKEY_reservation_type=7 + Env OCF_RESKEY_CRM_meta_notify=true + Env OCF_RESKEY_CRM_meta_master_max=2 + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare + Include required_args + Include default_status + +CASE-BLOCK prepare_type_5 + Include required_args_type_5 + Include default_status + +CASE-BLOCK prepare_type_7 + Include required_args_type_7 + Include default_status + +CASE "check base env" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "check base env: unset 'OCF_RESKEY_sg_persist_devs'" + Include prepare + Unenv OCF_RESKEY_devs + AgentRun start OCF_ERR_INSTALLED + +CASE "validate all" + Include required_args + AgentRun validate-all OCF_SUCCESS + +CASE "validate all--type:5" + Include required_args_type_5 + AgentRun validate-all OCF_SUCCESS + +CASE "validate all--type:7" + Include required_args_type_7 + AgentRun validate-all OCF_SUCCESS + +CASE "validate all--error configured" + Include required_args_error + AgentRun validate-all OCF_ERR_CONFIGURED + +CASE "normal start" + Include prepare + AgentRun start OCF_SUCCESS + +CASE "normal stop" + Include prepare + AgentRun start + AgentRun stop OCF_SUCCESS + +CASE "double start" + Include prepare + AgentRun start + AgentRun start OCF_SUCCESS + +CASE "double stop" + Include prepare + AgentRun stop + AgentRun stop OCF_SUCCESS + +CASE "monitor when running" + Include prepare + AgentRun start + AgentRun monitor OCF_SUCCESS + +CASE "monitor when not running" + Include prepare + AgentRun stop + AgentRun monitor OCF_NOT_RUNNING + +CASE "Primary/Secondary monitor" + Include prepare + AgentRun start + AgentRun promote + AgentRun monitor OCF_RUNNING_MASTER + AgentRun demote + AgentRun monitor OCF_SUCCESS + AgentRun stop + +CASE "promote/demote test in single-primary mode" + Include prepare + Include@$IP_2 prepare + + # start + AgentRun start + AgentRun@$IP_2 start + + # promote local first + AgentRun promote OCF_SUCCESS + + # demote local prepare for remote promote + AgentRun demote + + # remote promote + AgentRun@$IP_2 promote OCF_SUCCESS + AgentRun@$IP_2 monitor OCF_RUNNING_MASTER + AgentRun monitor OCF_SUCCESS + + # promote local then promote(by preempt) remote, which will cause local OCF_NOT_RUNNING + AgentRun promote OCF_SUCCESS + AgentRun monitor OCF_RUNNING_MASTER + AgentRun@$IP_2 monitor OCF_NOT_RUNNING + + # remove all reservation registration + AgentRun demote + AgentRun stop + AgentRun@$IP_2 stop + + +CASE "normal start--type 5" + Include prepare_type_5 + Include@$IP_2 prepare_type_5 + AgentRun start OCF_SUCCESS + AgentRun@$IP_2 start OCF_SUCCESS + +CASE "promote/demote test in single-primary mode" + Include prepare_type_5 + Include@$IP_2 prepare_type_5 + + # start + AgentRun start + AgentRun@$IP_2 start + + # promote local first + AgentRun promote OCF_SUCCESS + AgentRun monitor OCF_RUNNING_MASTER + + # demote local prepare for remote promote + AgentRun demote + # remote promote + AgentRun@$IP_2 promote OCF_SUCCESS + AgentRun@$IP_2 monitor OCF_RUNNING_MASTER + AgentRun monitor OCF_SUCCESS + + # promote local then promote(by preempt) remote, which will cause local OCF_NOT_RUNNING + AgentRun promote OCF_SUCCESS + AgentRun monitor OCF_RUNNING_MASTER + AgentRun@$IP_2 monitor OCF_NOT_RUNNING + + # remove all reservation registration + AgentRun demote + AgentRun stop + AgentRun@$IP_2 stop + +CASE "normal start--type 7: 2 masters" + Include prepare_type_7 + Include@$IP_2 prepare_type_7 + AgentRun start OCF_SUCCESS + AgentRun@$IP_2 start OCF_SUCCESS + + +CASE "Primary/Primary monitor--type 7" + Include prepare_type_7 + Include@$IP_2 prepare_type_7 + + AgentRun start OCF_SUCCESS + AgentRun@$IP_2 start OCF_SUCCESS + + AgentRun promote OCF_SUCCESS + AgentRun monitor OCF_RUNNING_MASTER + + AgentRun@$IP_2 promote OCF_SUCCESS + AgentRun monitor OCF_RUNNING_MASTER + AgentRun@$IP_2 monitor OCF_RUNNING_MASTER + + AgentRun demote OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + AgentRun@$IP_2 demote OCF_SUCCESS + AgentRun@$IP_2 monitor OCF_NOT_RUNNING + + AgentRun stop + AgentRun@$IP_2 stop diff --git a/tools/ocft/tomcat b/tools/ocft/tomcat new file mode 100644 index 0000000..56adf86 --- /dev/null +++ b/tools/ocft/tomcat @@ -0,0 +1,73 @@ +# tomcat +# +# NOTE: Clean up $catalina_home/logs before running this test +# otherwise creating the pid/log files may fail +# in the test case with a different user. + +CONFIG + Agent tomcat + AgentRoot /usr/lib/ocf/resource.d/heartbeat + HangTimeout 120 + +VARIABLE + # Adjust accrding to your configuration + catalina_home=/opt/tomcat7 + tomcat_user=tomcat7 + java_home=/usr/lib/jvm/java-1.6.0-openjdk.x86_64 + +CASE-BLOCK required_args_tomcat + Env OCF_RESKEY_catalina_home=${catalina_home} + Env OCF_RESKEY_tomcat_user=${tomcat_user} + Env OCF_RESKEY_java_home=${java_home} + +CASE-BLOCK args_clear + Unenv OCF_RESKEY_catalina_home + Unenv OCF_RESKEY_tomcat_user + Unenv OCF_RESKEY_java_home + +CASE-BLOCK default_status + AgentRun stop + +CASE-BLOCK prepare_tomcat + Include required_args_tomcat + Include default_status + +# Test CASE +# +CASE "normal start tomcat require_args (user:user)" + Include prepare_tomcat + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + +CASE "normal start tomcat require_args (user:root)" + Include prepare_tomcat + Unenv OCF_RESKEY_tomcat_user + AgentRun start OCF_SUCCESS + AgentRun monitor OCF_SUCCESS + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + +CASE "error start tomcat no catalina_home" + Include prepare_tomcat + Unenv OCF_RESKEY_catalina_home + AgentRun start OCF_ERR_INSTALLED + Include args_clear + +CASE "error start tomcat no java_home" + Include prepare_tomcat + Unenv OCF_RESKEY_java_home + AgentRun start OCF_ERR_INSTALLED + Include args_clear + +CASE "error start tomcat no java command" + Include prepare_tomcat + Env OCF_RESKEY_java_home=/var + AgentRun start OCF_ERR_INSTALLED + AgentRun stop OCF_SUCCESS + AgentRun monitor OCF_NOT_RUNNING + Include args_clear + |