[syslog-ng] [PATCH (3.5) 1/3] tests: Add a testcase for log_template_compile function

Juhász Viktor jviktor at balabit.hu
Fri Aug 23 18:14:58 CEST 2013


test_template_compile: new unit test implemented.
    
Main goal of this test is to help the refactoring the log_template_compile monster function
    
Signed-off-by: Juhasz Viktor <jviktor at balabit.hu>
---
 tests/unit/Makefile.am                      |    5 +
 tests/unit/test_template_compile.c   |  320 ++++++++++++++++++++++++++++++++++++
 2 files changed, 325 insertions(+)

diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 8841834..af5730f 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -8,6 +8,7 @@ tests_unit_TESTS			=  \
 	tests/unit/test_serialize 	   \
 	tests/unit/test_msgparse	   \
 	tests/unit/test_template	   \
+	tests/unit/test_template_compile   \
 	tests/unit/test_template_speed	   \
 	tests/unit/test_dnscache	   \
 	tests/unit/test_findcrlf	   \
@@ -56,6 +57,10 @@ tests_unit_test_template_LDADD		= \
 	$(unit_test_extra_modules)	  \
 	$(PREOPEN_BASICFUNCS)
 
+tests_unit_test_template_compile_CFLAGS		= $(TEST_CFLAGS)
+tests_unit_test_template_compile_LDADD		= \
+	$(TEST_LDADD)	$(unit_test_extra_modules)
+
 tests_unit_test_template_speed_LDADD	= \
 	$(TEST_LDADD) $(unit_test_extra_modules)
 
diff --git a/tests/unit/test_template_compile.c b/tests/unit/test_template_compile.c
new file mode 100644
index 0000000..23fed4f
--- /dev/null
+++ b/tests/unit/test_template_compile.c
@@ -0,0 +1,320 @@
+#include "templates.c"
+#include "logmsg.h"
+#include "testutils.h"
+#include "cfg.h"
+#include "plugin.h"
+
+#define SIMPLE_STRING "Test String"
+#define SIMPLE_MACRO "${MESSAGE}"
+#define SIMPLE_MACRO_UNBRACE "$MESSAGE"
+#define SIMPLE_MACRO_UNBRACE_ADD_TEXT "$MESSAGE test value"
+#define SIMPLE_MACRO_MSGREF "${MESSAGE}@1"
+#define SIMPLE_MACRO_INVALID_REF "${MESSAGE}@gmail.com"
+#define SIMPLE_MACRO_ADD_TEXT "${MESSAGE}test value"
+#define ESCAPED_CHAR "Test \\$STRING"
+#define VALID_SUBST "${MESSAGE:-default value}"
+#define TRICKY_VALUE "$$VALUE_NAME"
+#define TRICKY_VALUE_2 "$:VALUE_NAME"
+#define TRICKY_VALUE_3 "$${VALUE_NAME}"
+#define TRICKY_VALUE_4 "\\"
+#define TRICKY_VALUE_5 "$"
+#define TRICKY_VALUE_6 "${MESSAGE:-}"
+#define TRICKY_VALUE_7 "${}"
+
+#define INVALID_MACRO "${MESSAGE"
+#define INVALID_SUBST "${MESSAGE:1}"
+
+#define SIMPLE_VALUE "${VALUE_NAME}"
+#define SIMPLE_VALUE_UNBRACE "$VALUE_NAME"
+#define SIMPLE_VALUE_ESCAPED "${VALUE\\}NAME}"
+
+#define SIMPLE_TEMPLATE_FUNCTION "$(hello)"
+#define SIMPLE_TEMPLATE_FUNCTION_WITH_ADDITIONAL_TEXT "$(hello)test value"
+#define COMPLICATED_TEMPLATE_FUNCTION "$( hello \\tes\t\t\t value(xyz) \"value with spaces\" 'test value with spa\"ces')@2"
+#define COMPLICATED_TEMPLATE_FUNCTION_BAD_1 "$( hello \\tes\t\t\t value(xyz \"value with spaces\" 'test value with spa\"ces')"
+#define COMPLICATED_TEMPLATE_FUNCTION_BAD_2 "$( hello \\tes\t\t\t value xyz \"value with spaces\" 'test value with spa\"ces'"
+
+#define SIMPLE_UNKNOWN_FUNCTION "$(unknown function)"
+
+static void
+hello(LogMessage *msg, int argc, GString *argv[], GString *result)
+{
+  return;
+}
+
+TEMPLATE_FUNCTION_SIMPLE(hello);
+Plugin hello_plugin = TEMPLATE_FUNCTION_PLUGIN(hello, "hello");
+
+
+GlobalConfig *configuration;
+static void
+hide_internal_message(LogMessage *msg)
+{
+  log_msg_unref(msg);
+  return;
+}
+
+#define assert_common_element(actual, expected) \
+    assert_string(actual.text, expected.text, ASSERTION_ERROR("Bad compiled template text")); \
+    if (expected.default_value) \
+      { \
+        assert_string(actual.default_value, expected.default_value, ASSERTION_ERROR("Bad compiled template default value")); \
+      } \
+    else \
+      { \
+        assert_gpointer(actual.default_value, NULL, ASSERTION_ERROR("Bad compiled template default value")); \
+      } \
+    assert_gint(actual.msg_ref, expected.msg_ref, ASSERTION_ERROR("Bad compiled template msg_ref"));
+
+#define assert_value_element(actual, expected) \
+    assert_gint(actual.type, LTE_VALUE, ASSERTION_ERROR("Bad compiled template type")); \
+    assert_common_element(actual, expected); \
+    assert_gint(actual.value_handle, expected.value_handle, ASSERTION_ERROR("Bad compiled template macro"));
+
+#define assert_macro_element(actual, expected) \
+    assert_gint(actual.type, LTE_MACRO, ASSERTION_ERROR("Bad compiled template type")); \
+    assert_common_element(actual, expected); \
+    assert_gint(actual.macro, expected.macro, ASSERTION_ERROR("Bad compiled template macro"));
+
+#define assert_func_element(actual, expected) \
+    assert_gint(actual.type, LTE_FUNC, ASSERTION_ERROR("Bad compiled template type")); \
+    assert_common_element(actual, expected); \
+    assert_gpointer(actual.func.ops, expected.func.ops, ASSERTION_ERROR("Bad compiled template macro"));
+
+#define assert_bad_element(actual, expected, expected_error_message) \
+    assert_string(err->message, expected_error_message, ASSERTION_ERROR("Bad error message")); \
+    assert_macro_element(actual, expected)
+
+
+#define assert_template_compile(template_string) \
+    assert_true(log_template_compile(template, template_string, &err), ASSERTION_ERROR("Can't compile template")); \
+    assert_string(template->template, template_string, ASSERTION_ERROR("Bad stored template"));
+
+#define assert_failed_template_compile(template_string) assert_false(log_template_compile(template, template_string, &err), ASSERTION_ERROR("Can compile bad template"));
+
+#define fill_expected_template_element(element, text, default_value, spec, type, msg_ref)  {\
+    element.text; \
+    element.default_value; \
+    element.spec; \
+    element.type;  \
+    element.msg_ref; }
+
+
+
+void
+test_template_compile_macro()
+{
+  GError *err = NULL;
+  LogTemplateElem *element;
+  LogTemplateElem expected_element;
+  LogTemplate *template = log_template_new(configuration, NULL);
+
+  assert_template_compile(SIMPLE_STRING);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = SIMPLE_STRING, default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO_ADD_TEXT);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+  element = (LogTemplateElem *)template->compiled_template->next->data;
+  fill_expected_template_element(expected_element, text = "test value", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO_UNBRACE);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO_UNBRACE_ADD_TEXT);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+  element = (LogTemplateElem *)template->compiled_template->next->data;
+  fill_expected_template_element(expected_element, text = " test value", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO_MSGREF);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 2);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_MACRO_INVALID_REF);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 1);
+  assert_macro_element(element[0], expected_element);
+  element = (LogTemplateElem *)template->compiled_template->next->data;
+  fill_expected_template_element(expected_element, text = "gmail.com", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(ESCAPED_CHAR);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "Test $STRING", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(VALID_SUBST);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = "default value", macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "$VALUE_NAME", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_2);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "$:VALUE_NAME", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_3);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "${VALUE_NAME}", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_4);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_5);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "$", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_6);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = "", macro = M_MESSAGE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  log_template_unref(template);
+}
+
+void
+test_template_compile_value()
+{
+  GError *err = NULL;
+  LogTemplateElem *element;
+  LogTemplateElem expected_element;
+  LogTemplate *template = log_template_new(configuration, NULL);
+
+  assert_template_compile(SIMPLE_VALUE);
+  element = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, value_handle = log_msg_get_value_handle("VALUE_NAME"), type = LTE_VALUE, msg_ref = 0);
+  assert_value_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_VALUE_UNBRACE);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, value_handle = log_msg_get_value_handle("VALUE_NAME"), type = LTE_VALUE, msg_ref = 0);
+  assert_value_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_VALUE_ESCAPED);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, value_handle = log_msg_get_value_handle("VALUE\\"), type = LTE_VALUE, msg_ref = 0);
+  assert_value_element(element[0], expected_element);
+
+  assert_template_compile(TRICKY_VALUE_7);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, value_handle = log_msg_get_value_handle(""), type = LTE_VALUE, msg_ref = 0);
+  assert_value_element(element[0], expected_element);
+
+  log_template_unref(template);
+}
+
+void
+test_template_compile_func()
+{
+  GError *err = NULL;
+  LogTemplateElem *element;
+  LogTemplateElem expected_element;
+  LogTemplate *template = log_template_new(configuration, NULL);
+  plugin_register(configuration, &hello_plugin, 1);
+
+  assert_template_compile(SIMPLE_TEMPLATE_FUNCTION);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, func.ops = hello_construct(&hello_plugin, configuration, LL_CONTEXT_TEMPLATE_FUNC, "hello"), type = LTE_FUNC, msg_ref = 0);
+  assert_func_element(element[0], expected_element);
+
+  assert_template_compile(COMPLICATED_TEMPLATE_FUNCTION);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, func.ops = hello_construct(&hello_plugin, configuration, LL_CONTEXT_TEMPLATE_FUNC, "hello"), type = LTE_FUNC, msg_ref = 3);
+  assert_func_element(element[0], expected_element);
+
+  assert_template_compile(SIMPLE_TEMPLATE_FUNCTION_WITH_ADDITIONAL_TEXT);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "", default_value = NULL, func.ops = hello_construct(&hello_plugin, configuration, LL_CONTEXT_TEMPLATE_FUNC, "hello"), type = LTE_FUNC, msg_ref = 0);
+  assert_func_element(element[0], expected_element);
+  element = (LogTemplateElem *)template->compiled_template->next->data;
+  fill_expected_template_element(expected_element, text = "test value", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_macro_element(element[0], expected_element);
+
+  log_template_unref(template);
+}
+
+void
+test_template_compile_negativ_tests()
+{
+  GError *err = NULL;
+  LogTemplateElem *element;
+  LogTemplateElem expected_element;
+  LogTemplate *template = log_template_new(configuration, NULL);
+
+  assert_failed_template_compile(INVALID_MACRO);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "error in template: ${MESSAGE", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_bad_element(element[0], expected_element, "Invalid macro, '}' is missing, error_pos='9'");
+  g_clear_error(&err);
+
+
+  assert_failed_template_compile(INVALID_SUBST);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "error in template: ${MESSAGE:1}", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_bad_element(element[0], expected_element, "Unknown substitution function, error_pos='10'");
+  g_clear_error(&err);
+
+
+  assert_failed_template_compile(COMPLICATED_TEMPLATE_FUNCTION_BAD_1);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "error in template: $( hello \\tes\t\t\t value(xyz \"value with spaces\" 'test value with spa\"ces')", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_bad_element(element[0], expected_element, "Invalid template function reference, missing function name or inbalanced '(', error_pos='73'");
+  g_clear_error(&err);
+
+  assert_failed_template_compile(COMPLICATED_TEMPLATE_FUNCTION_BAD_2);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "error in template: $( hello \\tes\t\t\t value xyz \"value with spaces\" 'test value with spa\"ces'", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_bad_element(element[0], expected_element, "Invalid template function reference, missing function name or inbalanced '(', error_pos='72'");
+  g_clear_error(&err);
+
+  assert_failed_template_compile(SIMPLE_UNKNOWN_FUNCTION);
+  element  = (LogTemplateElem *)template->compiled_template->data;
+  fill_expected_template_element(expected_element, text = "error in template: $(unknown function)", default_value = NULL, macro = M_NONE, type = LTE_MACRO, msg_ref = 0);
+  assert_bad_element(element[0], expected_element, "Unknown template function unknown");
+  g_clear_error(&err);
+
+  log_template_unref(template);
+}
+
+int main(int argc, char **argv)
+{
+  msg_init(FALSE);
+  configuration = cfg_new(0x305);
+  log_msg_registry_init();
+  log_template_global_init();
+
+  msg_set_post_func(hide_internal_message);
+
+  test_template_compile_macro();
+  test_template_compile_value();
+  test_template_compile_func();
+  test_template_compile_negativ_tests();
+
+  log_msg_registry_deinit();
+  msg_deinit();
+  return 0;
+}
--




More information about the syslog-ng mailing list