Code

Merged branch 'master' of git://git.tokkee.org/sysdb.
[sysdb.git] / t / frontend / parser_test.c
index 212bfe1d44d4d47356b8b775d34ce47be39eb351..f64b9ebca95b05e66bb568a9c6535f72cc7f7462 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "frontend/connection.h"
 #include "frontend/parser.h"
+#include "core/store-private.h"
 #include "core/object.h"
 #include "libsysdb_test.h"
 
@@ -45,34 +46,50 @@ START_TEST(test_parse)
                sdb_conn_state_t expected_cmd;
        } golden_data[] = {
                /* empty commands */
-               { NULL,                 -1, -1, 0 },
-               { "",                   -1,  0, 0 },
-               { ";",                  -1,  0, 0 },
-               { ";;",                 -1,  0, 0 },
+               { NULL,                  -1, -1, 0 },
+               { "",                    -1,  0, 0 },
+               { ";",                   -1,  0, 0 },
+               { ";;",                  -1,  0, 0 },
 
                /* valid commands */
-               { "FETCH '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   },
-
-               { "LOOKUP hosts "
-                 "WHERE 'host'",       -1,  1, CONNECTION_LOOKUP },
+               { "FETCH '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   },
+
+               { "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 },
 
                /* comments */
-               { "/* some comment */", -1,  0, 0 },
-               { "-- another comment", -1,  0, 0 },
+               { "/* some comment */",  -1,  0, 0 },
+               { "-- another comment",  -1,  0, 0 },
 
                /* syntax errors */
-               { "INVALID",            -1, -1, 0 },
-               { "FETCH host",         -1, -1, 0 },
-               { "LIST; INVALID",       8, -1, 0 },
-               { "/* some incomplete", -1, -1, 0 },
-
-               { "LOOKUP hosts",       -1, -1, 0 },
-               { "LOOKUP invalid "
-                 "WHERE 'host'",       -1, -1, 0 },
+               { "INVALID",             -1, -1, 0 },
+               { "FETCH host",          -1, -1, 0 },
+               { "LIST; INVALID",        8, -1, 0 },
+               { "/* some incomplete",  -1, -1, 0 },
+
+               { "LOOKUP hosts",        -1, -1, 0 },
+               { "LOOKUP foo WHERE "
+                 "host.name = 'host'",  -1, -1, 0 },
        };
 
        size_t i;
@@ -120,34 +137,81 @@ START_TEST(test_parse_matcher)
                int expected;
        } golden_data[] = {
                /* empty expressions */
-               { NULL,                 -1, -1 },
-               { "",                   -1, -1 },
+               { NULL,                             -1, -1 },
+               { "",                               -1, -1 },
 
                /* valid expressions */
-               { "'localhost'",        -1,  0 },
-               { "'localhost' -- foo", -1,  0 },
-               { "'host' <garbage>",    6,  0 },
+               { "host.name = 'localhost'",        -1,  MATCHER_HOST },
+               { "host.name != 'localhost'",       -1,  MATCHER_NOT },
+               { "host.name =~ 'host'",            -1,  MATCHER_HOST },
+               { "host.name !~ 'host'",            -1,  MATCHER_NOT },
+               { "host.name = 'localhost' -- foo", -1,  MATCHER_HOST },
+               { "host.name = 'host' <garbage>",   18,  MATCHER_HOST },
+               /* match hosts by service */
+               { "service.name = 'name'",          -1,  MATCHER_HOST },
+               { "service.name != 'name'",         -1,  MATCHER_NOT },
+               { "service.name =~ 'pattern'",      -1,  MATCHER_HOST },
+               { "service.name !~ 'pattern'",      -1,  MATCHER_NOT },
+               /* match hosts by attribute */
+               { "attribute.name = 'name'",        -1,  MATCHER_HOST },
+               { "attribute.name != 'name'",       -1,  MATCHER_NOT },
+               { "attribute.name =~ 'pattern'",    -1,  MATCHER_HOST },
+               { "attribute.name !~ '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 },
+
+               /* 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 },
 
                /* syntax errors */
-               { "LIST",               -1, -1 },
-               { "foo &^ bar",         -1, -1 },
+               { "LIST",                           -1, -1 },
+               { "foo &^ bar",                     -1, -1 },
        };
 
        size_t i;
-       sdb_store_matcher_t *m;
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
-               _Bool ok;
-
+               sdb_store_matcher_t *m;
                m = sdb_fe_parse_matcher(golden_data[i].expr, golden_data[i].len);
-               if (golden_data[i].expected < 0)
-                       ok = m == NULL;
-               else
-                       ok = m != NULL;
 
-               fail_unless(ok, "sdb_fe_parse_matcher(%s) = %p; expected: %s",
-                               golden_data[i].expr, m, (golden_data[i].expected < 0)
-                               ? "NULL" : "<matcher>");
+               if (golden_data[i].expected < 0) {
+                       fail_unless(m == NULL,
+                                       "sdb_fe_parse_matcher(%s) = %p; expected: NULL",
+                                       golden_data[i].expr, m);
+                       continue;
+               }
+
+               fail_unless(m != NULL, "sdb_fe_parse_matcher(%s) = NULL; "
+                               "expected: <matcher>", golden_data[i].expr);
+               fail_unless(M(m)->type == golden_data[i].expected,
+                               "sdb_fe_parse_matcher(%s) returned matcher of type %d; "
+                               "expected: %d", golden_data[i].expr, M(m)->type,
+                               golden_data[i].expected);
 
                sdb_object_deref(SDB_OBJ(m));
        }