2013-09-19 15:44:41 +04:00
/*
* Copyright ( C ) 2011 - 2013 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/>.
*
*/
# include <config.h>
# include "testutils.h"
# include "testutilsqemu.h"
# include "qemumonitortestutils.h"
2018-12-13 17:53:50 +03:00
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
2016-04-28 18:02:38 +03:00
# include "qemu/qemu_capspriv.h"
2018-12-13 17:53:50 +03:00
# define LIBVIRT_QEMU_MONITOR_PRIV_H_ALLOW
2018-06-04 12:21:51 +03:00
# include "qemu/qemu_monitor_priv.h"
2019-02-14 13:25:50 +03:00
# define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW
# include "qemu/qemu_processpriv.h"
2013-09-19 15:44:41 +04:00
# define VIR_FROM_THIS VIR_FROM_NONE
typedef struct _testQemuData testQemuData ;
2013-10-29 23:57:19 +04:00
typedef testQemuData * testQemuDataPtr ;
2013-09-19 15:44:41 +04:00
struct _testQemuData {
2018-06-01 11:03:01 +03:00
virQEMUDriver driver ;
2019-10-22 16:31:37 +03:00
const char * inputDir ;
const char * outputDir ;
2019-10-22 17:08:10 +03:00
const char * prefix ;
const char * version ;
2016-04-25 15:19:49 +03:00
const char * archName ;
2019-10-22 16:44:37 +03:00
const char * suffix ;
2019-03-07 16:24:14 +03:00
int ret ;
2013-09-19 15:44:41 +04:00
} ;
2019-03-07 16:22:37 +03:00
static int
testQemuDataInit ( testQemuDataPtr data )
{
if ( qemuTestDriverInit ( & data - > driver ) < 0 )
return - 1 ;
2019-10-22 16:31:37 +03:00
data - > outputDir = TEST_QEMU_CAPS_PATH ;
2019-03-07 16:33:20 +03:00
2019-03-07 16:24:14 +03:00
data - > ret = 0 ;
2019-03-07 16:22:37 +03:00
return 0 ;
}
static void
testQemuDataReset ( testQemuDataPtr data )
{
qemuTestDriverFree ( & data - > driver ) ;
}
2013-09-19 15:44:41 +04:00
static int
testQemuCaps ( const void * opaque )
{
int ret = - 1 ;
2018-06-01 11:03:01 +03:00
testQemuData * data = ( void * ) opaque ;
2016-04-28 18:02:38 +03:00
char * repliesFile = NULL ;
char * capsFile = NULL ;
2013-09-19 15:44:41 +04:00
qemuMonitorTestPtr mon = NULL ;
2016-04-28 16:54:31 +03:00
virQEMUCapsPtr capsActual = NULL ;
2019-12-10 13:23:14 +03:00
char * binary = NULL ;
2016-04-28 18:02:38 +03:00
char * actual = NULL ;
2019-01-28 12:22:00 +03:00
unsigned int fakeMicrocodeVersion = 0 ;
const char * p ;
2013-09-19 15:44:41 +04:00
2019-10-22 16:26:14 +03:00
repliesFile = g_strdup_printf ( " %s/%s_%s.%s.%s " ,
data - > inputDir , data - > prefix , data - > version ,
data - > archName , data - > suffix ) ;
capsFile = g_strdup_printf ( " %s/%s_%s.%s.xml " ,
data - > outputDir , data - > prefix , data - > version ,
data - > archName ) ;
2013-09-19 15:44:41 +04:00
2019-06-07 14:53:45 +03:00
if ( ! ( mon = qemuMonitorTestNewFromFileFull ( repliesFile , & data - > driver , NULL ,
NULL ) ) )
2013-09-19 15:44:41 +04:00
goto cleanup ;
2019-02-14 13:25:50 +03:00
if ( qemuProcessQMPInitMonitor ( qemuMonitorTestGetMonitor ( mon ) ) < 0 )
goto cleanup ;
2019-12-10 13:23:14 +03:00
binary = g_strdup_printf ( " /usr/bin/qemu-system-%s " ,
data - > archName ) ;
if ( ! ( capsActual = virQEMUCapsNewBinary ( binary ) ) | |
2016-04-28 18:02:38 +03:00
virQEMUCapsInitQMPMonitor ( capsActual ,
qemuMonitorTestGetMonitor ( mon ) ) < 0 )
2013-09-19 15:44:41 +04:00
goto cleanup ;
2017-12-12 18:23:41 +03:00
if ( virQEMUCapsGet ( capsActual , QEMU_CAPS_KVM ) ) {
2018-06-04 12:21:51 +03:00
qemuMonitorResetCommandID ( qemuMonitorTestGetMonitor ( mon ) ) ;
2019-02-14 13:25:50 +03:00
if ( qemuProcessQMPInitMonitor ( qemuMonitorTestGetMonitor ( mon ) ) < 0 )
goto cleanup ;
2017-12-12 18:23:41 +03:00
if ( virQEMUCapsInitQMPMonitorTCG ( capsActual ,
qemuMonitorTestGetMonitor ( mon ) ) < 0 )
goto cleanup ;
2019-01-28 12:22:00 +03:00
/* calculate fake microcode version based on filename for a reproducible
* number for testing which does not change with the contents */
for ( p = data - > archName ; * p ; p + + )
fakeMicrocodeVersion + = * p ;
fakeMicrocodeVersion * = 100000 ;
2019-10-22 17:08:10 +03:00
for ( p = data - > version ; * p ; p + + )
2019-01-28 12:22:00 +03:00
fakeMicrocodeVersion + = * p ;
virQEMUCapsSetMicrocodeVersion ( capsActual , fakeMicrocodeVersion ) ;
2017-12-12 18:23:41 +03:00
}
2016-06-10 18:16:21 +03:00
2017-06-13 18:55:45 +03:00
if ( ! ( actual = virQEMUCapsFormatCache ( capsActual ) ) )
2013-09-19 15:44:41 +04:00
goto cleanup ;
2016-05-26 18:01:53 +03:00
if ( virTestCompareToFile ( actual , capsFile ) < 0 )
2013-09-19 15:44:41 +04:00
goto cleanup ;
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2013-09-19 15:44:41 +04:00
VIR_FREE ( repliesFile ) ;
VIR_FREE ( capsFile ) ;
2016-04-28 18:02:38 +03:00
VIR_FREE ( actual ) ;
2019-12-10 13:23:14 +03:00
VIR_FREE ( binary ) ;
2013-09-19 15:44:41 +04:00
qemuMonitorTestFree ( mon ) ;
2016-04-28 16:54:31 +03:00
virObjectUnref ( capsActual ) ;
2013-09-19 15:44:41 +04:00
return ret ;
}
2016-08-04 23:43:22 +03:00
static int
testQemuCapsCopy ( const void * opaque )
{
int ret = - 1 ;
const testQemuData * data = opaque ;
char * capsFile = NULL ;
virQEMUCapsPtr orig = NULL ;
virQEMUCapsPtr copy = NULL ;
char * actual = NULL ;
2019-10-22 16:26:14 +03:00
capsFile = g_strdup_printf ( " %s/%s_%s.%s.xml " ,
data - > outputDir , data - > prefix , data - > version ,
data - > archName ) ;
2016-08-04 23:43:22 +03:00
2019-11-29 13:40:39 +03:00
if ( ! ( orig = qemuTestParseCapabilitiesArch (
virArchFromString ( data - > archName ) , capsFile ) ) )
2016-08-04 23:43:22 +03:00
goto cleanup ;
if ( ! ( copy = virQEMUCapsNewCopy ( orig ) ) )
goto cleanup ;
2017-06-13 18:55:45 +03:00
if ( ! ( actual = virQEMUCapsFormatCache ( copy ) ) )
2016-08-04 23:43:22 +03:00
goto cleanup ;
if ( virTestCompareToFile ( actual , capsFile ) < 0 )
goto cleanup ;
ret = 0 ;
cleanup :
VIR_FREE ( capsFile ) ;
virObjectUnref ( orig ) ;
virObjectUnref ( copy ) ;
VIR_FREE ( actual ) ;
return ret ;
}
2019-03-07 16:53:18 +03:00
static int
2019-10-22 16:34:10 +03:00
doCapsTest ( const char * inputDir ,
2019-10-22 17:08:10 +03:00
const char * prefix ,
const char * version ,
2019-03-07 16:53:18 +03:00
const char * archName ,
2019-10-22 16:44:37 +03:00
const char * suffix ,
2019-03-07 18:02:37 +03:00
void * opaque )
2019-03-07 16:53:18 +03:00
{
2019-03-07 18:02:37 +03:00
testQemuDataPtr data = ( testQemuDataPtr ) opaque ;
2019-10-15 16:16:31 +03:00
g_autofree char * title = NULL ;
g_autofree char * copyTitle = NULL ;
2019-03-07 16:53:18 +03:00
2019-10-22 16:26:14 +03:00
title = g_strdup_printf ( " %s (%s) " , version , archName ) ;
copyTitle = g_strdup_printf ( " copy %s (%s) " , version , archName ) ;
2019-03-07 16:53:18 +03:00
2019-10-22 16:34:10 +03:00
data - > inputDir = inputDir ;
2019-10-22 17:08:10 +03:00
data - > prefix = prefix ;
data - > version = version ;
2019-03-07 16:53:18 +03:00
data - > archName = archName ;
2019-10-22 16:44:37 +03:00
data - > suffix = suffix ;
2019-03-07 16:53:18 +03:00
if ( virTestRun ( title , testQemuCaps , data ) < 0 )
data - > ret = - 1 ;
if ( virTestRun ( copyTitle , testQemuCapsCopy , data ) < 0 )
data - > ret = - 1 ;
return 0 ;
}
2013-09-19 15:44:41 +04:00
static int
mymain ( void )
{
testQemuData data ;
virEventRegisterDefaultImpl ( ) ;
2019-03-07 16:22:37 +03:00
if ( testQemuDataInit ( & data ) < 0 )
return EXIT_FAILURE ;
2019-04-16 13:33:14 +03:00
if ( testQemuCapsIterate ( " .replies " , doCapsTest , & data ) < 0 )
2019-03-07 18:02:37 +03:00
return EXIT_FAILURE ;
2013-09-19 15:44:41 +04:00
2016-04-26 16:04:55 +03:00
/*
* Run " tests/qemucapsprobe /path/to/qemu/binary >foo.replies "
* to generate updated or new * . replies data files .
2018-03-01 17:25:05 +03:00
*
* If you manually edit replies files you can run
* " tests/qemucapsfixreplies foo.replies " to fix the replies ids .
2019-03-13 16:28:07 +03:00
*
* Once a replies file has been generated and tweaked if necessary ,
* you can drop it into tests / qemucapabilitiesdata / ( with a sensible
* name - look at what ' s already there for inspiration ) and test
* programs will automatically pick it up .
*
* To generate the corresponding output files after a new replies
* file has been added , run " VIR_TEST_REGENERATE_OUTPUT=1 make check " .
2016-04-26 16:04:55 +03:00
*/
2019-03-07 16:22:37 +03:00
testQemuDataReset ( & data ) ;
tests: Avoid use of virQEMUDriverCreateXMLConf(NULL)
We use the function to create a virDomainXMLOption object that is
required for some functions. However, we don't pass the driver
pointer to the object anywhere - rather than pass NULL. This
causes trouble later when parsing a domain XML and calling post
parse callbacks:
Program received signal SIGSEGV, Segmentation fault.
0x000000000043fa3e in qemuDomainDefPostParse (def=0x7d36c0, caps=0x7caf10, opaque=0x0) at qemu/qemu_domain.c:1043
1043 qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator);
(gdb) bt
#0 0x000000000043fa3e in qemuDomainDefPostParse (def=0x7d36c0, caps=0x7caf10, opaque=0x0) at qemu/qemu_domain.c:1043
#1 0x00007ffff2928bf9 in virDomainDefPostParse (def=0x7d36c0, caps=0x7caf10, xmlopt=0x7c82c0) at conf/domain_conf.c:4269
#2 0x00007ffff294de04 in virDomainDefParseXML (xml=0x7da8c0, root=0x7dab80, ctxt=0x7da980, caps=0x7caf10, xmlopt=0x7c82c0, flags=0) at conf/domain_conf.c:16400
#3 0x00007ffff294e5b5 in virDomainDefParseNode (xml=0x7da8c0, root=0x7dab80, caps=0x7caf10, xmlopt=0x7c82c0, flags=0) at conf/domain_conf.c:16582
#4 0x00007ffff294e424 in virDomainDefParse (xmlStr=0x0, filename=0x7c7ef0 "/home/zippy/work/libvirt/libvirt.git/tests/securityselinuxlabeldata/disks.xml", caps=0x7caf10, xmlopt=0x7c82c0, flags=0) at conf/domain_conf.c:16529
#5 0x00007ffff294e4b2 in virDomainDefParseFile (filename=0x7c7ef0 "/home/zippy/work/libvirt/libvirt.git/tests/securityselinuxlabeldata/disks.xml", caps=0x7caf10, xmlopt=0x7c82c0, flags=0) at conf/domain_conf.c:16553
#6 0x00000000004303ca in testSELinuxLoadDef (testname=0x53c929 "disks") at securityselinuxlabeltest.c:192
#7 0x00000000004309e8 in testSELinuxLabeling (opaque=0x53c929) at securityselinuxlabeltest.c:313
#8 0x0000000000431207 in virtTestRun (title=0x53c92f "Labelling \"disks\"", body=0x430964 <testSELinuxLabeling>, data=0x53c929) at testutils.c:211
#9 0x0000000000430c5d in mymain () at securityselinuxlabeltest.c:373
#10 0x00000000004325c2 in virtTestMain (argc=1, argv=0x7fffffffd7e8, func=0x430b4a <mymain>) at testutils.c:863
#11 0x0000000000430deb in main (argc=1, argv=0x7fffffffd7e8) at securityselinuxlabeltest.c:381
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2015-09-22 17:27:57 +03:00
2019-03-07 16:24:14 +03:00
return ( data . ret = = 0 ) ? EXIT_SUCCESS : EXIT_FAILURE ;
2013-09-19 15:44:41 +04:00
}
2017-03-29 17:45:42 +03:00
VIR_TEST_MAIN ( mymain )