Create a new TestRunOrUnsupported test type, which represents a test
sequence where a failure with ENOTSUP in the last command only marks the
test as skipped. To be used mainly when testing features available only
with some versions of helper tools used in the appliance, for example.
---
generator/tests_c_api.ml | 26 ++++++++++++++++++++++++--
generator/types.ml | 5 +++++
generator/utils.ml | 3 ++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 8116e9e..7cf3763 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -41,6 +41,7 @@ let rec generate_c_api_tests () =
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <errno.h>
#include \"guestfs.h\"
#include \"guestfs-internal-frontend.h\"
@@ -335,6 +336,23 @@ and generate_test_perform name i test_name test =
let seq, last = get_seq_last seq in
List.iter (generate_test_command_call test_name) seq;
generate_test_command_call test_name ~expect_error:true last
+
+ | TestRunOrUnsupported seq ->
+ pr " /* TestRunOrUnsupported for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call test_name ~expect_error:true ~do_return:false
~ret:"ret" last;
+ pr " if (ret == -1) {\n";
+ pr " if (guestfs_last_errno (g) == ENOTSUP) {\n";
+ pr " skipped (\"%s\", \"last command %%s returned
ENOTSUP\", \"%s\");\n"
+ test_name (List.hd last);
+ pr " return 0;\n";
+ pr " }\n";
+ pr " fprintf (stderr, \"%%s: test failed: expected last command %%s to
pass or fail with ENOTSUP, but it failed with %%d: %%s\\n\",\n";
+ pr " \"%s\", \"%s\", guestfs_last_errno (g),
guestfs_last_error (g));\n"
+ test_name (List.hd last);
+ pr " return -1;\n";
+ pr " }\n"
);
pr " return 0;\n";
@@ -354,7 +372,7 @@ and generate_test_cleanup test_name cleanup =
* variable named 'ret'. If you expect to get an error then you should
* set expect_error:true.
*)
-and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
+and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test ?ret
test_name cmd=
let ret = match ret with Some ret -> ret | None -> gensym "ret" in
let name, args =
@@ -561,7 +579,11 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret
test_name cmd=
if expect_error then
pr " guestfs_pop_error_handler (g);\n";
- (match errcode_of_ret style_ret, expect_error with
+ let ret_errcode =
+ if do_return then errcode_of_ret style_ret
+ else `CannotReturnError in
+
+ (match ret_errcode, expect_error with
| `CannotReturnError, _ -> ()
| `ErrorIsMinusOne, false ->
pr " if (%s == -1)\n" ret;
diff --git a/generator/types.ml b/generator/types.ml
index 7fa65c9..b2f8724 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -245,6 +245,11 @@ and c_api_test =
*)
| TestLastFail of seq
+ (* Run the command sequence and expect either nothing to fail,
+ * or that the last command only can fail with ENOTSUP.
+ *)
+ | TestRunOrUnsupported of seq
+
(* Test prerequisites. *)
and c_api_test_prereq =
(* Test always runs. *)
diff --git a/generator/utils.ml b/generator/utils.ml
index 6eff6ad..34edf9d 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -266,7 +266,8 @@ let seq_of_test = function
| TestResultDevice (s, _)
| TestResultTrue s
| TestResultFalse s
- | TestLastFail s -> s
+ | TestLastFail s
+ | TestRunOrUnsupported s -> s
let c_quote str =
let str = replace_str str "\\" "\\\\" in
--
2.5.0