2015-05-22 15:21:46 +03:00
/*
* Copyright ( C ) 2015 Red Hat , Inc .
*
* 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"
# include "virerror.h"
2015-06-11 15:02:30 +03:00
# include "rpc/virnetdaemon.h"
2015-05-22 15:21:46 +03:00
# define VIR_FROM_THIS VIR_FROM_RPC
2015-12-01 13:54:08 +03:00
# if defined(HAVE_SOCKETPAIR) && defined(WITH_YAJL)
2015-05-22 15:21:46 +03:00
static virNetServerPtr
2016-03-01 17:34:15 +03:00
testCreateServer ( const char * server_name , const char * host , int family )
2015-05-22 15:21:46 +03:00
{
virNetServerPtr srv = NULL ;
virNetServerServicePtr svc1 = NULL , svc2 = NULL ;
virNetServerClientPtr cln1 = NULL , cln2 = NULL ;
virNetSocketPtr sk1 = NULL , sk2 = NULL ;
int fdclient [ 2 ] ;
2015-06-15 12:28:11 +03:00
const char * mdns_entry = NULL ;
const char * mdns_group = NULL ;
# ifdef WITH_AVAHI
mdns_entry = " libvirt-ro " ;
mdns_group = " libvirtTest " ;
# endif
2015-05-22 15:21:46 +03:00
if ( socketpair ( PF_UNIX , SOCK_STREAM , 0 , fdclient ) < 0 ) {
virReportSystemError ( errno , " %s " ,
" Cannot create socket pair " ) ;
goto cleanup ;
}
2016-04-13 21:54:40 +03:00
if ( ! ( srv = virNetServerNew ( server_name , 1 ,
2016-03-01 17:34:15 +03:00
10 , 50 , 5 , 100 , 10 ,
2015-07-20 15:51:24 +03:00
120 , 5 ,
2015-06-15 12:28:11 +03:00
mdns_group ,
2015-05-22 15:21:46 +03:00
NULL ,
NULL ,
NULL ,
NULL ) ) )
goto error ;
if ( ! ( svc1 = virNetServerServiceNewTCP ( host ,
NULL ,
family ,
VIR_NET_SERVER_SERVICE_AUTH_NONE ,
# ifdef WITH_GNUTLS
NULL ,
# endif
true ,
5 ,
2 ) ) )
goto error ;
if ( ! ( svc2 = virNetServerServiceNewTCP ( host ,
NULL ,
family ,
VIR_NET_SERVER_SERVICE_AUTH_POLKIT ,
# ifdef WITH_GNUTLS
NULL ,
# endif
false ,
25 ,
5 ) ) )
goto error ;
2015-06-15 12:28:11 +03:00
if ( virNetServerAddService ( srv , svc1 , mdns_entry ) < 0 )
2015-05-22 15:21:46 +03:00
goto error ;
2015-06-15 12:28:11 +03:00
if ( virNetServerAddService ( srv , svc2 , mdns_entry ) < 0 )
2015-05-22 15:21:46 +03:00
goto error ;
if ( virNetSocketNewConnectSockFD ( fdclient [ 0 ] , & sk1 ) < 0 )
goto error ;
if ( virNetSocketNewConnectSockFD ( fdclient [ 1 ] , & sk2 ) < 0 )
goto error ;
2016-04-13 21:54:40 +03:00
if ( ! ( cln1 = virNetServerClientNew ( virNetServerNextClientID ( srv ) ,
sk1 ,
2015-05-22 15:21:46 +03:00
VIR_NET_SERVER_SERVICE_AUTH_SASL ,
true ,
15 ,
# ifdef WITH_GNUTLS
NULL ,
# endif
NULL , NULL , NULL , NULL ) ) )
goto error ;
2016-04-13 21:54:40 +03:00
if ( ! ( cln2 = virNetServerClientNew ( virNetServerNextClientID ( srv ) ,
sk2 ,
2015-05-22 15:21:46 +03:00
VIR_NET_SERVER_SERVICE_AUTH_POLKIT ,
true ,
66 ,
# ifdef WITH_GNUTLS
NULL ,
# endif
NULL , NULL , NULL , NULL ) ) )
goto error ;
if ( virNetServerAddClient ( srv , cln1 ) < 0 )
goto error ;
if ( virNetServerAddClient ( srv , cln2 ) < 0 )
goto error ;
cleanup :
2015-06-15 11:41:17 +03:00
if ( ! srv )
virDispatchError ( NULL ) ;
2015-05-22 15:21:46 +03:00
virObjectUnref ( cln1 ) ;
virObjectUnref ( cln2 ) ;
virObjectUnref ( svc1 ) ;
virObjectUnref ( svc2 ) ;
2015-09-08 14:21:17 +03:00
virObjectUnref ( sk1 ) ;
virObjectUnref ( sk2 ) ;
2015-05-22 15:21:46 +03:00
return srv ;
error :
virObjectUnref ( srv ) ;
srv = NULL ;
goto cleanup ;
}
2015-08-10 14:01:44 +03:00
static char * testGenerateJSON ( const char * server_name )
2015-05-22 15:21:46 +03:00
{
2015-06-11 15:02:30 +03:00
virNetDaemonPtr dmn = NULL ;
2015-05-22 15:21:46 +03:00
virNetServerPtr srv = NULL ;
virJSONValuePtr json = NULL ;
char * jsonstr = NULL ;
bool has_ipv4 , has_ipv6 ;
/* Our pre-saved JSON file is created so that each service
* only has one socket . If we let libvirt bind to IPv4 and
* IPv6 we might end up with two sockets , so force one or
* the other based on what ' s available on thehost
*/
if ( virNetSocketCheckProtocols ( & has_ipv4 ,
& has_ipv6 ) < 0 )
return NULL ;
if ( ! has_ipv4 & & ! has_ipv6 )
return NULL ;
2016-03-01 17:34:15 +03:00
if ( ! ( srv = testCreateServer ( server_name ,
has_ipv4 ? " 127.0.0.1 " : " ::1 " ,
2015-08-10 14:01:44 +03:00
has_ipv4 ? AF_INET : AF_INET6 ) ) )
2015-05-22 15:21:46 +03:00
goto cleanup ;
2015-06-11 15:02:30 +03:00
if ( ! ( dmn = virNetDaemonNew ( ) ) )
goto cleanup ;
2016-03-01 17:40:31 +03:00
if ( virNetDaemonAddServer ( dmn , srv ) < 0 )
2015-06-11 15:02:30 +03:00
goto cleanup ;
if ( ! ( json = virNetDaemonPreExecRestart ( dmn ) ) )
2015-05-22 15:21:46 +03:00
goto cleanup ;
if ( ! ( jsonstr = virJSONValueToString ( json , true ) ) )
goto cleanup ;
2015-06-11 15:02:30 +03:00
2015-05-22 15:21:46 +03:00
fprintf ( stderr , " %s \n " , jsonstr ) ;
cleanup :
virNetServerClose ( srv ) ;
virObjectUnref ( srv ) ;
2015-06-11 15:02:30 +03:00
virObjectUnref ( dmn ) ;
2015-05-22 15:21:46 +03:00
virJSONValueFree ( json ) ;
2015-06-11 15:02:30 +03:00
if ( ! jsonstr )
virDispatchError ( NULL ) ;
2015-05-22 15:21:46 +03:00
return jsonstr ;
}
struct testExecRestartData {
const char * jsonfile ;
2015-08-10 14:01:44 +03:00
const char * * serverNames ;
2015-06-11 15:02:30 +03:00
int nservers ;
bool pass ;
2015-05-22 15:21:46 +03:00
} ;
static int testExecRestart ( const void * opaque )
{
2015-06-11 15:02:30 +03:00
size_t i ;
2015-05-22 15:21:46 +03:00
int ret = - 1 ;
2015-06-11 15:02:30 +03:00
virNetDaemonPtr dmn = NULL ;
2015-05-22 15:21:46 +03:00
virNetServerPtr srv = NULL ;
const struct testExecRestartData * data = opaque ;
char * infile = NULL , * outfile = NULL ;
char * injsonstr = NULL , * outjsonstr = NULL ;
virJSONValuePtr injson = NULL , outjson = NULL ;
int fdclient [ 2 ] = { - 1 , - 1 } , fdserver [ 2 ] = { - 1 , - 1 } ;
if ( socketpair ( PF_UNIX , SOCK_STREAM , 0 , fdclient ) < 0 ) {
virReportSystemError ( errno , " %s " ,
" Cannot create socket pair " ) ;
goto cleanup ;
}
if ( socketpair ( PF_UNIX , SOCK_STREAM , 0 , fdserver ) < 0 ) {
virReportSystemError ( errno , " %s " ,
" Cannot create socket pair " ) ;
goto cleanup ;
}
/* We're blindly assuming the test case isn't using
* fds 100 - > 103 for something else , which is probably
* fairly reasonable in general
*/
dup2 ( fdserver [ 0 ] , 100 ) ;
dup2 ( fdserver [ 1 ] , 101 ) ;
dup2 ( fdclient [ 0 ] , 102 ) ;
dup2 ( fdclient [ 1 ] , 103 ) ;
2015-06-11 15:02:30 +03:00
if ( virAsprintf ( & infile , " %s/virnetdaemondata/input-data-%s.json " ,
2015-05-22 15:21:46 +03:00
abs_srcdir , data - > jsonfile ) < 0 )
goto cleanup ;
2015-06-11 15:02:30 +03:00
if ( virAsprintf ( & outfile , " %s/virnetdaemondata/output-data-%s.json " ,
2015-05-22 15:21:46 +03:00
abs_srcdir , data - > jsonfile ) < 0 )
goto cleanup ;
if ( virFileReadAll ( infile , 8192 , & injsonstr ) < 0 )
goto cleanup ;
if ( ! ( injson = virJSONValueFromString ( injsonstr ) ) )
goto cleanup ;
2015-06-11 15:02:30 +03:00
if ( ! ( dmn = virNetDaemonNewPostExecRestart ( injson ) ) )
2015-05-22 15:21:46 +03:00
goto cleanup ;
2015-06-11 15:02:30 +03:00
for ( i = 0 ; i < data - > nservers ; i + + ) {
2015-08-10 14:01:44 +03:00
if ( ! ( srv = virNetDaemonAddServerPostExec ( dmn , data - > serverNames [ i ] ,
2015-06-11 15:02:30 +03:00
NULL , NULL , NULL ,
NULL , NULL ) ) )
goto cleanup ;
srv = NULL ;
}
if ( ! ( outjson = virNetDaemonPreExecRestart ( dmn ) ) )
2015-05-22 15:21:46 +03:00
goto cleanup ;
if ( ! ( outjsonstr = virJSONValueToString ( outjson , true ) ) )
goto cleanup ;
2016-05-26 18:01:53 +03:00
if ( virTestCompareToFile ( outjsonstr , outfile ) < 0 )
2015-06-11 15:02:30 +03:00
goto cleanup ;
2015-05-22 15:21:46 +03:00
2015-06-11 15:02:30 +03:00
ret = 0 ;
2015-05-22 15:21:46 +03:00
cleanup :
2015-06-11 15:02:30 +03:00
if ( ret < 0 ) {
2015-08-10 14:01:44 +03:00
if ( ! data - > pass ) {
VIR_TEST_DEBUG ( " Got expected error: %s \n " ,
virGetLastErrorMessage ( ) ) ;
virResetLastError ( ) ;
2015-06-11 15:02:30 +03:00
ret = 0 ;
2015-08-10 14:01:44 +03:00
}
} else if ( ! data - > pass ) {
VIR_TEST_DEBUG ( " Test should have failed \n " ) ;
ret = - 1 ;
2015-06-11 15:02:30 +03:00
}
2015-05-22 15:21:46 +03:00
VIR_FREE ( infile ) ;
VIR_FREE ( outfile ) ;
VIR_FREE ( injsonstr ) ;
VIR_FREE ( outjsonstr ) ;
virJSONValueFree ( injson ) ;
virJSONValueFree ( outjson ) ;
2015-06-11 15:02:30 +03:00
virObjectUnref ( dmn ) ;
2015-05-22 15:21:46 +03:00
VIR_FORCE_CLOSE ( fdserver [ 0 ] ) ;
VIR_FORCE_CLOSE ( fdserver [ 1 ] ) ;
VIR_FORCE_CLOSE ( fdclient [ 0 ] ) ;
VIR_FORCE_CLOSE ( fdclient [ 1 ] ) ;
return ret ;
}
static int
mymain ( void )
{
int ret = 0 ;
2015-08-10 14:01:44 +03:00
const char * server_names [ ] = { " testServer0 " , " testServer1 " } ;
2015-05-22 15:21:46 +03:00
2015-06-15 11:41:17 +03:00
if ( virInitialize ( ) < 0 | |
virEventRegisterDefaultImpl ( ) < 0 ) {
virDispatchError ( NULL ) ;
return EXIT_FAILURE ;
}
2015-05-22 15:21:46 +03:00
/* Hack to make it easier to generate new JSON files when
* the RPC classes change . Just set this env var , save
* the generated JSON , and replace the file descriptor
* numbers with 100 , 101 , 102 , 103.
*/
if ( getenv ( " VIR_GENERATE_JSON " ) ) {
2015-08-10 14:01:44 +03:00
char * json = testGenerateJSON ( server_names [ 0 ] ) ;
2015-06-11 15:02:30 +03:00
if ( ! json )
return EXIT_FAILURE ;
2015-05-22 15:21:46 +03:00
fprintf ( stdout , " %s \n " , json ) ;
VIR_FREE ( json ) ;
2015-06-11 15:02:30 +03:00
return ret ;
2015-05-22 15:21:46 +03:00
}
2015-08-10 14:01:44 +03:00
# define EXEC_RESTART_TEST_FULL(file, nservers, pass) \
do { \
struct testExecRestartData data = { \
file , server_names , nservers , pass \
} ; \
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " ExecRestart " file , \
testExecRestart , & data ) < 0 ) \
2015-08-10 14:01:44 +03:00
ret = - 1 ; \
2015-05-22 15:21:46 +03:00
} while ( 0 )
2015-08-10 14:01:44 +03:00
# define EXEC_RESTART_TEST(file, N) EXEC_RESTART_TEST_FULL(file, N, true)
# define EXEC_RESTART_TEST_FAIL(file, N) EXEC_RESTART_TEST_FULL(file, N, false)
2015-06-11 15:02:30 +03:00
2015-05-22 15:21:46 +03:00
# ifdef WITH_AVAHI
2015-08-10 14:01:44 +03:00
EXEC_RESTART_TEST ( " initial " , 1 ) ;
2015-05-22 15:21:46 +03:00
# endif
2015-08-10 14:01:44 +03:00
EXEC_RESTART_TEST ( " initial-nomdns " , 1 ) ;
EXEC_RESTART_TEST ( " anon-clients " , 1 ) ;
EXEC_RESTART_TEST ( " admin-nomdns " , 2 ) ;
EXEC_RESTART_TEST ( " admin-server-names " , 2 ) ;
2016-04-13 22:06:00 +03:00
EXEC_RESTART_TEST ( " no-keepalive-required " , 2 ) ;
2016-04-13 21:54:40 +03:00
EXEC_RESTART_TEST ( " client-ids " , 1 ) ;
2016-04-12 20:21:43 +03:00
EXEC_RESTART_TEST ( " client-timestamp " , 1 ) ;
2015-08-10 14:01:44 +03:00
EXEC_RESTART_TEST_FAIL ( " anon-clients " , 2 ) ;
2015-06-11 15:02:30 +03:00
2015-05-22 15:21:46 +03:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
}
2016-04-12 20:21:43 +03:00
VIRT_TEST_MAIN_PRELOAD ( mymain , abs_builddir " /.libs/virnetdaemonmock.so " )
2015-05-22 15:21:46 +03:00
# else
static int
mymain ( void )
{
return EXIT_AM_SKIP ;
}
VIRT_TEST_MAIN ( mymain ) ;
2016-04-12 20:21:43 +03:00
# endif