From 3f865d34918406c3198be6c51a5a4ac79c12294c Mon Sep 17 00:00:00 2001 From: Matthew Newton Date: Tue, 28 Jan 2020 01:12:54 +0000 Subject: [PATCH] rlm_json: json_encode xlat module tests --- src/tests/modules/json/encode.attrs | 13 ++ src/tests/modules/json/encode.unlang | 332 +++++++++++++++++++++++++++ src/tests/modules/json/module.conf | 147 ++++++++++++ 3 files changed, 492 insertions(+) create mode 100644 src/tests/modules/json/encode.attrs create mode 100644 src/tests/modules/json/encode.unlang diff --git a/src/tests/modules/json/encode.attrs b/src/tests/modules/json/encode.attrs new file mode 100644 index 000000000000..3b5a0c688c4d --- /dev/null +++ b/src/tests/modules/json/encode.attrs @@ -0,0 +1,13 @@ +# +# Input packet +# +User-Name = 'john' +Filter-Id = "f1" +Filter-Id += "f2" +NAS-Port = 999 +Service-Type = Login-User + +# +# Expected answer +# +Packet-Type == Access-Accept diff --git a/src/tests/modules/json/encode.unlang b/src/tests/modules/json/encode.unlang new file mode 100644 index 000000000000..f474db5a8b1e --- /dev/null +++ b/src/tests/modules/json/encode.unlang @@ -0,0 +1,332 @@ +# +# json_encode tests +# + + +# 0. Check basic xlat parsing + +update request { + &Tmp-String-1 := "%{json_encode:&request:[*]}" + &Tmp-String-2 := "%{json_encode:&request:[*] }" + &Tmp-String-3 := "%{json_encode: &request:[*]}" + &Tmp-String-4 := "%{json_encode: &request:[*] }" + &Tmp-String-5 := "%{json_encode: &request:[*] !&Filter-Id }" + &Tmp-String-6 := "%{json_encode:&request:[*] ! }" +# Check defaults are the same as output_mode "object": + &Tmp-String-7 := "%{json_object_encode:&request:[*]}" + &Tmp-String-8 := "%{json_object_no_encode:&request:[*]}" +} + + +if (&Tmp-String-1 == '{"User-Name":{"type":"string","value":"john"},"Filter-Id":{"type":"string","value":["f1","f2"]},"NAS-Port":{"type":"uint32","value":999},"Service-Type":{"type":"uint32","value":"Login-User"}}') { + test_pass +} else { + test_fail +} + +# Check xlat input formats +if (&Tmp-String-1 != &Tmp-String-2 || + &Tmp-String-1 != &Tmp-String-3 || + &Tmp-String-1 != &Tmp-String-4) { + test_fail +} + +# Check defaults +if (&Tmp-String-1 != &Tmp-String-7 || + &Tmp-String-1 != &Tmp-String-8) { + test_fail +} + +if (&Tmp-String-5 == '{"User-Name":{"type":"string","value":"john"},"NAS-Port":{"type":"uint32","value":999},"Service-Type":{"type":"uint32","value":"Login-User"}}') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-6 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Tmp-String-3 !* ANY + &Tmp-String-4 !* ANY + &Tmp-String-5 !* ANY + &Tmp-String-6 !* ANY + &Tmp-String-7 !* ANY + &Tmp-String-8 !* ANY +} + + +# 1a. Output mode "object" tests + +# These are unsorted dictionaries. Hopefully json-c doesn't suddenly +# decide that it's going to use a different ordering of the keys... + +update request { + &Tmp-String-1 := "%{json_object_encode:&request:[*]}" + &Tmp-String-2 := "%{json_object_ex_encode:&request:[*]}" +} + +if (&Tmp-String-1 == '{"User-Name":{"type":"string","value":"john"},"Filter-Id":{"type":"string","value":["f1","f2"]},"NAS-Port":{"type":"uint32","value":999},"Service-Type":{"type":"uint32","value":"Login-User"}}') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '{"pf:User-Name":{"type":"string","value":["john"]},"pf:Filter-Id":{"type":"string","value":["f1","f2"]},"pf:NAS-Port":{"type":"uint32","value":["999"]},"pf:Service-Type":{"type":"uint32","value":["1"]}}') { + test_pass +} else { + test_fail +} + +# 1b. "object" empty inputs + +update request { + &Tmp-String-1 := "%{json_object_encode:!&request:[*]}" + &Tmp-String-2 := "%{json_object_ex_encode:}" +} + +if (&Module-Failure-Message == 'Failed concatenating input: Invalid arguments. List was NULL') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-1 == '{}') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Module-Failure-Message !* ANY +} + + +# 2a. Output mode "object_simple" tests + +update request { + &Tmp-String-1 := "%{json_object_simple_encode:&request:[*]}" + &Tmp-String-2 := "%{json_object_simple_ex_encode:&request:[*]}" +} + +if (&Tmp-String-1 == '{"User-Name":"john","Filter-Id":["f1","f2"],"NAS-Port":999,"Service-Type":"Login-User"}') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '{"pf:User-Name":["john"],"pf:Filter-Id":["f1","f2"],"pf:NAS-Port":["999"],"pf:Service-Type":["1"]}') { + test_pass +} else { + test_fail +} + +# 2b. "object_simple" empty inputs + +update request { + &Tmp-String-1 := "%{json_object_simple_encode:!&request:[*]}" + &Tmp-String-2 := "%{json_object_simple_ex_encode:}" +} + +if (&Module-Failure-Message == 'Failed concatenating input: Invalid arguments. List was NULL') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-1 == '{}') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Module-Failure-Message !* ANY +} + + +# 3a. Output mode "array" tests + +update request { + &Tmp-String-1 := "%{json_array_encode:&request:[*]}" + &Tmp-String-2 := "%{json_array_ex_encode:&request:[*]}" +} + +if (&Tmp-String-1 == '[{"name":"User-Name","type":"string","value":"john"},{"name":"Filter-Id","type":"string","value":"f1"},{"name":"Filter-Id","type":"string","value":"f2"},{"name":"NAS-Port","type":"uint32","value":999},{"name":"Service-Type","type":"uint32","value":"Login-User"}]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '[{"name":"pf:User-Name","type":"string","value":["john"]},{"name":"pf:Filter-Id","type":"string","value":["f1","f2"]},{"name":"pf:NAS-Port","type":"uint32","value":["999"]},{"name":"pf:Service-Type","type":"uint32","value":["1"]}]') { + test_pass +} else { + test_fail +} + +# 3b. "array" empty inputs + +update request { + &Tmp-String-1 := "%{json_array_encode:!&request:[*]}" + &Tmp-String-2 := "%{json_array_ex_encode:}" +} + +if (&Module-Failure-Message == 'Failed concatenating input: Invalid arguments. List was NULL') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-1 == '[]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Module-Failure-Message !* ANY +} + + +# 4a. Output mode "array_of_names" tests + +update request { + &Tmp-String-1 := "%{json_array_names_encode:&request:[*]}" + &Tmp-String-2 := "%{json_array_names_ex_encode:&request:[*]}" +} + +if (&Tmp-String-1 == '["User-Name","Filter-Id","Filter-Id","NAS-Port","Service-Type"]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '["pf:User-Name","pf:Filter-Id","pf:Filter-Id","pf:NAS-Port","pf:Service-Type"]') { + test_pass +} else { + test_fail +} + +# 4b. "array_of_names" empty inputs + +update request { + &Tmp-String-1 := "%{json_array_names_encode:!&request:[*]}" + &Tmp-String-2 := "%{json_array_names_ex_encode:}" +} + +if (&Module-Failure-Message == 'Failed concatenating input: Invalid arguments. List was NULL') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-1 == '[]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Module-Failure-Message !* ANY +} + + +# 5a. Output mode "array_of_values" tests + +update request { + &Tmp-String-1 := "%{json_array_values_encode:&request:[*]}" + &Tmp-String-2 := "%{json_array_values_ex_encode:&request:[*]}" +} + +if (&Tmp-String-1 == '["john","f1","f2",999,"Login-User"]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '["john","f1","f2","999","1"]') { + test_pass +} else { + test_fail +} + +# 5b. "array_of_values" empty inputs + +update request { + &Tmp-String-1 := "%{json_array_values_encode:!&request:[*]}" + &Tmp-String-2 := "%{json_array_values_ex_encode:}" +} + +if (&Module-Failure-Message == 'Failed concatenating input: Invalid arguments. List was NULL') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-1 == '[]') { + test_pass +} else { + test_fail +} + +if (&Tmp-String-2 == '') { + test_pass +} else { + test_fail +} + +update request { + &Tmp-String-1 !* ANY + &Tmp-String-2 !* ANY + &Module-Failure-Message !* ANY +} + + +# Convert `make json.test` unlang update output to tests, for when +# things need updating. +# +# cat \ +# | cut -c44- \ +# | sed -e 's/\\"/"/g' \ +# -e 's/\s*$//' \ +# -e "s/:= \"/== '/" \ +# -e 's/^/if (/' \ +# -e "s/\"$/') {/" \ +# -e "s/$/\n test_pass\n} else {\n test_fail\n}\n/" diff --git a/src/tests/modules/json/module.conf b/src/tests/modules/json/module.conf index 437b7e586a9e..04d1b1d46022 100644 --- a/src/tests/modules/json/module.conf +++ b/src/tests/modules/json/module.conf @@ -1,3 +1,150 @@ json { +} + + +# +# Output mode "object" +# + +json json_object { + encode { + output_mode = object + } +} + +json json_object_no { + encode { + output_mode = object + + value { + single_value_as_array = no + enum_as_integer = no + always_string = no + } + } +} + + +json json_object_ex { + encode { + output_mode = object + + attribute { + prefix = "pf" + } + + value { + single_value_as_array = yes + enum_as_integer = yes + always_string = yes + } + } +} + + +# +# Output mode "object_simple" +# + +json json_object_simple { + encode { + output_mode = object_simple + } +} + +json json_object_simple_ex { + encode { + output_mode = object_simple + + attribute { + prefix = "pf" + } + + value { + single_value_as_array = yes + enum_as_integer = yes + always_string = yes + } + } +} + + +# +# Output mode "array" +# + +json json_array { + encode { + output_mode = array + } +} + +json json_array_ex { + encode { + output_mode = array + + attribute { + prefix = "pf" + } + + value { + single_value_as_array = yes + enum_as_integer = yes + always_string = yes + } + } +} + + +# +# Output mode "array_of_names" +# + +json json_array_names { + encode { + output_mode = array_of_names + } +} + +json json_array_names_ex { + encode { + output_mode = array_of_names + + attribute { + prefix = "pf" + } + + value { + single_value_as_array = yes # not valid + enum_as_integer = yes # not valid + always_string = yes # not valid + } + } +} + + +# +# Output mode "array_of_values" +# + +json json_array_values { + encode { + output_mode = array_of_values + } +} + +json json_array_values_ex { + encode { + output_mode = array_of_values + + attribute { + prefix = "pf" # not valid + } + value { + single_value_as_array = yes # not valid + enum_as_integer = yes + always_string = yes + } + } }