diff options
author | Andris Zeila <andris.zeila@zabbix.com> | 2019-07-16 10:34:45 +0300 |
---|---|---|
committer | Andris Zeila <andris.zeila@zabbix.com> | 2019-07-16 10:37:41 +0300 |
commit | c9de6ac944bc97fcc909a5236752d3ef2646dedb (patch) | |
tree | 467e7e4cab9ef12df492f65eecb84daaae54a928 /tests/libs/zbxjson | |
parent | cb86eb2989f33855f88c25efd7d29bd2b7d5bf25 (diff) |
.......PS. [ZBXNEXT-4502] added support of full jsonpath functionality
* commit 'e40b4995d877edebae4404ee4056df2b7d9ced72': (61 commits)
.......PS. [ZBXNEXT-4502] fixed jsonpath expression evaluation when checking for presence of an object or array
.......PS. [ZBXNEXT-4502] applied patch for adding sum() function support in jsonpath queries
.......PS. [ZBXNEXT-4502] fixed jsonpath queries for element existance when element value was string
.......PS. [ZBXNEXT-4502] fixed jsonpath function parsing when compiling jsonpath
.......PS. [ZBXNEXT-4502] removed duplicated function declaration
.......PS. [ZBXNEXT-4502] updated replaced deprecated zbx_json_open_path in 4.2 code with zbx_jsonpath_query, fixed merge
...G...... [ZBXNEXT-4502] fixed windows build
.......PS. [ZBXNEXT-4502] renamed zbx_json_path_open() to zbx_json_open_path()
.......PS. [ZBXNEXT-4502] fixed test case name
.......PS. [ZBXNEXT-4502] fixed comments
.......PS. [ZBXNEXT-4502] refactored jsonpath expression evaluation to avoid false positive analyzer warnings
...G...PS. [ZBXNEXT-4502] fixed coding style
...G...PS. [ZBXNEXT-4502] added more variant comparison test cases
...G...PS. [ZBXNEXT-4502] fixed coding style
...G...PS. [ZBXNEXT-4502] - changed json static error message buffer to thread local for windows
...G...PS. [ZBXNEXT-4502] improved comments
...G...PS. [ZBXNEXT-4502] fixed coding style: * reduced local variable scope * improved error message
...G...PS. [ZBXNEXT-4502] refactored zbx_jsonpath_compile() to avoid touching the output structure if the compilation failed Also fixed various coding style issues.
...G...PS. [ZBXNEXT-4502] fixed memory leak
...G...PS. [ZBXNEXT-4502] fixed coding style: * reduced local variable scope * use sizoef instead of 4 when copying integer variable contents * fixed comments
...
(cherry picked from commit 8ceddc49ebcb31e1be87dd1a948b9f827615b1db)
Diffstat (limited to 'tests/libs/zbxjson')
-rw-r--r-- | tests/libs/zbxjson/Makefile.am | 64 | ||||
-rw-r--r-- | tests/libs/zbxjson/jsonpath_next.c | 97 | ||||
-rw-r--r-- | tests/libs/zbxjson/jsonpath_next.yaml | 265 | ||||
-rw-r--r-- | tests/libs/zbxjson/jsonpath_next_test.c | 25 | ||||
-rw-r--r-- | tests/libs/zbxjson/jsonpath_next_test.h | 25 | ||||
-rw-r--r-- | tests/libs/zbxjson/mock_json.c | 1 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_json_open_path.c (renamed from tests/libs/zbxjson/zbx_json_path_open.c) | 20 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_json_open_path.yaml (renamed from tests/libs/zbxjson/zbx_json_path_open.yaml) | 42 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_jsonpath_compile.c | 257 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_jsonpath_compile.yaml | 1024 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_jsonpath_query.c | 100 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_jsonpath_query.inc.yaml | 77 | ||||
-rw-r--r-- | tests/libs/zbxjson/zbx_jsonpath_query.yaml | 711 |
13 files changed, 2268 insertions, 440 deletions
diff --git a/tests/libs/zbxjson/Makefile.am b/tests/libs/zbxjson/Makefile.am index e1d549a2e5b..f8b706d3d92 100644 --- a/tests/libs/zbxjson/Makefile.am +++ b/tests/libs/zbxjson/Makefile.am @@ -1,14 +1,16 @@ noinst_PROGRAMS = \ - jsonpath_next \ - zbx_json_path_open \ + zbx_json_open_path \ zbx_json_decodevalue \ - zbx_json_decodevalue_dyn + zbx_json_decodevalue_dyn \ + zbx_jsonpath_compile \ + zbx_jsonpath_query JSON_LIBS = \ $(top_srcdir)/tests/libzbxmocktest.a \ $(top_srcdir)/tests/libzbxmockdata.a \ $(top_srcdir)/src/libs/zbxjson/libzbxjson.a \ $(top_srcdir)/src/libs/zbxalgo/libzbxalgo.a \ + $(top_srcdir)/src/libs/zbxregexp/libzbxregexp.a \ $(top_srcdir)/src/libs/zbxcommon/libzbxcommon.a \ $(top_srcdir)/src/libs/zbxcomms/libzbxcomms.a \ $(top_srcdir)/src/libs/zbxcompress/libzbxcompress.a \ @@ -21,35 +23,18 @@ JSON_LIBS = \ $(top_srcdir)/src/libs/zbxconf/libzbxconf.a \ $(top_srcdir)/tests/libzbxmockdata.a -# jsonpath_next - -jsonpath_next_SOURCES = \ - jsonpath_next.c \ - ../../zbxmocktest.h - -jsonpath_next_LDADD = $(JSON_LIBS) - -if SERVER -jsonpath_next_LDADD += @SERVER_LIBS@ -jsonpath_next_LDFLAGS = @SERVER_LDFLAGS@ -endif - -jsonpath_next_CFLAGS = -I@top_srcdir@/tests - -# zbx_json_path_open - -zbx_json_path_open_SOURCES = \ - zbx_json_path_open.c \ +zbx_json_open_path_SOURCES = \ + zbx_json_open_path.c \ ../../zbxmocktest.h -zbx_json_path_open_LDADD = $(JSON_LIBS) +zbx_json_open_path_LDADD = $(JSON_LIBS) if SERVER -zbx_json_path_open_LDADD += @SERVER_LIBS@ -zbx_json_path_open_LDFLAGS = @SERVER_LDFLAGS@ +zbx_json_open_path_LDADD += @SERVER_LIBS@ +zbx_json_open_path_LDFLAGS = @SERVER_LDFLAGS@ endif -zbx_json_path_open_CFLAGS = -I@top_srcdir@/tests +zbx_json_open_path_CFLAGS = -I@top_srcdir@/tests # zbx_json_decodevalue @@ -83,3 +68,30 @@ endif zbx_json_decodevalue_dyn_CFLAGS = -I@top_srcdir@/tests +zbx_jsonpath_compile_SOURCES = \ + zbx_jsonpath_compile.c \ + ../../zbxmocktest.h + +zbx_jsonpath_compile_LDADD = $(JSON_LIBS) + +if SERVER +zbx_jsonpath_compile_LDADD += @SERVER_LIBS@ +zbx_jsonpath_compile_LDFLAGS = @SERVER_LDFLAGS@ +endif + +zbx_jsonpath_compile_CFLAGS = -I@top_srcdir@/tests + +# zbx_jsonpath_query + +zbx_jsonpath_query_SOURCES = \ + zbx_jsonpath_query.c \ + ../../zbxmocktest.h + +zbx_jsonpath_query_LDADD = $(JSON_LIBS) + +if SERVER +zbx_jsonpath_query_LDADD += @SERVER_LIBS@ +zbx_jsonpath_query_LDFLAGS = @SERVER_LDFLAGS@ +endif + +zbx_jsonpath_query_CFLAGS = -I@top_srcdir@/tests diff --git a/tests/libs/zbxjson/jsonpath_next.c b/tests/libs/zbxjson/jsonpath_next.c deleted file mode 100644 index 435b9f3fbf0..00000000000 --- a/tests/libs/zbxjson/jsonpath_next.c +++ /dev/null @@ -1,97 +0,0 @@ -/* -** Zabbix -** Copyright (C) 2001-2019 Zabbix SIA -** -** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**/ - -#include "zbxmocktest.h" -#include "zbxmockdata.h" -#include "zbxmockassert.h" -#include "zbxmockutil.h" - -#include "common.h" -#include "zbxjson.h" -#include "jsonpath_next_test.h" - -void zbx_mock_test_entry(void **state) -{ - zbx_mock_handle_t components, component; - const char *path, *next = NULL, *component_class, *component_value, *result; - zbx_mock_error_t err; - zbx_strloc_t loc; - int type, ret; - char *buffer; - - ZBX_UNUSED(state); - - path = zbx_mock_get_parameter_string("in.path"); - result = zbx_mock_get_parameter_string("out.result"); - components = zbx_mock_get_parameter_handle("out.components"); - - buffer = zbx_malloc(NULL, strlen(path) + 1); - - while (1) - { - if (SUCCEED != (ret = zbx_jsonpath_next(path, &next, &loc, &type))) - { - zbx_mock_assert_str_eq("Return value", result, "fail"); - break; - } - - if (ZBX_MOCK_SUCCESS != (err = zbx_mock_vector_element(components, &component))) - { - if (ZBX_MOCK_END_OF_VECTOR == err || ZBX_MOCK_NOT_A_VECTOR == err) - fail_msg("Too many path components parsed"); - else - fail_msg("Cannot get vector element: %s", zbx_mock_error_string(err)); - } - - component_class = zbx_mock_get_object_member_string(component, "class"); - - switch (type) - { - case 0: /* ZBX_JSONPATH_COMPONENT_DOT */ - zbx_mock_assert_str_eq("Component class", component_class, "dot"); - break; - case 1: /* ZBX_JSONPATH_COMPONENT_BRACKET */ - zbx_mock_assert_str_eq("Component class", component_class, "bracket"); - break; - case 2: /* ZBX_JSONPATH_ARRAY_INDEX */ - zbx_mock_assert_str_eq("Component class", component_class, "index"); - break; - } - - zbx_strlcpy(buffer, path + loc.l, loc.r - loc.l + 2); - - component_value = zbx_mock_get_object_member_string(component, "value"); - zbx_mock_assert_str_eq("Component value", component_value, buffer); - - if ('\0' == *next) - { - zbx_mock_assert_str_eq("Return value", result, "succeed"); - break; - } - } - - if (ZBX_MOCK_SUCCESS == (err = zbx_mock_vector_element(components, &component))) - fail_msg("Too many path components parsed"); - - if (ZBX_MOCK_END_OF_VECTOR != err && ZBX_MOCK_NOT_A_VECTOR != err) - fail_msg("Cannot get vector element: %s", zbx_mock_error_string(err)); - - zbx_free(buffer); -} - diff --git a/tests/libs/zbxjson/jsonpath_next.yaml b/tests/libs/zbxjson/jsonpath_next.yaml deleted file mode 100644 index 1a8e1b3d7d2..00000000000 --- a/tests/libs/zbxjson/jsonpath_next.yaml +++ /dev/null @@ -1,265 +0,0 @@ -# Invalid JSON paths - ---- -test case: Invalid path "" - empty path -in: - path: "" -out: - result: fail - components: ---- -test case: Invalid path "$" - only root node specified -in: - path: $ -out: - result: fail - components: ---- -test case: Invalid path "$." - missing dot notation member name -in: - path: $. -out: - result: fail - components: ---- -test case: Invalid path "$['a'" - unclosed bracket notation bracket -in: - path: $['a' -out: - result: fail - components: ---- -test case: Invalid path "$[a']" - unquoted bracket notation member name -in: - path: $[a'] -out: - result: fail - components: ---- -test case: Invalid path "$['']" - empty bracked notation member name -in: - path: $[''] -out: - result: fail - components: ---- -test case: Invalid path "$.a[]" - empty bracked notation member name -in: - path: $.a[] -out: - result: fail - components: - - class: dot - value: a ---- -test case: Invalid path "$.a[1" - missing array index closing bracket -in: - path: $.a[1 -out: - result: fail - components: - - class: dot - value: a ---- -test case: Invalid path "$['a'][]" - empty bracked notation member name -in: - path: $['a'][] -out: - result: fail - components: - - class: bracket - value: a ---- -test case: Invalid path "$['a'][1" - missing array index closing bracket -in: - path: $['a'][1 -out: - result: fail - components: - - class: bracket - value: a ---- -test case: Invalid path "$.a." - missing dot notation member name -in: - path: $.a. -out: - result: fail - components: - - class: dot - value: a ---- -test case: Invalid path "$.['a']" - missing dot notation member name -in: - path: $.['a'] -out: - result: fail - components: - -# Valid JSON paths - ---- -test case: Valid path "$.a" - get dot notation first level member -in: - path: $.a -out: - result: succeed - components: - - class: dot - value: a ---- -test case: Valid path "$['a']" - get bracket notation (single quotes) first level member -in: - path: $['a'] -out: - result: succeed - components: - - class: bracket - value: a ---- -test case: Valid path "$[ 'a' ]" - get bracket notation first level member with spacing around member name -in: - path: $[ 'a' ] -out: - result: succeed - components: - - class: bracket - value: a ---- -test case: Valid path '$["a"]' - get bracket notation (double quotes) first level member -in: - path: $["a"] -out: - result: succeed - components: - - class: bracket - value: a ---- -test case: Valid path "$.a.b" - get dot notation second level member -in: - path: $.a.b -out: - result: succeed - components: - - class: dot - value: a - - class: dot - value: b ---- -test case: Valid path "$['a'].b" - get mixed notation second level member -in: - path: $['a'].b -out: - result: succeed - components: - - class: bracket - value: a - - class: dot - value: b ---- -test case: Valid path "$['a']['b']" - get bracket notation second level member -in: - path: $['a']['b'] -out: - result: succeed - components: - - class: bracket - value: a - - class: bracket - value: b ---- -test case: Valid path $.a['b'] - get mixed notation second level member -in: - path: $.a['b'] -out: - result: succeed - components: - - class: dot - value: a - - class: bracket - value: b ---- -test case: Valid path $.a[0] - get first array element -in: - path: $.a[0] -out: - result: succeed - components: - - class: dot - value: a - - class: index - value: 0 ---- -test case: Valid path $.a[0].b[1] - get array elements from mixed dot notation members and arrays -in: - path: $.a[0].b[1] -out: - result: succeed - components: - - class: dot - value: a - - class: index - value: 0 - - class: dot - value: b - - class: index - value: 1 ---- -test case: Valid path $.a[1000] - get 1001th array element -in: - path: $.a[1000] -out: - result: succeed - components: - - class: dot - value: a - - class: index - value: 1000 ---- -test case: Valid path $.a[ 1 ] - get second array element with whitespace enclosing index -in: - path: $.a[ 1 ] -out: - result: succeed - components: - - class: dot - value: a - - class: index - value: 1 ---- -test case: Valid path $['a'][2] - get third array element of bracket notation first level member -in: - path: $['a'][2] -out: - result: succeed - components: - - class: bracket - value: a - - class: index - value: 2 ---- -test case: Valid path $['a'][2]['b'][3] - get array elements from mixed bracket notation members and arrays -in: - path: $['a'][2]['b'][3] -out: - result: succeed - components: - - class: bracket - value: a - - class: index - value: 2 - - class: bracket - value: b - - class: index - value: 3 ---- -test case: Valid path $[1][2] - get nested array element -in: - path: $[1][2] -out: - result: succeed - components: - - class: index - value: 1 - - class: index - value: 2 -... diff --git a/tests/libs/zbxjson/jsonpath_next_test.c b/tests/libs/zbxjson/jsonpath_next_test.c deleted file mode 100644 index dfe70beb8d4..00000000000 --- a/tests/libs/zbxjson/jsonpath_next_test.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -** Zabbix -** Copyright (C) 2001-2019 Zabbix SIA -** -** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**/ - -#include "jsonpath_next_test.h" - -int zbx_jsonpath_next(const char *path, const char **pnext, zbx_strloc_t *loc, int *type) -{ - return jsonpath_next(path, pnext, loc, type); -} diff --git a/tests/libs/zbxjson/jsonpath_next_test.h b/tests/libs/zbxjson/jsonpath_next_test.h deleted file mode 100644 index cd824446165..00000000000 --- a/tests/libs/zbxjson/jsonpath_next_test.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -** Zabbix -** Copyright (C) 2001-2019 Zabbix SIA -** -** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**/ - -#ifndef JSONPATH_NEXT_TEST_H -#define JSONPATH_NEXT_TEST_H - -int zbx_jsonpath_next(const char *path, const char **pnext, zbx_strloc_t *loc, int *type); - -#endif diff --git a/tests/libs/zbxjson/mock_json.c b/tests/libs/zbxjson/mock_json.c index 56172b0b3ac..7bd2454a2d6 100644 --- a/tests/libs/zbxjson/mock_json.c +++ b/tests/libs/zbxjson/mock_json.c @@ -23,6 +23,7 @@ #include "common.h" #include "zbxjson.h" +#include "mock_json.h" const char *zbx_mock_json_type_to_str(int type) { diff --git a/tests/libs/zbxjson/zbx_json_path_open.c b/tests/libs/zbxjson/zbx_json_open_path.c index e65b491e819..6ef6e25cbf6 100644 --- a/tests/libs/zbxjson/zbx_json_path_open.c +++ b/tests/libs/zbxjson/zbx_json_open_path.c @@ -24,6 +24,21 @@ #include "common.h" #include "zbxjson.h" +#include "../../../src/libs/zbxjson/json.h" + +static void json_value_dyn(const struct zbx_json_parse *jp, char **string, size_t *string_alloc) +{ + if (NULL == zbx_json_decodevalue_dyn(jp->start, string, string_alloc, NULL)) + { + size_t len = jp->end - jp->start + 2; + + if (*string_alloc < len) + *string = (char *)zbx_realloc(*string, len); + + zbx_strlcpy(*string, jp->start, len); + } +} + void zbx_mock_test_entry(void **state) { @@ -42,8 +57,9 @@ void zbx_mock_test_entry(void **state) ret = zbx_json_open(json, &jp); zbx_mock_assert_result_eq("Invalid zbx_json_open() return value", SUCCEED, ret); - if (FAIL == (ret = zbx_json_path_open(&jp, path, &jp_out))) + if (FAIL == (ret = zbx_json_open_path(&jp, path, &jp_out))) { + printf("zbx_json_path_open() error: %s\n", zbx_json_strerror()); zbx_mock_assert_str_eq("Invalid zbx_json_path_open() return value", result, "fail"); return; } @@ -51,7 +67,7 @@ void zbx_mock_test_entry(void **state) zbx_mock_assert_result_eq("Invalid zbx_json_path_open() return value", SUCCEED, ret); zbx_mock_assert_str_eq("Invalid zbx_json_path_open() return value", result, "succeed"); - zbx_json_value_dyn(&jp_out, &buffer, &size); + json_value_dyn(&jp_out, &buffer, &size); value = zbx_mock_get_parameter_string("out.value"); zbx_mock_assert_str_eq("Invalid value", value, buffer); diff --git a/tests/libs/zbxjson/zbx_json_path_open.yaml b/tests/libs/zbxjson/zbx_json_open_path.yaml index 5489806ee58..ea868f5490a 100644 --- a/tests/libs/zbxjson/zbx_json_path_open.yaml +++ b/tests/libs/zbxjson/zbx_json_open_path.yaml @@ -369,4 +369,46 @@ in: out: result: succeed value: "𐀀𐀀𐀀𐀀" +--- +test case: 'Invalid path $.*.b in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $.*.b +out: + result: fail +--- +test case: 'Invalid path $.a.b[?(@.x == "10")] in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $.a.b[?(@.x == "10")] +out: + result: fail +--- +test case: 'Invalid path $["a", "x"].b in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $['a', 'x'].b +out: + result: fail +--- +test case: 'Invalid path $.a.b[1,2] in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $.a.b[1,2] +out: + result: fail +--- +test case: 'Invalid path $.a.b.length() in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $.a.b.length() +out: + result: fail +--- +test case: 'Invalid path $..b in {"a":{"b": [{"x":10}, 2, 3] }}' +in: + json: '{"a":{"b": [{"x":10}, 2, 3] }}' + path: $..b +out: + result: fail ... diff --git a/tests/libs/zbxjson/zbx_jsonpath_compile.c b/tests/libs/zbxjson/zbx_jsonpath_compile.c new file mode 100644 index 00000000000..6cfe255d2aa --- /dev/null +++ b/tests/libs/zbxjson/zbx_jsonpath_compile.c @@ -0,0 +1,257 @@ +/* +** Zabbix +** Copyright (C) 2001-2019 Zabbix SIA +** +** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**/ + +#include "zbxmocktest.h" +#include "zbxmockdata.h" +#include "zbxmockassert.h" +#include "zbxmockutil.h" + +#include "common.h" +#include "zbxjson.h" + +#include "../../../src/libs/zbxjson/jsonpath.h" +#include "../../../src/libs/zbxjson/json.h" + +static int mock_str_to_segment_type(const char *segment_type) +{ + if (0 == strcmp("ZBX_JSONPATH_SEGMENT_MATCH_ALL", segment_type)) + return ZBX_JSONPATH_SEGMENT_MATCH_ALL; + if (0 == strcmp("ZBX_JSONPATH_SEGMENT_MATCH_LIST", segment_type)) + return ZBX_JSONPATH_SEGMENT_MATCH_LIST; + if (0 == strcmp("ZBX_JSONPATH_SEGMENT_MATCH_SLICE", segment_type)) + return ZBX_JSONPATH_SEGMENT_MATCH_RANGE; + if (0 == strcmp("ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION", segment_type)) + return ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION; + if (0 == strcmp("ZBX_JSONPATH_SEGMENT_FUNCTION", segment_type)) + return ZBX_JSONPATH_SEGMENT_FUNCTION; + + fail_msg("Unknown jsonpath segment type: %s", segment_type); + return -1; +} + +static void jsonpath_token_print(char **data, size_t *data_alloc, size_t *data_offset, + const zbx_jsonpath_token_t *token) +{ + switch (token->type) + { + case ZBX_JSONPATH_TOKEN_PATH_ABSOLUTE: + ZBX_FALLTHROUGH; + case ZBX_JSONPATH_TOKEN_PATH_RELATIVE: + ZBX_FALLTHROUGH; + case ZBX_JSONPATH_TOKEN_CONST_STR: + ZBX_FALLTHROUGH; + case ZBX_JSONPATH_TOKEN_CONST_NUM: + zbx_strcpy_alloc(data, data_alloc, data_offset, token->data); + break; + case ZBX_JSONPATH_TOKEN_PAREN_LEFT: + zbx_strcpy_alloc(data, data_alloc, data_offset, "("); + break; + case ZBX_JSONPATH_TOKEN_PAREN_RIGHT: + zbx_strcpy_alloc(data, data_alloc, data_offset, ")"); + break; + case ZBX_JSONPATH_TOKEN_OP_PLUS: + zbx_strcpy_alloc(data, data_alloc, data_offset, "+"); + break; + case ZBX_JSONPATH_TOKEN_OP_MINUS: + zbx_strcpy_alloc(data, data_alloc, data_offset, "-"); + break; + case ZBX_JSONPATH_TOKEN_OP_MULT: + zbx_strcpy_alloc(data, data_alloc, data_offset, "*"); + break; + case ZBX_JSONPATH_TOKEN_OP_DIV: + zbx_strcpy_alloc(data, data_alloc, data_offset, "/"); + break; + case ZBX_JSONPATH_TOKEN_OP_EQ: + zbx_strcpy_alloc(data, data_alloc, data_offset, "=="); + break; + case ZBX_JSONPATH_TOKEN_OP_NE: + zbx_strcpy_alloc(data, data_alloc, data_offset, "!="); + break; + case ZBX_JSONPATH_TOKEN_OP_GT: + zbx_strcpy_alloc(data, data_alloc, data_offset, ">"); + break; + case ZBX_JSONPATH_TOKEN_OP_GE: + zbx_strcpy_alloc(data, data_alloc, data_offset, ">="); + break; + case ZBX_JSONPATH_TOKEN_OP_LT: + zbx_strcpy_alloc(data, data_alloc, data_offset, "<"); + break; + case ZBX_JSONPATH_TOKEN_OP_LE: + zbx_strcpy_alloc(data, data_alloc, data_offset, "<="); + break; + case ZBX_JSONPATH_TOKEN_OP_NOT: + zbx_strcpy_alloc(data, data_alloc, data_offset, "!"); + break; + case ZBX_JSONPATH_TOKEN_OP_AND: + zbx_strcpy_alloc(data, data_alloc, data_offset, "&&"); + break; + case ZBX_JSONPATH_TOKEN_OP_OR: + zbx_strcpy_alloc(data, data_alloc, data_offset, "||"); + break; + case ZBX_JSONPATH_TOKEN_OP_REGEXP: + zbx_strcpy_alloc(data, data_alloc, data_offset, "=~"); + break; + default: + zbx_strcpy_alloc(data, data_alloc, data_offset, "?"); + break; + } +} + +static char *segment_data_to_str(const zbx_jsonpath_segment_t *segment) +{ + const char *functions[] = {"unknown", "min()", "max()", "avg()", "length()", "first()"}; + char *data = NULL; + size_t data_alloc = 0, data_offset = 0; + int i; + zbx_jsonpath_list_node_t *node; + zbx_vector_ptr_t nodes; + + switch (segment->type) + { + case ZBX_JSONPATH_SEGMENT_MATCH_ALL: + data = zbx_strdup(NULL, "*"); + break; + case ZBX_JSONPATH_SEGMENT_MATCH_LIST: + zbx_vector_ptr_create(&nodes); + + /* lists are kept in reverse order, invert it for clarity */ + for (node = segment->data.list.values; NULL != node; node = node->next) + zbx_vector_ptr_append(&nodes, node); + + for (i = nodes.values_num - 1; i >= 0; i--) + { + node = (zbx_jsonpath_list_node_t *)nodes.values[i]; + + if (ZBX_JSONPATH_LIST_NAME == segment->data.list.type) + { + zbx_snprintf_alloc(&data, &data_alloc, &data_offset, "\'%s'", + (char *)&node->data); + } + else + { + zbx_snprintf_alloc(&data, &data_alloc, &data_offset, "%d", + *(int *)&node->data); + } + + if (0 != i) + zbx_chrcpy_alloc(&data, &data_alloc, &data_offset, ','); + } + + zbx_vector_ptr_destroy(&nodes); + break; + case ZBX_JSONPATH_SEGMENT_MATCH_RANGE: + if (0 != (segment->data.range.flags & 0x01)) + zbx_snprintf_alloc(&data, &data_alloc, &data_offset, "%d", segment->data.range.start); + zbx_chrcpy_alloc(&data, &data_alloc, &data_offset, ':'); + if (0 != (segment->data.range.flags & 0x02)) + zbx_snprintf_alloc(&data, &data_alloc, &data_offset, "%d", segment->data.range.end); + break; + case ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION: + for (i = 0; i < segment->data.expression.tokens.values_num; i++) + { + if (0 != i) + zbx_strcpy_alloc(&data, &data_alloc, &data_offset, " , "); + + jsonpath_token_print(&data, &data_alloc, &data_offset, + segment->data.expression.tokens.values[i]); + } + break; + case ZBX_JSONPATH_SEGMENT_FUNCTION: + zbx_strcpy_alloc(&data, &data_alloc, &data_offset, functions[segment->data.function.type]); + break; + default: + data = zbx_strdup(NULL, "unknown"); + break; + } + + return data; +} + +static void validate_segment(int index, const char *segment_type, const char *segment_data, int detached, + const zbx_jsonpath_segment_t *segment) +{ + int type; + char prefix[MAX_STRING_LEN]; + char *data = NULL; + + zbx_snprintf(prefix, sizeof(prefix), "jsonpath segment #%d type", index + 1); + type = mock_str_to_segment_type(segment_type); + zbx_mock_assert_int_eq(prefix, type, segment->type); + + zbx_snprintf(prefix, sizeof(prefix), "jsonpath segment #%d detached", index + 1); + zbx_mock_assert_int_eq(prefix, detached, segment->detached); + + data = segment_data_to_str(segment); + zbx_snprintf(prefix, sizeof(prefix), "jsonpath segment #%d data", index + 1); + zbx_mock_assert_str_eq(prefix, segment_data, data); + zbx_free(data); +} + +void zbx_mock_test_entry(void **state) +{ + zbx_jsonpath_t jsonpath; + int returned_ret, expected_ret, index = 0; + zbx_mock_handle_t hsegments, hsegment, hdetached; + const char *segment_data, *segment_type, *value; + + ZBX_UNUSED(state); + + /* reset json error to check if compilation will set it */ + zbx_set_json_strerror("%s", ""); + + returned_ret = zbx_jsonpath_compile(zbx_mock_get_parameter_string("in.path"), &jsonpath); + + if (FAIL == returned_ret) + printf("zbx_jsonpath_compile() error: %s\n", zbx_json_strerror()); + + expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.result")); + zbx_mock_assert_result_eq("zbx_jsonpath_compile() return value", expected_ret, returned_ret); + + if (SUCCEED == returned_ret) + { + zbx_mock_assert_uint64_eq("jsonpath definite flag", zbx_mock_get_parameter_uint64("out.definite"), + jsonpath.definite); + hsegments = zbx_mock_get_parameter_handle("out.segments"); + + while (ZBX_MOCK_SUCCESS == zbx_mock_vector_element(hsegments, &hsegment)) + { + int detached = 0; + + zbx_mock_assert_int_ne("Too many path segments parsed", index, jsonpath.segments_num); + + segment_type = zbx_mock_get_object_member_string(hsegment, "type"); + segment_data = zbx_mock_get_object_member_string(hsegment, "data"); + + if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hsegment, "detached", &hdetached) && + ZBX_MOCK_SUCCESS == zbx_mock_string(hdetached, &value)) + { + detached = atoi(value); + } + + validate_segment(index, segment_type, segment_data, detached, &jsonpath.segments[index]); + index++; + } + + zbx_mock_assert_int_eq("Not enough path segments parsed", index, jsonpath.segments_num); + + zbx_jsonpath_clear(&jsonpath); + } + else + zbx_mock_assert_str_ne("zbx_jsonpath_compile() error", "", zbx_json_strerror()); +} diff --git a/tests/libs/zbxjson/zbx_jsonpath_compile.yaml b/tests/libs/zbxjson/zbx_jsonpath_compile.yaml new file mode 100644 index 00000000000..ec6475ee824 --- /dev/null +++ b/tests/libs/zbxjson/zbx_jsonpath_compile.yaml @@ -0,0 +1,1024 @@ +# Invalid definite jsonpaths + +--- +test case: Compile fail "" +in: + path: "" +out: + result: FAIL +--- +test case: Compile fail $ +in: + path: $ +out: + result: FAIL +--- +test case: Compile fail "$." +in: + path: $. +out: + result: FAIL +--- +test case: Compile fail "$['a'" +in: + path: $['a' +out: + result: FAIL +--- +test case: Compile fail "$[a']" +in: + path: $[a'] +out: + result: FAIL +--- +test case: Compile fail "$['']" +in: + path: $[''] +out: + result: FAIL +--- +test case: Compile fail "$.a[]" +in: + path: $.a[] +out: + result: FAIL +--- +test case: Compile fail "$.a[1" +in: + path: $.a[1 +out: + result: FAIL +--- +test case: Compile fail "$['a'][]" +in: + path: $['a'][] +out: + result: FAIL +--- +test case: Compile fail "$['a'][1" +in: + path: $['a'][1 +out: + result: FAIL +--- +test case: Compile fail "$.a." +in: + path: $.a. +out: + result: FAIL +--- + +# Valid definite jsonpaths +test case: Compile success "$.a" +in: + path: $.a +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" +--- +test case: Compile success "$['a']" +in: + path: $['a'] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" +--- +test case: Compile success "$[ 'a' ]" +in: + path: $[ 'a' ] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" +--- +test case: Compile success '$["a"]' +in: + path: $["a"] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" +--- +test case: Compile success "$.a.b" +in: + path: $.a.b +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" +--- +test case: Compile success "$['a'].b" +in: + path: $['a'].b +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" +--- +test case: Compile success "$['a']['b']" +in: + path: $['a']['b'] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" +--- +test case: Compile success $.a['b'] +in: + path: $.a['b'] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" +--- +test case: Compile success $.a[0] +in: + path: $.a[0] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 0 +--- +test case: Compile success $[-1] +in: + path: $[-1] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: -1 +--- +test case: Compile success $.a[0].b[1] +in: + path: $.a[0].b[1] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 0 + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1 +--- +test case: Compile success $.a[1000] +in: + path: $.a[1000] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1000 +--- +test case: Compile success $.a[ 1 ] +in: + path: $.a[ 1 ] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1 +--- +test case: Compile success $['a'][2] +in: + path: $['a'][2] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 2 +--- +test case: Compile success $['a'][2]['b'][3] +in: + path: $['a'][2]['b'][3] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 2 + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 3 +--- +test case: Compile success $[1][2] +in: + path: $[1][2] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1 + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 2 +--- +test case: Compile success $.['a'].['b'] +in: + path: $.['a'].['b'] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" +--- +# Invalid list based json filters + +test case: Compile fail $...a +in: + path: $...a +out: + result: FAIL +--- +test case: 'Compile fail $.**.a' +in: + path: '$.**.a' +out: + result: FAIL +--- +test case: Compile fail $[,1] +in: + path: $[,1] +out: + result: FAIL +--- +test case: Compile fail $[1,] +in: + path: $[1,] +out: + result: FAIL +--- +test case: Compile fail $[1,,2] +in: + path: $[1,,2] +out: + result: FAIL +--- +test case: Compile fail $[1,*,2] +in: + path: $[1,*,2] +out: + result: FAIL +--- +test case: Compile fail $[--1] +in: + path: $[--1] +out: + result: FAIL +--- +test case: Compile fail $[a] +in: + path: $[a] +out: + result: FAIL +--- +test case: Compile fail $[$a$] +in: + path: $[$a$] +out: + result: FAIL +--- +test case: Compile fail $[,'a'] +in: + path: $[,'a'] +out: + result: FAIL +--- +test case: Compile fail $['a',] +in: + path: $['a',] +out: + result: FAIL +--- +test case: Compile fail $['a',,'b'] +in: + path: $['a',,2] +out: + result: FAIL +--- +test case: Compile fail $['a',*,'b'] +in: + path: $['a',*,2] +out: + result: FAIL +--- +test case: Compile fail $[--'a'] +in: + path: $[--'a'] +out: + result: FAIL +--- +test case: Compile fail $[1,'a'] +in: + path: $[1,'a'] +out: + result: FAIL +--- +test case: Compile fail $['a\a'] +in: + path: $['a\a'] +out: + result: FAIL +--- +test case: Compile fail $['a\'] +in: + path: $['a\'] +out: + result: FAIL +--- +test case: Compile fail $['a\"'] +in: + path: $['a\"'] +out: + result: FAIL +--- +test case: Compile fail $['a\] +in: + path: $['a\] +out: + result: FAIL +--- +test case: Compile fail $['a\ +in: + path: $['a\ +out: + result: FAIL +--- +test case: Compile fail $["a\'"] +in: + path: $["a\'"] +out: + result: FAIL +--- +# Valid list based json filters + +test case: Compile success $[ 1 ] +in: + path: $[ 1 ] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1 +--- +test case: Compile success $[1,2] +in: + path: $[1,2] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1,2 +--- +test case: Compile success $[ 1 , 2 ] +in: + path: $[ 1 , 2 ] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: 1,2 +--- +test case: Compile success $[ -1 ] +in: + path: $[ -1 ] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: -1 +--- +test case: Compile success $[ -1, 2, 3 ] +in: + path: $[ -1, 2, 3 ] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: -1,2,3 +--- +test case: Compile success $[ ' a ' ] +in: + path: $[ ' a ' ] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "' a '" +--- +test case: Compile success $[ ' a ', "b" ] +in: + path: $[ ' a ', "b" ] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "' a ','b'" +--- +test case: Compile success $['a \'b\' \\/'] +in: + path: $['a \'b\' \\/'] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a 'b' \\/'" +--- +test case: Compile success $["a \"b\""] +in: + path: $["a \"b\""] +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a \"b\"'" +--- +test case: Compile success $.*.a +in: + path: $.*.a +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_ALL + data: "*" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" +--- +test case: Compile success $.* +in: + path: $.* +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_ALL + data: "*" +--- +test case: Compile success $[*] +in: + path: $[*] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_ALL + data: "*" +--- +test case: Compile success $..a.b..c +in: + path: $..a.b..c +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'a'" + detached: 1 + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'b'" + - type: ZBX_JSONPATH_SEGMENT_MATCH_LIST + data: "'c'" + detached: 1 +--- +# Slice based json filters + +test case: Compile fail $[1:2:3] +in: + path: $[1:2:3] +out: + result: FAIL +--- +test case: Compile success $[:] +in: + path: "$[:]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: ":" +--- +test case: Compile success $[1:] +in: + path: "$[1:]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: "1:" +--- +test case: Compile success $[:1] +in: + path: "$[:1]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: ":1" +--- +test case: Compile success $[1:2] +in: + path: "$[1:2]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: "1:2" +--- +test case: "Compile success $[-1:-1]" +in: + path: "$[-1:-1]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: "-1:-1" +--- +test case: "Compile success $[ 1 : 2 ]" +in: + path: "$[ 1 : 2 ]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: "1:2" +--- +test case: "Compile success $[ : 1 ]" +in: + path: "$[ : 1 ]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: ":1" +--- +test case: "Compile success $[ 1 : ]" +in: + path: "$[ 1 : ]" +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_SLICE + data: "1:" +--- +test case: Compile fail $.min( +in: + path: $.min( +out: + result: FAIL +--- +test case: Compile fail $.min(1) +in: + path: $.min(1) +out: + result: FAIL +--- +test case: Compile fail $.div() +in: + path: $.div() +out: + result: FAIL +--- +test case: Compile fail $.avg().data +in: + path: $.avg().data +out: + result: FAIL +--- +test case: Compile fail $.len() +in: + path: $.len() +out: + result: FAIL +--- +test case: Compile success $.min() +in: + path: $.min() +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "min()" +--- +test case: Compile success $.max() +in: + path: $.max() +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "max()" +--- +test case: Compile success $.avg() +in: + path: $.avg() +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "avg()" +--- +test case: Compile success $.length() +in: + path: $.length() +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "length()" +--- +test case: Compile success $.first().max() +in: + path: $.first().max() +out: + result: SUCCEED + definite: 1 + segments: + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "first()" + - type: ZBX_JSONPATH_SEGMENT_FUNCTION + data: "max()" +--- +test case: Compile fail $[?] +in: + path: $[?] +out: + result: FAIL +--- +test case: Compile fail $[?(] +in: + path: $[?(] +out: + result: FAIL +--- +test case: Compile fail $[?()] +in: + path: $[?()] +out: + result: FAIL +--- +test case: Compile fail $[?(+)] +in: + path: $[?(+)] +out: + result: FAIL +--- +test case: Compile fail $[?(==)] +in: + path: $[?(==)] +out: + result: FAIL +--- +test case: Compile fail $[?(()] +in: + path: $[?(()] +out: + result: FAIL +--- +test case: Compile fail $[?(+1)] +in: + path: $[?(+1)] +out: + result: FAIL +--- +test case: Compile fail $[?(!)] +in: + path: $[?(!)] +out: + result: FAIL +--- +test case: Compile fail $[?(a)] +in: + path: $[?(a)] +out: + result: FAIL +--- +test case: Compile fail $[?(())] +in: + path: $[?(())] +out: + result: FAIL +--- +test case: Compile fail $[?(1++1)] +in: + path: $[?(1++1)] +out: + result: FAIL +--- +test case: Compile fail $[?(1 - - 1)] +in: + path: $[?(1 - - 1)] +out: + result: FAIL +--- +test case: Compile fail $[?(1 + + 1)] +in: + path: $[?(1 + + 1)] +out: + result: FAIL +--- +test case: Compile fail $[?((1+1)+)] +in: + path: $[?((1+1)+)] +out: + result: FAIL +--- +test case: Compile fail $[?((1 + 1) + ())] +in: + path: $[?((1 + 1) + ())] +out: + result: FAIL +--- +test case: Compile fail $[?(a + 1)] +in: + path: $[?(a + 1)] +out: + result: FAIL +--- +test case: Compile fail $[?(1 + 'a)] +in: + path: $[?(1 + 'a)] +out: + result: FAIL +--- +test case: Compile fail $[?($..b + 1)] +in: + path: $[?($..b + 1)] +out: + result: FAIL +--- +test case: Compile fail $[?($['a])] +in: + path: $[?($['a])] +out: + result: FAIL +--- +test case: Compile fail $[?($[1,2])] +in: + path: $[?($[1,2])] +out: + result: FAIL +--- +test case: Compile fail $[?($.a.)] +in: + path: $[?($.a.)] +out: + result: FAIL +--- +test case: Compile success $[?(1)] +in: + path: $[?(1)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1" +--- +test case: Compile success $[?(-1)] +in: + path: $[?(-1)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "-1" +--- +test case: Compile success $[?($.a)] +in: + path: $[?($.a)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "$.a" +--- +test case: Compile success $[?(@.b)] +in: + path: $[?(@.b)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "@.b" +--- +test case: Compile success $[?(!1)] +in: + path: $[?(!1)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , !" +--- +test case: Compile success $[?(1 + 2)] +in: + path: $[?(1 + 2)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , +" +--- +test case: Compile success $[?(1 + 2 * 3)] +in: + path: $[?(1 + 2 * 3)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , 3 , * , +" +--- +test case: Compile success $[?(1 - 2 / 3)] +in: + path: $[?(1 - 2 / 3)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , 3 , / , -" +--- +test case: Compile success $[?((1 + 2) * 3)] +in: + path: $[?((1 + 2) * 3)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , + , 3 , *" +--- +test case: Compile success $[?($.a + 2 == 3)] +in: + path: $[?($.a + 2 == 3)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "$.a , 2 , + , 3 , ==" +--- +test case: Compile success $[?((1 + 2) * (3 - 4))] +in: + path: $[?((1 + 2) * (3 - 4))] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , + , 3 , 4 , - , *" +--- +test case: Compile success $[?(1 == 2 || !3*5)] +in: + path: $[?(1 == 2 || !3*5)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , == , 3 , ! , 5 , * , ||" +--- +test case: Compile success $[?(1 == 2 || !(3*5))] +in: + path: $[?(1 == 2 || !(3*5))] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , == , 3 , 5 , * , ! , ||" +--- +test case: Compile success $[?(1 == 2 * @.a)] +in: + path: $[?(1 == 2 * @.a)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , @.a , * , ==" +--- +test case: Compile success $[?((1)+(2))] +in: + path: $[?((1)+(2))] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , +" +--- +test case: Compile success $[?(1 + 2 - 3 + 4)] +in: + path: $[?(1 + 2 - 3 + 4)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , + , 3 , - , 4 , +" +--- +test case: Compile success $[?(1 == 2 == 3)] +in: + path: $[?(1 == 2 == 3)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "1 , 2 , == , 3 , ==" +--- +test case: Compile fail $[?(1 == 2 == 3] +in: + path: $[?(1 == 2 == 3] +out: + result: FAIL +--- +test case: Compile success $..[?(@.id)] +in: + path: $..[?(@.id)] +out: + result: SUCCEED + definite: 0 + segments: + - type: ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION + data: "@.id" + detached: 1 +... diff --git a/tests/libs/zbxjson/zbx_jsonpath_query.c b/tests/libs/zbxjson/zbx_jsonpath_query.c new file mode 100644 index 00000000000..10a7db13155 --- /dev/null +++ b/tests/libs/zbxjson/zbx_jsonpath_query.c @@ -0,0 +1,100 @@ +/* +** Zabbix +** Copyright (C) 2001-2019 Zabbix SIA +** +** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**/ + +#include "zbxmocktest.h" +#include "zbxmockdata.h" +#include "zbxmockassert.h" +#include "zbxmockutil.h" +#include "zbxmockjson.h" + +#include "common.h" +#include "zbxjson.h" +#include "../../../src/libs/zbxjson/json.h" + +static void check_definite_path_result(zbx_mock_handle_t handle, const char *returned_output) +{ + const char *expected_output; + struct zbx_json_parse jp; + + if (ZBX_MOCK_SUCCESS != zbx_mock_string(handle, &expected_output)) + fail_msg("Invalid test case out.value parameter"); + + if (FAIL == zbx_json_open(expected_output, &jp)) + zbx_mock_assert_str_eq("Definite query result", expected_output, returned_output); + else + zbx_mock_assert_json_eq("Indefinite query result", expected_output, returned_output); +} + +static void check_indefinite_path_result(zbx_mock_handle_t handle, const char *returned_output) +{ + const char *expected_output; + + if (ZBX_MOCK_SUCCESS != zbx_mock_string(handle, &expected_output)) + fail_msg("Invalid test case out.values parameter"); + + zbx_mock_assert_json_eq("Indefinite query result", expected_output, returned_output); +} + +void zbx_mock_test_entry(void **state) +{ + const char *data, *path; + struct zbx_json_parse jp; + char *output = NULL; + int expected_ret, returned_ret; + zbx_mock_handle_t handle; + + ZBX_UNUSED(state); + + /* reset json error to check if compilation will set it */ + zbx_set_json_strerror("%s", ""); + + data = zbx_mock_get_parameter_string("in.data"); + if (FAIL == zbx_json_open(data, &jp)) + fail_msg("Invalid json data: %s", zbx_json_strerror()); + + path = zbx_mock_get_parameter_string("in.path"); + returned_ret = zbx_jsonpath_query(&jp, path, &output); + expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.return")); + + if (FAIL == returned_ret) + printf("\tzbx_jsonpath_query() failed with: %s\n", zbx_json_strerror()); + + zbx_mock_assert_result_eq("zbx_jsonpath_query() return value", expected_ret, returned_ret); + + if (SUCCEED == returned_ret) + { + printf("\tzbx_jsonpath_query() query result: %s\n", ZBX_NULL2EMPTY_STR(output)); + if (ZBX_MOCK_SUCCESS == zbx_mock_parameter("out.value", &handle)) + { + zbx_mock_assert_ptr_ne("Query result", NULL, output); + check_definite_path_result(handle, output); + } + else if (ZBX_MOCK_SUCCESS == zbx_mock_parameter("out.values", &handle)) + { + zbx_mock_assert_ptr_ne("Query result", NULL, output); + check_indefinite_path_result(handle, output); + } + else + zbx_mock_assert_ptr_eq("Query result", NULL, output); + } + else + zbx_mock_assert_str_ne("tzbx_jsonpath_query() error", "", zbx_json_strerror()); + + zbx_free(output); +} diff --git a/tests/libs/zbxjson/zbx_jsonpath_query.inc.yaml b/tests/libs/zbxjson/zbx_jsonpath_query.inc.yaml new file mode 100644 index 00000000000..456f49ebe28 --- /dev/null +++ b/tests/libs/zbxjson/zbx_jsonpath_query.inc.yaml @@ -0,0 +1,77 @@ +--- +| + { + "books": [ + { + "category": "reference", + "author": "Nigel Rees", + "title": "Sayings of the Century", + "price": 8.95, + "id": 1 + }, + { + "category": "fiction", + "author": "Evelyn Waugh", + "title": "Sword of Honour", + "price": 12.99, + "id": 2 + }, + { + "category": "fiction", + "author": "Herman Melville", + "title": "Moby Dick", + "isbn": "0-553-21311-3", + "price": 8.99, + "id": 3 + }, + { + "category": "fiction", + "author": "J. R. R. Tolkien", + "title": "The Lord of the Rings", + "isbn": "0-395-19395-8", + "price": 22.99, + "id": 4 + } + ], + "services": { + "delivery": { + "servicegroup": 1000, + "description": "Next day delivery in local town", + "active": true, + "price": 5 + }, + "bookbinding": { + "servicegroup": 1001, + "description": "Printing and assembling book in A5 format", + "active": true, + "price": 154.99 + }, + "restoration": { + "servicegroup": 1002, + "description": "Various restoration methods", + "active": false, + "methods": [ + { + "description": "Checmical cleaning", + "price": 46 + }, + { + "description": "Pressing pages damaged by moisture", + "price": 24.5 + }, + { + "description": "Rebinding torn book", + "price": 99.49 + } + ] + } + }, + "filters": { + "price": 10, + "category": "fiction", + "no filters": "no \"filters\"" + }, + "closed message": "Store is closed", + "tags": ["a", "b", "c", "d", "e" ] + } +... diff --git a/tests/libs/zbxjson/zbx_jsonpath_query.yaml b/tests/libs/zbxjson/zbx_jsonpath_query.yaml new file mode 100644 index 00000000000..25b1e8888fc --- /dev/null +++ b/tests/libs/zbxjson/zbx_jsonpath_query.yaml @@ -0,0 +1,711 @@ +--- +test case: Query $[0] from ["a", "b"] +in: + data: '["a", "b"]' + path: $[0] +out: + return: SUCCEED + value: a +--- +test case: Query $[4] from ["a", "b"] +in: + data: '["a", "b"]' + path: $[4] +out: + return: SUCCEED +--- +test case: Query $[1] from ["a", "b"] +in: + data: '["a", "b"]' + path: $[1] +out: + return: SUCCEED + value: b +--- +test case: Query $[2] from ["a", "b"] +in: + data: '["a", "b"]' + path: $[2] +out: + return: SUCCEED +--- +test case: Query $[2].* from ["a", "b"] +in: + data: '["a", "b"]' + path: $[2].* +out: + return: SUCCEED +--- +test case: Query $.filters.price +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.filters.price +out: + return: SUCCEED + value: 10 +--- +test case: Query $.filters.category +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.filters.category +out: + return: SUCCEED + value: fiction +--- +test case: Query $.filters.id +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.filters.id +out: + return: SUCCEED +--- +test case: Query $.books[1].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[1].title +out: + return: SUCCEED + value: Sword of Honour +--- +test case: Query $['closed message'] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $['closed message'] +out: + return: SUCCEED + value: Store is closed +--- +test case: Query $.books[-1].author +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[-1].author +out: + return: SUCCEED + value: J. R. R. Tolkien +--- +test case: Query $.filters +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.filters +out: + return: SUCCEED + value: | + { + "price": 10, + "category": "fiction", + "no filters": "no \"filters\"" + } +--- +test case: Query $.books.length() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books.length() +out: + return: SUCCEED + value: 4 +--- +test case: Query $.tags[:] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[:] +out: + return: SUCCEED + value: '["a", "b", "c", "d", "e" ]' +--- +test case: Query $.tags[2:] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[2:] +out: + return: SUCCEED + value: '["c", "d", "e" ]' +--- +test case: Query $.tags[:2] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[:2] +out: + return: SUCCEED + value: '["a", "b"]' +--- +test case: Query $.tags[1:4] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[1:4] +out: + return: SUCCEED + value: '["b", "c", "d"]' +--- +test case: Query $.tags[-2:] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[-2:] +out: + return: SUCCEED + value: '["d", "e"]' +--- +test case: Query $.tags[:-3] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[:-3] +out: + return: SUCCEED + value: '["a", "b"]' +--- +test case: Query $.tags[:-3].length() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.tags[:-3].length() +out: + return: SUCCEED + value: 2 +--- +test case: Query $.books[0, 2].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[0, 2].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Moby Dick"]' +--- +test case: Query $.books[1]['author', "title"] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[1]['author', "title"] +out: + return: SUCCEED + value: '["Evelyn Waugh", "Sword of Honour"]' +--- +test case: Query $..id +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..id +out: + return: SUCCEED + value: '[1, 2, 3, 4]' +--- +test case: Query $.services..price +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.services..price +out: + return: SUCCEED + value: '[5, 154.99, 46, 24.5, 99.49]' +--- +test case: Query $.books[?(@.id == 1 + 1)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 1 + 1)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 4 / 2)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 4 / 2)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 7 - 5)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 7 - 5)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 0.4 * 5)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 0.4 * 5)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 4 - 0.4 * 5)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 4 - 0.4 * 5)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == -0.4 * 5 + 4)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == -0.4 * 5 + 4)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 0.4 * (-5) + 4)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 0.4 * (-5) + 4)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 2 || @.id == 4)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 2 || @.id == 4)].title +out: + return: SUCCEED + value: '["Sword of Honour", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.id == 2 && 2 * ((1 + 3) / 2 + 3) == 10)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 2 && 2 * ((1 + 3) / 2 + 3) == 10)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.id == 2 == 1)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 2 == 1)].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(!(@.id == 2))].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(!(@.id == 2))].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Moby Dick", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.id != 2)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id != 2)].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Moby Dick", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.title =~ " of ")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.title =~ " of ")].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Sword of Honour", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.price > 12.99)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price > 12.99)].title +out: + return: SUCCEED + value: '["The Lord of the Rings"]' +--- +test case: Query $.books[?(@.price >= 12.99)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price >= 12.99)].title +out: + return: SUCCEED + value: '["Sword of Honour", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.price < 12.99)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price < 12.99)].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Moby Dick"]' +--- +test case: Query $.books[?(@.price <= 12.99)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price <= 12.99)].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Sword of Honour", "Moby Dick"]' +--- +test case: Query $.books[?(@.author > "Herman Melville")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.author > "Herman Melville")].title +out: + return: SUCCEED + value: '["Sayings of the Century", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.author >= "Herman Melville")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.author >= "Herman Melville")].title +out: + return: SUCCEED + value: '["Sayings of the Century", "Moby Dick", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.author < "Herman Melville")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.author < "Herman Melville")].title +out: + return: SUCCEED + value: '["Sword of Honour"]' +--- +test case: Query $.books[?(@.author <= "Herman Melville")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.author <= "Herman Melville")].title +out: + return: SUCCEED + value: '["Sword of Honour", "Moby Dick"]' +--- +test case: Query $.books[?(@.price > $.filters.price)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price > $.filters.price)].title +out: + return: SUCCEED + value: '["Sword of Honour", "The Lord of the Rings"]' +--- +test case: Query $.books[?(@.category == $.filters.category)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.category == $.filters.category)].title +out: + return: SUCCEED + value: '["Sword of Honour","Moby Dick","The Lord of the Rings"]' +--- +test case: Query $.books[?(@.category != $.filters.category)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.category != $.filters.category)].title +out: + return: SUCCEED + value: '["Sayings of the Century"]' +--- +test case: Query $..[?(@.id)] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..[?(@.id)] +out: + return: SUCCEED + value: | + [ + { + "category": "reference", + "author": "Nigel Rees", + "title": "Sayings of the Century", + "price": 8.95, + "id": 1 + }, + { + "category": "fiction", + "author": "Evelyn Waugh", + "title": "Sword of Honour", + "price": 12.99, + "id": 2 + }, + { + "category": "fiction", + "author": "Herman Melville", + "title": "Moby Dick", + "isbn": "0-553-21311-3", + "price": 8.99, + "id": 3 + }, + { + "category": "fiction", + "author": "J. R. R. Tolkien", + "title": "The Lord of the Rings", + "isbn": "0-395-19395-8", + "price": 22.99, + "id": 4 + } + ] +--- +test case: Query $.services..[?(@.price > 50)].description +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.services..[?(@.price > 50)].description +out: + return: SUCCEED + value: '["Printing and assembling book in A5 format", "Rebinding torn book"]' +--- +test case: Query $..id.length() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..id.length() +out: + return: SUCCEED + value: 4 +--- +test case: Query $.books[?(@.price >= 12.99)].length() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.price >= 12.99)].length() +out: + return: SUCCEED + value: 2 +--- +test case: Query $.books[?(@.id == 2)].title.first() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.id == 2)].title.first() +out: + return: SUCCEED + value: Sword of Honour +--- +test case: Query $..tags.first().length() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..tags.first().length() +out: + return: SUCCEED + value: 5 +--- +test case: Query $.length() from ["a", "b"] +in: + data: '["a", "b"]' + path: $.length() +out: + return: SUCCEED + value: 2 +--- +test case: Query $.first() from ["a", "b"] +in: + data: '["a", "b"]' + path: $.first() +out: + return: SUCCEED + value: a +--- +test case: Query $.first().first() from [["a", "b"]] +in: + data: '[["a", "b"]]' + path: $.first().first() +out: + return: SUCCEED + value: a +--- +test case: Query $.first().first().first() from [[["a", "b"]]] +in: + data: '[[["a", "b"]]]' + path: $.first().first().first() +out: + return: SUCCEED + value: a +--- +test case: Query $.books[*].price.min() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[*].price.min() +out: + return: SUCCEED + value: 8.95 +--- +test case: Query $..price.max() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..price.max() +out: + return: SUCCEED + value: 154.99 +--- +test case: Query $.books[?(@.category == "fiction")].price.avg() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.category == "fiction")].price.avg() +out: + return: SUCCEED + value: 14.99 +--- +test case: Query $.books[?(@.category == $.filters.xyz)].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.category == $.filters.xyz)].title +out: + return: SUCCEED +--- +test case: Query $.filters['no filters'] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.filters['no filters'] +out: + return: SUCCEED + value: no "filters" +--- +test case: Query $.services[?(@.active=="true")].servicegroup +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.services[?(@.active=="true")].servicegroup +out: + return: SUCCEED + value: '[1000,1001]' +--- +test case: Query $.services[?(@.active=="false")].servicegroup +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.services[?(@.active=="false")].servicegroup +out: + return: SUCCEED + value: '[1002]' +--- +test case: Query $.books[?(@.title =~ "[a-z")].title +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[?(@.title =~ "[a-z")].title +out: + return: FAIL +--- +test case: $..books[?(!@.isbn)] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..books[?(!@.isbn)] +out: + return: SUCCEED + value: | + [ + { + "category": "reference", + "author": "Nigel Rees", + "title": "Sayings of the Century", + "price": 8.95, + "id": 1 + }, + { + "category": "fiction", + "author": "Evelyn Waugh", + "title": "Sword of Honour", + "price": 12.99, + "id": 2 + } + ] +--- +test case: $..books[?(@.isbn)] +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $..books[?(@.isbn)] +out: + return: SUCCEED + value: | + [ + { + "category": "fiction", + "author": "Herman Melville", + "title": "Moby Dick", + "isbn": "0-553-21311-3", + "price": 8.99, + "id": 3 + }, + { + "category": "fiction", + "author": "J. R. R. Tolkien", + "title": "The Lord of the Rings", + "isbn": "0-395-19395-8", + "price": 22.99, + "id": 4 + } + ] +--- +test case: Query $.books[*].price.sum() +include: &include zbx_jsonpath_query.inc.yaml +in: + data: *include + path: $.books[*].price.sum() +out: + return: SUCCEED + value: 53.92 +--- +test case: Query $[?(@.a)].id from [{"a":{"b":"c"}, "id":1}, {"x":{"y":"z"}, "id":2}] +in: + data: '[{"a":{"b":"c"}, "id":1}, {"x":{"y":"z"}, "id":2}]' + path: $[?(@.a)].id +out: + return: SUCCEED + values: '[1]' +--- +test case: Query $[?(!@.a)].id from [{"a":{"b":"c"}, "id":1}, {"x":{"y":"z"}, "id":2}] +in: + data: '[{"a":{"b":"c"}, "id":1}, {"x":{"y":"z"}, "id":2}]' + path: $[?(!@.a)].id +out: + return: SUCCEED + values: '[2]' +--- +test case: Query $[?(@.a)].id from [{"a":["b","c"], "id":1}, {"x":["y","z"], "id":2}] +in: + data: '[{"a":["b","c"], "id":1}, {"x":["y","z"], "id":2}]' + path: $[?(@.a)].id +out: + return: SUCCEED + values: '[1]' +--- +test case: Query $[?(!@.a)].id from [{"a":["b","c"], "id":1}, {"x":["y","z"], "id":2}] +in: + data: '[{"a":["b","c"], "id":1}, {"x":["y","z"], "id":2}]' + path: $[?(!@.a)].id +out: + return: SUCCEED + values: '[2]' +... + |