summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0ffb879)
raw | patch | inline | side by side (parent: 0ffb879)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 9 Apr 2014 15:34:56 +0000 (17:34 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 9 Apr 2014 15:34:56 +0000 (17:34 +0200) |
This is meant for logging and debugging. For now, it's used in tests to check
parsed and compiled matchers.
parsed and compiled matchers.
src/core/store_lookup.c | patch | blob | history | |
src/include/core/store.h | patch | blob | history | |
t/Makefile.am | patch | blob | history | |
t/core/store_lookup_test.c | patch | blob | history | |
t/libsysdb_test.h | patch | blob | history | |
t/libsysdb_testutils.c | [new file with mode: 0644] | patch | blob |
t/libsysdb_testutils.h | [new file with mode: 0644] | patch | blob |
index e5735d3728e8157ebc90d3157c0278ea6b42acdb..bb32157402d8c047a20326aab81e069a4073e5f1 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
return 1;
} /* match_name */
+static char *
+name_tostring(name_matcher_t *m, char *buf, size_t buflen)
+{
+ snprintf(buf, buflen, "{ %s%s%s, %p }",
+ m->name ? "'" : "", m->name ? m->name : "NULL", m->name ? "'" : "",
+ m->name_re);
+ return buf;
+} /* name_tostring */
+
+static char *
+logical_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ char left[buflen + 1], right[buflen + 1];
+
+ if (! m) {
+ /* this should not happen */
+ snprintf(buf, buflen, "()");
+ return buf;
+ }
+
+ assert((m->type == MATCHER_OR) || (m->type == MATCHER_AND));
+ snprintf(buf, buflen, "(%s, %s, %s)",
+ m->type == MATCHER_OR ? "OR" : "AND",
+ sdb_store_matcher_tostring(OP_M(m)->left, left, sizeof(left)),
+ sdb_store_matcher_tostring(OP_M(m)->right, right, sizeof(right)));
+ return buf;
+} /* logical_tostring */
+
+static char *
+unary_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ char op[buflen + 1];
+
+ if (! m) {
+ /* this should not happen */
+ snprintf(buf, buflen, "()");
+ return buf;
+ }
+
+ assert(m->type == MATCHER_NOT);
+ snprintf(buf, buflen, "(NOT, %s)",
+ sdb_store_matcher_tostring(UOP_M(m)->op, op, sizeof(op)));
+ return buf;
+} /* unary_tostring */
+
+static char *
+attr_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ char name[buflen + 1], value[buflen + 1];
+
+ if (! m) {
+ snprintf(buf, buflen, "ATTR{}");
+ return buf;
+ }
+
+ assert(m->type == MATCHER_ATTR);
+ snprintf(buf, buflen, "ATTR{ NAME%s, VALUE%s }",
+ name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+ name_tostring(&ATTR_M(m)->value, value, sizeof(value)));
+ return buf;
+} /* attr_tostring */
+
+static char *
+service_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ char name[buflen + 1], attr[buflen + 1];
+
+ if (! m) {
+ snprintf(buf, buflen, "SERVICE{}");
+ return buf;
+ }
+
+ assert(m->type == MATCHER_SERVICE);
+ snprintf(buf, buflen, "SERVICE{ NAME%s, %s }",
+ name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+ attr_tostring(SDB_STORE_MATCHER(SERVICE_M(m)->attr),
+ attr, sizeof(attr)));
+ return buf;
+} /* service_tostring */
+
+static char *
+host_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ char name[buflen + 1], service[buflen + 1], attr[buflen + 1];
+
+ if (! m) {
+ snprintf(buf, buflen, "HOST{}");
+ return buf;
+ }
+
+ assert(m->type == MATCHER_HOST);
+ snprintf(buf, buflen, "HOST{ NAME%s, %s, %s }",
+ name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+ service_tostring(SDB_STORE_MATCHER(HOST_M(m)->service),
+ service, sizeof(service)),
+ attr_tostring(SDB_STORE_MATCHER(HOST_M(m)->attr),
+ attr, sizeof(attr)));
+ return buf;
+} /* host_tostring */
+
/* match attribute specific values;
* always call this function through match_obj() */
static int
match_obj,
};
+typedef char *(*matcher_tostring_cb)(sdb_store_matcher_t *, char *, size_t);
+
+static matcher_tostring_cb matchers_tostring[] = {
+ logical_tostring,
+ logical_tostring,
+ unary_tostring,
+ attr_tostring,
+ service_tostring,
+ host_tostring,
+};
+
static int
match_logical(sdb_store_matcher_t *m, sdb_store_base_t *obj)
{
return matchers[m->type](m, obj);
} /* sdb_store_matcher_matches */
+char *
+sdb_store_matcher_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ if (! m)
+ return NULL;
+
+ if ((m->type < 0)
+ || (((size_t)m->type >= SDB_STATIC_ARRAY_LEN(matchers_tostring))))
+ return NULL;
+ return matchers_tostring[m->type](m, buf, buflen);
+} /* sdb_store_matcher_tostring */
+
int
sdb_store_lookup(sdb_store_matcher_t *m, sdb_store_lookup_cb cb,
void *user_data)
index cde6ad0b8c2763dd15b4759b27f005b87441db5a..6106b3fdbe2490629a6b1e42d02ee85184d134dc 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
int
sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj);
+/*
+ * sdb_store_matcher_tostring:
+ * Format a matcher object as string. This is meant for logging or debugging
+ * purposes.
+ */
+char *
+sdb_store_matcher_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen);
+
/*
* sdb_store_lookup_cb:
* Lookup callback. It is called for each matching object when looking up data
diff --git a/t/Makefile.am b/t/Makefile.am
index c63a2bb21d0c8f9a8e1ee25836723266f70fbebe..cc2607f75e2b09d9129cc9ff77cfe08630649932 100644 (file)
--- a/t/Makefile.am
+++ b/t/Makefile.am
libsysdb_test_SOURCES = \
libsysdb_test.c libsysdb_test.h \
+ libsysdb_testutils.c libsysdb_testutils.h \
core/data_test.c \
core/object_test.c \
core/store_test.c \
libsysdb_test_LDADD = $(top_builddir)/src/libsysdb.la @CHECK_LIBS@
libsysdb_net_test_SOURCES = \
- libsysdb_net_test.c libsysdb_test.h
+ libsysdb_net_test.c libsysdb_test.h \
+ libsysdb_testutils.c libsysdb_testutils.h
if BUILD_WITH_FOPENCOOKIE
libsysdb_net_test_SOURCES += utils/unixsock_test.c
endif
index 8aa730b1bdcf2d3ed29608c3a1913aab72cee2d7..6365b6b259a101feed4d0f9fded3491e5d28c383 100644 (file)
START_TEST(test_lookup)
{
+#define PTR_RE "0x[0-9a-f]+"
struct {
const char *query;
int expected;
+ const char *tostring_re;
} golden_data[] = {
- { "host.name = 'a'", 1 },
- { "host.name =~ 'a|b'", 2 },
- { "host.name =~ 'host'", 0 },
- { "host.name =~ '.'", 3 },
- { "service.name = 's1'", 2 },
- { "service.name =~ 's'", 2 },
- { "service.name !~ 's'", 1 },
- { "attribute.name = 'k1'", 1 },
- { "attribute.name = 'x'", 0 },
- { "attribute.k1 = 'v1'", 1 },
- { "attribute.k1 != 'v1'", 2 },
- { "attribute.k1 != 'v2'", 3 },
+ { "host.name = 'a'", 1,
+ "HOST\\{ NAME\\{ 'a', \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{\\} \\}" },
+ { "host.name =~ 'a|b'", 2,
+ "HOST\\{ NAME\\{ NULL, "PTR_RE" \\}, SERVICE\\{\\}, ATTR\\{\\} \\}" },
+ { "host.name =~ 'host'", 0,
+ "HOST\\{ NAME\\{ NULL, "PTR_RE" \\}, SERVICE\\{\\}, ATTR\\{\\} \\}" },
+ { "host.name =~ '.'", 3,
+ "HOST\\{ NAME\\{ NULL, "PTR_RE" \\}, SERVICE\\{\\}, ATTR\\{\\} \\}" },
+ { "service.name = 's1'", 2,
+ "HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{ "
+ "NAME\\{ 's1', \\(nil\\) }, ATTR\\{\\} "
+ "\\}, ATTR\\{\\} \\}" },
+ { "service.name =~ 's'", 2,
+ "HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{ "
+ "NAME\\{ NULL, "PTR_RE" }, ATTR\\{\\} "
+ "\\}, ATTR\\{\\} \\}" },
+ { "service.name !~ 's'", 1,
+ "(NOT, HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{ "
+ "NAME\\{ NULL, "PTR_RE" }, ATTR\\{\\} "
+ "\\}, ATTR\\{\\} \\})" },
+ { "attribute.name = 'k1'", 1,
+ "HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{ "
+ "NAME\\{ 'k1', \\(nil\\) }, VALUE\\{ NULL, \\(nil\\) \\} "
+ "\\} \\}" },
+ { "attribute.name = 'x'", 0,
+ "HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{ "
+ "NAME\\{ 'x', \\(nil\\) }, VALUE\\{ NULL, \\(nil\\) \\} "
+ "\\} \\}" },
+ { "attribute.k1 = 'v1'", 1,
+ "HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{ "
+ "NAME\\{ 'k1', \\(nil\\) }, VALUE\\{ 'v1', \\(nil\\) \\} "
+ "\\} \\}" },
+ { "attribute.k1 != 'v1'", 2,
+ "(NOT, HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{ "
+ "NAME\\{ 'k1', \\(nil\\) }, VALUE\\{ 'v1', \\(nil\\) \\} "
+ "\\} \\})" },
+ { "attribute.k1 != 'v2'", 3,
+ "(NOT, HOST\\{ NAME\\{ NULL, \\(nil\\) \\}, SERVICE\\{\\}, ATTR\\{ "
+ "NAME\\{ 'k1', \\(nil\\) }, VALUE\\{ 'v2', \\(nil\\) \\} "
+ "\\} \\})" },
};
int check, n;
"sdb_store_lookup called callback %d times; expected: 3", (int)n);
for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
- sdb_store_matcher_t *m = sdb_fe_parse_matcher(golden_data[i].query, -1);
+ sdb_store_matcher_t *m;
+ char buf[4096];
+
+ m = sdb_fe_parse_matcher(golden_data[i].query, -1);
fail_unless(m != NULL,
"sdb_fe_parse_matcher(%s, -1) = NULL; expected: <matcher>",
golden_data[i].query);
+ fail_unless(sdb_regmatches(golden_data[i].tostring_re,
+ sdb_store_matcher_tostring(m, buf, sizeof(buf))) == 0,
+ "sdb_fe_parse_matcher(%s, -1) = %s; expected: %s",
+ golden_data[i].query,
+ sdb_store_matcher_tostring(m, buf, sizeof(buf)),
+ golden_data[i].tostring_re);
n = 0;
sdb_store_lookup(m, lookup_cb, &n);
diff --git a/t/libsysdb_test.h b/t/libsysdb_test.h
index 3357260f6a52559ac0d70906aff2e5a927cd08cf..5f0e1b486eda09647e1fdd9cbd72d38c8f7af0b2 100644 (file)
--- a/t/libsysdb_test.h
+++ b/t/libsysdb_test.h
#include "sysdb.h"
#include "core/object.h"
+#include "libsysdb_testutils.h"
+
#include <check.h>
#include <string.h>
diff --git a/t/libsysdb_testutils.c b/t/libsysdb_testutils.c
--- /dev/null
+++ b/t/libsysdb_testutils.c
@@ -0,0 +1,54 @@
+/*
+ * SysDB - t/libsysdb_testutils.c
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "libsysdb_testutils.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <regex.h>
+
+int
+sdb_regmatches(const char *regex, const char *string)
+{
+ regex_t reg;
+ int status;
+
+ status = regcomp(®, regex, REG_EXTENDED | REG_NOSUB);
+ if (status)
+ return status;
+
+ status = regexec(®, string, /* matches = */ 0, NULL, /* flags = */ 0);
+ regfree(®);
+ return status;
+} /* sdb_regmatches */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/t/libsysdb_testutils.h b/t/libsysdb_testutils.h
--- /dev/null
+++ b/t/libsysdb_testutils.h
@@ -0,0 +1,49 @@
+/*
+ * SysDB - t/libsysdb_testutils.h
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Utility functions for test suites.
+ */
+
+#ifndef T_LIBSYSDB_UTILS_H
+#define T_LIBSYSDB_UTILS_H 1
+
+/*
+ * sdb_regmatches:
+ * Check if a regex matches a string.
+ *
+ * Returns:
+ * - 0 if the regex matches
+ * - a non-zero error value else (see regcomp(3) for details)
+ */
+int
+sdb_regmatches(const char *regex, const char *string);
+
+#endif /* T_LIBSYSDB_UTILS_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+