mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
tests/c-api: Various code refactorings.
- Don't use fixed names for the disks. This will allow us to parallelize this test. - Add a new "GETKEY:<key>" String parameter which can retrieve keys from the handle. The temporary disk names are stored as keys. - Don't test the close callback. However this uses the close callback mechanism to delete the temporary disks, and in any case close callbacks are well tested by the language binding tests. - The generated code now produces a static array of tests (instead of a 'perform_tests' function), making it possible to parallelize.
This commit is contained in:
@@ -2566,11 +2566,11 @@ data." };
|
||||
style = RString "format", [String "filename"], [];
|
||||
tests = [
|
||||
InitEmpty, Always, TestResultString (
|
||||
[["disk_format"; "test1.img"]], "raw");
|
||||
[["disk_format"; "GETKEY:test1"]], "raw");
|
||||
InitEmpty, Always, TestResultString (
|
||||
[["disk_format"; "test2.img"]], "raw");
|
||||
[["disk_format"; "GETKEY:test2"]], "raw");
|
||||
InitEmpty, Always, TestResultString (
|
||||
[["disk_format"; "test3.img"]], "raw");
|
||||
[["disk_format"; "GETKEY:test3"]], "raw");
|
||||
];
|
||||
shortdesc = "detect the disk format of a disk image";
|
||||
longdesc = "\
|
||||
@@ -2588,11 +2588,11 @@ See also: L<guestfs(3)/DISK IMAGE FORMATS>" };
|
||||
style = RInt64 "size", [String "filename"], [];
|
||||
tests = [
|
||||
InitEmpty, Always, TestResult (
|
||||
[["disk_virtual_size"; "test1.img"]], "ret == UINT64_C (524288000)");
|
||||
[["disk_virtual_size"; "GETKEY:test1"]], "ret == UINT64_C (524288000)");
|
||||
InitEmpty, Always, TestResult (
|
||||
[["disk_virtual_size"; "test2.img"]], "ret == UINT64_C (52428800)");
|
||||
[["disk_virtual_size"; "GETKEY:test2"]], "ret == UINT64_C (52428800)");
|
||||
InitEmpty, Always, TestResult (
|
||||
[["disk_virtual_size"; "test3.img"]], "ret == UINT64_C (10485760)");
|
||||
[["disk_virtual_size"; "GETKEY:test3"]], "ret == UINT64_C (10485760)");
|
||||
];
|
||||
shortdesc = "return virtual size of a disk";
|
||||
longdesc = "\
|
||||
@@ -2607,11 +2607,11 @@ circumstances. See L<guestfs(3)/CVE-2010-3851>." };
|
||||
style = RBool "backingfile", [String "filename"], [];
|
||||
tests = [
|
||||
InitEmpty, Always, TestResultFalse (
|
||||
[["disk_has_backing_file"; "test1.img"]]);
|
||||
[["disk_has_backing_file"; "GETKEY:test1"]]);
|
||||
InitEmpty, Always, TestResultFalse (
|
||||
[["disk_has_backing_file"; "test2.img"]]);
|
||||
[["disk_has_backing_file"; "GETKEY:test2"]]);
|
||||
InitEmpty, Always, TestResultFalse (
|
||||
[["disk_has_backing_file"; "test3.img"]]);
|
||||
[["disk_has_backing_file"; "GETKEY:test3"]]);
|
||||
];
|
||||
shortdesc = "return whether disk has a backing file";
|
||||
longdesc = "\
|
||||
|
||||
@@ -99,31 +99,12 @@ let rec generate_tests () =
|
||||
let nr_tests = List.length test_names in
|
||||
pr "size_t nr_tests = %d;\n" nr_tests;
|
||||
pr "\n";
|
||||
|
||||
pr "\
|
||||
size_t
|
||||
perform_tests (guestfs_h *g)
|
||||
{
|
||||
size_t test_num = 0;
|
||||
size_t nr_failed = 0;
|
||||
|
||||
";
|
||||
|
||||
iteri (
|
||||
fun i test_name ->
|
||||
pr " test_num++;\n";
|
||||
pr " next_test (g, test_num, nr_tests, \"%s\");\n" test_name;
|
||||
pr " if (%s (g) == -1) {\n" test_name;
|
||||
pr " printf (\"FAIL: %%s\\n\", \"%s\");\n" test_name;
|
||||
pr " nr_failed++;\n";
|
||||
pr " }\n";
|
||||
pr "struct test tests[%d] = {\n" nr_tests;
|
||||
List.iter (
|
||||
fun name ->
|
||||
pr " { .name = \"%s\", .test_fn = %s },\n" (c_quote name) name
|
||||
) test_names;
|
||||
|
||||
pr "\
|
||||
|
||||
return nr_failed;
|
||||
}
|
||||
"
|
||||
pr "};\n"
|
||||
|
||||
and generate_one_test name optional i (init, prereq, test) =
|
||||
let test_name = sprintf "test_%s_%d" name i in
|
||||
@@ -349,6 +330,10 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
|
||||
List.iter (
|
||||
function
|
||||
| OptString _, "NULL", _ -> ()
|
||||
| String _, arg, sym
|
||||
when String.length arg >= 7 && String.sub arg 0 7 = "GETKEY:" ->
|
||||
pr " const char *%s = guestfs_get_private (g, \"%s\");\n"
|
||||
sym (c_quote (String.sub arg 7 (String.length arg - 7)))
|
||||
| Pathname _, arg, sym
|
||||
| Device _, arg, sym
|
||||
| Mountable _, arg, sym
|
||||
|
||||
@@ -162,14 +162,6 @@ print_strings (char *const *argv)
|
||||
printf ("\t%s\n", argv[argc]);
|
||||
}
|
||||
|
||||
static void
|
||||
incr (guestfs_h *g, void *iv, uint64_t event, int eh, int flags,
|
||||
const char *buf, size_t buf_len, const uint64_t *array, size_t array_len)
|
||||
{
|
||||
int *i = (int *) iv;
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
static int compare_lists (char **, char **, int (*) (const char *, const char *));
|
||||
|
||||
/* Compare 'ret' to the string list that follows. */
|
||||
@@ -393,9 +385,8 @@ substitute_srcdir (const char *path)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
next_test (guestfs_h *g, size_t test_num, size_t nr_tests,
|
||||
const char *test_name)
|
||||
static void
|
||||
next_test (guestfs_h *g, size_t test_num, const char *test_name)
|
||||
{
|
||||
if (guestfs_get_verbose (g))
|
||||
printf ("-------------------------------------------------------------------------------\n");
|
||||
@@ -418,90 +409,82 @@ skipped (const char *test_name, const char *fs, ...)
|
||||
test_name, reason);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
static void
|
||||
delete_file (guestfs_h *g, void *filenamev,
|
||||
uint64_t event, int eh, int flags,
|
||||
const char *buf, size_t buf_len,
|
||||
const uint64_t *array, size_t array_len)
|
||||
{
|
||||
const char *filename;
|
||||
char *filename = filenamev;
|
||||
|
||||
unlink (filename);
|
||||
free (filename);
|
||||
}
|
||||
|
||||
static void
|
||||
add_disk (guestfs_h *g, const char *key, off_t size)
|
||||
{
|
||||
CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g);
|
||||
char *filename;
|
||||
int fd;
|
||||
size_t nr_failed ;
|
||||
int close_sentinel = 1;
|
||||
|
||||
if (asprintf (&filename, "%s/diskXXXXXX", tmpdir) == -1) {
|
||||
perror ("asprintf");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fd = mkostemp (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
perror ("mkstemp");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (ftruncate (fd, size) == -1) {
|
||||
perror ("ftruncate");
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (close (fd) == -1) {
|
||||
perror (filename);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (guestfs_add_drive (g, filename) == -1) {
|
||||
printf ("FAIL: guestfs_add_drive %s\n", filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (guestfs_set_event_callback (g, delete_file,
|
||||
GUESTFS_EVENT_CLOSE, 0, filename) == -1) {
|
||||
printf ("FAIL: guestfs_set_event_callback (GUESTFS_EVENT_CLOSE)\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Record the real filename in the named private key. Tests can
|
||||
* retrieve these names using the magic "GETKEY:<key>" String
|
||||
* parameter.
|
||||
*/
|
||||
guestfs_set_private (g, key, filename);
|
||||
}
|
||||
|
||||
/* Create the handle, with attached disks. */
|
||||
static guestfs_h *
|
||||
create_handle (void)
|
||||
{
|
||||
guestfs_h *g;
|
||||
|
||||
setbuf (stdout, NULL);
|
||||
|
||||
no_test_warnings ();
|
||||
|
||||
g = guestfs_create ();
|
||||
if (g == NULL) {
|
||||
printf ("FAIL: guestfs_create\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
filename = "test1.img";
|
||||
fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC, 0666);
|
||||
if (fd == -1) {
|
||||
perror (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (ftruncate (fd, 524288000) == -1) {
|
||||
perror ("ftruncate");
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (close (fd) == -1) {
|
||||
perror (filename);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (guestfs_add_drive (g, filename) == -1) {
|
||||
printf ("FAIL: guestfs_add_drive %s\n", filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
add_disk (g, "test1", 524288000);
|
||||
|
||||
filename = "test2.img";
|
||||
fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC, 0666);
|
||||
if (fd == -1) {
|
||||
perror (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (ftruncate (fd, 52428800) == -1) {
|
||||
perror ("ftruncate");
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (close (fd) == -1) {
|
||||
perror (filename);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (guestfs_add_drive (g, filename) == -1) {
|
||||
printf ("FAIL: guestfs_add_drive %s\n", filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
add_disk (g, "test2", 52428800);
|
||||
|
||||
filename = "test3.img";
|
||||
fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC, 0666);
|
||||
if (fd == -1) {
|
||||
perror (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (ftruncate (fd, 10485760) == -1) {
|
||||
perror ("ftruncate");
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (close (fd) == -1) {
|
||||
perror (filename);
|
||||
unlink (filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (guestfs_add_drive (g, filename) == -1) {
|
||||
printf ("FAIL: guestfs_add_drive %s\n", filename);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
add_disk (g, "test3", 10485760);
|
||||
|
||||
if (guestfs_add_drive_ro (g, "../data/test.iso") == -1) {
|
||||
printf ("FAIL: guestfs_add_drive_ro ../data/test.iso\n");
|
||||
@@ -529,21 +512,43 @@ main (int argc, char *argv[])
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nr_failed = perform_tests (g);
|
||||
return g;
|
||||
}
|
||||
|
||||
/* Check close callback is called. */
|
||||
guestfs_set_event_callback (g, incr, GUESTFS_EVENT_CLOSE, 0, &close_sentinel);
|
||||
static size_t
|
||||
perform_tests (guestfs_h *g)
|
||||
{
|
||||
size_t test_num;
|
||||
size_t nr_failed = 0;
|
||||
struct test *t;
|
||||
|
||||
guestfs_close (g);
|
||||
|
||||
if (close_sentinel != 2) {
|
||||
fprintf (stderr, "FAIL: close callback was not called\n");
|
||||
exit (EXIT_FAILURE);
|
||||
for (test_num = 0; test_num < nr_tests; ++test_num) {
|
||||
t = &tests[test_num];
|
||||
next_test (g, test_num, t->name);
|
||||
if (t->test_fn (g) == -1) {
|
||||
printf ("FAIL: %s\n", t->name);
|
||||
nr_failed++;
|
||||
}
|
||||
}
|
||||
|
||||
unlink ("test1.img");
|
||||
unlink ("test2.img");
|
||||
unlink ("test3.img");
|
||||
return nr_failed;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
size_t nr_failed;
|
||||
guestfs_h *g;
|
||||
|
||||
setbuf (stdout, NULL);
|
||||
|
||||
no_test_warnings ();
|
||||
|
||||
g = create_handle ();
|
||||
|
||||
nr_failed = perform_tests (g);
|
||||
|
||||
guestfs_close (g);
|
||||
|
||||
if (nr_failed > 0) {
|
||||
printf ("***** %zu / %zu tests FAILED *****\n", nr_failed, nr_tests);
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
#ifndef TESTS_H_
|
||||
#define TESTS_H_
|
||||
|
||||
struct test {
|
||||
int (*test_fn) (guestfs_h *g);
|
||||
const char *name;
|
||||
};
|
||||
extern struct test tests[];
|
||||
extern size_t nr_tests;
|
||||
|
||||
extern int init_none (guestfs_h *g);
|
||||
@@ -29,7 +34,6 @@ extern int init_basic_fs (guestfs_h *g);
|
||||
extern int init_basic_fs_on_lvm (guestfs_h *g);
|
||||
extern int init_iso_fs (guestfs_h *g);
|
||||
extern int init_scratch_fs (guestfs_h *g);
|
||||
extern size_t perform_tests (guestfs_h *g);
|
||||
extern void no_test_warnings (void);
|
||||
extern int is_string_list (char **ret, size_t n, ...);
|
||||
extern int is_device_list (char **ret, size_t n, ...);
|
||||
@@ -40,7 +44,6 @@ 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 char *substitute_srcdir (const char *path);
|
||||
extern void next_test (guestfs_h *g, size_t test_num, size_t nr_tests, const char *test_name);
|
||||
extern void skipped (const char *test_name, const char *fs, ...) __attribute__((format (printf,2,3)));
|
||||
|
||||
#endif /* TESTS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user