Code

Added tests for sdb_fe_parse_expr() and fixed the implementation.
authorSebastian Harl <sh@tokkee.org>
Fri, 17 Oct 2014 08:43:45 +0000 (10:43 +0200)
committerSebastian Harl <sh@tokkee.org>
Fri, 17 Oct 2014 08:43:45 +0000 (10:43 +0200)
That is, fixed a typo preventing the parsed expression from being returned and
fixed memory leaks in the matcher and expression parsers.

src/frontend/grammar.y
src/frontend/parser.c
t/unit/frontend/parser_test.c

index 4dda3c56b99f1cfd3e7b646b6595012a394550ff..192671823ac67cc1bc541dd22509cbfa50bccaf4 100644 (file)
@@ -228,7 +228,7 @@ statements:
                                n = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
                                                        conn_expr_t, conn_expr_destroy));
                                n->cmd = CONNECTION_EXPR;
-                               CONN_EXPR($$)->expr = $1;
+                               CONN_EXPR(n)->expr = $1;
 
                                sdb_llist_append(pt, SDB_OBJ(n));
                                sdb_object_deref(SDB_OBJ(n));
index f16b71fd952a0bcc4c94c95c5d6eedb8d0dad21c..785b7e40b59caecc3f34d5e8660f7d04f918e397 100644 (file)
@@ -112,8 +112,10 @@ sdb_fe_parse_matcher(const char *cond, int len)
        }
 
        node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0));
-       if (! node)
+       if (! node) {
+               sdb_llist_destroy(yyextra.parsetree);
                return NULL;
+       }
 
        if (node->cmd == CONNECTION_MATCHER) {
                m = CONN_MATCHER(node)->matcher;
@@ -152,8 +154,10 @@ sdb_fe_parse_expr(const char *expr, int len)
        }
 
        node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0));
-       if (! node)
+       if (! node) {
+               sdb_llist_destroy(yyextra.parsetree);
                return NULL;
+       }
 
        if (node->cmd == CONNECTION_EXPR) {
                e = CONN_EXPR(node)->expr;
index 0c7b30448c41d2231060355abc4381b4b3ec8026..844e739ca9d72b01c94fd66a1e2c2c04ef63bac1 100644 (file)
@@ -32,6 +32,7 @@
 #include "libsysdb_test.h"
 
 #include <check.h>
+#include <limits.h>
 
 /*
  * tests
@@ -386,6 +387,7 @@ START_TEST(test_parse_matcher)
                /* syntax errors */
                { "LIST",                       -1, -1 },
                { "foo &^ bar",                 -1, -1 },
+               { ".invalid",                   -1, -1 },
        };
 
        size_t i;
@@ -413,6 +415,72 @@ START_TEST(test_parse_matcher)
 }
 END_TEST
 
+START_TEST(test_parse_expr)
+{
+       struct {
+               const char *expr;
+               int len;
+               int expected;
+       } golden_data[] = {
+               /* empty expressions */
+               { NULL,                  -1, INT_MAX },
+               { "",                    -1, INT_MAX },
+
+               /* constant expressions */
+               { "'localhost'",         -1, 0 },
+               { "123",                 -1, 0 },
+               { "2014-08-16",          -1, 0 },
+               { "17:23",               -1, 0 },
+               { "17:23:53",            -1, 0 },
+               { "17:23:53.123",        -1, 0 },
+               { "17:23:53.123456789",  -1, 0 },
+               { "2014-08-16 17:23",    -1, 0 },
+               { "2014-08-16 17:23:53", -1, 0 },
+               { "10s",                 -1, 0 },
+               { "60m",                 -1, 0 },
+               { "10Y 24D 1h",          -1, 0 },
+
+               /* queryable fields */
+               { ".last_update",        -1, FIELD_VALUE },
+               { ".AGE",                -1, FIELD_VALUE },
+               { ".interval",           -1, FIELD_VALUE },
+               { ".Last_Update",        -1, FIELD_VALUE },
+               { ".backend",            -1, FIELD_VALUE },
+
+               /* attributes */
+               { "attribute[foo]",      -1, ATTR_VALUE },
+
+               /* syntax errors */
+               { "LIST",                -1, INT_MAX },
+               { "foo &^ bar",          -1, INT_MAX },
+               { ".invalid",            -1, INT_MAX },
+       };
+
+       size_t i;
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+               sdb_store_expr_t *e;
+               e = sdb_fe_parse_expr(golden_data[i].expr, golden_data[i].len);
+
+               if (golden_data[i].expected == INT_MAX) {
+                       fail_unless(e == NULL,
+                                       "sdb_fe_parse_expr(%s) = %p; expected: NULL",
+                                       golden_data[i].expr, e);
+                       continue;
+               }
+
+               fail_unless(e != NULL, "sdb_fe_parse_expr(%s) = NULL; "
+                               "expected: <expr>", golden_data[i].expr);
+               fail_unless(e->type == golden_data[i].expected,
+                               "sdb_fe_parse_expr(%s) returned expression of type %d; "
+                               "expected: %d", golden_data[i].expr, e->type,
+                               golden_data[i].expected);
+
+               sdb_object_deref(SDB_OBJ(e));
+       }
+}
+END_TEST
+
 Suite *
 fe_parser_suite(void)
 {
@@ -422,6 +490,7 @@ fe_parser_suite(void)
        tc = tcase_create("core");
        tcase_add_test(tc, test_parse);
        tcase_add_test(tc, test_parse_matcher);
+       tcase_add_test(tc, test_parse_expr);
        suite_add_tcase(s, tc);
 
        return s;