These are unit tests of basic features of the rules compiler, such as
evaluation of expressions and embedding C code.
---
.gitignore | 4 ++
generator/main.ml | 6 ++-
inspection/Makefile.am | 35 +++++++++++++-
inspection/test-harness.c | 51 ++++++++++++++++++++
inspection/test1.rules | 80 ++++++++++++++++++++++++++++++++
inspection/test2.rules | 116 ++++++++++++++++++++++++++++++++++++++++++++++
po/POTFILES | 3 ++
7 files changed, 293 insertions(+), 2 deletions(-)
create mode 100644 inspection/test-harness.c
create mode 100644 inspection/test1.rules
create mode 100644 inspection/test2.rules
diff --git a/.gitignore b/.gitignore
index 0106ec3..8188318 100644
--- a/.gitignore
+++ b/.gitignore
@@ -255,6 +255,10 @@ Makefile.in
/inspection/guestfs-inspection.8
/inspection/rules.c
/inspection/stamp-guestfs-inspection.pod
+/inspection/test1
+/inspection/test1.c
+/inspection/test2
+/inspection/test2.c
/inspector/actual-*.xml
/inspector/stamp-virt-inspector.pod
/inspector/test-xmllint.sh
diff --git a/generator/main.ml b/generator/main.ml
index 7625852..de325c6 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -212,7 +212,11 @@ Run it from the top source directory using the command
output_to "customize/customize-synopsis.pod"
generate_customize_synopsis_pod;
output_to "customize/customize-options.pod" generate_customize_options_pod;
- (* Run the rules compiler to generate inspection rules. *)
+ (* Run the rules compiler to generate test cases and inspection rules. *)
+ output_to "inspection/test1.c"
+ (Rules_compiler.compile "inspection/test1.rules");
+ output_to "inspection/test2.c"
+ (Rules_compiler.compile "inspection/test2.rules");
output_to "inspection/rules.c"
(Rules_compiler.compile "inspection/inspection.rules");
diff --git a/inspection/Makefile.am b/inspection/Makefile.am
index 9227249..c1be08a 100644
--- a/inspection/Makefile.am
+++ b/inspection/Makefile.am
@@ -18,7 +18,9 @@
include $(top_srcdir)/subdir-rules.mk
generator_built = \
- rules.c
+ rules.c \
+ test1.c \
+ test2.c
BUILT_SOURCES = \
$(generator_built)
@@ -90,3 +92,34 @@ stamp-guestfs-inspection.pod: guestfs-inspection.pod
--license GPLv2+ \
$<
touch $@
+
+# Tests.
+
+TESTS = test1 test2
+check_PROGRAMS = $(TESTS)
+
+test1_SOURCES = \
+ $(SHARED_SOURCE_FILES) \
+ facts.c \
+ inspection.h \
+ stringsbuf.c \
+ stringsbuf.h \
+ test-harness.c \
+ test1.c
+
+test1_LDADD = $(guestfs_inspection_LDADD)
+test1_CPPFLAGS = $(guestfs_inspection_CPPFLAGS)
+test1_CFLAGS = $(guestfs_inspection_CFLAGS)
+
+test2_SOURCES = \
+ $(SHARED_SOURCE_FILES) \
+ facts.c \
+ inspection.h \
+ stringsbuf.c \
+ stringsbuf.h \
+ test-harness.c \
+ test2.c
+
+test2_LDADD = $(guestfs_inspection_LDADD)
+test2_CPPFLAGS = $(guestfs_inspection_CPPFLAGS)
+test2_CFLAGS = $(guestfs_inspection_CFLAGS)
diff --git a/inspection/test-harness.c b/inspection/test-harness.c
new file mode 100644
index 0000000..cfe39df
--- /dev/null
+++ b/inspection/test-harness.c
@@ -0,0 +1,51 @@
+/* guestfs-inspection tests
+ * Copyright (C) 2009-2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "inspection.h"
+
+int verbose = 1;
+
+int
+main (int argc, char *argv[])
+{
+ /* Run the rules. */
+ rules ();
+
+ /* For debugging. */
+ print_true_facts ();
+
+ /* The tests should contain a TestOK rule which verifies that all
+ * true and false facts are what we expect. So we just need to
+ * check that TestOK is true and we're done.
+ */
+ CLEANUP_FREE fact *f = create_fact ("TestOK", NULL);
+ if (!is_fact (true, f)) {
+ fprintf (stderr, "%s: test failed, see debugging information above\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/inspection/test1.rules b/inspection/test1.rules
new file mode 100644
index 0000000..416ccd2
--- /dev/null
+++ b/inspection/test1.rules
@@ -0,0 +1,80 @@
+/* Libguestfs inspection rules unit test -*- prolog -*-
+ * Copyright (C) 2009-2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+Filesystem(fs) :-
+ (fs)*={{
+ const char *fses[] = { "/dev/sda1", "/dev/sda2",
"/dev/sda3", NULL };
+ size_t i;
+ for (i = 0; fses[i] != NULL; ++i)
+ set_fs (fses[i]);
+ return 0;
+ }}.
+
+File("/dev/sda1", "/etc/fstab").
+File("/dev/sda1", "/etc/debian_version").
+File("/dev/sda2", "/etc/fstab").
+File("/dev/sda2", "/etc/redhat-release").
+File("/dev/sda2", "/etc/fedora-release").
+File("/dev/sda3", "/etc/fstab").
+File("/dev/sda3", "/etc/fedora-release") :- false.
+File("/dev/sda3", "/etc/redhat-release").
+
+Symlink("/dev/sda1", "/bin").
+
+Directory("/dev/sda1", "/lib").
+Directory("/dev/sda1", "/etc").
+Directory("/dev/sda2", "/bin").
+Directory("/dev/sda2", "/etc").
+Directory("/dev/sda2", "/lib").
+Directory("/dev/sda3", "/bin").
+Directory("/dev/sda3", "/etc").
+Directory("/dev/sda3", "/lib").
+
+UnixRoot(fs) :-
+ Filesystem(fs),
+ (Directory(fs, "/bin"); Symlink(fs, "/bin")),
+ (File(fs, "/etc/fstab"); Symlink(fs, "/etc/fstab")),
+ (Directory(fs, "/lib"); Symlink(fs, "/lib")).
+
+Distro(rootfs, "RHEL") :-
+ UnixRoot(rootfs),
+ File(rootfs, "/etc/redhat-release"),
+ ! File(rootfs, "/etc/fedora-release").
+
+Distro(rootfs, "Fedora") :-
+ UnixRoot(rootfs),
+ File(rootfs, "/etc/fedora-release").
+
+Distro(rootfs, "Debian") :-
+ UnixRoot(rootfs),
+ File(rootfs, "/etc/debian_version").
+
+ProductName(rootfs, "Fedora", product_name) :-
+ Filesystem(rootfs),
+ Distro(rootfs, "Fedora"),
+ (product_name)={{
+ set_product_name ("Fedora release 23 (Twenty Three)");
+ return 0;
+ }}.
+
+/* This rule is checked by the test harness. */
+TestOK :-
+ Distro("/dev/sda1", "Debian"),
+ Distro("/dev/sda2", "Fedora"),
+ Distro("/dev/sda3", "RHEL"),
+ ProductName("/dev/sda2", "Fedora", "Fedora release 23
(Twenty Three)").
diff --git a/inspection/test2.rules b/inspection/test2.rules
new file mode 100644
index 0000000..09bc062
--- /dev/null
+++ b/inspection/test2.rules
@@ -0,0 +1,116 @@
+/* Libguestfs inspection rules unit test -*- prolog -*-
+ * Copyright (C) 2009-2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* Test false, true expressions. */
+TestTrue1.
+TestTrue2 :- true.
+TestFalse :- false.
+
+/* Basic boolean expressions. */
+TestAnd1 :- true, true.
+TestAnd2 :- true, false.
+TestAnd3 :- false, false.
+TestAnd4 :- false, true.
+TestOr1 :- true; true.
+TestOr2 :- true; false.
+TestOr3 :- false; false.
+TestOr4 :- false; true.
+TestNot1 :- !TestTrue1.
+TestNot2 :- !TestFalse.
+
+/* Precedence of AND and OR operators. */
+TestPrec :- true; true, false. /* should be parsed as true; (true, false) */
+
+/* Parentheses. */
+TestParen1 :- (true, true); false.
+TestParen2 :- false; (true, true).
+TestParen3 :- (true; false), true.
+TestParen4 :- true, (true; false).
+
+/* Cartesian product. */
+TestCartesian(x,y) :- true.
+
+/* Boolean code. */
+TestCTrue :- {{ return 1; }}.
+TestCFalse :- {{ return 0; }}.
+
+/* Assignment code. */
+TestCAssign1(x) :- (x)={{ set_x ("123"); return 0; }}.
+TestCAssign2(x,y) :- (x,y)={{ set_x_y ("123", "456"); return 0; }}.
+TestCAssign3(x,y,z) :- (x,y,z)={{ set_x_y_z ("123", "456",
"789"); return 0; }}.
+
+/* Assignment code for lists. */
+TestCListAssign1(x) :-
+ (x)*={{ /* no assignments */ return 0; }}.
+TestCListAssign2(x) :-
+ (x)*={{ set_x ("123"); return 0; }}.
+TestCListAssign3(x) :-
+ (x)*={{ set_x ("123"); set_x ("456"); return 0; }}.
+TestCListAssign4(x,y) :-
+ (x,y)*={{ /* no assignments */ return 0; }}.
+TestCListAssign5(x,y) :-
+ (x,y)*={{ set_x_y ("123", "456"); return 0; }}.
+TestCListAssign6(x,y) :-
+ (x,y)*={{ set_x_y ("123", "456"); set_x_y ("456",
"789"); return 0; }}.
+
+/* These assignments only differ in a small amount of checking code. */
+TestCListAssign7(x,y) :-
+ (x,y)?={{ /* no assignments */ return 0; }}.
+TestCListAssign8(x,y) :-
+ (x,y)?={{ set_x_y ("123", "456"); return 0; }}.
+TestCListAssign9(x,y) :-
+ (x,y)+={{ set_x_y ("123", "456"); return 0; }}.
+TestCListAssign10(x,y) :-
+ (x,y)+={{ set_x_y ("123", "456"); set_x_y ("456",
"789"); return 0; }}.
+
+/* Check no clashes in generated code with commonly used variables. */
+TestCAssignClash(i,j,fact,verbose,args,env) :-
+ (i,j,fact,verbose,args,env)={{
+ set_i_j_fact_verbose_args_env ("1", "2", "3",
"4", "5", "6");
+ return 0;
+ }}.
+
+/* This rule is checked by the test harness. */
+TestOK :-
+ TestTrue1, TestTrue2, !TestFalse,
+ TestAnd1, !TestAnd2, !TestAnd3, !TestAnd4,
+ TestOr1, TestOr2, !TestOr3, TestOr4,
+ !TestNot1, TestNot2,
+ TestPrec,
+ TestParen1, TestParen2, TestParen3, TestParen4,
+ TestCartesian("123", "123"),
+ TestCartesian("123", "456"),
+ TestCartesian("123", "789"),
+ TestCartesian("456", "123"), /* etc etc */
+ TestCTrue, !TestCFalse,
+ TestCAssign1("123"), TestCAssign2("123", "456"),
+ TestCAssign3("123", "456", "789"),
+ /* no assignments to TestCListAssign1 */
+ TestCListAssign2("123"),
+ TestCListAssign3("123"),
+ TestCListAssign3("456"),
+ /* no assignments to TestCListAssign4 */
+ TestCListAssign5("123", "456"),
+ TestCListAssign6("123", "456"),
+ TestCListAssign6("456", "789"),
+ /* no assignments to TestCListAssign7 */
+ TestCListAssign8("123", "456"),
+ TestCListAssign9("123", "456"),
+ TestCListAssign10("123", "456"),
+ TestCListAssign10("456", "789"),
+ TestCAssignClash("1", "2", "3", "4",
"5", "6").
diff --git a/po/POTFILES b/po/POTFILES
index b6332f6..afdc75f 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -263,6 +263,9 @@ inspection/facts.c
inspection/inspection.c
inspection/mount.c
inspection/stringsbuf.c
+inspection/test-harness.c
+inspection/test1.c
+inspection/test2.c
inspector/inspector.c
java/com_redhat_et_libguestfs_GuestFS.c
lua/lua-guestfs.c
--
2.5.0