]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-tests: Add unit tests for tunables code
authorMartin Schwenke <martin@meltin.net>
Mon, 31 Jan 2022 03:36:23 +0000 (14:36 +1100)
committerAmitay Isaacs <amitay@samba.org>
Wed, 6 Apr 2022 06:34:37 +0000 (06:34 +0000)
This aims to test ctdb_tunable_load_file() but also exercises
ctdb_tunable_names() and ctdb_tunable_get_value().
ctdb_tunable_set_value() is indirectly exercised via
ctdb_tunable_load_file().

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/tests/UNIT/cunit/tunable_test_001.sh [new file with mode: 0755]
ctdb/tests/src/tunable_test.c [new file with mode: 0644]
ctdb/wscript

diff --git a/ctdb/tests/UNIT/cunit/tunable_test_001.sh b/ctdb/tests/UNIT/cunit/tunable_test_001.sh
new file mode 100755 (executable)
index 0000000..2ae87f6
--- /dev/null
@@ -0,0 +1,306 @@
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+tfile="${CTDB_TEST_TMP_DIR}/tunable.$$"
+
+remove_files ()
+{
+       rm -f "$tfile"
+}
+test_cleanup remove_files
+
+defaults="\
+SeqnumInterval=1000
+ControlTimeout=60
+TraverseTimeout=20
+KeepaliveInterval=5
+KeepaliveLimit=5
+RecoverTimeout=30
+RecoverInterval=1
+ElectionTimeout=3
+TakeoverTimeout=9
+MonitorInterval=15
+TickleUpdateInterval=20
+EventScriptTimeout=30
+MonitorTimeoutCount=20
+RecoveryGracePeriod=120
+RecoveryBanPeriod=300
+DatabaseHashSize=100001
+DatabaseMaxDead=5
+RerecoveryTimeout=10
+EnableBans=1
+NoIPFailback=0
+VerboseMemoryNames=0
+RecdPingTimeout=60
+RecdFailCount=10
+LogLatencyMs=0
+RecLockLatencyMs=1000
+RecoveryDropAllIPs=120
+VacuumInterval=10
+VacuumMaxRunTime=120
+RepackLimit=10000
+VacuumFastPathCount=60
+MaxQueueDropMsg=1000000
+AllowUnhealthyDBRead=0
+StatHistoryInterval=1
+DeferredAttachTO=120
+AllowClientDBAttach=1
+FetchCollapse=1
+HopcountMakeSticky=50
+StickyDuration=600
+StickyPindown=200
+NoIPTakeover=0
+DBRecordCountWarn=100000
+DBRecordSizeWarn=10000000
+DBSizeWarn=100000000
+PullDBPreallocation=10485760
+LockProcessesPerDB=200
+RecBufferSizeLimit=1000000
+QueueBufferSize=1024
+IPAllocAlgorithm=2
+AllowMixedVersions=0
+"
+
+ok_tunable_defaults ()
+{
+       ok "$defaults"
+}
+
+# Set required output to a version of $defaults where values for
+# tunables specified in $tfile replace the default values
+ok_tunable ()
+{
+       # Construct a version of $defaults prepended with a lowercase
+       # version of the tunable variable, to allow case-insensitive
+       # matching.  This would be easier with the GNU sed
+       # case-insensitivity flag, but that is less portable.  The $0
+       # condition in awk causes empty lines to be skipped, in case
+       # there are trailing empty lines in $defaults.
+       _map=$(echo "$defaults" |
+              awk -F= '$0 { printf "%s:%s=%s\n", tolower($1), $1, $2 }')
+
+       # Replace values for tunables set in $tfile
+       while IFS='=    ' read -r _var _val ; do
+               case "$_var" in
+               \#* | "") continue ;;
+               esac
+               _decval=$((_val))
+               _vl=$(echo "$_var" | tr '[:upper:]' '[:lower:]')
+               _map=$(echo "$_map" |
+                      sed -e "s|^\\(${_vl}:.*=\\).*\$|\\1${_decval}|")
+       done <"$tfile"
+
+       # Set result, stripping off lowercase tunable prefix
+       ok "$(echo "$_map" | awk -F: '{ print $2 }')"
+}
+
+test_case "Unreadable file"
+: >"$tfile"
+chmod a-r "$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Failed to open ${tfile}
+EOF
+unit_test tunable_test "$tfile"
+rm -f "$tfile"
+
+test_case "Invalid file, contains 1 word"
+echo "Hello" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid line containing "Hello"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, contains multiple words"
+echo "Hello world!" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid line containing "Hello world!"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, missing value"
+echo "EnableBans=" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid line containing "EnableBans"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, invalid value (not a number)"
+echo "EnableBans=value" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid value "value" for tunable "EnableBans"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, missing key"
+echo "=123" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Syntax error
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, missing key but space before ="
+cat >"$tfile" <<EOF
+ =0
+EOF
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Syntax error
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, unknown tunable"
+echo "HelloWorld=123" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Unknown tunable "HelloWorld"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, obsolete tunable"
+echo "MaxRedirectCount=123" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Obsolete tunable "MaxRedirectCount"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, trailing non-whitespace garbage"
+echo "EnableBans=0xgg" >"$tfile"
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid value "0xgg" for tunable "EnableBans"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, multiple errors"
+cat >"$tfile" <<EOF
+EnableBans=
+EnableBans=value
+=123
+HelloWorld=123
+MaxRedirectCount =123
+EOF
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Invalid line containing "EnableBans"
+ctdb_tunable_load_file: Invalid value "value" for tunable "EnableBans"
+ctdb_tunable_load_file: Syntax error
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "Invalid file, errors followed by valid"
+cat >"$tfile" <<EOF
+HelloWorld=123
+EnableBans=value
+EnableBans=0
+EOF
+required_error EINVAL <<EOF
+ctdb_tunable_load_file: Unknown tunable "HelloWorld"
+ctdb_tunable_load_file: Invalid value "value" for tunable "EnableBans"
+EOF
+unit_test tunable_test "$tfile"
+
+test_case "OK, missing file"
+rm -f "$tfile"
+ok_tunable_defaults
+unit_test tunable_test "$tfile"
+
+test_case "OK, empty file"
+: >"$tfile"
+ok_tunable_defaults
+unit_test tunable_test "$tfile"
+
+test_case "OK, comments and blanks only"
+cat >"$tfile" <<EOF
+# This is a comment
+
+# There are also some blank lines
+
+
+EOF
+ok_tunable_defaults
+unit_test tunable_test "$tfile"
+
+test_case "OK, 1 tunable"
+cat >"$tfile" <<EOF
+EnableBans=0
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 1 tunable, hex"
+cat >"$tfile" <<EOF
+EnableBans=0xf
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 1 tunable, octal"
+cat >"$tfile" <<EOF
+EnableBans=072
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 1 tunable, tab before ="
+cat >"$tfile" <<EOF
+EnableBans     =0
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 1 tunable, space after ="
+cat >"$tfile" <<EOF
+EnableBans= 0
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 2 tunables, multiple spaces around ="
+cat >"$tfile" <<EOF
+EnableBans      =  0
+RecoverInterval = 10
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, 2 tunables, whitespace everywhere"
+cat >"$tfile" <<EOF
+       EnableBans      = 0  
+       RecoverInterval = 10 
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, several tunables"
+cat >"$tfile" <<EOF
+EnableBans=0
+RecoverInterval=10
+ElectionTimeout=5
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, several tunables, varying case"
+cat >"$tfile" <<EOF
+enablebans=0
+ReCoVerInTeRvAl=10
+ELECTIONTIMEOUT=5
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
+
+test_case "OK, miscellaneous..."
+cat >"$tfile" <<EOF
+# Leading comment
+enablebans=0
+ReCoVerInTeRvAl         =    10
+
+# Intermediate comment after a blank line
+  ELECTIONTIMEOUT=25   
+
+
+# Final comment among blanks lines
+
+
+
+
+EOF
+ok_tunable
+unit_test tunable_test "$tfile"
diff --git a/ctdb/tests/src/tunable_test.c b/ctdb/tests/src/tunable_test.c
new file mode 100644 (file)
index 0000000..ea94aec
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+   Test tunable handling
+
+   Copyright (C) Martin Schwenke, DataDirect Networks  2022
+
+   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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+
+#include <talloc.h>
+#include <assert.h>
+
+#include "common/tunable.c"
+
+int main(int argc, const char **argv)
+{
+       TALLOC_CTX *mem_ctx;
+       struct ctdb_tunable_list tun_list;
+       struct ctdb_var_list *list;
+       bool status;
+       int ret = 0;
+       int i;
+
+       if (argc != 2) {
+               fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
+               return 1;
+       }
+
+       mem_ctx = talloc_new(NULL);
+       assert(mem_ctx != NULL);
+
+       status = ctdb_tunable_load_file(mem_ctx, &tun_list, argv[1]);
+       if (!status) {
+               ret = EINVAL;
+               goto done;
+       }
+
+       list = ctdb_tunable_names(mem_ctx);
+       assert(list != NULL);
+
+       for (i = 0; i < list->count; i++) {
+               const char *var = list->var[i];
+               uint32_t val;
+
+               status = ctdb_tunable_get_value(&tun_list, var, &val);
+               if (!status) {
+                       ret = EIO;
+                       goto done;
+               }
+
+               printf("%s=%"PRIu32"\n", var, val);
+               fflush(stdout);
+       }
+
+done:
+       talloc_free(mem_ctx);
+       return ret;
+}
index 4a28dfd3cf09ca15d93c412ec7d83b7c2ca3fdae..2be9d28e26b17f69e2b65238f1f32a9b93834f87 100644 (file)
@@ -920,6 +920,7 @@ def build(bld):
         'conf_test',
         'line_test',
         'event_script_test',
+        'tunable_test',
     ]
 
     for target in ctdb_unit_tests: