[netcf-devel] [PATCH 4/7] Lift out test functions to tutil.{c,h}

Jonas Eriksson jonas.j.eriksson at ericsson.com
Thu Jul 23 12:37:05 UTC 2009


* tutil.{c,h}:
  - Added format_error, read_test_file, assert_ncf_no_error,
    parse_xml, xml_attrs_subset, xml_next_element, xml_nodes_equal,
    assert_xml_equals, run, setup, teardown from test-initscripts.c
  - Created identify_driver, in order for setup() to create a
    (correctly named) root dir for the tests.

* test-initscripts.c:
  - Removed functions named above
  - Added call to identify_driver("initscripts") before starting tests
---
 tests/Makefile.am        |    2 +-
 tests/test-initscripts.c |  199 +++--------------------------------------
 tests/tutil.c            |  223 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/tutil.h            |   87 ++++++++++++++++++
 4 files changed, 325 insertions(+), 186 deletions(-)
 create mode 100644 tests/tutil.c
 create mode 100644 tests/tutil.h

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 431c734..b5688ef 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,7 +21,7 @@ INCLUDES = -I$(top_srcdir)/src
 # FIXME: Needs to be conditionalized
 check_PROGRAMS=test-initscripts
 
-test_initscripts_SOURCES = test-initscripts.c cutest.c cutest.h
+test_initscripts_SOURCES = test-initscripts.c cutest.c cutest.h tutil.c tutil.h
 test_initscripts_LDADD = $(top_builddir)/src/libnetcf.la $(GNULIB)
 
 # Clean up files generated by test-initscripts
diff --git a/tests/test-initscripts.c b/tests/test-initscripts.c
index 7f62c0b..9a16c17 100644
--- a/tests/test-initscripts.c
+++ b/tests/test-initscripts.c
@@ -27,195 +27,17 @@
 #include "safe-alloc.h"
 #include "read-file.h"
 
+#include "tutil.h"
+
 #include <stdio.h>
 
 #include <libxml/tree.h>
 
-static const char *abs_top_srcdir;
-static const char *abs_top_builddir;
-static char *root, *src_root;
-static struct netcf *ncf;
-
-#define die(msg)                                                    \
-    do {                                                            \
-        fprintf(stderr, "%s:%d: Fatal error: %s\n", __FILE__, __LINE__, msg); \
-        exit(EXIT_FAILURE);                                         \
-    } while(0)
-
-static void format_error(char **strp, const char *format, ...) {
-  va_list args;
-  int r;
-
-  va_start (args, format);
-  r = vasprintf (strp, format, args);
-  va_end (args);
-  if (r < 0)
-      die("Failed to format error message (out of memory)");
-}
-
-static char *read_test_file(CuTest *tc, const char *relpath) {
-    char *path = NULL;
-    char *txt = NULL;
-    size_t length;
-
-    if (asprintf(&path, "%s/tests/%s", abs_top_srcdir, relpath) < 0)
-        CuFail(tc, "Could not format path for file");
-    txt = read_file(path, &length);
-    if (txt == NULL)
-        CuFail(tc, "Failed to read file");
-    return txt;
-}
-
-static void assert_ncf_no_error(CuTest *tc) {
-    CuAssertIntEquals(tc, NETCF_NOERROR, ncf_error(ncf, NULL, NULL));
-}
-
-static xmlDocPtr parse_xml(const char *xml_str) {
-    xmlParserCtxtPtr pctxt;
-    xmlDocPtr xml = NULL;
-
-    /* Set up a parser context so we can catch the details of XML errors. */
-    pctxt = xmlNewParserCtxt();
-    if (pctxt == NULL || pctxt->sax == NULL)
-        die("xmlNewParserCtxt failed");
-
-    xml = xmlCtxtReadDoc (pctxt, BAD_CAST xml_str, "netcf.xml", NULL,
-                          XML_PARSE_NOENT | XML_PARSE_NONET |
-                          XML_PARSE_NOWARNING);
-    if (xml == NULL)
-        die("failed to parse xml document");
-    if (xmlDocGetRootElement(xml) == NULL)
-        die("missing root element");
-
-    xmlFreeParserCtxt(pctxt);
-    return xml;
-}
-
-static int xml_attrs_subset(xmlNodePtr n1, xmlNodePtr n2, char **err) {
-    for (xmlAttrPtr a1 = n1->properties; a1 != NULL; a1 = a1->next) {
-        xmlChar *v1 = xmlGetProp(n1, a1->name);
-        xmlChar *v2 = xmlGetProp(n2, a1->name);
-        if (!xmlStrEqual(v1, v2)) {
-            format_error(err, "Different values for attribute %s/@%s: %s != %s (lines %d and %d)", n1->name, a1->name, v1, v2, n1->line, n2->line);
-            return 0;
-        }
-    }
-    return 1;
-}
-
-static xmlNodePtr xml_next_element(xmlNodePtr n) {
-    while (n != NULL && n->type != XML_ELEMENT_NODE)
-        n = n->next;
-    return n;
-}
-
-static int xml_nodes_equal(xmlNodePtr n1, xmlNodePtr n2, char **err) {
-    if (n1 == NULL && n2 == NULL)
-        return 1;
-    if (n1 == NULL && n2 != NULL) {
-        format_error(err, "First node null, second node %s (line %d)",
-                     n2->name, n2->line);
-        return 0;
-    }
-    if (n1 != NULL && n2 == NULL) {
-        format_error(err, "First node %s, second node null (line %d)",
-                     n1->name, n1->line);
-        return 0;
-    }
-    if (!xmlStrEqual(n1->name, n2->name)) {
-        format_error(err, "Different node names: %s != %s (lines %d and %d)",
-                     n1->name, n2->name, n1->line, n2->line);
-        return 0;
-    }
-    if (! xml_attrs_subset(n1, n2, err))
-        return 0;
-    if (! xml_attrs_subset(n2, n1, err))
-        return 0;
-
-    n1 = xml_next_element(n1->children);
-    n2 = xml_next_element(n2->children);
-    while (n1 != NULL && n2 != NULL) {
-        if (! xml_nodes_equal(n1, n2, err))
-            return 0;
-        n1 = xml_next_element(n1->next);
-        n2 = xml_next_element(n2->next);
-    }
-    if (n1 != NULL) {
-        format_error(err, "Additional element %s (line %d)",
-                     n1->name, n1->line);
-        return 0;
-    } else if (n2 != NULL) {
-        format_error(err, "Additional element %s (line %d)",
-                     n2->name, n2->line);
-        return 0;
-    }
-    return 1;
-}
-
-static void assert_xml_equals(CuTest *tc, const char *fname,
-                              char *exp, char *act) {
-    char *err, *msg;
-    xmlDocPtr exp_doc, act_doc;
-    int result;
-
-    exp_doc = parse_xml(exp);
-    act_doc = parse_xml(act);
-    result = xml_nodes_equal(xmlDocGetRootElement(exp_doc),
-                             xmlDocGetRootElement(act_doc), &err);
-    xmlFreeDoc(exp_doc);
-    xmlFreeDoc(act_doc);
-
-    if (! result) {
-        format_error(&msg, "%s: %s\nExpected XML:\n%s\nActual XML:\n%s\n",
-                     fname, err, exp, act);
-        CuFail(tc, msg);
-    }
-}
-
-static void run(CuTest *tc, const char *format, ...) {
-    char *command;
-    va_list args;
-    int r;
-
-    va_start(args, format);
-    r = vasprintf(&command, format, args);
-    va_end (args);
-    if (r < 0)
-        CuFail(tc, "Failed to format command (out of memory)");
-    r = system(command);
-    if (r < 0 || (WIFEXITED(r) && WEXITSTATUS(r) != 0)) {
-        char *msg;
-        r = asprintf(&msg, "Command %s failed with status %d\n",
-                     command, WEXITSTATUS(r));
-        CuFail(tc, msg);
-        free(msg);
-    }
-}
-
-static void setup(CuTest *tc) {
-    int r;
-
-    if (asprintf(&root, "%s/build/test_initscripts/%s",
-                 abs_top_builddir, tc->name) < 0) {
-        CuFail(tc, "failed to set root");
-    }
-
-    run(tc, "test -d %s && chmod -R u+w %s || :", root, root);
-    run(tc, "rm -rf %s", root);
-    run(tc, "mkdir -p %s", root);
-    run(tc, "cp -pr %s/* %s", src_root, root);
-    run(tc, "chmod -R u+w %s", root);
-    run(tc, "chmod -R a-w %s/sys", root);
-
-    r = ncf_init(&ncf, root);
-    CuAssertIntEquals(tc, 0, r);
-}
-
-static void teardown(ATTRIBUTE_UNUSED CuTest *tc) {
-    ncf_close(ncf);
-    free(root);
-    root = NULL;
-}
+extern const char *abs_top_srcdir;
+extern const char *abs_top_builddir;
+extern char *driver_name;
+extern char *root, *src_root;
+extern struct netcf *ncf;
 
 static void testListInterfaces(CuTest *tc) {
     int nint;
@@ -345,6 +167,11 @@ int main(void) {
         die("failed to set src_root");
     }
 
+    driver_name = strdup("initscripts");
+    if (driver_name == NULL) {
+        die("failed to set driver name");
+    }
+
     CuSuiteSetup(suite, setup, teardown);
 
     SUITE_ADD_TEST(suite, testListInterfaces);
@@ -358,6 +185,7 @@ int main(void) {
     CuSuiteDetails(suite, &output);
     printf("%s\n", output);
     free(output);
+    free(driver_name);
     return suite->failCount;
 }
 
@@ -369,3 +197,4 @@ int main(void) {
  *  tab-width: 4
  * End:
  */
+/* vim: set ts=4 sw=4 et: */
diff --git a/tests/tutil.c b/tests/tutil.c
new file mode 100644
index 0000000..777b2f4
--- /dev/null
+++ b/tests/tutil.c
@@ -0,0 +1,223 @@
+/*
+ * tutil.c: Global utility functions for automated testing of netcf
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: David Lutterkort <lutter at redhat.com>
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <libxml/tree.h>
+
+#include "internal.h"
+#include "cutest.h"
+#include "safe-alloc.h"
+#include "read-file.h"
+
+#include "tutil.h"
+
+const char *abs_top_srcdir;
+const char *abs_top_builddir;
+char *driver_name = NULL;
+char *root, *src_root;
+struct netcf *ncf;
+
+void format_error(char **strp, const char *format, ...) {
+  va_list args;
+  int r;
+
+  va_start (args, format);
+  r = vasprintf (strp, format, args);
+  va_end (args);
+  if (r < 0)
+      die("Failed to format error message (out of memory)");
+}
+
+char *read_test_file(CuTest *tc, const char *relpath) {
+    char *path = NULL;
+    char *txt = NULL;
+    size_t length;
+
+    if (asprintf(&path, "%s/tests/%s", abs_top_srcdir, relpath) < 0)
+        CuFail(tc, "Could not format path for file");
+    txt = read_file(path, &length);
+    if (txt == NULL)
+        CuFail(tc, "Failed to read file");
+    return txt;
+}
+
+void assert_ncf_no_error(CuTest *tc) {
+    CuAssertIntEquals(tc, NETCF_NOERROR, ncf_error(ncf, NULL, NULL));
+}
+
+xmlDocPtr parse_xml(const char *xml_str) {
+    xmlParserCtxtPtr pctxt;
+    xmlDocPtr xml = NULL;
+
+    /* Set up a parser context so we can catch the details of XML errors. */
+    pctxt = xmlNewParserCtxt();
+    if (pctxt == NULL || pctxt->sax == NULL)
+        die("xmlNewParserCtxt failed");
+
+    xml = xmlCtxtReadDoc (pctxt, BAD_CAST xml_str, "netcf.xml", NULL,
+                          XML_PARSE_NOENT | XML_PARSE_NONET |
+                          XML_PARSE_NOWARNING);
+    if (xml == NULL)
+        die("failed to parse xml document");
+    if (xmlDocGetRootElement(xml) == NULL)
+        die("missing root element");
+
+    xmlFreeParserCtxt(pctxt);
+    return xml;
+}
+
+int xml_attrs_subset(xmlNodePtr n1, xmlNodePtr n2, char **err) {
+    for (xmlAttrPtr a1 = n1->properties; a1 != NULL; a1 = a1->next) {
+        xmlChar *v1 = xmlGetProp(n1, a1->name);
+        xmlChar *v2 = xmlGetProp(n2, a1->name);
+        if (!xmlStrEqual(v1, v2)) {
+            format_error(err, "Different values for attribute %s/@%s: %s != %s (lines %d and %d)", n1->name, a1->name, v1, v2, n1->line, n2->line);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+xmlNodePtr xml_next_element(xmlNodePtr n) {
+    while (n != NULL && n->type != XML_ELEMENT_NODE)
+        n = n->next;
+    return n;
+}
+
+int xml_nodes_equal(xmlNodePtr n1, xmlNodePtr n2, char **err) {
+    if (n1 == NULL && n2 == NULL)
+        return 1;
+    if (n1 == NULL && n2 != NULL) {
+        format_error(err, "First node null, second node %s (line %d)",
+                     n2->name, n2->line);
+        return 0;
+    }
+    if (n1 != NULL && n2 == NULL) {
+        format_error(err, "First node %s, second node null (line %d)",
+                     n1->name, n1->line);
+        return 0;
+    }
+    if (!xmlStrEqual(n1->name, n2->name)) {
+        format_error(err, "Different node names: %s != %s (lines %d and %d)",
+                     n1->name, n2->name, n1->line, n2->line);
+        return 0;
+    }
+    if (! xml_attrs_subset(n1, n2, err))
+        return 0;
+    if (! xml_attrs_subset(n2, n1, err))
+        return 0;
+
+    n1 = xml_next_element(n1->children);
+    n2 = xml_next_element(n2->children);
+    while (n1 != NULL && n2 != NULL) {
+        if (! xml_nodes_equal(n1, n2, err))
+            return 0;
+        n1 = xml_next_element(n1->next);
+        n2 = xml_next_element(n2->next);
+    }
+    if (n1 != NULL) {
+        format_error(err, "Additional element %s (line %d)",
+                     n1->name, n1->line);
+        return 0;
+    } else if (n2 != NULL) {
+        format_error(err, "Additional element %s (line %d)",
+                     n2->name, n2->line);
+        return 0;
+    }
+    return 1;
+}
+
+void assert_xml_equals(CuTest *tc, const char *fname,
+                              char *exp, char *act) {
+    char *err, *msg;
+    xmlDocPtr exp_doc, act_doc;
+    int result;
+
+    exp_doc = parse_xml(exp);
+    act_doc = parse_xml(act);
+    result = xml_nodes_equal(xmlDocGetRootElement(exp_doc),
+                             xmlDocGetRootElement(act_doc), &err);
+    xmlFreeDoc(exp_doc);
+    xmlFreeDoc(act_doc);
+
+    if (! result) {
+        format_error(&msg, "%s: %s\nExpected XML:\n%s\nActual XML:\n%s\n",
+                     fname, err, exp, act);
+        CuFail(tc, msg);
+    }
+}
+
+void run(CuTest *tc, const char *format, ...) {
+    char *command;
+    va_list args;
+    int r;
+
+    va_start(args, format);
+    r = vasprintf(&command, format, args);
+    va_end (args);
+    if (r < 0)
+        CuFail(tc, "Failed to format command (out of memory)");
+    r = system(command);
+    if (r < 0 || (WIFEXITED(r) && WEXITSTATUS(r) != 0)) {
+        char *msg;
+        r = asprintf(&msg, "Command %s failed with status %d\n",
+                     command, WEXITSTATUS(r));
+        CuFail(tc, msg);
+        free(msg);
+    }
+}
+
+void setup(CuTest *tc) {
+    int r;
+
+    if (asprintf(&root, "%s/build/test_%s/%s",
+                 abs_top_builddir, driver_name, tc->name) < 0) {
+        CuFail(tc, "failed to set root");
+    }
+
+    run(tc, "test -d %s && chmod -R u+w %s || :", root, root);
+    run(tc, "rm -rf %s", root);
+    run(tc, "mkdir -p %s", root);
+    run(tc, "cp -pr %s/* %s", src_root, root);
+    run(tc, "chmod -R u+w %s", root);
+    run(tc, "chmod -R a-w %s/sys", root);
+
+    r = ncf_init(&ncf, root);
+    CuAssertIntEquals(tc, 0, r);
+}
+
+void teardown(ATTRIBUTE_UNUSED CuTest *tc) {
+    ncf_close(ncf);
+    free(root);
+    root = NULL;
+}
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
+/* vim: set ts=4 sw=4 et: */
diff --git a/tests/tutil.h b/tests/tutil.h
new file mode 100644
index 0000000..035f829
--- /dev/null
+++ b/tests/tutil.h
@@ -0,0 +1,87 @@
+/*
+ * tutil.h: Global utility functions for automated testing of netcf
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: David Lutterkort <lutter at redhat.com>
+ */
+
+#ifndef _TUTIL_H
+#define _TUTIL_H
+
+#include <config.h>
+#include <libxml/tree.h>
+
+#include "internal.h"
+#include "cutest.h"
+#include "safe-alloc.h"
+
+#include "tutil.h"
+
+#define die(msg)                                                    \
+    do {                                                            \
+        fprintf(stderr, "%s:%d: Fatal error: %s\n", __FILE__, __LINE__, msg); \
+        exit(EXIT_FAILURE);                                         \
+    } while(0)
+
+/* Write a string of FORMAT, ... to STRP */
+void format_error(char **strp, const char *format, ...);
+
+/* Read data from file, return pointer to result */
+char *read_test_file(CuTest *tc, const char *relpath);
+
+/* Assert that the ncf instance is in the NOERROR-state */
+void assert_ncf_no_error(CuTest *tc);
+
+/* Parse the xml in XML_STR and return a xmlDocPtr to the parsed structure */
+xmlDocPtr parse_xml(const char *xml_str);
+
+/* Check that all attributes of N1 and N2 are equal */
+int xml_attrs_subset(xmlNodePtr n1, xmlNodePtr n2, char **err);
+
+/* Get the next element of type XML_ELEMENT_NODE following N, or NULL */
+xmlNodePtr xml_next_element(xmlNodePtr n);
+
+/* Check that the nodes N1 and N2 are alike (including their children) */
+int xml_nodes_equal(xmlNodePtr n1, xmlNodePtr n2, char **err);
+
+/* Assert the the EXP (expected) and ACT (actual) XML text blobs are alike.
+ * FNAME is used for error reporting in the case that they are not alike. */
+void assert_xml_equals(CuTest *tc, const char *fname,
+                       char *exp, char *act);
+
+/* Run command formed by FORMAT, raise an error if the the command did not
+ * exit with status 0 */
+void run(CuTest *tc, const char *format, ...);
+
+/* Setup test directories */
+void setup(CuTest *tc);
+
+/* Close and free all resources */
+void teardown(ATTRIBUTE_UNUSED CuTest *tc);
+
+#endif
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
+/* vim: set ts=4 sw=4 et: */
-- 
1.6.2



More information about the netcf-devel mailing list