2010-05-25 15:14:06 +04:00
/*
* commandtest . c : Test the libCommand API
*
2012-01-28 03:35:14 +04:00
* Copyright ( C ) 2010 - 2012 Red Hat , Inc .
2010-05-25 15:14:06 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library 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
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2012-07-21 14:06:23 +04:00
* License along with this library ; If not , see
* < http : //www.gnu.org/licenses/>.
2010-05-25 15:14:06 +04:00
*/
# include <config.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <signal.h>
# include <sys/stat.h>
# include <fcntl.h>
# include "testutils.h"
# include "internal.h"
# include "nodeinfo.h"
# include "util.h"
# include "memory.h"
# include "command.h"
2011-07-19 22:32:58 +04:00
# include "virfile.h"
2011-08-13 01:54:49 +04:00
# include "virpidfile.h"
2012-06-01 01:50:07 +04:00
# include "virterror_internal.h"
# define VIR_FROM_THIS VIR_FROM_NONE
2010-05-25 15:14:06 +04:00
# ifdef WIN32
2011-07-28 19:48:12 +04:00
int
main ( void )
2010-05-25 15:14:06 +04:00
{
2011-07-28 19:48:12 +04:00
return EXIT_AM_SKIP ;
2010-05-25 15:14:06 +04:00
}
# else
2010-12-06 13:51:41 +03:00
static int checkoutput ( const char * testname )
{
2010-05-25 15:14:06 +04:00
int ret = - 1 ;
char * expectname = NULL ;
char * expectlog = NULL ;
char * actualname = NULL ;
char * actuallog = NULL ;
if ( virAsprintf ( & expectname , " %s/commanddata/%s.log " , abs_srcdir ,
testname ) < 0 )
goto cleanup ;
if ( virAsprintf ( & actualname , " %s/commandhelper.log " , abs_builddir ) < 0 )
goto cleanup ;
if ( virFileReadAll ( expectname , 1024 * 64 , & expectlog ) < 0 ) {
fprintf ( stderr , " cannot read %s \n " , expectname ) ;
goto cleanup ;
}
if ( virFileReadAll ( actualname , 1024 * 64 , & actuallog ) < 0 ) {
fprintf ( stderr , " cannot read %s \n " , actualname ) ;
goto cleanup ;
}
if ( STRNEQ ( expectlog , actuallog ) ) {
virtTestDifference ( stderr , expectlog , actuallog ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
2011-05-03 20:37:13 +04:00
if ( actualname )
unlink ( actualname ) ;
2010-05-25 15:14:06 +04:00
VIR_FREE ( actuallog ) ;
VIR_FREE ( actualname ) ;
VIR_FREE ( expectlog ) ;
VIR_FREE ( expectname ) ;
return ret ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open
* No slot for return status must log error .
*/
2010-12-06 13:51:41 +03:00
static int test0 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd ;
int ret = - 1 ;
cmd = virCommandNew ( abs_builddir " /commandhelper-doesnotexist " ) ;
if ( virCommandRun ( cmd , NULL ) = = 0 )
goto cleanup ;
2010-12-06 14:58:56 +03:00
if ( virGetLastError ( ) = = NULL )
2010-05-25 15:14:06 +04:00
goto cleanup ;
2010-12-06 14:58:56 +03:00
2010-05-25 15:14:06 +04:00
virResetLastError ( ) ;
ret = 0 ;
cleanup :
virCommandFree ( cmd ) ;
return ret ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open
* Capturing return status must not log error .
*/
2010-12-06 13:51:41 +03:00
static int test1 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd ;
int ret = - 1 ;
int status ;
cmd = virCommandNew ( abs_builddir " /commandhelper-doesnotexist " ) ;
if ( virCommandRun ( cmd , & status ) < 0 )
goto cleanup ;
if ( status = = 0 )
goto cleanup ;
ret = 0 ;
cleanup :
virCommandFree ( cmd ) ;
return ret ;
}
/*
* Run program ( twice ) , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test2 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
int ret ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
if ( ( ret = checkoutput ( " test2 " ) ) ! = 0 ) {
virCommandFree ( cmd ) ;
return ret ;
}
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test2 " ) ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* stdin / out / err + two extra FD open
*/
2010-12-06 13:51:41 +03:00
static int test3 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
int newfd1 = dup ( STDERR_FILENO ) ;
int newfd2 = dup ( STDERR_FILENO ) ;
int newfd3 = dup ( STDERR_FILENO ) ;
2010-12-07 00:48:11 +03:00
int ret = - 1 ;
2010-05-25 15:14:06 +04:00
virCommandPreserveFD ( cmd , newfd1 ) ;
virCommandTransferFD ( cmd , newfd3 ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
if ( fcntl ( newfd1 , F_GETFL ) < 0 | |
fcntl ( newfd2 , F_GETFL ) < 0 | |
fcntl ( newfd3 , F_GETFL ) > = 0 ) {
puts ( " fds in wrong state " ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
2010-12-07 00:48:11 +03:00
ret = checkoutput ( " test3 " ) ;
cleanup :
2010-05-25 15:14:06 +04:00
virCommandFree ( cmd ) ;
VIR_FORCE_CLOSE ( newfd1 ) ;
VIR_FORCE_CLOSE ( newfd2 ) ;
2010-12-07 00:48:11 +03:00
return ret ;
2010-05-25 15:14:06 +04:00
}
/*
* Run program , no args , inherit all ENV , CWD is /
* Only stdin / out / err open .
* Daemonized
*/
2010-12-06 13:51:41 +03:00
static int test4 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
2011-08-13 01:54:49 +04:00
char * pidfile = virPidFileBuildPath ( abs_builddir , " commandhelper " ) ;
2010-12-07 00:48:11 +03:00
pid_t pid ;
int ret = - 1 ;
if ( ! pidfile )
goto cleanup ;
2010-05-25 15:14:06 +04:00
virCommandSetPidFile ( cmd , pidfile ) ;
virCommandDaemonize ( cmd ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
2011-08-13 01:54:49 +04:00
if ( virPidFileRead ( abs_builddir , " commandhelper " , & pid ) < 0 ) {
2010-05-25 15:14:06 +04:00
printf ( " cannot read pidfile \n " ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
while ( kill ( pid , 0 ) ! = - 1 )
usleep ( 100 * 1000 ) ;
2010-12-07 00:48:11 +03:00
ret = checkoutput ( " test4 " ) ;
2010-05-25 15:14:06 +04:00
2010-12-07 00:48:11 +03:00
cleanup :
virCommandFree ( cmd ) ;
2011-05-03 20:37:13 +04:00
if ( pidfile )
unlink ( pidfile ) ;
2010-05-25 15:14:06 +04:00
VIR_FREE ( pidfile ) ;
2010-12-07 00:48:11 +03:00
return ret ;
2010-05-25 15:14:06 +04:00
}
/*
* Run program , no args , inherit filtered ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test5 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandAddEnvPassCommon ( cmd ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test5 " ) ;
}
/*
* Run program , no args , inherit filtered ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test6 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandAddEnvPass ( cmd , " DISPLAY " ) ;
virCommandAddEnvPass ( cmd , " DOESNOTEXIST " ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test6 " ) ;
}
/*
* Run program , no args , inherit filtered ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test7 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandAddEnvPassCommon ( cmd ) ;
virCommandAddEnvPass ( cmd , " DISPLAY " ) ;
virCommandAddEnvPass ( cmd , " DOESNOTEXIST " ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test7 " ) ;
}
/*
* Run program , no args , inherit filtered ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test8 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandAddEnvString ( cmd , " LANG=C " ) ;
virCommandAddEnvPair ( cmd , " USER " , " test " ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test8 " ) ;
}
/*
* Run program , some args , inherit all ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test9 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
const char * const args [ ] = { " arg1 " , " arg2 " , NULL } ;
2011-11-10 04:19:33 +04:00
virBuffer buf = VIR_BUFFER_INITIALIZER ;
2010-05-25 15:14:06 +04:00
virCommandAddArg ( cmd , " -version " ) ;
virCommandAddArgPair ( cmd , " -log " , " bar.log " ) ;
virCommandAddArgSet ( cmd , args ) ;
2011-11-10 04:19:33 +04:00
virCommandAddArgBuffer ( cmd , & buf ) ;
virBufferAddLit ( & buf , " arg4 " ) ;
virCommandAddArgBuffer ( cmd , & buf ) ;
virCommandAddArgList ( cmd , " arg5 " , " arg6 " , NULL ) ;
if ( virBufferUse ( & buf ) ) {
printf ( " Buffer not transferred \n " ) ;
virBufferFreeAndReset ( & buf ) ;
virCommandFree ( cmd ) ;
return - 1 ;
}
2010-05-25 15:14:06 +04:00
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test9 " ) ;
}
/*
* Run program , some args , inherit all ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test10 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
const char * const args [ ] = {
" -version " , " -log=bar.log " , NULL ,
} ;
virCommandAddArgSet ( cmd , args ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test10 " ) ;
}
/*
* Run program , some args , inherit all ENV , keep CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test11 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
const char * args [ ] = {
abs_builddir " /commandhelper " ,
" -version " , " -log=bar.log " , NULL ,
} ;
virCommandPtr cmd = virCommandNewArgs ( args ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test11 " ) ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open . Set stdin data
*/
2010-12-06 13:51:41 +03:00
static int test12 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandSetInputBuffer ( cmd , " Hello World \n " ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
return - 1 ;
}
virCommandFree ( cmd ) ;
return checkoutput ( " test12 " ) ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open . Set stdin data
*/
2010-12-06 13:51:41 +03:00
static int test13 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
char * outactual = NULL ;
const char * outexpect = " BEGIN STDOUT \n "
" Hello World \n "
" END STDOUT \n " ;
int ret = - 1 ;
virCommandSetInputBuffer ( cmd , " Hello World \n " ) ;
virCommandSetOutputBuffer ( cmd , & outactual ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
2010-12-07 00:48:11 +03:00
if ( ! outactual )
goto cleanup ;
2010-05-25 15:14:06 +04:00
virCommandFree ( cmd ) ;
2010-12-07 00:48:11 +03:00
cmd = NULL ;
2010-05-25 15:14:06 +04:00
if ( ! STREQ ( outactual , outexpect ) ) {
2012-01-28 03:35:14 +04:00
virtTestDifference ( stderr , outexpect , outactual ) ;
2010-05-25 15:14:06 +04:00
goto cleanup ;
}
2010-12-07 00:48:11 +03:00
ret = checkoutput ( " test13 " ) ;
2010-05-25 15:14:06 +04:00
cleanup :
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
VIR_FREE ( outactual ) ;
return ret ;
}
/*
* Run program , no args , inherit all ENV , keep CWD .
* Only stdin / out / err open . Set stdin data
*/
2010-12-06 13:51:41 +03:00
static int test14 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
char * outactual = NULL ;
const char * outexpect = " BEGIN STDOUT \n "
" Hello World \n "
" END STDOUT \n " ;
char * erractual = NULL ;
const char * errexpect = " BEGIN STDERR \n "
" Hello World \n "
" END STDERR \n " ;
2012-01-28 02:40:20 +04:00
char * jointactual = NULL ;
const char * jointexpect = " BEGIN STDOUT \n "
" BEGIN STDERR \n "
" Hello World \n "
" Hello World \n "
" END STDOUT \n "
" END STDERR \n " ;
2010-05-25 15:14:06 +04:00
int ret = - 1 ;
virCommandSetInputBuffer ( cmd , " Hello World \n " ) ;
virCommandSetOutputBuffer ( cmd , & outactual ) ;
virCommandSetErrorBuffer ( cmd , & erractual ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
2010-12-07 00:48:11 +03:00
if ( ! outactual | | ! erractual )
goto cleanup ;
2010-05-25 15:14:06 +04:00
virCommandFree ( cmd ) ;
2012-01-28 02:40:20 +04:00
cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
virCommandSetInputBuffer ( cmd , " Hello World \n " ) ;
virCommandSetOutputBuffer ( cmd , & jointactual ) ;
virCommandSetErrorBuffer ( cmd , & jointactual ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
if ( ! jointactual )
goto cleanup ;
2010-05-25 15:14:06 +04:00
if ( ! STREQ ( outactual , outexpect ) ) {
2012-01-28 03:35:14 +04:00
virtTestDifference ( stderr , outexpect , outactual ) ;
2010-05-25 15:14:06 +04:00
goto cleanup ;
}
if ( ! STREQ ( erractual , errexpect ) ) {
2012-01-28 03:35:14 +04:00
virtTestDifference ( stderr , errexpect , erractual ) ;
2010-05-25 15:14:06 +04:00
goto cleanup ;
}
2012-01-28 02:40:20 +04:00
if ( ! STREQ ( jointactual , jointexpect ) ) {
virtTestDifference ( stderr , jointexpect , jointactual ) ;
goto cleanup ;
}
2010-05-25 15:14:06 +04:00
2010-12-07 00:48:11 +03:00
ret = checkoutput ( " test14 " ) ;
2010-05-25 15:14:06 +04:00
cleanup :
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
VIR_FREE ( outactual ) ;
VIR_FREE ( erractual ) ;
2012-01-28 02:40:20 +04:00
VIR_FREE ( jointactual ) ;
2010-05-25 15:14:06 +04:00
return ret ;
}
/*
* Run program , no args , inherit all ENV , change CWD .
* Only stdin / out / err open
*/
2010-12-06 13:51:41 +03:00
static int test15 ( const void * unused ATTRIBUTE_UNUSED )
{
2010-05-25 15:14:06 +04:00
virCommandPtr cmd = virCommandNew ( abs_builddir " /commandhelper " ) ;
2010-12-06 15:03:26 +03:00
char * cwd = NULL ;
int ret = - 1 ;
2010-05-25 15:14:06 +04:00
2010-12-06 15:03:26 +03:00
if ( virAsprintf ( & cwd , " %s/commanddata " , abs_srcdir ) < 0 )
goto cleanup ;
virCommandSetWorkingDirectory ( cmd , cwd ) ;
2010-05-25 15:14:06 +04:00
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
2010-12-06 15:03:26 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
2010-12-06 15:03:26 +03:00
ret = checkoutput ( " test15 " ) ;
cleanup :
VIR_FREE ( cwd ) ;
2010-05-25 15:14:06 +04:00
virCommandFree ( cmd ) ;
2010-12-06 15:03:26 +03:00
return ret ;
2010-05-25 15:14:06 +04:00
}
/*
* Don ' t run program ; rather , log what would be run .
*/
2010-12-06 13:51:41 +03:00
static int test16 ( const void * unused ATTRIBUTE_UNUSED )
{
2011-07-28 19:51:26 +04:00
virCommandPtr cmd = virCommandNew ( " true " ) ;
2010-05-25 15:14:06 +04:00
char * outactual = NULL ;
2011-07-28 19:51:26 +04:00
const char * outexpect = " A=B true C " ;
2010-05-25 15:14:06 +04:00
int ret = - 1 ;
int fd = - 1 ;
virCommandAddEnvPair ( cmd , " A " , " B " ) ;
virCommandAddArg ( cmd , " C " ) ;
if ( ( outactual = virCommandToString ( cmd ) ) = = NULL ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot convert to string: %s \n " , err - > message ) ;
2010-12-07 00:48:11 +03:00
goto cleanup ;
2010-05-25 15:14:06 +04:00
}
if ( ( fd = open ( abs_builddir " /commandhelper.log " ,
O_CREAT | O_TRUNC | O_WRONLY , 0600 ) ) < 0 ) {
printf ( " Cannot open log file: %s \n " , strerror ( errno ) ) ;
goto cleanup ;
}
virCommandWriteArgLog ( cmd , fd ) ;
if ( VIR_CLOSE ( fd ) < 0 ) {
printf ( " Cannot close log file: %s \n " , strerror ( errno ) ) ;
goto cleanup ;
}
if ( ! STREQ ( outactual , outexpect ) ) {
2012-01-28 03:35:14 +04:00
virtTestDifference ( stderr , outexpect , outactual ) ;
2010-05-25 15:14:06 +04:00
goto cleanup ;
}
2010-12-07 00:48:11 +03:00
ret = checkoutput ( " test16 " ) ;
2010-05-25 15:14:06 +04:00
cleanup :
2010-12-07 00:48:11 +03:00
virCommandFree ( cmd ) ;
2010-05-25 15:14:06 +04:00
VIR_FORCE_CLOSE ( fd ) ;
VIR_FREE ( outactual ) ;
return ret ;
}
2010-12-04 00:14:16 +03:00
/*
* Test string handling when no output is present .
*/
static int test17 ( const void * unused ATTRIBUTE_UNUSED )
{
2011-07-28 19:51:26 +04:00
virCommandPtr cmd = virCommandNew ( " true " ) ;
2010-12-04 00:14:16 +03:00
int ret = - 1 ;
char * outbuf ;
char * errbuf ;
virCommandSetOutputBuffer ( cmd , & outbuf ) ;
if ( outbuf ! = NULL ) {
puts ( " buffer not sanitized at registration " ) ;
goto cleanup ;
}
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
if ( ! outbuf | | * outbuf ) {
puts ( " output buffer is not an allocated empty string " ) ;
goto cleanup ;
}
VIR_FREE ( outbuf ) ;
if ( ( outbuf = strdup ( " should not be leaked " ) ) = = NULL ) {
puts ( " test framework failure " ) ;
goto cleanup ;
}
virCommandSetErrorBuffer ( cmd , & errbuf ) ;
if ( errbuf ! = NULL ) {
puts ( " buffer not sanitized at registration " ) ;
goto cleanup ;
}
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
if ( ! outbuf | | * outbuf | | ! errbuf | | * errbuf ) {
puts ( " output buffers are not allocated empty strings " ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
virCommandFree ( cmd ) ;
VIR_FREE ( outbuf ) ;
VIR_FREE ( errbuf ) ;
return ret ;
}
2010-12-21 21:49:49 +03:00
/*
* Run long - running daemon , to ensure no hang .
*/
static int test18 ( const void * unused ATTRIBUTE_UNUSED )
{
virCommandPtr cmd = virCommandNewArgList ( " sleep " , " 100 " , NULL ) ;
2011-08-13 01:54:49 +04:00
char * pidfile = virPidFileBuildPath ( abs_builddir , " commandhelper " ) ;
2010-12-21 21:49:49 +03:00
pid_t pid ;
int ret = - 1 ;
if ( ! pidfile )
goto cleanup ;
virCommandSetPidFile ( cmd , pidfile ) ;
virCommandDaemonize ( cmd ) ;
alarm ( 5 ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
alarm ( 0 ) ;
2011-08-13 01:54:49 +04:00
if ( virPidFileRead ( abs_builddir , " commandhelper " , & pid ) < 0 ) {
2010-12-21 21:49:49 +03:00
printf ( " cannot read pidfile \n " ) ;
goto cleanup ;
}
2011-03-23 01:22:37 +03:00
virCommandFree ( cmd ) ;
cmd = NULL ;
if ( kill ( pid , 0 ) ! = 0 ) {
printf ( " daemon should still be running \n " ) ;
goto cleanup ;
}
2010-12-21 21:49:49 +03:00
while ( kill ( pid , SIGINT ) ! = - 1 )
usleep ( 100 * 1000 ) ;
ret = 0 ;
cleanup :
virCommandFree ( cmd ) ;
2011-05-03 20:37:13 +04:00
if ( pidfile )
unlink ( pidfile ) ;
2010-12-21 21:49:49 +03:00
VIR_FREE ( pidfile ) ;
return ret ;
}
2011-03-23 01:22:37 +03:00
/*
* Asynchronously run long - running daemon , to ensure no hang .
*/
static int test19 ( const void * unused ATTRIBUTE_UNUSED )
{
virCommandPtr cmd = virCommandNewArgList ( " sleep " , " 100 " , NULL ) ;
pid_t pid ;
int ret = - 1 ;
alarm ( 5 ) ;
if ( virCommandRunAsync ( cmd , & pid ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
if ( kill ( pid , 0 ) ! = 0 ) {
printf ( " Child should still be running " ) ;
goto cleanup ;
}
virCommandAbort ( cmd ) ;
if ( kill ( pid , 0 ) = = 0 ) {
printf ( " Child should be aborted " ) ;
goto cleanup ;
}
alarm ( 0 ) ;
ret = 0 ;
cleanup :
virCommandFree ( cmd ) ;
return ret ;
}
2010-12-21 21:49:49 +03:00
2012-06-01 01:50:07 +04:00
/*
* Run program , no args , inherit all ENV , keep CWD .
* Ignore huge stdin data , to provoke SIGPIPE or EPIPE in parent .
*/
static int test20 ( const void * unused ATTRIBUTE_UNUSED )
{
virCommandPtr cmd = virCommandNewArgList ( abs_builddir " /commandhelper " ,
" --close-stdin " , NULL ) ;
char * buf ;
int ret = - 1 ;
struct sigaction sig_action ;
sig_action . sa_handler = SIG_IGN ;
sig_action . sa_flags = 0 ;
sigemptyset ( & sig_action . sa_mask ) ;
sigaction ( SIGPIPE , & sig_action , NULL ) ;
if ( virAsprintf ( & buf , " 1 \n %100000d \n " , 2 ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
virCommandSetInputBuffer ( cmd , buf ) ;
if ( virCommandRun ( cmd , NULL ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
printf ( " Cannot run child %s \n " , err - > message ) ;
goto cleanup ;
}
ret = checkoutput ( " test20 " ) ;
cleanup :
virCommandFree ( cmd ) ;
VIR_FREE ( buf ) ;
return ret ;
}
2011-05-11 19:51:30 +04:00
static const char * const newenv [ ] = {
" PATH=/usr/bin:/bin " ,
" HOSTNAME=test " ,
" LANG=C " ,
" HOME=/home/test " ,
" USER=test " ,
" LOGNAME=test "
" TMPDIR=/tmp " ,
" DISPLAY=:0.0 " ,
NULL
} ;
2010-05-25 15:14:06 +04:00
static int
2011-04-29 20:21:20 +04:00
mymain ( void )
2010-05-25 15:14:06 +04:00
{
int ret = 0 ;
2011-01-29 00:22:39 +03:00
int fd ;
2010-05-25 15:14:06 +04:00
if ( chdir ( " /tmp " ) < 0 )
2012-03-22 15:33:35 +04:00
return EXIT_FAILURE ;
2010-05-25 15:14:06 +04:00
2011-02-24 15:12:27 +03:00
setpgid ( 0 , 0 ) ;
2012-04-28 01:25:35 +04:00
ignore_value ( setsid ( ) ) ;
2011-02-24 15:12:27 +03:00
2012-01-07 01:07:23 +04:00
/* Our test expects particular fd values; to get that, we must not
* leak fds that we inherited from a lazy parent . At the same
* time , virInitialize may open some fds ( perhaps via third - party
* libraries that it uses ) , and we must not kill off an fd that
* this process opens as it might break expectations of a
* pthread_atfork handler , as well as interfering with our tests
* trying to ensure we aren ' t leaking to our children . The
* solution is to do things in two phases - reserve the fds we
* want by overwriting any externally inherited fds , then
* initialize , then clear the slots for testing . */
if ( ( fd = open ( " /dev/null " , O_RDONLY ) ) < 0 | |
dup2 ( fd , 3 ) < 0 | |
dup2 ( fd , 4 ) < 0 | |
dup2 ( fd , 5 ) < 0 | |
( fd > 5 & & VIR_CLOSE ( fd ) < 0 ) )
return EXIT_FAILURE ;
2011-08-25 15:05:54 +04:00
/* Prime the debug/verbose settings from the env vars,
* since we ' re about to reset ' environ ' */
2012-04-28 01:25:35 +04:00
ignore_value ( virTestGetDebug ( ) ) ;
ignore_value ( virTestGetVerbose ( ) ) ;
2011-08-25 15:05:54 +04:00
2012-04-28 01:25:35 +04:00
if ( virInitialize ( ) < 0 )
return EXIT_FAILURE ;
2012-01-07 01:07:23 +04:00
/* Phase two of killing interfering fds; see above. */
2011-01-29 00:22:39 +03:00
fd = 3 ;
VIR_FORCE_CLOSE ( fd ) ;
fd = 4 ;
VIR_FORCE_CLOSE ( fd ) ;
fd = 5 ;
VIR_FORCE_CLOSE ( fd ) ;
2010-12-11 01:30:56 +03:00
2010-05-25 15:14:06 +04:00
environ = ( char * * ) newenv ;
# define DO_TEST(NAME) \
if ( virtTestRun ( " Command Exec " # NAME " test " , \
1 , NAME , NULL ) < 0 ) \
ret = - 1
DO_TEST ( test0 ) ;
DO_TEST ( test1 ) ;
DO_TEST ( test2 ) ;
DO_TEST ( test3 ) ;
DO_TEST ( test4 ) ;
DO_TEST ( test5 ) ;
DO_TEST ( test6 ) ;
DO_TEST ( test7 ) ;
DO_TEST ( test8 ) ;
DO_TEST ( test9 ) ;
DO_TEST ( test10 ) ;
DO_TEST ( test11 ) ;
DO_TEST ( test12 ) ;
DO_TEST ( test13 ) ;
DO_TEST ( test14 ) ;
DO_TEST ( test15 ) ;
DO_TEST ( test16 ) ;
2010-12-04 00:14:16 +03:00
DO_TEST ( test17 ) ;
2010-12-21 21:49:49 +03:00
DO_TEST ( test18 ) ;
2011-03-23 01:22:37 +03:00
DO_TEST ( test19 ) ;
2012-06-01 01:50:07 +04:00
DO_TEST ( test20 ) ;
2010-05-25 15:14:06 +04:00
2012-03-22 15:33:35 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
2010-05-25 15:14:06 +04:00
}
VIRT_TEST_MAIN ( mymain )
2011-07-28 19:48:12 +04:00
# endif /* !WIN32 */