2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2006-08-24 21:46:28 +00:00
|
|
|
|
|
|
|
#include <unistd.h>
|
2024-03-21 16:50:09 +00:00
|
|
|
#include <fcntl.h>
|
2007-11-26 12:03:34 +00:00
|
|
|
|
Wed Dec 5 13:48:00 UTC 2007 Richard W.M. Jones <rjones@redhat.com>
* python/libvir.c, python/libvirt_wrap.h, qemud/qemud.c,
qemud/remote.c, src/internal.h, src/openvz_conf.c,
src/openvz_driver.c, src/proxy_internal.h, src/qemu_conf.c,
src/qemu_driver.c, src/remote_internal.h, src/test.h, src/util.c,
src/xen_unified.c, src/xen_unified.h, tests/nodeinfotest.c,
tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c, tests/reconnect.c,
tests/sexpr2xmltest.c, tests/virshtest.c, tests/xencapstest.c,
tests/xmconfigtest.c, tests/xml2sexprtest.c:
Change #include <> to #include "" for local includes.
Removed many includes from src/internal.h and put them in
the C files which actually use them.
Removed <ansidecl.h> - unused.
Added a comment around __func__.
Removed a clashing redefinition of VERSION symbol.
All limits (PATH_MAX etc) now done in src/internal.h, so we
don't need to include those headers in other files.
2007-12-05 13:56:22 +00:00
|
|
|
#include "internal.h"
|
2006-08-24 21:46:28 +00:00
|
|
|
#include "testutils.h"
|
2020-02-09 01:00:06 +00:00
|
|
|
#include "vircommand.h"
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2024-03-21 16:50:09 +00:00
|
|
|
#include "util/virthread.h"
|
|
|
|
|
2013-06-07 15:10:28 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
2011-07-28 15:48:12 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
|
|
|
int
|
|
|
|
main(void)
|
|
|
|
{
|
|
|
|
return EXIT_AM_SKIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2024-03-20 16:45:56 +00:00
|
|
|
static void testFilterLine(char *buffer,
|
|
|
|
const char *toRemove)
|
2014-03-18 08:13:43 +00:00
|
|
|
{
|
2018-09-13 08:55:21 +00:00
|
|
|
char *start;
|
|
|
|
|
2024-03-20 16:45:56 +00:00
|
|
|
while ((start = strstr(buffer, toRemove))) {
|
|
|
|
char *end;
|
2018-09-13 08:55:21 +00:00
|
|
|
|
2024-03-20 16:45:56 +00:00
|
|
|
if (!(end = strstr(start+1, "\n"))) {
|
|
|
|
*start = '\0';
|
|
|
|
} else {
|
|
|
|
memmove(start, end, strlen(end)+1);
|
|
|
|
}
|
2018-09-13 08:55:21 +00:00
|
|
|
}
|
2006-08-24 21:46:28 +00:00
|
|
|
}
|
|
|
|
|
2011-04-24 22:25:10 +00:00
|
|
|
static int
|
2024-03-12 12:52:48 +00:00
|
|
|
testCompareOutputLit(const char *expectFile,
|
|
|
|
const char *filter,
|
2024-03-22 15:23:57 +00:00
|
|
|
const char *const *env,
|
2024-03-12 12:52:48 +00:00
|
|
|
const char *const argv[])
|
2011-04-24 22:25:10 +00:00
|
|
|
{
|
2024-03-12 16:15:39 +00:00
|
|
|
g_autofree char *actual = NULL;
|
2020-02-09 01:00:06 +00:00
|
|
|
const char *empty = "";
|
|
|
|
g_autoptr(virCommand) cmd = NULL;
|
2024-03-12 16:15:39 +00:00
|
|
|
int exitstatus = 0;
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2022-08-23 12:35:47 +00:00
|
|
|
cmd = virCommandNewArgs(argv);
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2020-02-09 01:00:06 +00:00
|
|
|
virCommandAddEnvString(cmd, "LANG=C");
|
2024-03-22 15:23:57 +00:00
|
|
|
|
|
|
|
while (env && *env) {
|
|
|
|
virCommandAddEnvString(cmd, *env);
|
|
|
|
env++;
|
|
|
|
}
|
|
|
|
|
2020-02-09 01:00:06 +00:00
|
|
|
virCommandSetInputBuffer(cmd, empty);
|
2024-03-12 16:15:39 +00:00
|
|
|
virCommandSetOutputBuffer(cmd, &actual);
|
|
|
|
virCommandSetErrorBuffer(cmd, &actual);
|
2020-02-09 01:00:06 +00:00
|
|
|
|
2024-03-12 16:15:39 +00:00
|
|
|
if (virCommandRun(cmd, &exitstatus) < 0)
|
2020-02-09 01:00:06 +00:00
|
|
|
return -1;
|
|
|
|
|
2024-03-12 16:15:39 +00:00
|
|
|
if (exitstatus != 0) {
|
|
|
|
g_autofree char *tmp = g_steal_pointer(&actual);
|
|
|
|
|
|
|
|
actual = g_strdup_printf("%s\n## Exit code: %d\n", tmp, exitstatus);
|
2020-02-09 01:00:06 +00:00
|
|
|
}
|
|
|
|
|
2024-03-20 16:45:56 +00:00
|
|
|
if (filter)
|
|
|
|
testFilterLine(actual, filter);
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2024-03-22 14:10:15 +00:00
|
|
|
if (virTestCompareToFileFull(actual, expectFile, false) < 0)
|
|
|
|
return -1;
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2020-02-09 01:07:19 +00:00
|
|
|
return 0;
|
2008-11-24 07:11:26 +00:00
|
|
|
}
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2019-03-12 14:11:47 +00:00
|
|
|
# define VIRSH_DEFAULT abs_top_builddir "/tools/virsh", \
|
2006-08-24 21:46:28 +00:00
|
|
|
"--connect", \
|
|
|
|
"test:///default"
|
|
|
|
|
|
|
|
static char *custom_uri;
|
|
|
|
|
2019-03-12 14:11:47 +00:00
|
|
|
# define VIRSH_CUSTOM abs_top_builddir "/tools/virsh", \
|
2006-08-24 21:46:28 +00:00
|
|
|
"--connect", \
|
|
|
|
custom_uri
|
|
|
|
|
2010-10-15 16:34:11 +00:00
|
|
|
struct testInfo {
|
2024-03-12 12:52:48 +00:00
|
|
|
const char *testname; /* used to generate output filename */
|
|
|
|
const char *filter;
|
2010-10-15 16:34:11 +00:00
|
|
|
const char *const *argv;
|
2024-03-18 14:38:39 +00:00
|
|
|
bool expensive;
|
2024-03-22 15:23:57 +00:00
|
|
|
const char *const *env; /* extra environment variables to pass */
|
|
|
|
bool forbid_root;
|
2024-03-12 16:03:56 +00:00
|
|
|
bool need_readline;
|
2010-10-15 16:34:11 +00:00
|
|
|
};
|
|
|
|
|
2024-03-12 12:52:48 +00:00
|
|
|
static int testCompare(const void *data)
|
2014-03-18 08:13:43 +00:00
|
|
|
{
|
2010-10-15 16:34:11 +00:00
|
|
|
const struct testInfo *info = data;
|
2024-03-12 12:52:48 +00:00
|
|
|
g_autofree char *outfile = NULL;
|
|
|
|
|
2024-03-18 14:38:39 +00:00
|
|
|
if (info->expensive && virTestGetExpensive() == 0)
|
|
|
|
return EXIT_AM_SKIP;
|
|
|
|
|
2024-03-22 15:23:57 +00:00
|
|
|
if (info->forbid_root && geteuid() == 0)
|
|
|
|
return EXIT_AM_SKIP;
|
|
|
|
|
2024-03-12 16:03:56 +00:00
|
|
|
# ifndef WITH_READLINE
|
|
|
|
if (info->need_readline)
|
|
|
|
return EXIT_AM_SKIP;
|
|
|
|
# endif
|
|
|
|
|
2024-03-12 12:52:48 +00:00
|
|
|
if (info->testname) {
|
|
|
|
outfile = g_strdup_printf("%s/virshtestdata/%s.out",
|
|
|
|
abs_srcdir, info->testname);
|
|
|
|
}
|
|
|
|
|
2024-03-22 15:23:57 +00:00
|
|
|
return testCompareOutputLit(outfile, info->filter, info->env, info->argv);
|
2010-10-15 16:34:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-21 16:50:09 +00:00
|
|
|
static void
|
|
|
|
testPipeFeeder(void *opaque)
|
|
|
|
{
|
|
|
|
/* feed more than observed buffer size which was historically 128k in the
|
|
|
|
* test this was adapted from */
|
|
|
|
size_t emptyspace = 140 * 1024;
|
|
|
|
const char *pipepath = opaque;
|
|
|
|
const char *xml =
|
|
|
|
"<domain type='test' id='2'>\n"
|
|
|
|
" <name>t2</name>\n"
|
|
|
|
" <uuid>004b96e1-2d78-c30f-5aa5-000000000000</uuid>\n"
|
|
|
|
" <memory>8388608</memory>\n"
|
|
|
|
" <vcpu>2</vcpu>\n"
|
|
|
|
" <os>\n"
|
|
|
|
" <type>xen</type>\n"
|
|
|
|
" </os>\n"
|
|
|
|
"</domain>\n";
|
|
|
|
size_t xmlsize = strlen(xml);
|
|
|
|
g_autofree char *doc = g_new0(char, emptyspace + xmlsize + 1);
|
|
|
|
VIR_AUTOCLOSE fd = -1;
|
|
|
|
|
tests: fix hang in virshtest 'read-big-pipe' case
The virshtest program testPipeFeeder method is doing this:
mkfifo("test.fifo", 0600) ;
int fd = open("test.fifo", O_RDWR);
char buf[...];
memset(buf, 'a', sizeof(buf));
write(fd, buf, sizeof(buf)) == sizeof(buf));
close(fd);
while the the 'virsh' child process then ends up doing:
fd = open("test.fifo", O_RDONLY);
read(fd, buf, sizeof(buf)) == sizeof(buf));
close(fd);
The 'virsh' code hangs on open() on at least ppc64 and some other
arches. It can be provoked to hang even on x86 by reducing the size of
the buffer. It can be prevented from hanging on ppc64 by increasing the
size of the buffer.
What is happening is a result of differing page sizes, altering the
overall pipe capacity size, since pipes on linux default to 16 pages
in size and thus have architecture specific capacity when measured
in bytes.
* On x86, testPipeFeeder opens R+W, tries to write 140kb and
write() blocks because the pipe is full. This gives time for
virsh to start up, and it can open the pipe for O_RDONLY
since testPipeFeeder still has it open for write. Everything
works as intended.
* On ppc64, testPipeFeeder opens R+W, tries to write 140kb
and write() succeeds because the larger 64kb page size
resulted in greater buffer capacity for the pipe. It thus
quickly closes the pipe, removing the writer, and triggering
discard of all the unread data. Now virsh starts up, tries
to open the pipe for O_RDONLY and blocks waiting for a new
writer to open it, which will never happen. Meson kills
the test after 30 seconds.
NB, every now & then, it will not block because virsh starts
up quickly enough that testPipeFeeder has not yet closed the
write end of the pipe, giving the illusion of correctness.
The key flaw here is that it should not have been using O_RDWR
in testPipeFeeder. Synchronization is required such that both
virsh and testPipeFeeder have their respective ends of the pipe
open before any data is sent. This is trivially arranged by
using O_WRONLY in testPipeFeeder.
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2024-05-08 10:50:09 +00:00
|
|
|
if ((fd = open(pipepath, O_WRONLY)) < 0) {
|
2024-03-21 16:50:09 +00:00
|
|
|
fprintf(stderr, "\nfailed to open pipe '%s': %s\n", pipepath, g_strerror(errno));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(doc, ' ', emptyspace);
|
2024-05-08 12:03:20 +00:00
|
|
|
g_assert(virStrcpy(doc + emptyspace, xml, xmlsize + 1) == 0);
|
2024-03-21 16:50:09 +00:00
|
|
|
|
2024-05-08 12:03:20 +00:00
|
|
|
if (safewrite(fd, doc, emptyspace + xmlsize) < 0) {
|
2024-03-21 16:50:09 +00:00
|
|
|
fprintf(stderr, "\nfailed to write to pipe '%s': %s\n", pipepath, g_strerror(errno));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
testVirshPipe(const void *data G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
char tmpdir[] = "/tmp/libvirt_virshtest_XXXXXXX";
|
|
|
|
g_autofree char *pipepath = NULL;
|
|
|
|
virThread feeder;
|
|
|
|
bool join = false;
|
|
|
|
g_autofree char *cmdstr = NULL;
|
|
|
|
const char *argv[] = { VIRSH_DEFAULT, NULL, NULL };
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!g_mkdtemp(tmpdir)) {
|
|
|
|
fprintf(stderr, "\nfailed to create temporary directory\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pipepath = g_strdup_printf("%s/pipe", tmpdir);
|
|
|
|
|
|
|
|
|
|
|
|
cmdstr = g_strdup_printf("define %s ; list --all", pipepath);
|
|
|
|
argv[3] = cmdstr;
|
|
|
|
|
|
|
|
if (mkfifo(pipepath, 0600) < 0) {
|
|
|
|
fprintf(stderr, "\nfailed to create pipe '%s': %s\n", pipepath, g_strerror(errno));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virThreadCreate(&feeder, true, testPipeFeeder, pipepath) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
join = true;
|
|
|
|
|
|
|
|
if (testCompareOutputLit(abs_srcdir "/virshtestdata/read-big-pipe.out",
|
2024-03-22 15:23:57 +00:00
|
|
|
"/tmp/libvirt_virshtest", NULL, argv) < 0)
|
2024-03-21 16:50:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (join)
|
|
|
|
virThreadJoin(&feeder);
|
|
|
|
unlink(pipepath);
|
|
|
|
rmdir(tmpdir);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
static int
|
2011-04-29 16:21:20 +00:00
|
|
|
mymain(void)
|
2006-08-24 21:46:28 +00:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2024-03-12 16:03:56 +00:00
|
|
|
bool need_readline = false;
|
2006-08-24 21:46:28 +00:00
|
|
|
|
2019-10-22 13:26:14 +00:00
|
|
|
custom_uri = g_strdup_printf("test://%s/../examples/xml/test/testnode.xml",
|
|
|
|
abs_srcdir);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2024-03-18 14:38:39 +00:00
|
|
|
# define DO_TEST_SCRIPT_FULL(testname_, expensive, testfilter, ...) \
|
2024-03-20 08:48:32 +00:00
|
|
|
{ \
|
|
|
|
const char *testname = testname_; \
|
|
|
|
g_autofree char *infile = g_strdup_printf("%s/virshtestdata/%s.in", \
|
|
|
|
abs_srcdir, testname); \
|
|
|
|
const char *myargv[] = { __VA_ARGS__, NULL, NULL }; \
|
|
|
|
const char **tmp = myargv; \
|
2024-03-12 16:03:56 +00:00
|
|
|
const struct testInfo info = { testname, testfilter, myargv, expensive, NULL, false, need_readline}; \
|
2024-03-20 08:48:32 +00:00
|
|
|
g_autofree char *scriptarg = NULL; \
|
|
|
|
if (virFileReadAll(infile, 256 * 1024, &scriptarg) < 0) { \
|
|
|
|
fprintf(stderr, "\nfailed to load '%s'\n", infile); \
|
|
|
|
ret = -1; \
|
|
|
|
} \
|
|
|
|
while (*tmp) \
|
|
|
|
tmp++; \
|
|
|
|
*tmp = scriptarg; \
|
|
|
|
if (virTestRun(testname, testCompare, &info) < 0) \
|
|
|
|
ret = -1; \
|
|
|
|
} while (0);
|
|
|
|
|
2024-03-18 14:38:39 +00:00
|
|
|
# define DO_TEST_SCRIPT(testname_, testfilter, ...) \
|
|
|
|
DO_TEST_SCRIPT_FULL(testname_, false, testfilter, __VA_ARGS__);
|
|
|
|
|
2024-03-20 16:34:45 +00:00
|
|
|
DO_TEST_SCRIPT("info-default", NULL, VIRSH_DEFAULT);
|
|
|
|
DO_TEST_SCRIPT("info-custom", NULL, VIRSH_CUSTOM);
|
2024-03-20 16:48:12 +00:00
|
|
|
DO_TEST_SCRIPT("domain-id", "\nCPU time:", VIRSH_CUSTOM);
|
2024-03-20 16:52:19 +00:00
|
|
|
DO_TEST_SCRIPT("blkiotune", NULL, VIRSH_CUSTOM);
|
2024-03-20 16:58:39 +00:00
|
|
|
DO_TEST_SCRIPT("iothreads", NULL, VIRSH_CUSTOM);
|
2024-03-20 16:34:45 +00:00
|
|
|
|
2024-03-22 15:23:57 +00:00
|
|
|
# define DO_TEST_INFO(infostruct) \
|
|
|
|
if (virTestRun((infostruct)->testname, testCompare, (infostruct)) < 0) \
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
# define DO_TEST_FULL(testname, filter, ...) \
|
2017-11-03 12:09:47 +00:00
|
|
|
do { \
|
2024-03-12 12:38:24 +00:00
|
|
|
const char *myargv[] = { __VA_ARGS__, NULL }; \
|
2024-03-12 16:03:56 +00:00
|
|
|
const struct testInfo info = { testname, NULL, myargv, false, NULL, false, need_readline }; \
|
2024-03-22 15:23:57 +00:00
|
|
|
DO_TEST_INFO(&info); \
|
2010-10-15 16:34:11 +00:00
|
|
|
} while (0)
|
|
|
|
|
2024-03-12 12:38:24 +00:00
|
|
|
/* automatically numbered test invocation */
|
2024-03-12 13:34:03 +00:00
|
|
|
# define DO_TEST(...) \
|
|
|
|
DO_TEST_FULL(virTestCounterNext(), NULL, VIRSH_DEFAULT, __VA_ARGS__);
|
2024-03-12 12:38:24 +00:00
|
|
|
|
|
|
|
|
2010-10-15 16:34:11 +00:00
|
|
|
/* Arg parsing quote removal tests. */
|
2024-03-12 12:38:24 +00:00
|
|
|
virTestCounterReset("echo-quote-removal-");
|
2024-03-12 13:34:03 +00:00
|
|
|
DO_TEST("echo a \t b");
|
|
|
|
DO_TEST("echo \"a \t b\"");
|
|
|
|
DO_TEST("echo 'a \t b'");
|
|
|
|
DO_TEST("echo a\\ \\\t\\ b");
|
|
|
|
DO_TEST("echo", "'", "\"", "\\;echo\ta");
|
|
|
|
DO_TEST("echo \\' \\\" \\;echo\ta");
|
|
|
|
DO_TEST("echo \\' \\\" \\\\;echo\ta");
|
|
|
|
DO_TEST("echo \"'\" '\"' '\\'\"\\\\\"");
|
2010-10-15 16:34:11 +00:00
|
|
|
|
|
|
|
/* Tests of echo flags. */
|
2024-03-20 15:27:18 +00:00
|
|
|
DO_TEST_SCRIPT("echo-escaping", NULL, VIRSH_DEFAULT);
|
2024-03-12 12:38:24 +00:00
|
|
|
|
|
|
|
virTestCounterReset("echo-escaping-");
|
2024-03-12 13:34:03 +00:00
|
|
|
DO_TEST("echo", "a", "A", "0", "+", "*", ";", ".", "'", "\"", "/", "?", "=", " ", "\n", "<", ">", "&");
|
|
|
|
DO_TEST("echo", "--shell", "a", "A", "0", "+", "*", ";", ".", "'", "\"", "/", "?", "=", " ", "\n", "<", ">", "&");
|
|
|
|
DO_TEST("echo", "--xml", "a", "A", "0", "+", "*", ";", ".", "'", "\"", "/", "?", "=", " ", "\n", "<", ">", "&");
|
2010-10-15 16:34:11 +00:00
|
|
|
|
|
|
|
/* Tests of -- handling. */
|
2024-03-12 12:38:24 +00:00
|
|
|
virTestCounterReset("dash-dash-argument-");
|
2024-03-12 13:34:03 +00:00
|
|
|
DO_TEST("--", "echo", "--shell", "a");
|
|
|
|
DO_TEST("--", "echo", "a", "--shell");
|
|
|
|
DO_TEST("--", "echo", "--", "a", "--shell");
|
|
|
|
DO_TEST("echo", "--", "--", "--shell", "a");
|
|
|
|
DO_TEST("echo --s\\h'e'\"l\"l -- a");
|
|
|
|
DO_TEST("echo \t '-'\"-\" \t --shell \t a");
|
2010-10-15 16:34:11 +00:00
|
|
|
|
2012-03-02 18:01:15 +00:00
|
|
|
/* Tests of alias handling. */
|
2024-03-20 08:48:32 +00:00
|
|
|
DO_TEST_SCRIPT("echo-alias", NULL, VIRSH_DEFAULT);
|
2024-03-12 13:34:03 +00:00
|
|
|
DO_TEST_FULL("echo-alias-argv", NULL, VIRSH_DEFAULT, "echo", "--str", "hello");
|
2012-03-02 18:01:15 +00:00
|
|
|
|
2019-02-21 18:36:32 +00:00
|
|
|
/* Tests of multiple commands. */
|
2024-03-12 12:38:24 +00:00
|
|
|
virTestCounterReset("multiple-commands-");
|
2024-03-12 13:34:03 +00:00
|
|
|
DO_TEST(" echo a; echo b;");
|
|
|
|
DO_TEST("\necho a\n echo b\n");
|
|
|
|
DO_TEST("ec\\\nho a\n echo \\\n b;");
|
|
|
|
DO_TEST("\"ec\\\nho\" a\n echo \"\\\n b\";");
|
|
|
|
DO_TEST("ec\\\nho a\n echo '\\\n b';");
|
|
|
|
DO_TEST("echo a # b");
|
|
|
|
DO_TEST("echo a #b\necho c");
|
|
|
|
DO_TEST("echo a # b\\\necho c");
|
|
|
|
DO_TEST("echo a '#' b");
|
|
|
|
DO_TEST("echo a \\# b");
|
|
|
|
DO_TEST("#unbalanced; 'quotes\"\necho a # b");
|
|
|
|
DO_TEST("\\# ignored;echo a\n'#also' ignored");
|
2019-02-21 18:36:32 +00:00
|
|
|
|
2024-05-15 06:53:08 +00:00
|
|
|
/* test of the --help option handling */
|
|
|
|
DO_TEST_SCRIPT("help-option", NULL, VIRSH_DEFAULT, "-q");
|
|
|
|
|
2021-08-11 13:22:59 +00:00
|
|
|
/* test of splitting in vshStringToArray */
|
2024-03-20 13:42:46 +00:00
|
|
|
DO_TEST_SCRIPT("echo-split", NULL, VIRSH_DEFAULT, "-q");
|
2010-10-15 16:34:11 +00:00
|
|
|
|
2024-03-18 14:19:34 +00:00
|
|
|
/* comprehensive coverage of argument assignment */
|
|
|
|
DO_TEST_SCRIPT("argument-assignment", NULL, VIRSH_DEFAULT, "-k0", "-d0");
|
2024-03-18 14:38:39 +00:00
|
|
|
DO_TEST_SCRIPT("snapshot-create-args", NULL, VIRSH_DEFAULT, "-q");
|
2024-03-18 14:38:39 +00:00
|
|
|
DO_TEST_SCRIPT("numeric-parsing", NULL, VIRSH_DEFAULT);
|
2024-03-18 14:38:39 +00:00
|
|
|
/* The 'numeric-parsing-event' invokes virsh event with a 1 second timeout,
|
|
|
|
* thus is marked expensive */
|
|
|
|
DO_TEST_SCRIPT_FULL("numeric-parsing-event", true, NULL, VIRSH_DEFAULT);
|
2024-03-19 14:19:26 +00:00
|
|
|
DO_TEST_SCRIPT("attach-disk", NULL, VIRSH_DEFAULT);
|
2024-03-21 09:20:25 +00:00
|
|
|
DO_TEST_SCRIPT("vcpupin", NULL, VIRSH_DEFAULT);
|
2024-03-21 11:14:06 +00:00
|
|
|
DO_TEST_SCRIPT("lifecycle", "\nCPU time:", VIRSH_CUSTOM);
|
2024-03-18 14:19:34 +00:00
|
|
|
|
2024-03-21 09:42:13 +00:00
|
|
|
DO_TEST_FULL("domain-id-overflow", NULL, VIRSH_CUSTOM, "-q", "domname", "4294967298");
|
2024-03-21 09:51:02 +00:00
|
|
|
DO_TEST_FULL("schedinfo-invalid-argument", NULL, VIRSH_DEFAULT, "schedinfo", "1", "--set", "j=k");
|
2024-03-21 21:21:34 +00:00
|
|
|
DO_TEST_FULL("pool-define-as", NULL, VIRSH_DEFAULT, "-q",
|
|
|
|
"pool-define-as", "--print-xml", "P", "dir", "src-host",
|
|
|
|
"/src/path", "/src/dev", "S", "/target-path");
|
2024-03-21 09:42:13 +00:00
|
|
|
|
2024-03-21 12:49:07 +00:00
|
|
|
DO_TEST_SCRIPT("snapshot", "<creationTime", VIRSH_DEFAULT);
|
|
|
|
DO_TEST_FULL("snapshot-redefine", NULL, VIRSH_DEFAULT,
|
|
|
|
"cd " abs_srcdir "/virshtestdata ;"
|
|
|
|
"echo 'Redefine must be in topological order; this will fail' ;"
|
|
|
|
"snapshot-create test --redefine snapshot-s2.xml --validate ;"
|
|
|
|
"echo 'correct order' ;"
|
|
|
|
"snapshot-create test --redefine snapshot-s3.xml --validate ;"
|
|
|
|
"snapshot-create test --redefine snapshot-s2.xml --current --validate ;"
|
|
|
|
"snapshot-info test --current");
|
|
|
|
|
2024-03-21 12:49:07 +00:00
|
|
|
DO_TEST_SCRIPT("checkpoint", "<creationTime", VIRSH_DEFAULT);
|
|
|
|
DO_TEST_FULL("checkpoint-redefine", NULL, VIRSH_DEFAULT,
|
|
|
|
"cd " abs_srcdir "/virshtestdata ;"
|
|
|
|
"echo 'Redefine must be in topological order; this will fail' ;"
|
|
|
|
"checkpoint-create test --redefine checkpoint-c2.xml ;"
|
|
|
|
"echo 'correct order' ;"
|
|
|
|
"checkpoint-create test --redefine checkpoint-c3.xml ;"
|
|
|
|
"checkpoint-create test --redefine checkpoint-c2.xml ;"
|
|
|
|
"checkpoint-info test c2");
|
|
|
|
|
2024-09-05 12:33:30 +00:00
|
|
|
DO_TEST_SCRIPT("script-friendly-options", NULL, VIRSH_CUSTOM);
|
|
|
|
|
2024-03-12 16:03:56 +00:00
|
|
|
/* completion doesn't work on non-readline builds */
|
|
|
|
need_readline = true;
|
|
|
|
|
|
|
|
DO_TEST_FULL("completion-command", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "ech");
|
|
|
|
DO_TEST_FULL("completion-command-complete", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo");
|
|
|
|
DO_TEST_FULL("completion-args", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "");
|
|
|
|
DO_TEST_FULL("completion-arg-partial", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "--xm", "--s");
|
|
|
|
DO_TEST_FULL("completion-arg-full-bool", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "--nonexistant-arg", "--xml");
|
|
|
|
DO_TEST_FULL("completion-arg-full-bool-next", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "--nonexistant-arg", "--xml", "");
|
|
|
|
DO_TEST_FULL("completion-arg-full-string", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "--nonexistant-arg", "--prefix");
|
|
|
|
DO_TEST_FULL("completion-arg-full-string-next", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "echo", "--nonexistant-arg", "--prefix", "");
|
|
|
|
DO_TEST_FULL("completion-arg-full-argv", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstats", "--domain");
|
|
|
|
DO_TEST_FULL("completion-arg-full-argv-next", NULL, VIRSH_DEFAULT,
|
|
|
|
"complete", "--", "domstats", "--domain", "");
|
|
|
|
DO_TEST_FULL("completion-argv-multiple", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstats", "--domain", "fc", "--domain", "fv");
|
|
|
|
DO_TEST_FULL("completion-argv-multiple-next", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstats", "--domain", "fv", "--domain", "fc", "");
|
|
|
|
DO_TEST_FULL("completion-argv-multiple-positional", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstats", "--domain", "fc", "fv");
|
|
|
|
DO_TEST_FULL("completion-argv-multiple-positional-next", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstats", "--domain", "fc", "fv", "");
|
|
|
|
DO_TEST_FULL("completion-arg-positional-empty", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstate", "");
|
|
|
|
DO_TEST_FULL("completion-arg-positional-partial", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstate", "fv");
|
|
|
|
DO_TEST_FULL("completion-arg-positional-partial-next", NULL, VIRSH_CUSTOM,
|
|
|
|
"complete", "--", "domstate", "fv", "");
|
|
|
|
|
|
|
|
DO_TEST_SCRIPT("completion", NULL, VIRSH_DEFAULT);
|
|
|
|
|
|
|
|
need_readline = false;
|
|
|
|
|
2024-03-21 16:50:09 +00:00
|
|
|
if (virTestRun("read-big-pipe", testVirshPipe, NULL) < 0)
|
|
|
|
ret = -1;
|
|
|
|
|
2024-03-22 15:23:57 +00:00
|
|
|
/* Test precedence of URI lookup in virsh:
|
|
|
|
*
|
|
|
|
* Precedence is the following (lowest priority first):
|
|
|
|
*
|
|
|
|
* 1) if run as root, 'uri_default' from /etc/libvirtd/libvirt.conf,
|
|
|
|
* otherwise qemu:///session. There is no way to mock this file for
|
|
|
|
* virsh/libvirt.so and the user may have set anything in there that
|
|
|
|
* would spoil the test, so we don't test this
|
|
|
|
*
|
|
|
|
* 2) 'uri_default' from $XDG_CONFIG_HOME/libvirt/libvirt.conf
|
|
|
|
*
|
|
|
|
* 3) LIBVIRT_DEFAULT_URI
|
|
|
|
*
|
|
|
|
* 4) VIRSH_DEFAULT_CONNECT_URI
|
|
|
|
*
|
|
|
|
* 5) parameter -c (--connect)
|
|
|
|
*
|
|
|
|
* There are two pre-prepared directories in tests/virshtestdata/ serving
|
|
|
|
* as mock XDG_CONFIG_HOME containing the test configs.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
const char *uriTest = "uri; connect; uri";
|
|
|
|
const char *myargv_noconnect[] = { abs_top_builddir "/tools/virsh", uriTest, NULL };
|
|
|
|
const char *xdgDirBad = "XDG_CONFIG_HOME=" abs_srcdir "/virshtestdata/uriprecedence-xdg/bad/";
|
2024-03-12 16:03:56 +00:00
|
|
|
struct testInfo info = { NULL, NULL, myargv_noconnect, false, NULL, false, false };
|
2024-03-22 15:23:57 +00:00
|
|
|
|
|
|
|
/* test 1 - default from config */
|
|
|
|
{
|
|
|
|
const char *myenv[] = {
|
|
|
|
"XDG_CONFIG_HOME=" abs_srcdir "/virshtestdata/uriprecedence-xdg/good/",
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
info.testname = "uriprecedence-xdg-config";
|
|
|
|
info.env = myenv;
|
|
|
|
info.forbid_root = true;
|
|
|
|
|
|
|
|
DO_TEST_INFO(&info);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* all other tests don't care */
|
|
|
|
info.forbid_root = false;
|
|
|
|
|
|
|
|
/* test 2 - LIBVIRT_DEFAULT_URI env variable */
|
|
|
|
{
|
|
|
|
const char *myenv[] = {
|
|
|
|
xdgDirBad,
|
|
|
|
"LIBVIRT_DEFAULT_URI=test:///default?good_uri",
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
info.testname = "uriprecedence-LIBVIRT_DEFAULT_URI";
|
|
|
|
info.env = myenv;
|
|
|
|
|
|
|
|
DO_TEST_INFO(&info);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* test 3 - VIRSH_DEFAULT_CONNECT_URI env variable */
|
|
|
|
{
|
|
|
|
const char *myenv[] = {
|
|
|
|
xdgDirBad,
|
|
|
|
"LIBVIRT_DEFAULT_URI=test:///default?bad_uri",
|
|
|
|
"VIRSH_DEFAULT_CONNECT_URI=test:///default?good_uri",
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
info.testname = "uriprecedence-VIRSH_DEFAULT_CONNECT_URI";
|
|
|
|
info.env = myenv;
|
|
|
|
|
|
|
|
DO_TEST_INFO(&info);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* test 3 - --connect parameter */
|
|
|
|
{
|
|
|
|
const char *myenv[] = {
|
|
|
|
xdgDirBad,
|
|
|
|
"LIBVIRT_DEFAULT_URI=test:///default?bad_uri",
|
|
|
|
"VIRSH_DEFAULT_CONNECT_URI=test:///default?bad_uri",
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *myargv[] = {
|
|
|
|
abs_top_builddir "/tools/virsh",
|
|
|
|
"--connect", "test:///default?good_uri",
|
|
|
|
uriTest,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
info.testname = "uriprecedence-param";
|
|
|
|
info.env = myenv;
|
|
|
|
info.argv = myargv;
|
|
|
|
|
|
|
|
DO_TEST_INFO(&info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-02 23:16:43 +00:00
|
|
|
VIR_FREE(custom_uri);
|
2014-03-17 09:38:38 +00:00
|
|
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
2006-08-24 21:46:28 +00:00
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
|
2017-03-29 14:45:42 +00:00
|
|
|
VIR_TEST_MAIN(mymain)
|
2011-07-28 15:48:12 +00:00
|
|
|
|
|
|
|
#endif /* WIN32 */
|