]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-tests: Add tests for tunables directory loading
authorMartin Schwenke <mschwenke@ddn.com>
Fri, 27 Jun 2025 07:35:03 +0000 (17:35 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 22 Jul 2025 23:02:34 +0000 (23:02 +0000)
The missing 2nd file testcase becomes the missing directory testcase,
because you can't easily have both.  See the comment in
tunable_test.c.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/tests/UNIT/cunit/tunable_test_001.sh
ctdb/tests/src/tunable_test.c

index caac08bd2451cdb09b3bce96cd93a48ecc7ecf6c..a639c8772cb7ec2770b623ed5ceb4df0000e5786 100755 (executable)
@@ -4,10 +4,13 @@
 
 tfile="${CTDB_TEST_TMP_DIR}/tunable.$$"
 tfile2="${CTDB_TEST_TMP_DIR}/tunable2.$$"
+tdir="${CTDB_TEST_TMP_DIR}/tunabled.$$"
 
 remove_files()
 {
        rm -f "$tfile" "$tfile2"
+       rm -f "${tdir}/"* 2>/dev/null || true
+       rmdir "$tdir" 2>/dev/null || true
 }
 test_cleanup remove_files
 
@@ -136,7 +139,18 @@ ok_tunable()
        ok_tunable_1 "$_f1"
 
        if [ -n "$_f2" ]; then
-               ok_tunable_1 "$_f2"
+               if [ -f "$_f2" ]; then
+                       ok_tunable_1 "$_f2"
+               elif [ -d "$_f2" ]; then
+                       for _t in "${_f2}/"*.tunables; do
+                               if [ ! -e "$_t" ]; then
+                                       break
+                               fi
+                               ok_tunable_1 "$_t"
+                       done
+               elif [ ! -e "$_f2" ]; then
+                       tunable_log "INFO" "Optional tunables directory ${_f2} not found"
+               fi
        fi
 
        # Set result, stripping off lowercase tunable prefix
@@ -406,7 +420,68 @@ EOF
 ok_tunable "$tfile" "$tfile2"
 unit_test tunable_test "$tfile" "$tfile2"
 
-test_case "OK, several tunables, missing 2nd file"
+#
+# 2nd argument is a directory
+#
+
+test_case "OK, several tunables, missing directory"
 rm -f "$tfile2"
-ok_tunable "$tfile" "$tfile2"
-unit_test tunable_test "$tfile" "$tfile2"
+rmdir "$tdir" 2>/dev/null || true
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+test_case "OK, several tunables, empty directory"
+mkdir -p "$tdir"
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+test_case "OK, several tunables, README in directory"
+cat >"${tdir}/README" <<EOF
+This will be ignored because the file doesn't end in ".tunables"
+
+RecoverInterval=55
+EOF
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+#
+# README can stay there...
+#
+# Subsequent testcases add files, leaving existing ones there
+#
+
+test_case "OK, several tunables,  single file in directory"
+cat >"${tdir}/f70.tunables" <<EOF
+RecoverInterval=45
+EOF
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+test_case "OK, several tunables,  2 disjoint files in directory"
+cat >"${tdir}/f10.tunables" <<EOF
+RecoverTimeout=42
+EOF
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+test_case "OK, several tunables,  3rd file in directory overlaps"
+cat >"${tdir}/f40.tunables" <<EOF
+RecoverInterval=21
+RecoverTimeout=54
+EOF
+ok_tunable "$tfile" "$tdir"
+unit_test tunable_test "$tfile" "$tdir"
+
+test_case "OK, several tunables, error in directory file"
+cat >"${tdir}/f20.tunables" <<EOF
+Oops!
+EOF
+required_error EINVAL <<EOF
+Loading tunables from ${tfile}
+Loading tunables from ${tdir}/f10.tunables
+Loading tunables from ${tdir}/f20.tunables
+${tdir}/f20.tunables: Invalid tunables line containing "Oops!"
+Loading tunables from ${tdir}/f40.tunables
+Loading tunables from ${tdir}/f70.tunables
+EOF
+unit_test tunable_test "$tfile" "$tdir"
index 2a40eddbc1dd27f4c6bd3149e086e1828bf72984..748b31e23723ed94c91e0f707fa786b0e7515580 100644 (file)
 
 #include "common/tunable.c"
 
+static void usage(const char * prog)
+{
+       fprintf(stderr,
+               "Usage: %s <filename> [<filename>|<dir>]\n",
+               prog);
+       exit(1);
+}
+
 int main(int argc, const char **argv)
 {
        TALLOC_CTX *mem_ctx;
@@ -37,8 +45,7 @@ int main(int argc, const char **argv)
        int i;
 
        if (argc != 2 && argc != 3) {
-               fprintf(stderr, "Usage: %s <filename> [<filename>]\n", argv[0]);
-               return 1;
+               usage(argv[0]);
        }
 
        mem_ctx = talloc_new(NULL);
@@ -55,7 +62,33 @@ int main(int argc, const char **argv)
        }
 
        if (argc == 3) {
-               status = ctdb_tunable_load_file(mem_ctx, &tun_list, argv[2]);
+               struct stat st = {};
+               int stat_failed = false;
+
+               ret = stat(argv[2], &st);
+               if (ret != 0) {
+                       if (errno == ENOENT || errno == EACCES) {
+                               stat_failed = true;
+                       } else {
+                               usage(argv[0]);
+                       }
+               }
+
+               /*
+                * If stat() failed then continue and test the failure
+                * path in directory loading.  The failure path in
+                * file loading can already be tested with the
+                * mandatory 1st file argument.
+                */
+               if (stat_failed || S_ISDIR(st.st_mode)) {
+                       status = ctdb_tunable_load_directory(mem_ctx,
+                                                            &tun_list,
+                                                            argv[2]);
+               } else {
+                       status = ctdb_tunable_load_file(mem_ctx,
+                                                       &tun_list,
+                                                       argv[2]);
+               }
                if (!status) {
                        ret = EINVAL;
                        goto done;
@@ -65,6 +98,7 @@ int main(int argc, const char **argv)
        list = ctdb_tunable_names(mem_ctx);
        assert(list != NULL);
 
+       ret = 0;
        for (i = 0; i < list->count; i++) {
                const char *var = list->var[i];
                uint32_t val;