2
* commandtest.c: Test the libCommand API
4
* Copyright (C) 2010-2011 Red Hat, Inc.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31
#include "testutils.h"
42
mymain(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
49
static char *progname;
50
static char *abs_srcdir;
53
static int checkoutput(const char *testname)
57
char *expectname = NULL;
58
char *expectlog = NULL;
59
char *actualname = NULL;
60
char *actuallog = NULL;
62
if (!getcwd(cwd, sizeof(cwd)))
65
if (virAsprintf(&expectname, "%s/commanddata/%s.log", abs_srcdir,
68
if (virAsprintf(&actualname, "%s/commandhelper.log", abs_builddir) < 0)
71
if (virFileReadAll(expectname, 1024*64, &expectlog) < 0) {
72
fprintf(stderr, "cannot read %s\n", expectname);
76
if (virFileReadAll(actualname, 1024*64, &actuallog) < 0) {
77
fprintf(stderr, "cannot read %s\n", actualname);
81
if (STRNEQ(expectlog, actuallog)) {
82
virtTestDifference(stderr, expectlog, actuallog);
98
* Run program, no args, inherit all ENV, keep CWD.
99
* Only stdin/out/err open
100
* No slot for return status must log error.
102
static int test0(const void *unused ATTRIBUTE_UNUSED)
107
cmd = virCommandNew(abs_builddir "/commandhelper-doesnotexist");
108
if (virCommandRun(cmd, NULL) == 0)
111
if (virGetLastError() == NULL)
123
* Run program, no args, inherit all ENV, keep CWD.
124
* Only stdin/out/err open
125
* Capturing return status must not log error.
127
static int test1(const void *unused ATTRIBUTE_UNUSED)
133
cmd = virCommandNew(abs_builddir "/commandhelper-doesnotexist");
134
if (virCommandRun(cmd, &status) < 0)
146
* Run program (twice), no args, inherit all ENV, keep CWD.
147
* Only stdin/out/err open
149
static int test2(const void *unused ATTRIBUTE_UNUSED)
151
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
154
if (virCommandRun(cmd, NULL) < 0) {
155
virErrorPtr err = virGetLastError();
156
printf("Cannot run child %s\n", err->message);
161
if ((ret = checkoutput("test2")) != 0) {
166
if (virCommandRun(cmd, NULL) < 0) {
167
virErrorPtr err = virGetLastError();
168
printf("Cannot run child %s\n", err->message);
175
return checkoutput("test2");
179
* Run program, no args, inherit all ENV, keep CWD.
180
* stdin/out/err + two extra FD open
182
static int test3(const void *unused ATTRIBUTE_UNUSED)
184
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
185
int newfd1 = dup(STDERR_FILENO);
186
int newfd2 = dup(STDERR_FILENO);
187
int newfd3 = dup(STDERR_FILENO);
190
virCommandPreserveFD(cmd, newfd1);
191
virCommandTransferFD(cmd, newfd3);
193
if (virCommandRun(cmd, NULL) < 0) {
194
virErrorPtr err = virGetLastError();
195
printf("Cannot run child %s\n", err->message);
199
if (fcntl(newfd1, F_GETFL) < 0 ||
200
fcntl(newfd2, F_GETFL) < 0 ||
201
fcntl(newfd3, F_GETFL) >= 0) {
202
puts("fds in wrong state");
206
ret = checkoutput("test3");
210
VIR_FORCE_CLOSE(newfd1);
211
VIR_FORCE_CLOSE(newfd2);
217
* Run program, no args, inherit all ENV, CWD is /
218
* Only stdin/out/err open.
221
static int test4(const void *unused ATTRIBUTE_UNUSED)
223
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
224
char *pidfile = virFilePid(abs_builddir, "commandhelper");
231
virCommandSetPidFile(cmd, pidfile);
232
virCommandDaemonize(cmd);
234
if (virCommandRun(cmd, NULL) < 0) {
235
virErrorPtr err = virGetLastError();
236
printf("Cannot run child %s\n", err->message);
240
if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
241
printf("cannot read pidfile\n");
244
while (kill(pid, 0) != -1)
247
ret = checkoutput("test4");
258
* Run program, no args, inherit filtered ENV, keep CWD.
259
* Only stdin/out/err open
261
static int test5(const void *unused ATTRIBUTE_UNUSED)
263
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
265
virCommandAddEnvPassCommon(cmd);
267
if (virCommandRun(cmd, NULL) < 0) {
268
virErrorPtr err = virGetLastError();
269
printf("Cannot run child %s\n", err->message);
276
return checkoutput("test5");
281
* Run program, no args, inherit filtered ENV, keep CWD.
282
* Only stdin/out/err open
284
static int test6(const void *unused ATTRIBUTE_UNUSED)
286
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
288
virCommandAddEnvPass(cmd, "DISPLAY");
289
virCommandAddEnvPass(cmd, "DOESNOTEXIST");
291
if (virCommandRun(cmd, NULL) < 0) {
292
virErrorPtr err = virGetLastError();
293
printf("Cannot run child %s\n", err->message);
300
return checkoutput("test6");
305
* Run program, no args, inherit filtered ENV, keep CWD.
306
* Only stdin/out/err open
308
static int test7(const void *unused ATTRIBUTE_UNUSED)
310
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
312
virCommandAddEnvPassCommon(cmd);
313
virCommandAddEnvPass(cmd, "DISPLAY");
314
virCommandAddEnvPass(cmd, "DOESNOTEXIST");
316
if (virCommandRun(cmd, NULL) < 0) {
317
virErrorPtr err = virGetLastError();
318
printf("Cannot run child %s\n", err->message);
325
return checkoutput("test7");
329
* Run program, no args, inherit filtered ENV, keep CWD.
330
* Only stdin/out/err open
332
static int test8(const void *unused ATTRIBUTE_UNUSED)
334
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
336
virCommandAddEnvString(cmd, "LANG=C");
337
virCommandAddEnvPair(cmd, "USER", "test");
339
if (virCommandRun(cmd, NULL) < 0) {
340
virErrorPtr err = virGetLastError();
341
printf("Cannot run child %s\n", err->message);
348
return checkoutput("test8");
353
* Run program, some args, inherit all ENV, keep CWD.
354
* Only stdin/out/err open
356
static int test9(const void *unused ATTRIBUTE_UNUSED)
358
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
359
const char* const args[] = { "arg1", "arg2", NULL };
361
virCommandAddArg(cmd, "-version");
362
virCommandAddArgPair(cmd, "-log", "bar.log");
363
virCommandAddArgSet(cmd, args);
364
virCommandAddArgList(cmd, "arg3", "arg4", NULL);
366
if (virCommandRun(cmd, NULL) < 0) {
367
virErrorPtr err = virGetLastError();
368
printf("Cannot run child %s\n", err->message);
375
return checkoutput("test9");
380
* Run program, some args, inherit all ENV, keep CWD.
381
* Only stdin/out/err open
383
static int test10(const void *unused ATTRIBUTE_UNUSED)
385
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
386
const char *const args[] = {
387
"-version", "-log=bar.log", NULL,
390
virCommandAddArgSet(cmd, args);
392
if (virCommandRun(cmd, NULL) < 0) {
393
virErrorPtr err = virGetLastError();
394
printf("Cannot run child %s\n", err->message);
401
return checkoutput("test10");
405
* Run program, some args, inherit all ENV, keep CWD.
406
* Only stdin/out/err open
408
static int test11(const void *unused ATTRIBUTE_UNUSED)
410
const char *args[] = {
411
abs_builddir "/commandhelper",
412
"-version", "-log=bar.log", NULL,
414
virCommandPtr cmd = virCommandNewArgs(args);
416
if (virCommandRun(cmd, NULL) < 0) {
417
virErrorPtr err = virGetLastError();
418
printf("Cannot run child %s\n", err->message);
425
return checkoutput("test11");
429
* Run program, no args, inherit all ENV, keep CWD.
430
* Only stdin/out/err open. Set stdin data
432
static int test12(const void *unused ATTRIBUTE_UNUSED)
434
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
436
virCommandSetInputBuffer(cmd, "Hello World\n");
438
if (virCommandRun(cmd, NULL) < 0) {
439
virErrorPtr err = virGetLastError();
440
printf("Cannot run child %s\n", err->message);
447
return checkoutput("test12");
451
* Run program, no args, inherit all ENV, keep CWD.
452
* Only stdin/out/err open. Set stdin data
454
static int test13(const void *unused ATTRIBUTE_UNUSED)
456
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
457
char *outactual = NULL;
458
const char *outexpect = "BEGIN STDOUT\n"
463
virCommandSetInputBuffer(cmd, "Hello World\n");
464
virCommandSetOutputBuffer(cmd, &outactual);
466
if (virCommandRun(cmd, NULL) < 0) {
467
virErrorPtr err = virGetLastError();
468
printf("Cannot run child %s\n", err->message);
477
if (!STREQ(outactual, outexpect)) {
478
virtTestDifference(stderr, outactual, outexpect);
482
ret = checkoutput("test13");
491
* Run program, no args, inherit all ENV, keep CWD.
492
* Only stdin/out/err open. Set stdin data
494
static int test14(const void *unused ATTRIBUTE_UNUSED)
496
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
497
char *outactual = NULL;
498
const char *outexpect = "BEGIN STDOUT\n"
501
char *erractual = NULL;
502
const char *errexpect = "BEGIN STDERR\n"
507
virCommandSetInputBuffer(cmd, "Hello World\n");
508
virCommandSetOutputBuffer(cmd, &outactual);
509
virCommandSetErrorBuffer(cmd, &erractual);
511
if (virCommandRun(cmd, NULL) < 0) {
512
virErrorPtr err = virGetLastError();
513
printf("Cannot run child %s\n", err->message);
516
if (!outactual || !erractual)
522
if (!STREQ(outactual, outexpect)) {
523
virtTestDifference(stderr, outactual, outexpect);
526
if (!STREQ(erractual, errexpect)) {
527
virtTestDifference(stderr, erractual, errexpect);
531
ret = checkoutput("test14");
542
* Run program, no args, inherit all ENV, change CWD.
543
* Only stdin/out/err open
545
static int test15(const void *unused ATTRIBUTE_UNUSED)
547
virCommandPtr cmd = virCommandNew(abs_builddir "/commandhelper");
551
if (virAsprintf(&cwd, "%s/commanddata", abs_srcdir) < 0)
553
virCommandSetWorkingDirectory(cmd, cwd);
555
if (virCommandRun(cmd, NULL) < 0) {
556
virErrorPtr err = virGetLastError();
557
printf("Cannot run child %s\n", err->message);
561
ret = checkoutput("test15");
571
* Don't run program; rather, log what would be run.
573
static int test16(const void *unused ATTRIBUTE_UNUSED)
575
virCommandPtr cmd = virCommandNew("/bin/true");
576
char *outactual = NULL;
577
const char *outexpect = "A=B /bin/true C";
581
virCommandAddEnvPair(cmd, "A", "B");
582
virCommandAddArg(cmd, "C");
584
if ((outactual = virCommandToString(cmd)) == NULL) {
585
virErrorPtr err = virGetLastError();
586
printf("Cannot convert to string: %s\n", err->message);
589
if ((fd = open(abs_builddir "/commandhelper.log",
590
O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) {
591
printf("Cannot open log file: %s\n", strerror (errno));
594
virCommandWriteArgLog(cmd, fd);
595
if (VIR_CLOSE(fd) < 0) {
596
printf("Cannot close log file: %s\n", strerror (errno));
600
if (!STREQ(outactual, outexpect)) {
601
virtTestDifference(stderr, outactual, outexpect);
605
ret = checkoutput("test16");
615
* Test string handling when no output is present.
617
static int test17(const void *unused ATTRIBUTE_UNUSED)
619
virCommandPtr cmd = virCommandNew("/bin/true");
624
virCommandSetOutputBuffer(cmd, &outbuf);
625
if (outbuf != NULL) {
626
puts("buffer not sanitized at registration");
630
if (virCommandRun(cmd, NULL) < 0) {
631
virErrorPtr err = virGetLastError();
632
printf("Cannot run child %s\n", err->message);
636
if (!outbuf || *outbuf) {
637
puts("output buffer is not an allocated empty string");
641
if ((outbuf = strdup("should not be leaked")) == NULL) {
642
puts("test framework failure");
646
virCommandSetErrorBuffer(cmd, &errbuf);
647
if (errbuf != NULL) {
648
puts("buffer not sanitized at registration");
652
if (virCommandRun(cmd, NULL) < 0) {
653
virErrorPtr err = virGetLastError();
654
printf("Cannot run child %s\n", err->message);
658
if (!outbuf || *outbuf || !errbuf || *errbuf) {
659
puts("output buffers are not allocated empty strings");
672
* Run long-running daemon, to ensure no hang.
674
static int test18(const void *unused ATTRIBUTE_UNUSED)
676
virCommandPtr cmd = virCommandNewArgList("sleep", "100", NULL);
677
char *pidfile = virFilePid(abs_builddir, "commandhelper");
684
virCommandSetPidFile(cmd, pidfile);
685
virCommandDaemonize(cmd);
688
if (virCommandRun(cmd, NULL) < 0) {
689
virErrorPtr err = virGetLastError();
690
printf("Cannot run child %s\n", err->message);
695
if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
696
printf("cannot read pidfile\n");
699
while (kill(pid, SIGINT) != -1)
713
mymain(int argc, char **argv)
719
abs_srcdir = getenv("abs_srcdir");
721
abs_srcdir = getcwd(cwd, sizeof(cwd));
726
fprintf(stderr, "Usage: %s\n", progname);
727
return(EXIT_FAILURE);
730
if (chdir("/tmp") < 0)
731
return(EXIT_FAILURE);
733
/* Kill off any inherited fds that might interfere with our
744
const char *const newenv[] = {
745
"PATH=/usr/bin:/bin",
755
environ = (char **)newenv;
757
# define DO_TEST(NAME) \
758
if (virtTestRun("Command Exec " #NAME " test", \
759
1, NAME, NULL) < 0) \
782
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
787
VIRT_TEST_MAIN(mymain)