<p dir="ltr">Thanks for the patch. Some comments below.<br></p>
<p dir="ltr">On Dec 2, 2013 4:34 PM, &quot;Juhász Viktor&quot; &lt;<a href="mailto:jviktor@balabit.hu">jviktor@balabit.hu</a>&gt; wrote:<br>
&gt;<br>
&gt; These tests evince some problems about clone implementation.<br>
&gt; The clone implementations didn&#39;t increased the reference of the condition,<br>
&gt; and it leaks the template which is used by the constructors (set, subst).<br>
&gt;<br>
&gt; These errors are corrected in this patch.<br>
&gt;<br>
&gt; Signed-off-by: Juhász Viktor &lt;<a href="mailto:jviktor@balabit.hu">jviktor@balabit.hu</a>&gt;<br>
&gt; ---<br>
&gt;  lib/rewrite/Makefile.am        |  2 +<br>
&gt;  lib/rewrite/rewrite-set-tag.c  |  2 +-<br>
&gt;  lib/rewrite/rewrite-set.c      |  4 +-<br>
&gt;  lib/rewrite/rewrite-subst.c    |  4 +-<br>
&gt;  lib/rewrite/tests/Makefile.am  |  9 ++++<br>
&gt;  lib/rewrite/tests/test_clone.c | 96 ++++++++++++++++++++++++++++++++++++++++++<br>
&gt;  libtest/test_case.h            | 37 ++++++++++++++++<br>
&gt;  7 files changed, 149 insertions(+), 5 deletions(-)<br>
&gt;  create mode 100644 lib/rewrite/tests/Makefile.am<br>
&gt;  create mode 100644 lib/rewrite/tests/test_clone.c<br>
&gt;  create mode 100644 libtest/test_case.h<br>
&gt;<br>
&gt; diff --git a/lib/rewrite/Makefile.am b/lib/rewrite/Makefile.am<br>
&gt; index b111935..bc6547f 100644<br>
&gt; --- a/lib/rewrite/Makefile.am<br>
&gt; +++ b/lib/rewrite/Makefile.am<br>
&gt; @@ -21,3 +21,5 @@ BUILT_SOURCES +=                              \<br>
&gt;         lib/rewrite/rewrite-expr-grammar.h<br>
&gt;<br>
&gt;  EXTRA_DIST += lib/rewrite/rewrite-expr-grammar.ym<br>
&gt; +<br>
&gt; +include lib/rewrite/tests/Makefile.am<br>
&gt; diff --git a/lib/rewrite/rewrite-set-tag.c b/lib/rewrite/rewrite-set-tag.c<br>
&gt; index 45d3cbf..154973d 100644<br>
&gt; --- a/lib/rewrite/rewrite-set-tag.c<br>
&gt; +++ b/lib/rewrite/rewrite-set-tag.c<br>
&gt; @@ -56,7 +56,7 @@ log_rewrite_set_tag_clone(LogPipe *s)<br>
&gt;    log_rewrite_init(&amp;cloned-&gt;super);<br>
&gt;    cloned-&gt;super.super.clone = log_rewrite_set_tag_clone;<br>
&gt;    cloned-&gt;super.process = log_rewrite_set_tag_process;<br>
&gt; -  cloned-&gt;super.condition = self-&gt;super.condition;<br>
&gt; +  cloned-&gt;super.condition = self-&gt;super.condition ? filter_expr_ref(self-&gt;super.condition) : NULL;<br>
&gt;<br>
&gt;    cloned-&gt;tag_id = self-&gt;tag_id;<br>
&gt;    cloned-&gt;value = self-&gt;value;<br>
&gt; diff --git a/lib/rewrite/rewrite-set.c b/lib/rewrite/rewrite-set.c<br>
&gt; index 5b117ff..de42c8d 100644<br>
&gt; --- a/lib/rewrite/rewrite-set.c<br>
&gt; +++ b/lib/rewrite/rewrite-set.c<br>
&gt; @@ -56,9 +56,9 @@ log_rewrite_set_clone(LogPipe *s)<br>
&gt;    LogRewriteSet *self = (LogRewriteSet *) s;<br>
&gt;    LogRewriteSet *cloned;<br>
&gt;<br>
&gt; -  cloned = (LogRewriteSet *) log_rewrite_set_new(log_template_ref(self-&gt;value_template));<br>
&gt; +  cloned = (LogRewriteSet *) log_rewrite_set_new(self-&gt;value_template);<br>
&gt;    cloned-&gt;super.value_handle = self-&gt;super.value_handle;<br>
&gt; -  cloned-&gt;super.condition = self-&gt;super.condition;<br>
&gt; +  cloned-&gt;super.condition = self-&gt;super.condition ? filter_expr_ref(self-&gt;super.condition) : NULL;<br>
&gt;    return &amp;cloned-&gt;super.super;<br>
&gt;  }<br>
&gt;<br>
&gt; diff --git a/lib/rewrite/rewrite-subst.c b/lib/rewrite/rewrite-subst.c<br>
&gt; index f16afae..385fb82 100644<br>
&gt; --- a/lib/rewrite/rewrite-subst.c<br>
&gt; +++ b/lib/rewrite/rewrite-subst.c<br>
&gt; @@ -101,10 +101,10 @@ log_rewrite_subst_clone(LogPipe *s)<br>
&gt;    LogRewriteSubst *self = (LogRewriteSubst *) s;<br>
&gt;    LogRewriteSubst *cloned;<br>
&gt;<br>
&gt; -  cloned = (LogRewriteSubst *) log_rewrite_subst_new(log_template_ref(self-&gt;replacement));<br>
&gt; +  cloned = (LogRewriteSubst *) log_rewrite_subst_new(self-&gt;replacement);<br>
&gt;    cloned-&gt;matcher = log_matcher_ref(self-&gt;matcher);<br>
&gt;    cloned-&gt;super.value_handle = self-&gt;super.value_handle;<br>
&gt; -  cloned-&gt;super.condition = self-&gt;super.condition;<br>
&gt; +  cloned-&gt;super.condition = self-&gt;super.condition ? filter_expr_ref(self-&gt;super.condition) : NULL;<br>
&gt;    return &amp;cloned-&gt;super.super;<br>
&gt;  }<br>
&gt;<br>
&gt; diff --git a/lib/rewrite/tests/Makefile.am b/lib/rewrite/tests/Makefile.am<br>
&gt; new file mode 100644<br>
&gt; index 0000000..c5f740d<br>
&gt; --- /dev/null<br>
&gt; +++ b/lib/rewrite/tests/Makefile.am<br>
&gt; @@ -0,0 +1,9 @@<br>
&gt; +lib_rewrite_tests_TESTS = lib/rewrite/tests/test_clone<br>
&gt; +<br>
&gt; +check_PROGRAMS                         += ${lib_rewrite_tests_TESTS}<br>
&gt; +<br>
&gt; +lib_rewrite_tests_test_clone_CFLAGS  = $(TEST_CFLAGS)    \<br>
&gt; +  -I${top_srcdir}/lib/rewrite/tests<br>
&gt; +<br>
&gt; +lib_rewrite_tests_test_clone_LDADD      = $(TEST_LDADD)        \<br>
&gt; +       $(PREOPEN_SYSLOGFORMAT)<br>
&gt; diff --git a/lib/rewrite/tests/test_clone.c b/lib/rewrite/tests/test_clone.c<br>
&gt; new file mode 100644<br>
&gt; index 0000000..8bb6d90<br>
&gt; --- /dev/null<br>
&gt; +++ b/lib/rewrite/tests/test_clone.c<br>
&gt; @@ -0,0 +1,96 @@<br>
&gt; +#include &quot;apphook.h&quot;<br>
&gt; +#include &quot;plugin.h&quot;<br>
&gt; +#include &quot;testutils.h&quot;<br>
&gt; +#include &quot;lib/rewrite/rewrite-expr.h&quot;<br>
&gt; +#include &quot;lib/rewrite/rewrite-set.h&quot;<br>
&gt; +#include &quot;lib/rewrite/rewrite-subst.h&quot;<br>
&gt; +#include &quot;lib/rewrite/rewrite-set-tag.h&quot;<br>
&gt; +#include &quot;lib/filter/filter-cmp.h&quot;<br>
&gt; +#include &quot;test_case.h&quot;<br>
&gt; +<br>
&gt; +typedef struct _RewriteTestCase {<br>
&gt; +  TestCase super;<br>
&gt; +  LogRewrite *test_set_rewrite;<br>
&gt; +  LogRewrite *test_subst_rewrite;<br>
&gt; +  LogRewrite *test_tag_rewrite;<br>
&gt; +} RewriteTestCase;<br>
&gt; +<br>
&gt; +void<br>
&gt; +rewrite_testcase_setup(TestCase *s)<br>
&gt; +{<br>
&gt; +  RewriteTestCase *self = (RewriteTestCase *)s;<br>
&gt; +  configuration = cfg_new(0x305);<br>
&gt; +<br>
&gt; +  FilterExprNode *set_condition = fop_cmp_new(log_template_new(configuration, &quot;OP1&quot;), log_template_new(configuration, &quot;OP2&quot;), 10520);<br>
&gt; +  FilterExprNode *subst_condition = fop_cmp_new(log_template_new(configuration, &quot;OP1&quot;), log_template_new(configuration, &quot;OP2&quot;), 10520);<br>
&gt; +  FilterExprNode *set_tag_condition = fop_cmp_new(log_template_new(configuration, &quot;OP1&quot;), log_template_new(configuration, &quot;OP2&quot;), 10520);<br>
&gt; +<br>
&gt; +  LogTemplate *test_template = log_template_new(configuration, &quot;TEST&quot;);<br>
&gt; +<br>
&gt; +  self-&gt;test_set_rewrite = log_rewrite_set_new(test_template);<br>
&gt; +  self-&gt;test_subst_rewrite = log_rewrite_subst_new(test_template);<br>
&gt; +<br>
&gt; +  self-&gt;test_tag_rewrite = log_rewrite_set_tag_new(&quot;test_tag&quot;, FALSE);<br>
&gt; +<br>
&gt; +  log_rewrite_set_condition(self-&gt;test_set_rewrite, set_condition);<br>
&gt; +  log_rewrite_set_condition(self-&gt;test_subst_rewrite, subst_condition);<br>
&gt; +  log_rewrite_set_condition(self-&gt;test_tag_rewrite, set_tag_condition);<br>
&gt; +<br>
&gt; +  log_rewrite_subst_set_matcher(self-&gt;test_subst_rewrite, log_matcher_posix_re_new());<br>
&gt; +<br>
&gt; +  log_template_unref(test_template);<br>
&gt; +<br></p>
<p dir="ltr">Lots of duplicates here. Cant we somehow reduce that?</p>
<p dir="ltr">Loop or functions?</p>
<p dir="ltr">&gt; +<br>
&gt; +void<br>
&gt; +rewrite_testcase_teardown(TestCase *s)<br>
&gt; +{<br>
&gt; +  RewriteTestCase *self = (RewriteTestCase *)s;<br>
&gt; +  log_pipe_unref((LogPipe *)self-&gt;test_subst_rewrite);<br>
&gt; +  log_pipe_unref((LogPipe *)self-&gt;test_set_rewrite);<br>
&gt; +  log_pipe_unref((LogPipe *)self-&gt;test_tag_rewrite);</p>
<p dir="ltr">Again, loop here would make more sense.<br></p>
<p dir="ltr">&gt; +  cfg_free(configuration);<br>
&gt; +}<br>
&gt; +<br>
&gt; +void<br>
&gt; +test_clone(LogRewrite *rule)<br>
&gt; +{<br>
&gt; +  LogPipe *cloned_rule = log_pipe_clone((LogPipe *)rule);<br>
&gt; +  assert_guint32(rule-&gt;condition-&gt;ref_cnt, 2, ASSERTION_ERROR(&quot;Bad reference number of condition&quot;));<br>
&gt; +  log_pipe_unref(cloned_rule);<br>
&gt; +  assert_guint32(rule-&gt;condition-&gt;ref_cnt, 1, ASSERTION_ERROR(&quot;Bad reference number of condition&quot;));<br>
&gt; +}<br></p>
<p dir="ltr">This should probably be called an assert_something</p>
<p dir="ltr">Also it should test something else the refcount is private, testing its value is fragile.<br></p>
<p dir="ltr">&gt; +<br>
&gt; +void<br>
&gt; +test_reference_on_set_condition_cloned(TestCase *s)<br>
&gt; +{<br>
&gt; +  RewriteTestCase *self = (RewriteTestCase *) s;<br>
&gt; +  test_clone(self-&gt;test_set_rewrite);<br>
&gt; +}<br>
&gt; +<br>
&gt; +void<br>
&gt; +test_reference_on_subst_condition_cloned(TestCase *s)<br>
&gt; +{<br>
&gt; +  RewriteTestCase *self = (RewriteTestCase *) s;<br>
&gt; +  test_clone(self-&gt;test_subst_rewrite);<br>
&gt; +}<br>
&gt; +<br>
&gt; +void<br>
&gt; +test_reference_on_tag_condition_cloned(TestCase *s)<br>
&gt; +{<br>
&gt; +  RewriteTestCase *self = (RewriteTestCase *) s;<br>
&gt; +  test_clone(self-&gt;test_tag_rewrite);<br>
&gt; +}<br>
&gt; +<br>
&gt; +int<br>
&gt; +main(int argc, char **argv)<br>
&gt; +{<br>
&gt; +       app_startup();<br>
&gt; +       putenv(&quot;TZ=MET-1METDST&quot;);<br>
&gt; +       tzset();<br>
&gt; +<br>
&gt; +       start_grabbing_messages();<br>
&gt; +       RUN_TESTCASE(RewriteTestCase, rewrite_testcase, test_reference_on_set_condition_cloned);<br>
&gt; +       RUN_TESTCASE(RewriteTestCase, rewrite_testcase, test_reference_on_subst_condition_cloned);<br>
&gt; +       RUN_TESTCASE(RewriteTestCase, rewrite_testcase, test_reference_on_tag_condition_cloned);<br>
&gt; +       stop_grabbing_messages();<br>
&gt; +}<br>
&gt; diff --git a/libtest/test_case.h b/libtest/test_case.h<br>
&gt; new file mode 100644<br>
&gt; index 0000000..4a49c9a<br>
&gt; --- /dev/null<br>
&gt; +++ b/libtest/test_case.h<br>
&gt; @@ -0,0 +1,37 @@<br>
&gt; +/*<br>
&gt; + * test_case.h<br>
&gt; + *<br>
&gt; + *  Created on: Nov 27, 2013<br>
&gt; + *      Author: jviktor<br>
&gt; + */<br>
&gt; +<br>
&gt; +#ifndef TEST_CASE_H_<br>
&gt; +#define TEST_CASE_H_<br>
&gt; +<br>
&gt; +typedef struct _TestCase TestCase;<br>
&gt; +<br>
&gt; +struct _TestCase {<br>
&gt; +  void (*setup)(TestCase *self);<br>
&gt; +  void (*run)(TestCase *self);<br>
&gt; +  void (*teardown)(TestCase *self);<br>
&gt; +};<br>
&gt; +<br>
&gt; +<br>
&gt; +static void<br>
&gt; +run_test_case(TestCase *tc)<br>
&gt; +{<br>
&gt; +  if (tc-&gt;setup) tc-&gt;setup(tc);<br>
&gt; +  tc-&gt;run(tc);<br>
&gt; +  if (tc-&gt;teardown) tc-&gt;teardown(tc);<br>
&gt; +}<br>
&gt; +<br>
&gt; +#define RUN_TESTCASE(class_name, test_case_prefix, test_function) { \<br>
&gt; +  class_name *tc = g_new0(class_name, 1); \<br>
&gt; +  tc-&gt;super.setup = test_case_prefix ## _setup; \<br>
&gt; +  tc-&gt;super.teardown = test_case_prefix ## _teardown; \<br>
&gt; +  tc-&gt;super.run = test_function;\<br>
&gt; +  run_test_case(&amp;tc-&gt;super); \<br>
&gt; +  g_free(tc); \<br>
&gt; +}</p>
<p dir="ltr">Im all for working on testutils.h however I dont see what this buys for us.</p>
<p dir="ltr">It&#39;s equivalent to three lines of code without allowing descendant classes, and not really reusable.</p>
<p dir="ltr">Also, a number of current unit tests should be converted to prove it helps.<br></p>
<p dir="ltr">&gt; +<br>
&gt; +#endif /* TEST_CASE_H_ */<br>
&gt; --<br>
&gt; 1.8.3.2<br>
&gt;<br>
&gt; ______________________________________________________________________________<br>
&gt; Member info: <a href="https://lists.balabit.hu/mailman/listinfo/syslog-ng">https://lists.balabit.hu/mailman/listinfo/syslog-ng</a><br>
&gt; Documentation: <a href="http://www.balabit.com/support/documentation/?product=syslog-ng">http://www.balabit.com/support/documentation/?product=syslog-ng</a><br>
&gt; FAQ: <a href="http://www.balabit.com/wiki/syslog-ng-faq">http://www.balabit.com/wiki/syslog-ng-faq</a><br>
&gt;<br>
</p>