2008-01-29 21:15:54 +03:00
# include <config.h>
2007-11-26 15:03:34 +03:00
2008-05-29 19:31:49 +04:00
# include <unistd.h>
2020-04-01 01:44:00 +03:00
# include <fcntl.h>
2007-07-26 03:16:30 +04:00
# include "testutils.h"
# include "internal.h"
2018-12-13 17:53:50 +03:00
# define LIBVIRT_VIRHOSTCPUPRIV_H_ALLOW
2016-04-13 20:53:02 +03:00
# include "virhostcpupriv.h"
2011-07-19 22:32:58 +04:00
# include "virfile.h"
2017-04-05 17:13:52 +03:00
# include "virfilewrapper.h"
2007-07-26 03:16:30 +04:00
2013-06-07 19:10:28 +04:00
# define VIR_FROM_THIS VIR_FROM_NONE
2017-04-05 17:13:52 +03:00
# define SYSFS_SYSTEM_PATH " / sys / devices / system"
2014-06-17 14:25:23 +04:00
# if !(defined __linux__)
2008-12-18 15:08:05 +03:00
2011-07-28 19:48:12 +04:00
int
main ( void )
2008-12-18 15:08:05 +03:00
{
2011-07-28 19:48:12 +04:00
return EXIT_AM_SKIP ;
2008-12-18 15:08:05 +03:00
}
# else
2011-04-25 02:25:10 +04:00
static int
2016-04-13 17:28:55 +03:00
linuxTestCompareFiles ( const char * cpuinfofile ,
2014-06-17 14:25:23 +04:00
virArch arch ,
2011-12-01 11:17:52 +04:00
const char * outputfile )
2011-04-25 02:25:10 +04:00
{
2021-09-04 23:37:31 +03:00
g_autofree char * actualData = NULL ;
2007-07-26 03:16:30 +04:00
virNodeInfo nodeinfo ;
2021-09-04 21:15:29 +03:00
g_autoptr ( FILE ) cpuinfo = NULL ;
2007-07-26 03:16:30 +04:00
cpuinfo = fopen ( cpuinfofile , " r " ) ;
2014-06-17 15:22:02 +04:00
if ( ! cpuinfo ) {
fprintf ( stderr , " unable to open: %s : %s \n " ,
2019-10-02 18:30:36 +03:00
cpuinfofile , g_strerror ( errno ) ) ;
2021-09-04 23:41:36 +03:00
return - 1 ;
2014-06-17 15:22:02 +04:00
}
2010-05-18 13:58:32 +04:00
memset ( & nodeinfo , 0 , sizeof ( nodeinfo ) ) ;
2016-04-13 20:16:16 +03:00
if ( virHostCPUGetInfoPopulateLinux ( cpuinfo , arch ,
& nodeinfo . cpus , & nodeinfo . mhz ,
& nodeinfo . nodes , & nodeinfo . sockets ,
& nodeinfo . cores , & nodeinfo . threads ) < 0 ) {
2010-08-23 18:48:33 +04:00
if ( virTestGetDebug ( ) ) {
2018-05-05 15:04:21 +03:00
if ( virGetLastErrorCode ( ) )
2019-05-03 11:31:02 +03:00
VIR_TEST_DEBUG ( " \n %s " , virGetLastErrorMessage ( ) ) ;
2010-08-23 18:48:33 +04:00
}
2021-09-04 23:41:36 +03:00
return - 1 ;
2007-07-26 03:16:30 +04:00
}
2019-10-22 16:26:14 +03:00
actualData = g_strdup_printf ( " CPUs: %u/%u, MHz: %u, Nodes: %u, Sockets: %u, "
" Cores: %u, Threads: %u \n " ,
nodeinfo . cpus , VIR_NODEINFO_MAXCPUS ( nodeinfo ) ,
nodeinfo . mhz , nodeinfo . nodes , nodeinfo . sockets ,
nodeinfo . cores , nodeinfo . threads ) ;
2007-07-26 03:16:30 +04:00
2016-05-26 18:01:53 +03:00
if ( virTestCompareToFile ( actualData , outputfile ) < 0 )
2021-09-04 23:41:36 +03:00
return - 1 ;
2011-04-25 02:25:10 +04:00
2021-09-04 23:41:36 +03:00
return 0 ;
2007-07-26 03:16:30 +04:00
}
2014-01-16 15:37:27 +04:00
static int
2021-03-11 10:16:13 +03:00
linuxCPUStatsToBuf ( virBuffer * buf ,
2014-01-16 15:37:27 +04:00
int cpu ,
virNodeCPUStatsPtr param ,
size_t nparams )
{
size_t i = 0 ;
2018-09-28 01:46:36 +03:00
unsigned long long tick_to_nsec ;
long long sc_clk_tck ;
if ( ( sc_clk_tck = sysconf ( _SC_CLK_TCK ) ) < 0 ) {
fprintf ( stderr , " sysconf(_SC_CLK_TCK) fails : %s \n " ,
2019-10-02 18:30:36 +03:00
g_strerror ( errno ) ) ;
2018-09-28 01:46:36 +03:00
return - 1 ;
}
tick_to_nsec = ( 1000ull * 1000ull * 1000ull ) / sc_clk_tck ;
2014-01-16 15:37:27 +04:00
if ( cpu < 0 )
virBufferAddLit ( buf , " cpu: \n " ) ;
else
virBufferAsprintf ( buf , " cpu%d: \n " , cpu ) ;
for ( i = 0 ; i < nparams ; i + + )
virBufferAsprintf ( buf , " %s: %llu \n " , param [ i ] . field ,
2018-09-28 01:46:36 +03:00
param [ i ] . value / tick_to_nsec ) ;
2014-01-16 15:37:27 +04:00
virBufferAddChar ( buf , ' \n ' ) ;
return 0 ;
}
static int
linuxCPUStatsCompareFiles ( const char * cpustatfile ,
size_t ncpus ,
const char * outfile )
{
int ret = - 1 ;
2021-09-04 23:37:31 +03:00
g_autofree char * actualData = NULL ;
2021-09-04 21:15:29 +03:00
g_autoptr ( FILE ) cpustat = NULL ;
2014-01-16 15:37:27 +04:00
virNodeCPUStatsPtr params = NULL ;
2020-07-03 02:35:41 +03:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2014-01-16 15:37:27 +04:00
size_t i ;
int nparams = 0 ;
if ( ! ( cpustat = fopen ( cpustatfile , " r " ) ) ) {
virReportSystemError ( errno , " failed to open '%s': " , cpustatfile ) ;
goto fail ;
}
2016-04-13 20:16:16 +03:00
if ( virHostCPUGetStatsLinux ( NULL , 0 , NULL , & nparams ) < 0 )
2014-01-16 15:37:27 +04:00
goto fail ;
2020-09-23 02:04:17 +03:00
params = g_new0 ( virNodeCPUStats , nparams ) ;
2014-01-16 15:37:27 +04:00
2016-04-13 20:16:16 +03:00
if ( virHostCPUGetStatsLinux ( cpustat , VIR_NODE_CPU_STATS_ALL_CPUS , params ,
& nparams ) < 0 )
2014-01-16 15:37:27 +04:00
goto fail ;
if ( linuxCPUStatsToBuf ( & buf , VIR_NODE_CPU_STATS_ALL_CPUS ,
params , nparams ) < 0 )
goto fail ;
for ( i = 0 ; i < ncpus ; i + + ) {
2016-04-13 20:16:16 +03:00
if ( virHostCPUGetStatsLinux ( cpustat , i , params , & nparams ) < 0 )
2014-01-16 15:37:27 +04:00
goto fail ;
if ( linuxCPUStatsToBuf ( & buf , i , params , nparams ) < 0 )
goto fail ;
}
2021-02-23 18:59:04 +03:00
actualData = virBufferContentAndReset ( & buf ) ;
2014-01-16 15:37:27 +04:00
2016-05-26 18:01:53 +03:00
if ( virTestCompareToFile ( actualData , outfile ) < 0 )
2014-01-16 15:37:27 +04:00
goto fail ;
ret = 0 ;
2014-03-25 10:53:44 +04:00
fail :
2014-01-16 15:37:27 +04:00
VIR_FREE ( params ) ;
return ret ;
}
2007-07-26 03:16:30 +04:00
2016-04-13 20:53:02 +03:00
struct linuxTestHostCPUData {
2014-06-17 14:25:23 +04:00
const char * testName ;
virArch arch ;
} ;
2011-04-25 02:25:10 +04:00
static int
2016-04-13 20:53:02 +03:00
linuxTestHostCPU ( const void * opaque )
2011-04-25 02:25:10 +04:00
{
int result = - 1 ;
2021-09-04 23:37:31 +03:00
g_autofree char * cpuinfo = NULL ;
g_autofree char * sysfs_prefix = NULL ;
g_autofree char * output = NULL ;
2016-04-13 20:53:02 +03:00
struct linuxTestHostCPUData * data = ( struct linuxTestHostCPUData * ) opaque ;
2014-06-17 14:25:23 +04:00
const char * archStr = virArchToString ( data - > arch ) ;
2012-05-11 23:59:59 +04:00
2019-10-22 16:26:14 +03:00
sysfs_prefix = g_strdup_printf ( " %s/virhostcpudata/linux-%s " ,
abs_srcdir , data - > testName ) ;
cpuinfo = g_strdup_printf ( " %s/virhostcpudata/linux-%s-%s.cpuinfo " ,
abs_srcdir , archStr , data - > testName ) ;
output = g_strdup_printf ( " %s/virhostcpudata/linux-%s-%s.expected " ,
abs_srcdir , archStr , data - > testName ) ;
2011-04-25 02:25:10 +04:00
2017-04-05 17:13:52 +03:00
virFileWrapperAddPrefix ( SYSFS_SYSTEM_PATH , sysfs_prefix ) ;
2016-04-13 17:28:55 +03:00
result = linuxTestCompareFiles ( cpuinfo , data - > arch , output ) ;
2017-04-05 17:13:52 +03:00
virFileWrapperRemovePrefix ( SYSFS_SYSTEM_PATH ) ;
2011-04-25 02:25:10 +04:00
return result ;
2007-07-26 03:16:30 +04:00
}
2020-04-01 01:44:00 +03:00
static int
hostCPUSignature ( const void * opaque )
{
const struct linuxTestHostCPUData * data = opaque ;
const char * arch = virArchToString ( data - > arch ) ;
g_autofree char * cpuinfo = NULL ;
g_autofree char * expected = NULL ;
g_autofree char * signature = NULL ;
g_autoptr ( FILE ) f = NULL ;
cpuinfo = g_strdup_printf ( " %s/virhostcpudata/linux-%s-%s.cpuinfo " ,
abs_srcdir , arch , data - > testName ) ;
expected = g_strdup_printf ( " %s/virhostcpudata/linux-%s-%s.signature " ,
abs_srcdir , arch , data - > testName ) ;
if ( ! ( f = fopen ( cpuinfo , " r " ) ) ) {
virReportSystemError ( errno ,
" Failed to open cpuinfo file '%s' " , cpuinfo ) ;
return - 1 ;
}
if ( virHostCPUReadSignature ( data - > arch , f , & signature ) < 0 )
return - 1 ;
if ( ! signature & & ! virFileExists ( expected ) )
return 0 ;
return virTestCompareToFile ( signature , expected ) ;
}
2014-01-16 15:37:27 +04:00
struct nodeCPUStatsData {
const char * name ;
int ncpus ;
2020-02-21 21:10:45 +03:00
bool shouldFail ;
2014-01-16 15:37:27 +04:00
} ;
static int
linuxTestNodeCPUStats ( const void * data )
{
const struct nodeCPUStatsData * testData = data ;
int result = - 1 ;
2021-09-04 23:37:31 +03:00
g_autofree char * cpustatfile = NULL ;
g_autofree g_autofree char * outfile = NULL ;
2014-01-16 15:37:27 +04:00
2019-10-22 16:26:14 +03:00
cpustatfile = g_strdup_printf ( " %s/virhostcpudata/linux-cpustat-%s.stat " ,
abs_srcdir , testData - > name ) ;
outfile = g_strdup_printf ( " %s/virhostcpudata/linux-cpustat-%s.out " ,
abs_srcdir , testData - > name ) ;
2014-01-16 15:37:27 +04:00
result = linuxCPUStatsCompareFiles ( cpustatfile ,
testData - > ncpus ,
outfile ) ;
2020-02-21 21:10:45 +03:00
if ( result < 0 ) {
if ( testData - > shouldFail ) {
/* Expected error */
result = 0 ;
}
} else {
if ( testData - > shouldFail ) {
fprintf ( stderr , " Expected a failure, got success " ) ;
result = - 1 ;
}
}
2014-01-16 15:37:27 +04:00
return result ;
}
2007-07-26 03:16:30 +04:00
2008-05-29 19:31:49 +04:00
static int
2011-04-29 20:21:20 +04:00
mymain ( void )
2007-07-26 03:16:30 +04:00
{
int ret = 0 ;
Convert 'int i' to 'size_t i' in tests/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2016-04-13 20:53:02 +03:00
const struct linuxTestHostCPUData nodeData [ ] = {
2014-06-17 14:25:23 +04:00
{ " test1 " , VIR_ARCH_X86_64 } ,
{ " test1 " , VIR_ARCH_PPC } ,
{ " test2 " , VIR_ARCH_X86_64 } ,
{ " test3 " , VIR_ARCH_X86_64 } ,
{ " test4 " , VIR_ARCH_X86_64 } ,
{ " test5 " , VIR_ARCH_X86_64 } ,
{ " test6 " , VIR_ARCH_X86_64 } ,
{ " test7 " , VIR_ARCH_X86_64 } ,
{ " test8 " , VIR_ARCH_X86_64 } ,
2014-06-17 13:22:05 +04:00
{ " raspberrypi " , VIR_ARCH_ARMV6L } ,
2015-03-31 23:38:41 +03:00
{ " f21-mustang " , VIR_ARCH_AARCH64 } ,
2015-03-31 23:40:28 +03:00
{ " rhelsa-3.19.0-mustang " , VIR_ARCH_AARCH64 } ,
2017-12-11 18:30:39 +03:00
{ " rhel74-moonshot " , VIR_ARCH_AARCH64 } ,
2018-08-02 18:24:48 +03:00
{ " high-ids " , VIR_ARCH_AARCH64 } ,
2015-07-27 05:17:05 +03:00
{ " deconf-cpus " , VIR_ARCH_PPC64 } ,
2015-07-27 11:08:30 +03:00
/* subcores, default configuration */
{ " subcores1 " , VIR_ARCH_PPC64 } ,
2015-07-27 11:08:31 +03:00
/* subcores, some of the cores are offline */
{ " subcores2 " , VIR_ARCH_PPC64 } ,
2015-07-27 11:08:32 +03:00
/* subcores, invalid configuration */
{ " subcores3 " , VIR_ARCH_PPC64 } ,
2017-12-19 13:08:01 +03:00
{ " with-frequency " , VIR_ARCH_S390X } ,
2019-12-16 21:08:24 +03:00
{ " with-die " , VIR_ARCH_X86_64 } ,
2007-07-26 03:16:30 +04:00
} ;
2010-05-18 14:32:39 +04:00
if ( virInitialize ( ) < 0 )
return EXIT_FAILURE ;
2007-07-26 03:16:30 +04:00
2020-04-01 01:44:00 +03:00
for ( i = 0 ; i < G_N_ELEMENTS ( nodeData ) ; i + + ) {
g_autofree char * sigTest = NULL ;
2017-03-07 12:18:06 +03:00
if ( virTestRun ( nodeData [ i ] . testName , linuxTestHostCPU , & nodeData [ i ] ) ! = 0 )
ret = - 1 ;
2007-07-26 03:16:30 +04:00
2020-04-01 01:44:00 +03:00
sigTest = g_strdup_printf ( " %s CPU signature " , nodeData [ i ] . testName ) ;
if ( virTestRun ( sigTest , hostCPUSignature , & nodeData [ i ] ) ! = 0 )
ret = - 1 ;
}
2020-02-21 21:10:45 +03:00
# define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \
2014-01-16 15:37:27 +04:00
do { \
2020-02-21 21:10:45 +03:00
static struct nodeCPUStatsData data = { name , ncpus , shouldFail } ; \
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " CPU stats " name , linuxTestNodeCPUStats , & data ) < 0 ) \
2014-01-16 15:37:27 +04:00
ret = - 1 ; \
} while ( 0 )
2020-02-21 21:10:45 +03:00
DO_TEST_CPU_STATS ( " 24cpu " , 24 , false ) ;
DO_TEST_CPU_STATS ( " 24cpu " , 25 , true ) ;
2014-01-16 15:37:27 +04:00
2014-03-17 13:38:38 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
2007-07-26 03:16:30 +04:00
}
2008-05-29 19:31:49 +04:00
2019-08-21 19:13:16 +03:00
VIR_TEST_MAIN_PRELOAD ( mymain , VIR_TEST_MOCK ( " virhostcpu " ) )
2011-07-28 19:48:12 +04:00
# endif /* __linux__ */