X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=t%2Funit%2Fparser%2Fparser_test.c;h=3d2e40cbc4df0b4e6c59e0415c421d3d996ae716;hp=68e152740368d029ba9dd3ad96acb5be9cd7c81d;hb=1ef0d00327e4b5f56b438f44053f48fd8b198baa;hpb=195f73cdb0c1087bf3f3a82267204fca9eb3104c diff --git a/t/unit/parser/parser_test.c b/t/unit/parser/parser_test.c index 68e1527..3d2e40c 100644 --- a/t/unit/parser/parser_test.c +++ b/t/unit/parser/parser_test.c @@ -31,6 +31,7 @@ #include "parser/parser.h" #include "core/object.h" +#include "core/store.h" #include "testutils.h" #include @@ -357,7 +358,21 @@ struct { { "LOOKUP hosts MATCHING " "name < ''", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, - /* NULL */ + /* typed expressions */ + { "LOOKUP services MATCHING " + "host.attribute['a'] = 'a'", + -1, 1, SDB_AST_TYPE_LOOKUP, SDB_SERVICE }, + /* TODO: this should work but the analyzer currently sees ATTRIBUTE + * (instead of SERVICE-ATTRIBUTE) as the child type + { "LOOKUP services MATCHING " + "ANY attribute.service.name = 's'", + -1, 1, SDB_AST_TYPE_LOOKUP, SDB_SERVICE }, + */ + { "LOOKUP hosts MATCHING " + "ANY service.service.name = 's'", + -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + + /* NULL / TRUE / FALSE */ { "LOOKUP hosts MATCHING " "attribute['foo'] " "IS NULL", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, @@ -369,6 +384,26 @@ struct { "IS NULL", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, { "LOOKUP hosts MATCHING " "ANY service.name IS NULL", -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "attribute['foo'] " + "IS TRUE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP hosts MATCHING " + "attribute['foo'] " + "IS NOT TRUE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP hosts MATCHING " + "NOT attribute['foo'] " + "IS TRUE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP hosts MATCHING " + "attribute['foo'] " + "IS FALSE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP hosts MATCHING " + "attribute['foo'] " + "IS NOT FALSE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP hosts MATCHING " + "NOT attribute['foo'] " + "IS FALSE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST }, + { "LOOKUP metrics MATCHING " + "timeseries IS TRUE", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_METRIC }, /* invalid numeric constants */ { "LOOKUP hosts MATCHING " @@ -409,14 +444,25 @@ struct { * syntactically correct but semantically invalid commands */ -#if 0 /* invalid fields */ + { "LIST hosts FILTER " + "field = 'a'", -1, -1, 0, 0 }, + { "LIST services FILTER " + "field = 'a'", -1, -1, 0, 0 }, + { "LIST metrics FILTER " + "field = 'a'", -1, -1, 0, 0 }, { "LIST hosts FILTER " "value = 'a'", -1, -1, 0, 0 }, { "LIST services FILTER " "value = 'a'", -1, -1, 0, 0 }, { "LIST metrics FILTER " "value = 'a'", -1, -1, 0, 0 }, + { "LIST metrics FILTER " + "name.1 = 'a'", -1, -1, 0, 0 }, + { "LIST hosts FILTER " + "timeseries IS TRUE", -1, -1, 0, 0 }, + { "LIST services FILTER " + "timeseries IS TRUE", -1, -1, 0, 0 }, /* type mismatches */ { "LOOKUP hosts MATCHING " @@ -426,11 +472,6 @@ struct { "1 IN backend ", -1, -1, 0, 0 }, { "LOOKUP hosts MATCHING " "1 NOT IN backend ", -1, -1, 0, 0 }, - { "LOOKUP hosts MATCHING " - "ANY backend !~ backend", - -1, -1, 0, 0 }, - { "LOOKUP hosts MATCHING " - "ANY backend = 1", -1, -1, 0, 0 }, { "LOOKUP hosts MATCHING " "age > 0", -1, -1, 0, 0 }, { "LOOKUP hosts MATCHING " @@ -449,6 +490,7 @@ struct { "age + 1 > 0s", -1, -1, 0, 0 }, { "LOOKUP hosts MATCHING " "age - 1 > 0s", -1, -1, 0, 0 }, + /* datetime integer is allowed */ { "LOOKUP hosts MATCHING " "age || 1 > 0s", -1, -1, 0, 0 }, @@ -512,8 +554,31 @@ struct { "name + 1 IS NULL", -1, -1, 0, 0 }, { "LOOKUP hosts FILTER " "name + 1 IS NULL", -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "name + 1 IS TRUE", -1, -1, 0, 0 }, + { "LOOKUP hosts FILTER " + "name + 1 IS TRUE", -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "name + 1 IS FALSE", -1, -1, 0, 0 }, + { "LOOKUP hosts FILTER " + "name + 1 IS FALSE", -1, -1, 0, 0 }, + + /* invalid iterators */ + { "LOOKUP hosts MATCHING " + "ANY backend !~ backend", + -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "ANY backend = 1", -1, -1, 0, 0 }, { "LOOKUP hosts MATCHING " "ANY 'patt' =~ 'p'", -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "ALL 1 || '2' < '3'", -1, -1, 0, 0 }, + { "LOOKUP hosts MATCHING " + "ALL name =~ 'a'", -1, -1, 0, 0 }, + /* this could work in theory but is not supported atm */ + { "LOOKUP hosts MATCHING " + "ANY backend || 'a' = 'b'", + -1, -1, 0, 0 }, /* invalid LIST commands */ { "LIST", -1, -1, 0, 0 }, @@ -595,7 +660,6 @@ struct { "2015-02-01", -1, -1, 0, 0 }, { "STORE metric attribute " "'metric'.'key' 123", -1, -1, 0, 0 }, -#endif }; START_TEST(test_parse) @@ -603,6 +667,7 @@ START_TEST(test_parse) sdb_strbuf_t *errbuf = sdb_strbuf_create(64); sdb_llist_t *check; sdb_ast_node_t *node; + sdb_store_query_t *q; _Bool ok; check = sdb_parser_parse(parse_data[_i].query, @@ -664,7 +729,14 @@ START_TEST(test_parse) SDB_STORE_TYPE_TO_NAME(parse_data[_i].expected_extra)); } + /* TODO: this should move into front-end specific tests */ + q = sdb_store_query_prepare(node); + fail_unless(q != NULL, + "sdb_store_query_prepare(AST<%s>) = NULL; expected: ", + parse_data[_i].query); + sdb_object_deref(SDB_OBJ(node)); + sdb_object_deref(SDB_OBJ(q)); sdb_llist_destroy(check); sdb_strbuf_destroy(errbuf); } @@ -765,12 +837,13 @@ struct { { "ALL attribute.name !~ 'pattern'", -1, SDB_AST_ALL }, { "ALL attribute.name &^ 'pattern'", -1, -1 }, { "ANY attribute !~ 'pattern'", -1, -1 }, + /* composite expressions */ { "name =~ 'pattern' AND " - "ANY service.name =~ 'pattern'", -1, SDB_AST_AND }, + "ANY service.name =~ 'pattern'", -1, SDB_AST_AND }, { "name =~ 'pattern' OR " - "ANY service.name =~ 'pattern'", -1, SDB_AST_OR }, - { "NOT name = 'host'", -1, SDB_AST_NOT }, + "ANY service.name =~ 'pattern'", -1, SDB_AST_OR }, + { "NOT name = 'host'", -1, SDB_AST_NOT }, /* numeric expressions */ { "attribute['foo'] < 123", -1, SDB_AST_LT }, { "attribute['foo'] <= 123", -1, SDB_AST_LE }, @@ -792,9 +865,13 @@ struct { "2014-08-16 17:23", -1, SDB_AST_EQ }, { "attribute['foo'] = " "2014-08-16 17:23:53", -1, SDB_AST_EQ }, - /* NULL */ + /* NULL / TRUE / FALSE */ { "attribute['foo'] IS NULL", -1, SDB_AST_ISNULL }, { "attribute['foo'] IS NOT NULL", -1, SDB_AST_NOT }, + { "attribute['foo'] IS TRUE", -1, SDB_AST_ISTRUE }, + { "attribute['foo'] IS NOT TRUE", -1, SDB_AST_NOT }, + { "attribute['foo'] IS FALSE", -1, SDB_AST_ISFALSE }, + { "attribute['foo'] IS NOT FALSE", -1, SDB_AST_NOT }, /* array expressions */ { "backend < ['a']", -1, SDB_AST_LT }, { "backend <= ['a']", -1, SDB_AST_LE }, @@ -838,6 +915,13 @@ struct { { "'be' NOT IN backend", -1, SDB_AST_NOT }, { "['a','b'] IN backend", -1, SDB_AST_IN }, { "['a','b'] NOT IN backend", -1, SDB_AST_NOT }, + { "timeseries IS TRUE", -1, SDB_AST_ISTRUE }, + { "timeseries IS FALSE", -1, SDB_AST_ISFALSE }, + { "timeseries IS NOT TRUE", -1, SDB_AST_NOT }, + { "timeseries IS NOT FALSE", -1, SDB_AST_NOT }, + { "timeseries > 0", -1, -1 }, + { "timeseries = TRUE", -1, -1 }, + { "timeseries != FALSE", -1, -1 }, /* check operator precedence */ { "name = 'name' OR " @@ -968,6 +1052,20 @@ struct { { "(age + age) * age", -1, SDB_AST_MUL, SDB_TYPE_DATETIME }, { "age + (age * age)", -1, SDB_AST_ADD, SDB_TYPE_DATETIME }, + /* boolean expressions */ + { "timeseries + 1", -1, -1, -1 }, + { "timeseries - 1", -1, -1, -1 }, + { "timeseries * 1", -1, -1, -1 }, + { "timeseries / 1", -1, -1, -1 }, + { "timeseries \% 1", -1, -1, -1 }, + { "timeseries CONCAT 1", -1, -1, -1 }, + { "timeseries + timeseries", -1, -1, -1 }, + { "timeseries - timeseries", -1, -1, -1 }, + { "timeseries * timeseries", -1, -1, -1 }, + { "timeseries / timeseries", -1, -1, -1 }, + { "timeseries \% timeseries", -1, -1, -1 }, + { "timeseries CONCAT timeseries", -1, -1, -1 }, + /* syntax errors */ { "LIST", -1, -1, -1 }, { "foo &^ bar", -1, -1, -1 },