X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=t%2Funit%2Ffrontend%2Fparser_test.c;h=bca86452dffc44afe22f2fb5b3418eaa7e6f42f3;hp=e245c29e56f1b89d279c5c7052c63208dae7b2a2;hb=b4d485cde96751e1ec832d0e75a3e6081006a1a4;hpb=77a6c3b08a4ad75673a4b6209230a52082927589 diff --git a/t/unit/frontend/parser_test.c b/t/unit/frontend/parser_test.c index e245c29..bca8645 100644 --- a/t/unit/frontend/parser_test.c +++ b/t/unit/frontend/parser_test.c @@ -53,29 +53,132 @@ START_TEST(test_parse) /* valid commands */ { "FETCH 'host'", -1, 1, CONNECTION_FETCH }, + { "FETCH 'host' FILTER " + "host = 'host'", -1, 1, CONNECTION_FETCH }, + { "LIST", -1, 1, CONNECTION_LIST }, { "LIST -- comment", -1, 1, CONNECTION_LIST }, { "LIST;", -1, 1, CONNECTION_LIST }, { "LIST; INVALID", 5, 1, CONNECTION_LIST }, + { "LIST FILTER " + "host = 'host'", -1, 1, CONNECTION_LIST }, + + { "LOOKUP hosts", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host = 'host'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING NOT " + "host = 'host'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' AND " + "service =~ 'p'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING NOT " + "host =~ 'p' AND " + "service =~ 'p'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' AND " + "service =~ 'p' OR " + "service =~ 'r'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING NOT " + "host =~ 'p' AND " + "service =~ 'p' OR " + "service =~ 'r'", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' " + "FILTER :age > 1D", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' " + "FILTER :age > 1D AND " + ":interval < 240s" , -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' " + "FILTER NOT :age>1D", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host =~ 'p' " + "FILTER :age>" + ":interval", -1, 1, CONNECTION_LOOKUP }, + + /* numeric constants */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1234", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo != " + "+234", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo < " + "-234", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo > " + "12.4", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo <= " + "12. + .3", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo >= " + ".4", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "+12e3", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "+12e-3", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "-12e+3", -1, 1, CONNECTION_LOOKUP }, + + /* date, time, interval constants */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1 Y 42D", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1s 42D", -1, 1, CONNECTION_LOOKUP }, + /* + * TODO: Something like 1Y42D should work as well but it doesn't since + * the scanner will tokenize it into {digit}{identifier} :-/ + * + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1Y42D", -1, 1, CONNECTION_LOOKUP }, + */ - { "LOOKUP hosts WHERE " - "host.name = 'host'", -1, 1, CONNECTION_LOOKUP }, - { "LOOKUP hosts WHERE NOT " - "host.name = 'host'", -1, 1, CONNECTION_LOOKUP }, - { "LOOKUP hosts WHERE " - "host.name =~ 'p' AND " - "service.name =~ 'p'", -1, 1, CONNECTION_LOOKUP }, - { "LOOKUP hosts WHERE NOT " - "host.name =~ 'p' AND " - "service.name =~ 'p'", -1, 1, CONNECTION_LOOKUP }, - { "LOOKUP hosts WHERE " - "host.name =~ 'p' AND " - "service.name =~ 'p' OR " - "service.name =~ 'r'", -1, 1, CONNECTION_LOOKUP }, - { "LOOKUP hosts WHERE NOT " - "host.name =~ 'p' AND " - "service.name =~ 'p' OR " - "service.name =~ 'r'", -1, 1, CONNECTION_LOOKUP }, + /* NULL */ + { "LOOKUP hosts MATCHING " + "attribute.foo " + "IS NULL", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo " + "IS NOT NULL", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "NOT attribute.foo " + "IS NULL", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "host IS NULL", -1, -1, 0 }, + { "LOOKUP hosts MATCHING " + "service IS NULL", -1, -1, 0 }, + + /* invalid numeric constants */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "+-12e+3", -1, -1, 0 }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "-12e-+3", -1, -1, 0 }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "e+3", -1, -1, 0 }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "3e", -1, -1, 0 }, + /* following SQL standard, we don't support hex numbers */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "0x12", -1, -1, 0 }, + + /* invalid expressions */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1.23 + 'foo'", -1, -1, 0 }, /* comments */ { "/* some comment */", -1, 0, 0 }, @@ -87,9 +190,19 @@ START_TEST(test_parse) { "LIST; INVALID", 8, -1, 0 }, { "/* some incomplete", -1, -1, 0 }, - { "LOOKUP hosts", -1, -1, 0 }, - { "LOOKUP foo WHERE " - "host.name = 'host'", -1, -1, 0 }, + { "LIST MATCHING " + "host = 'host'", -1, -1, 0 }, + { "FETCH 'host' MATCHING " + "host = 'host'", -1, -1, 0 }, + + { "LOOKUP foo", -1, -1, 0 }, + { "LOOKUP foo MATCHING " + "host = 'host'", -1, -1, 0 }, + { "LOOKUP foo FILTER " + "host = 'host'", -1, -1, 0 }, + { "LOOKUP foo MATCHING " + "host = 'host' FILTER " + "host = 'host'", -1, -1, 0 }, }; size_t i; @@ -137,60 +250,80 @@ START_TEST(test_parse_matcher) int expected; } golden_data[] = { /* empty expressions */ - { NULL, -1, -1 }, - { "", -1, -1 }, + { NULL, -1, -1 }, + { "", -1, -1 }, /* valid expressions */ - { "host.name = 'localhost'", -1, MATCHER_NAME }, - { "host.name != 'localhost'", -1, MATCHER_NOT }, - { "host.name =~ 'host'", -1, MATCHER_NAME }, - { "host.name !~ 'host'", -1, MATCHER_NOT }, - { "host.name = 'localhost' -- foo", -1, MATCHER_NAME }, - { "host.name = 'host' ", 18, MATCHER_NAME }, + { "host = 'localhost'", -1, MATCHER_NAME }, + { "host != 'localhost'", -1, MATCHER_NOT }, + { "host =~ 'host'", -1, MATCHER_NAME }, + { "host !~ 'host'", -1, MATCHER_NOT }, + { "host = 'localhost' -- foo", -1, MATCHER_NAME }, + { "host = 'host' ", 13, MATCHER_NAME }, /* match hosts by service */ - { "service.name = 'name'", -1, MATCHER_NAME }, - { "service.name != 'name'", -1, MATCHER_NOT }, - { "service.name =~ 'pattern'", -1, MATCHER_NAME }, - { "service.name !~ 'pattern'", -1, MATCHER_NOT }, + { "service = 'name'", -1, MATCHER_NAME }, + { "service != 'name'", -1, MATCHER_NOT }, + { "service =~ 'pattern'", -1, MATCHER_NAME }, + { "service !~ 'pattern'", -1, MATCHER_NOT }, /* match hosts by attribute */ - { "attribute.name = 'name'", -1, MATCHER_NAME }, - { "attribute.name != 'name'", -1, MATCHER_NOT }, - { "attribute.name =~ 'pattern'", -1, MATCHER_NAME }, - { "attribute.name !~ 'pattern'", -1, MATCHER_NOT }, + { "attribute = 'name'", -1, MATCHER_NAME }, + { "attribute != 'name'", -1, MATCHER_NOT }, + { "attribute =~ 'pattern'", -1, MATCHER_NAME }, + { "attribute !~ 'pattern'", -1, MATCHER_NOT }, /* composite expressions */ - { "host.name =~ 'pattern' AND " - "service.name =~ 'pattern'", -1, MATCHER_AND }, - { "host.name =~ 'pattern' OR " - "service.name =~ 'pattern'", -1, MATCHER_OR }, - { "NOT host.name = 'host'", -1, MATCHER_NOT }, + { "host =~ 'pattern' AND " + "service =~ 'pattern'", -1, MATCHER_AND }, + { "host =~ 'pattern' OR " + "service =~ 'pattern'", -1, MATCHER_OR }, + { "NOT host = 'host'", -1, MATCHER_NOT }, + /* numeric expressions */ + { "attribute.foo < 123", -1, MATCHER_LT }, + { "attribute.foo <= 123", -1, MATCHER_LE }, + { "attribute.foo = 123", -1, MATCHER_EQ }, + { "attribute.foo >= 123", -1, MATCHER_GE }, + { "attribute.foo > 123", -1, MATCHER_GT }, + /* NULL; while this is an implementation detail, + * IS NULL currently maps to an equality matcher */ + { "attribute.foo IS NULL", -1, MATCHER_ISNULL }, + { "attribute.foo IS NOT NULL", -1, MATCHER_NOT }, + + /* object field matchers */ + { ":last_update < 10s", -1, MATCHER_LT }, + { ":AGE <= 1m", -1, MATCHER_LE }, + { ":interval = 10h", -1, MATCHER_EQ }, + { ":Last_Update >= 24D", -1, MATCHER_GE }, + { ":age > 1M", -1, MATCHER_GT }, + { ":age != 20Y", -1, MATCHER_NOT }, + { ":backend != 'be'", -1, MATCHER_NOT }, + { ":age <= 2 * :interval", -1, MATCHER_LE }, /* check operator precedence */ - { "host.name = 'name' OR " - "service.name = 'name' AND " - "attribute.name = 'name' OR " - "attribute.foo = 'bar'", -1, MATCHER_OR }, - { "host.name = 'name' AND " - "service.name = 'name' AND " - "attribute.name = 'name' OR " - "attribute.foo = 'bar'", -1, MATCHER_OR }, - { "host.name = 'name' AND " - "service.name = 'name' OR " - "attribute.name = 'name' AND " - "attribute.foo = 'bar'", -1, MATCHER_OR }, - { "(host.name = 'name' OR " - "service.name = 'name') AND " - "(attribute.name = 'name' OR " - "attribute.foo = 'bar')", -1, MATCHER_AND }, - { "NOT host.name = 'name' OR " - "service.name = 'name'", -1, MATCHER_OR }, - { "NOT host.name = 'name' OR " - "NOT service.name = 'name'", -1, MATCHER_OR }, - { "NOT (host.name = 'name' OR " - "NOT service.name = 'name')", -1, MATCHER_NOT }, + { "host = 'name' OR " + "service = 'name' AND " + "attribute = 'name' OR " + "attribute.foo = 'bar'", -1, MATCHER_OR }, + { "host = 'name' AND " + "service = 'name' AND " + "attribute = 'name' OR " + "attribute.foo = 'bar'", -1, MATCHER_OR }, + { "host = 'name' AND " + "service = 'name' OR " + "attribute = 'name' AND " + "attribute.foo = 'bar'", -1, MATCHER_OR }, + { "(host = 'name' OR " + "service = 'name') AND " + "(attribute = 'name' OR " + "attribute.foo = 'bar')", -1, MATCHER_AND }, + { "NOT host = 'name' OR " + "service = 'name'", -1, MATCHER_OR }, + { "NOT host = 'name' OR " + "NOT service = 'name'", -1, MATCHER_OR }, + { "NOT (host = 'name' OR " + "NOT service = 'name')", -1, MATCHER_NOT }, /* syntax errors */ - { "LIST", -1, -1 }, - { "foo &^ bar", -1, -1 }, + { "LIST", -1, -1 }, + { "foo &^ bar", -1, -1 }, }; size_t i;