mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
tests: Split C API tests into regular C file + generated tests file.
This commit is contained in:
@@ -39,251 +39,18 @@ let rec generate_tests () =
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <pcre.h>
|
||||
|
||||
#include \"guestfs.h\"
|
||||
#include \"guestfs-internal-frontend.h\"
|
||||
|
||||
static guestfs_h *g;
|
||||
|
||||
/* FIXME: nearly identical code appears in fish.c */
|
||||
static void
|
||||
print_strings (char *const *argv)
|
||||
{
|
||||
size_t argc;
|
||||
|
||||
for (argc = 0; argv[argc] != NULL; ++argc)
|
||||
printf (\"\\t%%s\\n\", argv[argc]);
|
||||
}
|
||||
|
||||
static void
|
||||
incr (guestfs_h *g, void *iv)
|
||||
{
|
||||
int *i = (int *) iv;
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
static int compare_lists (char **, char **, int (*) (const char *, const char *));
|
||||
static int compare_devices (const char *, const char *);
|
||||
|
||||
/* Compare 'ret' to the string list that follows. */
|
||||
static int
|
||||
is_string_list (char **ret, size_t n, ...)
|
||||
{
|
||||
CLEANUP_FREE /* sic */ char **expected = malloc ((n+1) * sizeof (char *));
|
||||
size_t i;
|
||||
va_list args;
|
||||
|
||||
va_start (args, n);
|
||||
for (i = 0; i < n; ++i)
|
||||
expected[i] = va_arg (args, char *);
|
||||
expected[n] = NULL;
|
||||
va_end (args);
|
||||
return compare_lists (ret, expected, strcmp);
|
||||
}
|
||||
|
||||
/* Compare 'ret' to the device list that follows. */
|
||||
static int
|
||||
is_device_list (char **ret, size_t n, ...)
|
||||
{
|
||||
CLEANUP_FREE /* sic */ char **expected = malloc ((n+1) * sizeof (char *));
|
||||
size_t i;
|
||||
va_list args;
|
||||
|
||||
va_start (args, n);
|
||||
for (i = 0; i < n; ++i)
|
||||
expected[i] = va_arg (args, char *);
|
||||
expected[n] = NULL;
|
||||
va_end (args);
|
||||
return compare_lists (ret, expected, compare_devices);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_lists (char **ret, char **expected,
|
||||
int (*compare) (const char *, const char *))
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; ret[i] != NULL; ++i) {
|
||||
if (!expected[i]) {
|
||||
fprintf (stderr, \"test failed: returned list is too long\\n\");
|
||||
goto fail;
|
||||
}
|
||||
if (compare (ret[i], expected[i]) != 0) {
|
||||
fprintf (stderr, \"test failed: elements differ at position %%zu\\n\", i);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (expected[i]) {
|
||||
fprintf (stderr, \"test failed: returned list is too short\\n\");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 1; /* test expecting true for OK */
|
||||
|
||||
fail:
|
||||
fprintf (stderr, \"returned list was:\\n\");
|
||||
print_strings (ret);
|
||||
fprintf (stderr, \"expected list was:\\n\");
|
||||
print_strings (expected);
|
||||
return 0; /* test expecting false for failure */
|
||||
}
|
||||
|
||||
/* Compare two device names, ignoring hd/sd/vd */
|
||||
static int
|
||||
compare_devices (const char *dev1, const char *dev2)
|
||||
{
|
||||
CLEANUP_FREE char *copy1 = NULL, *copy2 = NULL;
|
||||
|
||||
assert (dev1 && dev2);
|
||||
if (strlen (dev1) < 6 || strlen (dev2) < 6)
|
||||
return -1;
|
||||
|
||||
copy1 = strdup (dev1);
|
||||
copy2 = strdup (dev2);
|
||||
copy1[5] = 'h';
|
||||
copy2[5] = 'h';
|
||||
|
||||
return strcmp (copy1, copy2);
|
||||
}
|
||||
|
||||
/* Compare returned buffer with expected buffer. Note the buffers have
|
||||
* a length and may contain ASCII NUL characters.
|
||||
*/
|
||||
static int
|
||||
compare_buffers (const char *b1, size_t s1, const char *b2, size_t s2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return s1 - s2;
|
||||
return memcmp (b1, b2, s1);
|
||||
}
|
||||
|
||||
/* Get md5sum of the named file. */
|
||||
static void
|
||||
md5sum (const char *filename, char *result)
|
||||
{
|
||||
char cmd[256];
|
||||
snprintf (cmd, sizeof cmd, \"md5sum %%s\", filename);
|
||||
FILE *pp = popen (cmd, \"r\");
|
||||
if (pp == NULL) {
|
||||
perror (cmd);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (fread (result, 1, 32, pp) != 32) {
|
||||
perror (\"md5sum: fread\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (pclose (pp) != 0) {
|
||||
perror (\"pclose\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
result[32] = '\\0';
|
||||
}
|
||||
|
||||
/* Compare MD5 has to expected hash of a file. */
|
||||
static int
|
||||
check_file_md5 (const char *ret, const char *filename)
|
||||
{
|
||||
char expected[33];
|
||||
|
||||
md5sum (filename, expected);
|
||||
if (STRNEQ (ret, expected)) {
|
||||
fprintf (stderr, \"test failed: MD5 returned (%%s) does not match MD5 of file %%s (%%s)\\n\",
|
||||
ret, filename, expected);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the value for a key in a hashtable.
|
||||
* Note: the return value is part of the hash and should not be freed.
|
||||
*/
|
||||
static const char *
|
||||
get_key (char **hash, const char *key)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; hash[i] != NULL; i += 2) {
|
||||
if (STREQ (hash[i], key))
|
||||
return hash[i+1];
|
||||
}
|
||||
|
||||
return NULL; /* key not found */
|
||||
}
|
||||
|
||||
/* Compare hash key's value to expected value. */
|
||||
static int
|
||||
check_hash (char **ret, const char *key, const char *expected)
|
||||
{
|
||||
const char *value = get_key (ret, key);
|
||||
|
||||
if (STRNEQ (value, expected)) {
|
||||
fprintf (stderr, \"test failed: hash key %%s = \\\"%%s\\\" is not expected value \\\"%%s\\\"\\n\",
|
||||
key, value, expected);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Match string with a PCRE regular expression. */
|
||||
static int
|
||||
match_re (const char *str, const char *pattern)
|
||||
{
|
||||
const char *err;
|
||||
int offset;
|
||||
pcre *re;
|
||||
size_t len = strlen (str);
|
||||
int vec[30], r;
|
||||
|
||||
re = pcre_compile (pattern, 0, &err, &offset, NULL);
|
||||
if (re == NULL) {
|
||||
fprintf (stderr, \"tests: cannot compile regular expression '%%s': %%s\\n\",
|
||||
pattern, err);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]);
|
||||
pcre_free (re);
|
||||
|
||||
return r != PCRE_ERROR_NOMATCH;
|
||||
}
|
||||
|
||||
static void
|
||||
next_test (guestfs_h *g, size_t test_num, size_t nr_tests,
|
||||
const char *test_name)
|
||||
{
|
||||
if (guestfs_get_verbose (g))
|
||||
printf (\"-------------------------------------------------------------------------------\\n\");
|
||||
printf (\"%%3zu/%%3zu %%s\\n\", test_num, nr_tests, test_name);
|
||||
}
|
||||
|
||||
static void
|
||||
skipped (const char *test_name, const char *fs, ...)
|
||||
{
|
||||
va_list args;
|
||||
CLEANUP_FREE char *reason = NULL;
|
||||
int len;
|
||||
|
||||
va_start (args, fs);
|
||||
len = vasprintf (&reason, fs, args);
|
||||
va_end (args);
|
||||
assert (len >= 0);
|
||||
|
||||
printf (\" %%s skipped (reason: %%s)\\n\",
|
||||
test_name, reason);
|
||||
}
|
||||
#include \"tests.h\"
|
||||
|
||||
";
|
||||
|
||||
(* Generate a list of commands which are not tested anywhere. *)
|
||||
pr "static void\n";
|
||||
pr "void\n";
|
||||
pr "no_test_warnings (void)\n";
|
||||
pr "{\n";
|
||||
pr " size_t i;\n";
|
||||
@@ -328,121 +95,19 @@ skipped (const char *test_name, const char *fs, ...)
|
||||
mapi (generate_one_test name optional) tests
|
||||
) (List.rev all_functions) in
|
||||
let test_names = List.concat test_names in
|
||||
|
||||
let nr_tests = List.length test_names in
|
||||
pr "size_t nr_tests = %d;\n" nr_tests;
|
||||
pr "\n";
|
||||
|
||||
pr "\
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
size_t
|
||||
perform_tests (void)
|
||||
{
|
||||
const char *filename;
|
||||
int fd;
|
||||
const size_t nr_tests = %d;
|
||||
size_t test_num = 0;
|
||||
size_t nr_failed = 0;
|
||||
|
||||
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, %d) == -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);
|
||||
}
|
||||
|
||||
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, %d) == -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);
|
||||
}
|
||||
|
||||
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, %d) == -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_add_drive_ro (g, \"../data/test.iso\") == -1) {
|
||||
printf (\"FAIL: guestfs_add_drive_ro ../data/test.iso\\n\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
|
||||
alarm (600);
|
||||
|
||||
if (guestfs_launch (g) == -1) {
|
||||
printf (\"FAIL: guestfs_launch\\n\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Cancel previous alarm. */
|
||||
alarm (0);
|
||||
|
||||
/* Create ext2 filesystem on /dev/sdb1 partition. */
|
||||
if (guestfs_part_disk (g, \"/dev/sdb\", \"mbr\") == -1) {
|
||||
printf (\"FAIL: guestfs_part_disk\\n\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (guestfs_mkfs (g, \"ext2\", \"/dev/sdb1\") == -1) {
|
||||
printf (\"FAIL: guestfs_mkfs (/dev/sdb1)\\n\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
" nr_tests (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024);
|
||||
";
|
||||
|
||||
iteri (
|
||||
fun i test_name ->
|
||||
@@ -453,33 +118,12 @@ main (int argc, char *argv[])
|
||||
pr " nr_failed++;\n";
|
||||
pr " }\n";
|
||||
) test_names;
|
||||
pr "\n";
|
||||
|
||||
pr " /* Check close callback is called. */
|
||||
int close_sentinel = 1;
|
||||
guestfs_set_close_callback (g, incr, &close_sentinel);
|
||||
pr "\
|
||||
|
||||
guestfs_close (g);
|
||||
|
||||
if (close_sentinel != 2) {
|
||||
fprintf (stderr, \"FAIL: close callback was not called\\n\");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
unlink (\"test1.img\");
|
||||
unlink (\"test2.img\");
|
||||
unlink (\"test3.img\");
|
||||
|
||||
";
|
||||
|
||||
pr " if (nr_failed > 0) {\n";
|
||||
pr " printf (\"***** %%zu / %%zu tests FAILED *****\\n\", nr_failed, nr_tests);\n";
|
||||
pr " exit (EXIT_FAILURE);\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
|
||||
pr " exit (EXIT_SUCCESS);\n";
|
||||
pr "}\n"
|
||||
return nr_failed;
|
||||
}
|
||||
"
|
||||
|
||||
and generate_one_test name optional i (init, prereq, test) =
|
||||
let test_name = sprintf "test_%s_%d" name i in
|
||||
|
||||
@@ -71,7 +71,10 @@ TESTS_ENVIRONMENT = \
|
||||
|
||||
#SKIP_TEST_CHECKSUM_8=$(shell if test `find ../initramfs -name squashfs.ko | wc -l` -eq 0; then echo 1; fi)
|
||||
|
||||
tests_SOURCES = tests.c
|
||||
tests_SOURCES = \
|
||||
tests.c \
|
||||
tests.h \
|
||||
tests-main.c
|
||||
tests_CPPFLAGS = \
|
||||
-DGUESTFS_PRIVATE=1 \
|
||||
-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
|
||||
|
||||
396
tests/c-api/tests-main.c
Normal file
396
tests/c-api/tests-main.c
Normal file
@@ -0,0 +1,396 @@
|
||||
/* libguestfs
|
||||
* Copyright (C) 2009-2013 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 <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <pcre.h>
|
||||
|
||||
#include "guestfs.h"
|
||||
#include "guestfs-internal-frontend.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
guestfs_h *g;
|
||||
|
||||
static void
|
||||
print_strings (char *const *argv)
|
||||
{
|
||||
size_t argc;
|
||||
|
||||
for (argc = 0; argv[argc] != NULL; ++argc)
|
||||
printf ("\t%s\n", argv[argc]);
|
||||
}
|
||||
|
||||
static void
|
||||
incr (guestfs_h *g, void *iv)
|
||||
{
|
||||
int *i = (int *) iv;
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
static int compare_lists (char **, char **, int (*) (const char *, const char *));
|
||||
|
||||
/* Compare 'ret' to the string list that follows. */
|
||||
int
|
||||
is_string_list (char **ret, size_t n, ...)
|
||||
{
|
||||
CLEANUP_FREE /* sic */ char **expected = malloc ((n+1) * sizeof (char *));
|
||||
size_t i;
|
||||
va_list args;
|
||||
|
||||
va_start (args, n);
|
||||
for (i = 0; i < n; ++i)
|
||||
expected[i] = va_arg (args, char *);
|
||||
expected[n] = NULL;
|
||||
va_end (args);
|
||||
return compare_lists (ret, expected, strcmp);
|
||||
}
|
||||
|
||||
/* Compare 'ret' to the device list that follows. */
|
||||
int
|
||||
is_device_list (char **ret, size_t n, ...)
|
||||
{
|
||||
CLEANUP_FREE /* sic */ char **expected = malloc ((n+1) * sizeof (char *));
|
||||
size_t i;
|
||||
va_list args;
|
||||
|
||||
va_start (args, n);
|
||||
for (i = 0; i < n; ++i)
|
||||
expected[i] = va_arg (args, char *);
|
||||
expected[n] = NULL;
|
||||
va_end (args);
|
||||
return compare_lists (ret, expected, compare_devices);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_lists (char **ret, char **expected,
|
||||
int (*compare) (const char *, const char *))
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; ret[i] != NULL; ++i) {
|
||||
if (!expected[i]) {
|
||||
fprintf (stderr, "test failed: returned list is too long\n");
|
||||
goto fail;
|
||||
}
|
||||
if (compare (ret[i], expected[i]) != 0) {
|
||||
fprintf (stderr, "test failed: elements differ at position %zu\n", i);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (expected[i]) {
|
||||
fprintf (stderr, "test failed: returned list is too short\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 1; /* test expecting true for OK */
|
||||
|
||||
fail:
|
||||
fprintf (stderr, "returned list was:\n");
|
||||
print_strings (ret);
|
||||
fprintf (stderr, "expected list was:\n");
|
||||
print_strings (expected);
|
||||
return 0; /* test expecting false for failure */
|
||||
}
|
||||
|
||||
/* Compare two device names, ignoring hd/sd/vd */
|
||||
int
|
||||
compare_devices (const char *dev1, const char *dev2)
|
||||
{
|
||||
CLEANUP_FREE char *copy1 = NULL, *copy2 = NULL;
|
||||
|
||||
assert (dev1 && dev2);
|
||||
if (strlen (dev1) < 6 || strlen (dev2) < 6)
|
||||
return -1;
|
||||
|
||||
copy1 = strdup (dev1);
|
||||
copy2 = strdup (dev2);
|
||||
copy1[5] = 'h';
|
||||
copy2[5] = 'h';
|
||||
|
||||
return strcmp (copy1, copy2);
|
||||
}
|
||||
|
||||
/* Compare returned buffer with expected buffer. Note the buffers have
|
||||
* a length and may contain ASCII NUL characters.
|
||||
*/
|
||||
int
|
||||
compare_buffers (const char *b1, size_t s1, const char *b2, size_t s2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return s1 - s2;
|
||||
return memcmp (b1, b2, s1);
|
||||
}
|
||||
|
||||
/* Get md5sum of the named file. */
|
||||
static void
|
||||
md5sum (const char *filename, char *result)
|
||||
{
|
||||
char cmd[256];
|
||||
snprintf (cmd, sizeof cmd, "md5sum %s", filename);
|
||||
FILE *pp = popen (cmd, "r");
|
||||
if (pp == NULL) {
|
||||
perror (cmd);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (fread (result, 1, 32, pp) != 32) {
|
||||
perror ("md5sum: fread");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (pclose (pp) != 0) {
|
||||
perror ("pclose");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
result[32] = '\0';
|
||||
}
|
||||
|
||||
/* Compare MD5 has to expected hash of a file. */
|
||||
int
|
||||
check_file_md5 (const char *ret, const char *filename)
|
||||
{
|
||||
char expected[33];
|
||||
|
||||
md5sum (filename, expected);
|
||||
if (STRNEQ (ret, expected)) {
|
||||
fprintf (stderr, "test failed: MD5 returned (%s) does not match MD5 of file %s (%s)\n",
|
||||
ret, filename, expected);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the value for a key in a hashtable.
|
||||
* Note: the return value is part of the hash and should not be freed.
|
||||
*/
|
||||
const char *
|
||||
get_key (char **hash, const char *key)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; hash[i] != NULL; i += 2) {
|
||||
if (STREQ (hash[i], key))
|
||||
return hash[i+1];
|
||||
}
|
||||
|
||||
return NULL; /* key not found */
|
||||
}
|
||||
|
||||
/* Compare hash key's value to expected value. */
|
||||
int
|
||||
check_hash (char **ret, const char *key, const char *expected)
|
||||
{
|
||||
const char *value = get_key (ret, key);
|
||||
|
||||
if (STRNEQ (value, expected)) {
|
||||
fprintf (stderr, "test failed: hash key %s = \"%s\" is not expected value \"%s\"\n",
|
||||
key, value, expected);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Match string with a PCRE regular expression. */
|
||||
int
|
||||
match_re (const char *str, const char *pattern)
|
||||
{
|
||||
const char *err;
|
||||
int offset;
|
||||
pcre *re;
|
||||
size_t len = strlen (str);
|
||||
int vec[30], r;
|
||||
|
||||
re = pcre_compile (pattern, 0, &err, &offset, NULL);
|
||||
if (re == NULL) {
|
||||
fprintf (stderr, "tests: cannot compile regular expression '%s': %s\n",
|
||||
pattern, err);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]);
|
||||
pcre_free (re);
|
||||
|
||||
return r != PCRE_ERROR_NOMATCH;
|
||||
}
|
||||
|
||||
void
|
||||
next_test (guestfs_h *g, size_t test_num, size_t nr_tests,
|
||||
const char *test_name)
|
||||
{
|
||||
if (guestfs_get_verbose (g))
|
||||
printf ("-------------------------------------------------------------------------------\n");
|
||||
printf ("%3zu/%3zu %s\n", test_num, nr_tests, test_name);
|
||||
}
|
||||
|
||||
void
|
||||
skipped (const char *test_name, const char *fs, ...)
|
||||
{
|
||||
va_list args;
|
||||
CLEANUP_FREE char *reason = NULL;
|
||||
int len;
|
||||
|
||||
va_start (args, fs);
|
||||
len = vasprintf (&reason, fs, args);
|
||||
va_end (args);
|
||||
assert (len >= 0);
|
||||
|
||||
printf (" %s skipped (reason: %s)\n",
|
||||
test_name, reason);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const char *filename;
|
||||
int fd;
|
||||
size_t nr_failed ;
|
||||
int close_sentinel = 1;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (guestfs_add_drive_ro (g, "../data/test.iso") == -1) {
|
||||
printf ("FAIL: guestfs_add_drive_ro ../data/test.iso\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
|
||||
alarm (600);
|
||||
|
||||
if (guestfs_launch (g) == -1) {
|
||||
printf ("FAIL: guestfs_launch\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Cancel previous alarm. */
|
||||
alarm (0);
|
||||
|
||||
/* Create ext2 filesystem on /dev/sdb1 partition. */
|
||||
if (guestfs_part_disk (g, "/dev/sdb", "mbr") == -1) {
|
||||
printf ("FAIL: guestfs_part_disk\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (guestfs_mkfs (g, "ext2", "/dev/sdb1") == -1) {
|
||||
printf ("FAIL: guestfs_mkfs (/dev/sdb1)\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nr_failed = perform_tests ();
|
||||
|
||||
/* Check close callback is called. */
|
||||
guestfs_set_close_callback (g, incr, &close_sentinel);
|
||||
|
||||
guestfs_close (g);
|
||||
|
||||
if (close_sentinel != 2) {
|
||||
fprintf (stderr, "FAIL: close callback was not called\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
unlink ("test1.img");
|
||||
unlink ("test2.img");
|
||||
unlink ("test3.img");
|
||||
|
||||
if (nr_failed > 0) {
|
||||
printf ("***** %zu / %zu tests FAILED *****\n", nr_failed, nr_tests);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
38
tests/c-api/tests.h
Normal file
38
tests/c-api/tests.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* libguestfs
|
||||
* Copyright (C) 2009-2013 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.
|
||||
*/
|
||||
|
||||
#ifndef TESTS_H_
|
||||
#define TESTS_H_
|
||||
|
||||
extern guestfs_h *g;
|
||||
extern size_t nr_tests;
|
||||
|
||||
extern size_t perform_tests (void);
|
||||
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, ...);
|
||||
extern int compare_devices (const char *dev1, const char *dev2);
|
||||
extern int compare_buffers (const char *b1, size_t s1, const char *b2, size_t s2);
|
||||
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 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, ...);
|
||||
|
||||
#endif /* TESTS_H_ */
|
||||
Reference in New Issue
Block a user