Add a IfNotCrossAppliance prereq for tests, so a test using it can only
be run when the appliance is a copy of the running host system; this can
help marking tests which run stuff (usually built in the host) inside
the appliance.
---
generator/tests_c_api.ml | 14 +++++++++++++-
generator/types.ml | 5 +++++
tests/c-api/tests-main.c | 39 +++++++++++++++++++++++++++++++++++++++
tests/c-api/tests.h | 1 +
4 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 43a99e3..17a6af9 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -67,7 +67,7 @@ let rec generate_c_api_tests () =
fun { tests = tests } ->
let seqs = filter_map (
function
- | (_, (Always|IfAvailable _), test, cleanup) ->
+ | (_, (Always|IfAvailable _|IfNotCrossAppliance), test, cleanup) ->
Some (seq_of_test test @ cleanup)
| (_, Disabled, _, _) -> None
) tests in
@@ -151,6 +151,15 @@ static int
pr "\n"
in
+ let utsname_test () =
+ pr " if (using_cross_appliance ()) {\n";
+ pr " skipped (\"%s\", \"cannot run when appliance and host are
different\");\n"
+ test_name;
+ pr " return 0;\n";
+ pr " }\n";
+ pr "\n"
+ in
+
(match optional with
| Some group -> group_test group
| None -> ()
@@ -165,6 +174,9 @@ static int
generate_one_test_body name i test_name init cleanup
| Always ->
generate_one_test_body name i test_name init cleanup
+ | IfNotCrossAppliance ->
+ utsname_test ();
+ generate_one_test_body name i test_name init cleanup
);
pr "}\n";
diff --git a/generator/types.ml b/generator/types.ml
index 63aa235..59aa1a0 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -253,6 +253,11 @@ and c_api_test_prereq =
(* Run the test only if 'string' is available in the daemon. *)
| IfAvailable of string
+ (* Run the test when the appliance and the OS differ - for example,
+ * when using a fixed appliance created in a different OS/distribution.
+ *)
+ | IfNotCrossAppliance
+
(* Some initial scenarios for testing. *)
and c_api_test_init =
(* Do nothing, block devices could contain random stuff including
diff --git a/tests/c-api/tests-main.c b/tests/c-api/tests-main.c
index e81e15e..6f4816f 100644
--- a/tests/c-api/tests-main.c
+++ b/tests/c-api/tests-main.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
+#include <sys/utsname.h>
#include <pcre.h>
@@ -38,6 +39,8 @@
#include "tests.h"
+static int is_cross_appliance;
+
int
init_none (guestfs_h *g)
{
@@ -395,6 +398,12 @@ substitute_srcdir (const char *path)
return ret;
}
+int
+using_cross_appliance (void)
+{
+ return is_cross_appliance;
+}
+
static void
next_test (guestfs_h *g, size_t test_num, const char *test_name)
{
@@ -475,6 +484,35 @@ create_handle (void)
return g;
}
+static int
+check_cross_appliance (guestfs_h *g)
+{
+ struct utsname host;
+ CLEANUP_FREE_UTSNAME struct guestfs_utsname *appliance = NULL;
+ int r;
+ struct guestfs_utsname host_utsname;
+
+ r = uname (&host);
+ if (r == -1) {
+ fprintf (stderr, "call to uname failed\n");
+ exit (EXIT_FAILURE);
+ }
+
+ appliance = guestfs_utsname (g);
+ if (appliance == NULL) {
+ fprintf (stderr, "call to guestfs_utsname failed: %d, %s\n",
+ guestfs_last_errno (g), guestfs_last_error (g));
+ exit (EXIT_FAILURE);
+ }
+
+ host_utsname.uts_sysname = host.sysname;
+ host_utsname.uts_release = host.release;
+ host_utsname.uts_version = host.version;
+ host_utsname.uts_machine = host.machine;
+
+ return guestfs_compare_utsname (appliance, &host_utsname);
+}
+
static size_t
perform_tests (guestfs_h *g)
{
@@ -505,6 +543,7 @@ main (int argc, char *argv[])
no_test_warnings ();
g = create_handle ();
+ is_cross_appliance = check_cross_appliance (g);
nr_failed = perform_tests (g);
diff --git a/tests/c-api/tests.h b/tests/c-api/tests.h
index 7959570..12fd316 100644
--- a/tests/c-api/tests.h
+++ b/tests/c-api/tests.h
@@ -43,6 +43,7 @@ extern int check_file_md5 (const char *ret, const char *filename);
extern const char *get_key (char **hash, const char *key);
extern int check_hash (char **ret, const char *key, const char *expected);
extern int match_re (const char *str, const char *pattern);
+extern int using_cross_appliance (void);
extern char *substitute_srcdir (const char *path);
extern void skipped (const char *test_name, const char *fs, ...) __attribute__((format
(printf,2,3)));
--
1.9.3