2013-07-18 13:54:21 +04:00
/*
2014-03-17 13:38:38 +04:00
* Copyright ( C ) 2013 , 2014 Red Hat , Inc .
2013-07-18 13:54:21 +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
* License along with this library . If not , see
* < http : //www.gnu.org/licenses/>.
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
# include <config.h>
# include "testutils.h"
2014-05-21 01:04:44 +04:00
# if defined(WITH_DBUS) && defined(__linux__)
2013-09-17 21:11:25 +04:00
# include <stdlib.h>
2014-03-12 16:20:07 +04:00
# include <dbus / dbus.h>
2013-09-17 21:11:25 +04:00
# include "virsystemd.h"
# include "virlog.h"
2014-03-12 16:20:07 +04:00
# include "virmock.h"
2013-09-17 21:11:25 +04:00
# define VIR_FROM_THIS VIR_FROM_NONE
2013-07-18 13:54:21 +04:00
2014-02-28 16:16:17 +04:00
VIR_LOG_INIT ( " tests.systemdtest " ) ;
2014-06-03 15:02:52 +04:00
VIR_MOCK_WRAP_RET_ARGS ( dbus_connection_send_with_reply_and_block ,
2014-03-12 16:20:07 +04:00
DBusMessage * ,
DBusConnection * , connection ,
DBusMessage * , message ,
int , timeout_milliseconds ,
DBusError * , error )
{
DBusMessage * reply = NULL ;
const char * service = dbus_message_get_destination ( message ) ;
const char * member = dbus_message_get_member ( message ) ;
2014-06-03 15:02:52 +04:00
VIR_MOCK_REAL_INIT ( dbus_connection_send_with_reply_and_block ) ;
2014-03-12 16:20:07 +04:00
if ( STREQ ( service , " org.freedesktop.machine1 " ) ) {
if ( getenv ( " FAIL_BAD_SERVICE " ) ) {
dbus_set_error_const ( error ,
" org.freedesktop.systemd.badthing " ,
" Something went wrong creating the machine " ) ;
} else {
reply = dbus_message_new ( DBUS_MESSAGE_TYPE_METHOD_RETURN ) ;
}
2014-04-11 11:20:48 +04:00
} else if ( STREQ ( service , " org.freedesktop.login1 " ) ) {
char * supported = getenv ( " RESULT_SUPPORT " ) ;
DBusMessageIter iter ;
reply = dbus_message_new ( DBUS_MESSAGE_TYPE_METHOD_RETURN ) ;
dbus_message_iter_init_append ( reply , & iter ) ;
if ( ! dbus_message_iter_append_basic ( & iter ,
DBUS_TYPE_STRING ,
& supported ) )
goto error ;
2014-03-12 16:20:07 +04:00
} else if ( STREQ ( service , " org.freedesktop.DBus " ) & &
STREQ ( member , " ListActivatableNames " ) ) {
const char * svc1 = " org.foo.bar.wizz " ;
const char * svc2 = " org.freedesktop.machine1 " ;
2014-04-11 11:20:48 +04:00
const char * svc3 = " org.freedesktop.login1 " ;
2014-03-12 16:20:07 +04:00
DBusMessageIter iter ;
DBusMessageIter sub ;
reply = dbus_message_new ( DBUS_MESSAGE_TYPE_METHOD_RETURN ) ;
dbus_message_iter_init_append ( reply , & iter ) ;
dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY ,
" s " , & sub ) ;
if ( ! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc1 ) )
goto error ;
if ( ! getenv ( " FAIL_NO_SERVICE " ) & &
! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc2 ) )
goto error ;
2014-04-11 11:20:48 +04:00
if ( ! getenv ( " FAIL_NO_SERVICE " ) & &
! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc3 ) )
goto error ;
2014-03-12 16:20:07 +04:00
dbus_message_iter_close_container ( & iter , & sub ) ;
} else if ( STREQ ( service , " org.freedesktop.DBus " ) & &
STREQ ( member , " ListNames " ) ) {
const char * svc1 = " org.foo.bar.wizz " ;
const char * svc2 = " org.freedesktop.systemd1 " ;
2014-04-11 11:20:48 +04:00
const char * svc3 = " org.freedesktop.login1 " ;
2014-03-12 16:20:07 +04:00
DBusMessageIter iter ;
DBusMessageIter sub ;
reply = dbus_message_new ( DBUS_MESSAGE_TYPE_METHOD_RETURN ) ;
dbus_message_iter_init_append ( reply , & iter ) ;
dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY ,
" s " , & sub ) ;
if ( ! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc1 ) )
goto error ;
if ( ( ! getenv ( " FAIL_NO_SERVICE " ) & & ! getenv ( " FAIL_NOT_REGISTERED " ) ) & &
! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc2 ) )
goto error ;
2014-04-11 11:20:48 +04:00
if ( ( ! getenv ( " FAIL_NO_SERVICE " ) & & ! getenv ( " FAIL_NOT_REGISTERED " ) ) & &
! dbus_message_iter_append_basic ( & sub ,
DBUS_TYPE_STRING ,
& svc3 ) )
goto error ;
2014-03-12 16:20:07 +04:00
dbus_message_iter_close_container ( & iter , & sub ) ;
} else {
reply = dbus_message_new ( DBUS_MESSAGE_TYPE_METHOD_RETURN ) ;
}
return reply ;
error :
dbus_message_unref ( reply ) ;
return NULL ;
}
2013-07-18 13:54:21 +04:00
static int testCreateContainer ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
if ( virSystemdCreateMachine ( " demo " ,
" lxc " ,
true ,
uuid ,
" /proc/123/root " ,
123 ,
true ,
2014-11-11 20:38:43 +03:00
0 , NULL ,
2013-07-18 13:54:21 +04:00
" highpriority.slice " ) < 0 ) {
fprintf ( stderr , " %s " , " Failed to create LXC machine \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-09-30 18:46:29 +04:00
static int testTerminateContainer ( const void * opaque ATTRIBUTE_UNUSED )
{
if ( virSystemdTerminateMachine ( " demo " ,
" lxc " ,
true ) < 0 ) {
fprintf ( stderr , " %s " , " Failed to terminate LXC machine \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-07-18 13:54:21 +04:00
static int testCreateMachine ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
if ( virSystemdCreateMachine ( " demo " ,
" qemu " ,
false ,
uuid ,
NULL ,
123 ,
false ,
2014-11-11 20:38:43 +03:00
0 , NULL ,
2013-07-18 13:54:21 +04:00
NULL ) < 0 ) {
fprintf ( stderr , " %s " , " Failed to create KVM machine \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-09-30 18:46:29 +04:00
static int testTerminateMachine ( const void * opaque ATTRIBUTE_UNUSED )
{
if ( virSystemdTerminateMachine ( " demo " ,
" qemu " ,
false ) < 0 ) {
fprintf ( stderr , " %s " , " Failed to terminate KVM machine \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-07-18 13:54:21 +04:00
static int testCreateNoSystemd ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
2013-07-22 19:33:37 +04:00
int rv ;
2013-07-18 13:54:21 +04:00
setenv ( " FAIL_NO_SERVICE " , " 1 " , 1 ) ;
2013-07-22 19:33:37 +04:00
if ( ( rv = virSystemdCreateMachine ( " demo " ,
" qemu " ,
true ,
uuid ,
NULL ,
123 ,
false ,
2014-11-11 20:38:43 +03:00
0 , NULL ,
2013-07-22 19:33:37 +04:00
NULL ) ) = = 0 ) {
2013-09-11 18:29:52 +04:00
unsetenv ( " FAIL_NO_SERVICE " ) ;
2013-07-18 13:54:21 +04:00
fprintf ( stderr , " %s " , " Unexpected create machine success \n " ) ;
return - 1 ;
}
2013-09-11 18:29:52 +04:00
unsetenv ( " FAIL_NO_SERVICE " ) ;
2013-07-18 13:54:21 +04:00
2013-07-22 19:33:37 +04:00
if ( rv ! = - 2 ) {
fprintf ( stderr , " %s " , " Unexpected create machine error \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-07-18 13:54:21 +04:00
2014-02-28 00:21:57 +04:00
static int testCreateSystemdNotRunning ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
int rv ;
setenv ( " FAIL_NOT_REGISTERED " , " 1 " , 1 ) ;
if ( ( rv = virSystemdCreateMachine ( " demo " ,
" qemu " ,
true ,
uuid ,
NULL ,
123 ,
false ,
2014-11-11 20:38:43 +03:00
0 , NULL ,
2014-02-28 00:21:57 +04:00
NULL ) ) = = 0 ) {
unsetenv ( " FAIL_NOT_REGISTERED " ) ;
fprintf ( stderr , " %s " , " Unexpected create machine success \n " ) ;
return - 1 ;
}
unsetenv ( " FAIL_NOT_REGISTERED " ) ;
if ( rv ! = - 2 ) {
fprintf ( stderr , " %s " , " Unexpected create machine error \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-07-22 19:33:37 +04:00
static int testCreateBadSystemd ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
int rv ;
setenv ( " FAIL_BAD_SERVICE " , " 1 " , 1 ) ;
if ( ( rv = virSystemdCreateMachine ( " demo " ,
" qemu " ,
true ,
uuid ,
NULL ,
123 ,
false ,
2014-11-11 20:38:43 +03:00
0 , NULL ,
2013-07-22 19:33:37 +04:00
NULL ) ) = = 0 ) {
2013-09-11 18:29:52 +04:00
unsetenv ( " FAIL_BAD_SERVICE " ) ;
2013-07-22 19:33:37 +04:00
fprintf ( stderr , " %s " , " Unexpected create machine success \n " ) ;
2013-07-18 13:54:21 +04:00
return - 1 ;
}
2013-09-11 18:29:52 +04:00
unsetenv ( " FAIL_BAD_SERVICE " ) ;
2013-07-18 13:54:21 +04:00
2013-07-22 19:33:37 +04:00
if ( rv ! = - 1 ) {
fprintf ( stderr , " %s " , " Unexpected create machine error \n " ) ;
return - 1 ;
}
2013-07-18 13:54:21 +04:00
2013-07-22 19:33:37 +04:00
return 0 ;
2013-07-18 13:54:21 +04:00
}
2013-07-26 18:18:55 +04:00
2014-11-11 20:38:43 +03:00
static int testCreateNetwork ( const void * opaque ATTRIBUTE_UNUSED )
{
unsigned char uuid [ VIR_UUID_BUFLEN ] = {
1 , 1 , 1 , 1 ,
2 , 2 , 2 , 2 ,
3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4
} ;
int nicindexes [ ] = {
2 , 1729 , 87539319 ,
} ;
size_t nnicindexes = ARRAY_CARDINALITY ( nicindexes ) ;
if ( virSystemdCreateMachine ( " demo " ,
" lxc " ,
true ,
uuid ,
" /proc/123/root " ,
123 ,
true ,
nnicindexes , nicindexes ,
" highpriority.slice " ) < 0 ) {
fprintf ( stderr , " %s " , " Failed to create LXC machine \n " ) ;
return - 1 ;
}
return 0 ;
}
2015-11-24 17:56:12 +03:00
struct testNameData {
2013-07-26 18:18:55 +04:00
const char * name ;
const char * expected ;
} ;
static int
testScopeName ( const void * opaque )
{
2015-11-24 17:56:12 +03:00
const struct testNameData * data = opaque ;
2013-07-26 18:18:55 +04:00
int ret = - 1 ;
char * actual = NULL ;
2015-07-16 16:35:05 +03:00
if ( ! ( actual = virSystemdMakeScopeName ( data - > name , " lxc " ) ) )
2013-07-26 18:18:55 +04:00
goto cleanup ;
if ( STRNEQ ( actual , data - > expected ) ) {
fprintf ( stderr , " Expected '%s' but got '%s' \n " ,
data - > expected , actual ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
VIR_FREE ( actual ) ;
return ret ;
}
2015-11-24 17:56:12 +03:00
static int
testMachineName ( const void * opaque )
{
const struct testNameData * data = opaque ;
int ret = - 1 ;
char * actual = NULL ;
if ( ! ( actual = virSystemdMakeMachineName ( data - > name , " qemu " , true ) ) )
goto cleanup ;
if ( STRNEQ ( actual , data - > expected ) ) {
fprintf ( stderr , " Expected '%s' but got '%s' \n " ,
data - > expected , actual ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
VIR_FREE ( actual ) ;
return ret ;
}
2014-04-11 11:20:48 +04:00
typedef int ( * virSystemdCanHelper ) ( bool * result ) ;
struct testPMSupportData {
virSystemdCanHelper tested ;
} ;
static int testPMSupportHelper ( const void * opaque )
{
int rv ;
bool result ;
size_t i ;
const char * results [ 4 ] = { " yes " , " no " , " na " , " challenge " } ;
int expected [ 4 ] = { 1 , 0 , 0 , 1 } ;
const struct testPMSupportData * data = opaque ;
for ( i = 0 ; i < 4 ; i + + ) {
setenv ( " RESULT_SUPPORT " , results [ i ] , 1 ) ;
if ( ( rv = data - > tested ( & result ) ) < 0 ) {
fprintf ( stderr , " %s " , " Unexpected canSuspend error \n " ) ;
return - 1 ;
}
if ( result ! = expected [ i ] ) {
fprintf ( stderr , " Unexpected result for answer '%s' \n " , results [ i ] ) ;
goto error ;
}
unsetenv ( " RESULT_SUPPORT " ) ;
}
return 0 ;
error :
unsetenv ( " RESULT_SUPPORT " ) ;
return - 1 ;
}
static int testPMSupportHelperNoSystemd ( const void * opaque )
{
int rv ;
bool result ;
const struct testPMSupportData * data = opaque ;
setenv ( " FAIL_NO_SERVICE " , " 1 " , 1 ) ;
if ( ( rv = data - > tested ( & result ) ) = = 0 ) {
unsetenv ( " FAIL_NO_SERVICE " ) ;
fprintf ( stderr , " %s " , " Unexpected canSuspend success \n " ) ;
return - 1 ;
}
unsetenv ( " FAIL_NO_SERVICE " ) ;
if ( rv ! = - 2 ) {
fprintf ( stderr , " %s " , " Unexpected canSuspend error \n " ) ;
return - 1 ;
}
return 0 ;
}
static int testPMSupportSystemdNotRunning ( const void * opaque )
{
int rv ;
bool result ;
const struct testPMSupportData * data = opaque ;
setenv ( " FAIL_NOT_REGISTERED " , " 1 " , 1 ) ;
if ( ( rv = data - > tested ( & result ) ) = = 0 ) {
unsetenv ( " FAIL_NOT_REGISTERED " ) ;
fprintf ( stderr , " %s " , " Unexpected canSuspend success \n " ) ;
return - 1 ;
}
unsetenv ( " FAIL_NOT_REGISTERED " ) ;
if ( rv ! = - 2 ) {
fprintf ( stderr , " %s " , " Unexpected canSuspend error \n " ) ;
return - 1 ;
}
return 0 ;
}
2013-07-18 13:54:21 +04:00
static int
mymain ( void )
{
int ret = 0 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test create container " , testCreateContainer , NULL ) < 0 )
2013-07-18 13:54:21 +04:00
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test terminate container " , testTerminateContainer , NULL ) < 0 )
2013-09-30 18:46:29 +04:00
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test create machine " , testCreateMachine , NULL ) < 0 )
2013-07-18 13:54:21 +04:00
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test terminate machine " , testTerminateMachine , NULL ) < 0 )
2013-09-30 18:46:29 +04:00
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test create no systemd " , testCreateNoSystemd , NULL ) < 0 )
2013-07-22 19:33:37 +04:00
ret = - 1 ;
2014-02-28 00:21:57 +04:00
if ( virtTestRun ( " Test create systemd not running " ,
testCreateSystemdNotRunning , NULL ) < 0 )
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test create bad systemd " , testCreateBadSystemd , NULL ) < 0 )
2013-07-18 13:54:21 +04:00
ret = - 1 ;
2014-11-11 20:38:43 +03:00
if ( virtTestRun ( " Test create with network " , testCreateNetwork , NULL ) < 0 )
ret = - 1 ;
2013-07-18 13:54:21 +04:00
2015-07-16 16:35:05 +03:00
# define TEST_SCOPE(name, unitname) \
2013-07-26 18:18:55 +04:00
do { \
2015-11-24 17:56:12 +03:00
struct testNameData data = { \
2015-07-16 16:35:05 +03:00
name , unitname \
2013-07-26 18:18:55 +04:00
} ; \
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Test scopename " , testScopeName , & data ) < 0 ) \
2013-07-26 18:18:55 +04:00
ret = - 1 ; \
} while ( 0 )
2015-07-16 16:35:05 +03:00
TEST_SCOPE ( " demo " , " machine-lxc \\ x2ddemo.scope " ) ;
TEST_SCOPE ( " demo-name " , " machine-lxc \\ x2ddemo \\ x2dname.scope " ) ;
TEST_SCOPE ( " demo!name " , " machine-lxc \\ x2ddemo \\ x21name.scope " ) ;
TEST_SCOPE ( " .demo " , " machine-lxc \\ x2d \\ x2edemo.scope " ) ;
2015-11-24 17:56:12 +03:00
TEST_SCOPE ( " bull💩 " , " machine-lxc \\ x2dbull \\ xf0 \\ x9f \\ x92 \\ xa9.scope " ) ;
# define TEST_MACHINE(name, machinename) \
do { \
struct testNameData data = { \
name , machinename \
} ; \
if ( virtTestRun ( " Test scopename " , testMachineName , & data ) < 0 ) \
ret = - 1 ; \
} while ( 0 )
TEST_MACHINE ( " demo " , " qemu-demo " ) ;
TEST_MACHINE ( " demo-name " , " qemu-demo \\ x2dname " ) ;
TEST_MACHINE ( " demo!name " , " qemu-demo \\ x21name " ) ;
TEST_MACHINE ( " .demo " , " qemu- \\ x2edemo " ) ;
TEST_MACHINE ( " bull \U0001f4a9 " , " qemu-bull \\ xf0 \\ x9f \\ x92 \\ xa9 " ) ;
2013-07-26 18:18:55 +04:00
2014-04-11 11:20:48 +04:00
# define TESTS_PM_SUPPORT_HELPER(name, function) \
do { \
struct testPMSupportData data = { \
function \
} ; \
if ( virtTestRun ( " Test " name " " , testPMSupportHelper , & data ) < 0 ) \
ret = - 1 ; \
if ( virtTestRun ( " Test " name " no systemd " , \
testPMSupportHelperNoSystemd , & data ) < 0 ) \
ret = - 1 ; \
if ( virtTestRun ( " Test systemd " name " not running " , \
testPMSupportSystemdNotRunning , & data ) < 0 ) \
ret = - 1 ; \
} while ( 0 )
TESTS_PM_SUPPORT_HELPER ( " canSuspend " , & virSystemdCanSuspend ) ;
TESTS_PM_SUPPORT_HELPER ( " canHibernate " , & virSystemdCanHibernate ) ;
TESTS_PM_SUPPORT_HELPER ( " canHybridSleep " , & virSystemdCanHybridSleep ) ;
2014-03-17 13:38:38 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
2013-07-18 13:54:21 +04:00
}
2014-03-12 16:20:07 +04:00
VIRT_TEST_MAIN_PRELOAD ( mymain , abs_builddir " /.libs/virmockdbus.so " )
2013-09-17 21:11:25 +04:00
2014-05-21 01:04:44 +04:00
# else /* ! (WITH_DBUS && __linux__) */
2013-09-17 21:11:25 +04:00
int
main ( void )
{
return EXIT_AM_SKIP ;
}
2014-03-12 16:20:07 +04:00
# endif /* ! WITH_DBUS */