]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
make a real PROTOCOL TEST
authorAlan T. DeKok <aland@freeradius.org>
Fri, 24 Feb 2023 21:04:56 +0000 (16:04 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 24 Feb 2023 21:14:20 +0000 (16:14 -0500)
and glue it into:

* unit_test_module, as TEST is now a normal protocol
* process/test/base.c - as above

* src/test/process - more magic && code to run tests

src/bin/unit_test_module.c
src/process/test/base.c
src/tests/keywords/policy.conf
src/tests/process/all.mk
src/tests/process/policy.conf [new file with mode: 0644]
src/tests/process/radius/access_accept
src/tests/process/radius/policy.conf [new file with mode: 0644]
src/tests/process/radius/server.conf [new file with mode: 0644]
src/tests/process/share/.gitignore [new file with mode: 0644]
src/tests/process/share/test/dictionary
src/tests/process/unit_test_module.conf

index 873f7158b382dc658262c7460697e963d9aedb07..4734e259955d2e89988de049674c6c50d1b7da8e 100644 (file)
@@ -778,19 +778,10 @@ int main(int argc, char *argv[])
                EXIT_WITH_FAILURE;
        }
 
-       /*
-        *      Manually load the protocol dictionary, unless it's "test"
-        */
-       if (strcmp(PROTOCOL_NAME, "test") != 0) {
-               if (fr_dict_autoload(unit_test_module_dict) < 0) {
-                       fr_perror("%s", config->name);
-                       EXIT_WITH_FAILURE;
-               }
-       } else {
-               dict_protocol = fr_dict_internal();
-               dict_freeradius = dict_protocol;
+       if (fr_dict_autoload(unit_test_module_dict) < 0) {
+               fr_perror("%s", config->name);
+               EXIT_WITH_FAILURE;
        }
-
        if (fr_dict_attr_autoload(unit_test_module_dict_attr) < 0) {
                fr_perror("%s", config->name);
                EXIT_WITH_FAILURE;
@@ -864,7 +855,6 @@ int main(int argc, char *argv[])
         *      Do some sanity checking.
         */
        dict_check = virtual_server_dict_by_name("default");
-
        if (!dict_check || (dict_check != dict_protocol)) {
                ERROR("Virtual server namespace does not match requested namespace '%s'", PROTOCOL_NAME);
                EXIT_WITH_FAILURE;
@@ -1150,8 +1140,7 @@ cleanup:
        /*
         *      Free our explicitly loaded internal dictionary
         */
-       if ((dict_protocol != dict_freeradius) &&
-           (fr_dict_free(&dict, __FILE__) < 0)) {
+       if (fr_dict_free(&dict, __FILE__) < 0) {
                fr_perror("unit_test_module - dict");
                ret = EXIT_FAILURE;
        }
index 99cffab23ee367d67c8b8a3f8060630559a642ea..3bceaf763495c20edc56a0cb7c2fb5258557d701 100644 (file)
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/arp/arp.h>
 
-static fr_dict_t const *dict_freeradius;
+static fr_dict_t const *dict_test;
 
 extern fr_dict_autoload_t process_test_dict[];
 fr_dict_autoload_t process_test_dict[] = {
-       { .out = &dict_freeradius, .proto = "freeradius" },
+       { .out = &dict_test, .proto = "test" },
        { NULL }
 };
 
@@ -37,7 +37,7 @@ static fr_dict_attr_t const *attr_packet_type;
 
 extern fr_dict_attr_autoload_t process_test_dict_attr[];
 fr_dict_attr_autoload_t process_test_dict_attr[] = {
-       { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius},
+       { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_test},
        { NULL }
 };
 
@@ -97,7 +97,7 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc
 
        request->component = "test";
        request->module = NULL;
-       fr_assert(request->dict == dict_freeradius);
+       fr_assert(request->dict == dict_test);
 
        UPDATE_STATE(packet);
 
@@ -131,5 +131,5 @@ fr_process_module_t process_test = {
        },
        .process        = mod_process,
        .compile_list   = compile_list,
-       .dict           = &dict_freeradius,
+       .dict           = &dict_test,
 };
index 284a69768221cd3d44897072b85b0fd9eed2a743..c9f2cd1140f7dc87ddde1ceaa78e56f752112500 100644 (file)
@@ -55,12 +55,12 @@ success {
 
 test_fail {
        &reply += {
-               &Result-Status = "Failure in test at line %(interpreter:...line)"
+               &Result-Status = "Failure in test file %(interpreter:...filename) at line %(interpreter:...line)"
        }
 
        if (&parent.request) {
                &parent.reply += {
-                       &Result-Status = "Failure in test at line %(interpreter:...line)"
+                       &Result-Status = "Failure in test file %(interpreter:...filename) at line %(interpreter:...line)"
                }
        }
 }
index 41cbc7347115f156a66302699cc9d5af6307d605..a76630ec97043ed67718bf160e4bc16da8674cb9 100644 (file)
@@ -30,6 +30,16 @@ $(eval $(call TEST_BOOTSTRAP))
 
 # -S parse_new_conditions=yes -S use_new_conditions=yes -S forbid_update=yes
 
+#
+#  The dictionaries are in "share", because the server tries to load
+#  local dictionaries from "./dictionary".
+#
+src/tests/process/share/%: ${top_srcdir}/share/dictionary/%
+       @ln -sf $< $@
+
+ifneq "$(OPENSSL_LIBS)" ""
+PROCESS_DICT_TLS := $(DIR)/share/tls
+endif
 
 #
 #  For sheer laziness, allow "make test.process.foo"
@@ -46,6 +56,10 @@ test.process.help: TEST_PROCESS_HELP += test.process.${1}
 #  With filenames added for the output files
 #
 $(OUTPUT)/${1}: $(patsubst %,${BUILD_DIR}/lib/local/process_%.la,$(subst /,,$(dir ${1})) test)
+
+$(OUTPUT)/${1}: $(DIR)/$(subst /,,$(dir ${1}))/server.conf
+
+$(OUTPUT)/${1}: | $(DIR)/share/$(subst /,,$(dir ${1})) $(DIR)/share/freeradius $(PROCESS_DICT_TLS)
 endef
 $(foreach x,$(FILES),$(eval $(call PROCESS_TEST,$x)))
 
@@ -70,12 +84,12 @@ $(foreach x,$(FILES),$(eval $(call PROCESS_TEST,$x)))
 #      (make -k test.process 2>&1) | grep 'PROCESS=' | sed 's/PROCESS=//;s/ .*$//'
 #
 PROCESS_ARGS := -p test
-PROCESS_ARGS += -D share/dictionary -d $(DIR)/
+PROCESS_ARGS += -D $(DIR)/share -d $(DIR)/
 PROCESS_ARGS += -S parse_new_conditions=yes -S use_new_conditions=yes -S forbid_update=yes
-PROCESS_ARGS += -i $(DIR)/test.attrs
+PROCESS_ARGS += -i $(DIR)/test.attrs -f $(DIR)/test.attrs
 
 $(OUTPUT)/%: $(DIR)/% $(TEST_BIN_DIR)/unit_test_module $(DIR)/unit_test_module.conf
-       $(eval CMD:=PROCESS=$< $(TEST_BIN)/unit_test_module $(PROCESS_ARGS) -r "$@" -xx)
+       $(eval CMD:=PROCESS=$< PROTOCOL=$(dir $<) $(TEST_BIN)/unit_test_module $(PROCESS_ARGS) -r "$@" -xx)
        @echo PROCESS-TEST $(notdir $@)
        @mkdir -p $(dir $@)
        @if ! $(CMD) > "$@.log" 2>&1 || ! test -f "$@"; then \
diff --git a/src/tests/process/policy.conf b/src/tests/process/policy.conf
new file mode 100644 (file)
index 0000000..64435b0
--- /dev/null
@@ -0,0 +1,57 @@
+#
+#  Common policies for the test cases.
+#
+#  Copied from test.keywords with some minor changesk
+#
+#
+
+#
+#  Outputs the contents of the control list in debugging (-X) mode
+#
+debug_control {
+       %(debug_attr:&control.[*])
+}
+
+#
+#  Outputs the contents of the request list in debugging (-X) mode
+#
+debug_request {
+       %(debug_attr:&request.[*])
+}
+
+#
+#  Outputs the contents of the reply list in debugging (-X) mode
+#
+debug_reply {
+       %(debug_attr:&reply.[*])
+}
+
+#
+#  Outputs the contents of the main lists in debugging (-X) mode
+#
+debug_all {
+       debug_control
+       debug_request
+       debug_reply
+}
+
+#
+#  Set the test to successful, but only if there are no failures.
+#
+success {
+       &reply.Result-Status = "success"
+
+       ok
+}
+
+test_fail {
+       &reply += {
+               &Failure = "Failure in test file %(interpreter:....filename) at line %(interpreter:...line)"
+       }
+
+       if (&parent.request) {
+               &parent.reply += {
+                       &Failure = "Failure in test file %(interpreter:....filename) at line %(interpreter:...line)"
+               }
+       }
+}
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5c99e4f029bcfbf5bd7d0861ccf0a73ec7364bfb 100644 (file)
@@ -0,0 +1,11 @@
+subrequest RADIUS.Access-Request {
+       &User-Name = "bob"
+       &User-Password = "hello"
+
+
+       call radius {
+               if (&reply.Packet-Type != Access-Accept) {
+                       test_fail
+               }
+       }
+}
diff --git a/src/tests/process/radius/policy.conf b/src/tests/process/radius/policy.conf
new file mode 100644 (file)
index 0000000..f587e21
--- /dev/null
@@ -0,0 +1,17 @@
+#
+#  Send Access-Accept immediately
+#
+accept {
+       &reply.Packet-Type := Access-Accept
+
+       handled
+}
+
+#
+#  Send Access-Challenge immediately
+#
+challenge {
+       &reply.Packet-Type := Access-Challenge
+
+       handled
+}
diff --git a/src/tests/process/radius/server.conf b/src/tests/process/radius/server.conf
new file mode 100644 (file)
index 0000000..9cce859
--- /dev/null
@@ -0,0 +1,16 @@
+server radius {
+       namespace = radius
+
+recv Access-Request {
+       accept
+}
+
+send Access-Accept {
+       ok
+}
+
+send Access-Challenge {
+       &reply.Reply-Message := "challenge"
+}
+
+}
\ No newline at end of file
diff --git a/src/tests/process/share/.gitignore b/src/tests/process/share/.gitignore
new file mode 100644 (file)
index 0000000..6ddd6da
--- /dev/null
@@ -0,0 +1,3 @@
+*
+!test
+!.gitignore
index 24a624cf80f7e91be30d2fe497221dfc762e899e..f701a16ee90e988bece8a618514480987a6df582 100644 (file)
@@ -1,3 +1,7 @@
+PROTOCOL Test 314159
+
+BEGIN-PROTOCOL Test
+
 #
 #  Only for tests.
 #
@@ -6,3 +10,10 @@ FLAGS internal
 DEFINE         Packet-Type                             uint32
 VALUE  Packet-Type             Request                 1
 VALUE  Packet-Type             Reply                   2
+
+END-PROTOCOL Test
+
+#
+#  Generic test failure message
+#
+DEFINE         Failure                                 string
index 5550e39f6bf322be4fadb701ce6bb24e5c8488c8..c2ed45a982dc4e4eb6be1129415a948a06feda2e 100644 (file)
@@ -11,6 +11,19 @@ $INCLUDE ../../../raddb/mods-available/always
 
 }
 
+policy {
+$-INCLUDE $ENV{PROTOCOL}/policy.conf
+$INCLUDE policy.conf
+}
+
+#
+#  Include the virtual server for the protocol
+#
+$INCLUDE $ENV{PROTOCOL}/server.conf
+
+#
+#  And our basic test framework.
+#
 server default {
        namespace = test
 
@@ -20,14 +33,22 @@ server default {
        test {
        }
 
+       #
+       #  This section runs the per-protocol state machine.
+       #
+       #  It creates subrequests, calls the per-protocol process
+       #  routine, and checks the results.
+       #
        recv Request {
-
+#
+#  All of the tests run within a "subrequest".
+#
 $INCLUDE $ENV{PROCESS}
-
-               ok
        }
 
        send Reply {
-               ok
+               if (!&reply.Failure) {
+                       success
+               }
        }
 }