2010-12-06 20:03:22 +03:00
/*
* Copyright ( C ) 2011 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 , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
# include <config.h>
# include <stdlib.h>
# include <signal.h>
# include "testutils.h"
# include "util.h"
# include "virterror_internal.h"
# include "memory.h"
# include "logging.h"
# include "rpc/virnetmessage.h"
# define VIR_FROM_THIS VIR_FROM_RPC
static int testMessageHeaderEncode ( const void * args ATTRIBUTE_UNUSED )
{
static virNetMessage msg ;
static const char expect [ ] = {
0x00 , 0x00 , 0x00 , 0x1c , /* Length */
0x11 , 0x22 , 0x33 , 0x44 , /* Program */
0x00 , 0x00 , 0x00 , 0x01 , /* Version */
0x00 , 0x00 , 0x06 , 0x66 , /* Procedure */
0x00 , 0x00 , 0x00 , 0x00 , /* Type */
0x00 , 0x00 , 0x00 , 0x99 , /* Serial */
0x00 , 0x00 , 0x00 , 0x00 , /* Status */
} ;
memset ( & msg , 0 , sizeof ( msg ) ) ;
msg . header . prog = 0x11223344 ;
msg . header . vers = 0x01 ;
msg . header . proc = 0x666 ;
msg . header . type = VIR_NET_CALL ;
msg . header . serial = 0x99 ;
msg . header . status = VIR_NET_OK ;
if ( virNetMessageEncodeHeader ( & msg ) < 0 )
return - 1 ;
if ( ARRAY_CARDINALITY ( expect ) ! = msg . bufferOffset ) {
VIR_DEBUG ( " Expect message offset %zu got %zu " ,
sizeof ( expect ) , msg . bufferOffset ) ;
return - 1 ;
}
if ( msg . bufferLength ! = sizeof ( msg . buffer ) ) {
VIR_DEBUG ( " Expect message offset %zu got %zu " ,
sizeof ( msg . buffer ) , msg . bufferLength ) ;
return - 1 ;
}
if ( memcmp ( expect , msg . buffer , sizeof ( expect ) ) ! = 0 ) {
virtTestDifferenceBin ( stderr , expect , msg . buffer , sizeof ( expect ) ) ;
return - 1 ;
}
return 0 ;
}
static int testMessageHeaderDecode ( const void * args ATTRIBUTE_UNUSED )
{
static virNetMessage msg = {
. bufferOffset = 0 ,
. bufferLength = 0x4 ,
. buffer = {
0x00 , 0x00 , 0x00 , 0x1c , /* Length */
0x11 , 0x22 , 0x33 , 0x44 , /* Program */
0x00 , 0x00 , 0x00 , 0x01 , /* Version */
0x00 , 0x00 , 0x06 , 0x66 , /* Procedure */
0x00 , 0x00 , 0x00 , 0x01 , /* Type */
0x00 , 0x00 , 0x00 , 0x99 , /* Serial */
0x00 , 0x00 , 0x00 , 0x01 , /* Status */
} ,
. header = { 0 , 0 , 0 , 0 , 0 , 0 } ,
} ;
msg . header . prog = 0x11223344 ;
msg . header . vers = 0x01 ;
msg . header . proc = 0x666 ;
msg . header . type = VIR_NET_CALL ;
msg . header . serial = 0x99 ;
msg . header . status = VIR_NET_OK ;
if ( virNetMessageDecodeLength ( & msg ) < 0 ) {
VIR_DEBUG ( " Failed to decode message header " ) ;
return - 1 ;
}
if ( msg . bufferOffset ! = 0x4 ) {
VIR_DEBUG ( " Expecting offset %zu got %zu " ,
( size_t ) 4 , msg . bufferOffset ) ;
return - 1 ;
}
if ( msg . bufferLength ! = 0x1c ) {
VIR_DEBUG ( " Expecting length %zu got %zu " ,
( size_t ) 0x1c , msg . bufferLength ) ;
return - 1 ;
}
if ( virNetMessageDecodeHeader ( & msg ) < 0 ) {
VIR_DEBUG ( " Failed to decode message header " ) ;
return - 1 ;
}
if ( msg . bufferOffset ! = msg . bufferLength ) {
VIR_DEBUG ( " Expect message offset %zu got %zu " ,
msg . bufferOffset , msg . bufferLength ) ;
return - 1 ;
}
if ( msg . header . prog ! = 0x11223344 ) {
VIR_DEBUG ( " Expect prog %d got %d " ,
0x11223344 , msg . header . prog ) ;
return - 1 ;
}
if ( msg . header . vers ! = 0x1 ) {
VIR_DEBUG ( " Expect vers %d got %d " ,
0x11223344 , msg . header . vers ) ;
return - 1 ;
}
if ( msg . header . proc ! = 0x666 ) {
VIR_DEBUG ( " Expect proc %d got %d " ,
0x666 , msg . header . proc ) ;
return - 1 ;
}
if ( msg . header . type ! = VIR_NET_REPLY ) {
VIR_DEBUG ( " Expect type %d got %d " ,
VIR_NET_REPLY , msg . header . type ) ;
return - 1 ;
}
if ( msg . header . serial ! = 0x99 ) {
VIR_DEBUG ( " Expect serial %d got %d " ,
0x99 , msg . header . serial ) ;
return - 1 ;
}
if ( msg . header . status ! = VIR_NET_ERROR ) {
VIR_DEBUG ( " Expect status %d got %d " ,
VIR_NET_ERROR , msg . header . status ) ;
return - 1 ;
}
return 0 ;
}
static int testMessagePayloadEncode ( const void * args ATTRIBUTE_UNUSED )
{
virNetMessageError err ;
static virNetMessage msg ;
2011-06-29 06:47:54 +04:00
int ret = - 1 ;
2010-12-06 20:03:22 +03:00
static const char expect [ ] = {
0x00 , 0x00 , 0x00 , 0x74 , /* Length */
0x11 , 0x22 , 0x33 , 0x44 , /* Program */
0x00 , 0x00 , 0x00 , 0x01 , /* Version */
0x00 , 0x00 , 0x06 , 0x66 , /* Procedure */
0x00 , 0x00 , 0x00 , 0x02 , /* Type */
0x00 , 0x00 , 0x00 , 0x99 , /* Serial */
0x00 , 0x00 , 0x00 , 0x01 , /* Status */
0x00 , 0x00 , 0x00 , 0x01 , /* Error code */
0x00 , 0x00 , 0x00 , 0x07 , /* Error domain */
0x00 , 0x00 , 0x00 , 0x01 , /* Error message pointer */
0x00 , 0x00 , 0x00 , 0x0b , /* Error message length */
' H ' , ' e ' , ' l ' , ' l ' , /* Error message string */
' o ' , ' ' , ' W ' , ' o ' ,
' r ' , ' l ' , ' d ' , ' \0 ' ,
0x00 , 0x00 , 0x00 , 0x02 , /* Error level */
0x00 , 0x00 , 0x00 , 0x00 , /* Error domain pointer */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str1 pointer */
0x00 , 0x00 , 0x00 , 0x03 , /* Error str1 length */
' O ' , ' n ' , ' e ' , ' \0 ' , /* Error str1 message */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str2 pointer */
0x00 , 0x00 , 0x00 , 0x03 , /* Error str2 length */
' T ' , ' w ' , ' o ' , ' \0 ' , /* Error str2 message */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str3 pointer */
0x00 , 0x00 , 0x00 , 0x05 , /* Error str3 length */
' T ' , ' h ' , ' r ' , ' e ' , /* Error str3 message */
' e ' , ' \0 ' , ' \0 ' , ' \0 ' ,
0x00 , 0x00 , 0x00 , 0x01 , /* Error int1 */
0x00 , 0x00 , 0x00 , 0x02 , /* Error int2 */
0x00 , 0x00 , 0x00 , 0x00 , /* Error network pointer */
} ;
memset ( & msg , 0 , sizeof ( msg ) ) ;
memset ( & err , 0 , sizeof ( err ) ) ;
err . code = VIR_ERR_INTERNAL_ERROR ;
err . domain = VIR_FROM_RPC ;
2011-06-29 06:47:54 +04:00
err . level = VIR_ERR_ERROR ;
2010-12-06 20:03:22 +03:00
if ( VIR_ALLOC ( err . message ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
* err . message = strdup ( " Hello World " ) ;
if ( VIR_ALLOC ( err . str1 ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
* err . str1 = strdup ( " One " ) ;
if ( VIR_ALLOC ( err . str2 ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
* err . str2 = strdup ( " Two " ) ;
if ( VIR_ALLOC ( err . str3 ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
* err . str3 = strdup ( " Three " ) ;
2011-06-29 06:47:54 +04:00
2010-12-06 20:03:22 +03:00
err . int1 = 1 ;
err . int2 = 2 ;
msg . header . prog = 0x11223344 ;
msg . header . vers = 0x01 ;
msg . header . proc = 0x666 ;
msg . header . type = VIR_NET_MESSAGE ;
msg . header . serial = 0x99 ;
msg . header . status = VIR_NET_ERROR ;
if ( virNetMessageEncodeHeader ( & msg ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
if ( virNetMessageEncodePayload ( & msg , ( xdrproc_t ) xdr_virNetMessageError , & err ) < 0 )
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
if ( ARRAY_CARDINALITY ( expect ) ! = msg . bufferLength ) {
VIR_DEBUG ( " Expect message length %zu got %zu " ,
sizeof ( expect ) , msg . bufferLength ) ;
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
}
if ( msg . bufferOffset ! = 0 ) {
VIR_DEBUG ( " Expect message offset 0 got %zu " ,
msg . bufferOffset ) ;
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
}
if ( memcmp ( expect , msg . buffer , sizeof ( expect ) ) ! = 0 ) {
virtTestDifferenceBin ( stderr , expect , msg . buffer , sizeof ( expect ) ) ;
2011-06-29 06:47:54 +04:00
goto cleanup ;
2010-12-06 20:03:22 +03:00
}
2011-06-29 06:47:54 +04:00
ret = 0 ;
cleanup :
if ( err . message )
VIR_FREE ( * err . message ) ;
if ( err . str1 )
VIR_FREE ( * err . str1 ) ;
if ( err . str2 )
VIR_FREE ( * err . str2 ) ;
if ( err . str3 )
VIR_FREE ( * err . str3 ) ;
VIR_FREE ( err . message ) ;
VIR_FREE ( err . str1 ) ;
VIR_FREE ( err . str2 ) ;
VIR_FREE ( err . str3 ) ;
return ret ;
2010-12-06 20:03:22 +03:00
}
static int testMessagePayloadDecode ( const void * args ATTRIBUTE_UNUSED )
{
virNetMessageError err ;
static virNetMessage msg = {
. bufferOffset = 0 ,
. bufferLength = 0x4 ,
. buffer = {
0x00 , 0x00 , 0x00 , 0x74 , /* Length */
0x11 , 0x22 , 0x33 , 0x44 , /* Program */
0x00 , 0x00 , 0x00 , 0x01 , /* Version */
0x00 , 0x00 , 0x06 , 0x66 , /* Procedure */
0x00 , 0x00 , 0x00 , 0x02 , /* Type */
0x00 , 0x00 , 0x00 , 0x99 , /* Serial */
0x00 , 0x00 , 0x00 , 0x01 , /* Status */
0x00 , 0x00 , 0x00 , 0x01 , /* Error code */
0x00 , 0x00 , 0x00 , 0x07 , /* Error domain */
0x00 , 0x00 , 0x00 , 0x01 , /* Error message pointer */
0x00 , 0x00 , 0x00 , 0x0b , /* Error message length */
' H ' , ' e ' , ' l ' , ' l ' , /* Error message string */
' o ' , ' ' , ' W ' , ' o ' ,
' r ' , ' l ' , ' d ' , ' \0 ' ,
0x00 , 0x00 , 0x00 , 0x02 , /* Error level */
0x00 , 0x00 , 0x00 , 0x00 , /* Error domain pointer */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str1 pointer */
0x00 , 0x00 , 0x00 , 0x03 , /* Error str1 length */
' O ' , ' n ' , ' e ' , ' \0 ' , /* Error str1 message */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str2 pointer */
0x00 , 0x00 , 0x00 , 0x03 , /* Error str2 length */
' T ' , ' w ' , ' o ' , ' \0 ' , /* Error str2 message */
0x00 , 0x00 , 0x00 , 0x01 , /* Error str3 pointer */
0x00 , 0x00 , 0x00 , 0x05 , /* Error str3 length */
' T ' , ' h ' , ' r ' , ' e ' , /* Error str3 message */
' e ' , ' \0 ' , ' \0 ' , ' \0 ' ,
0x00 , 0x00 , 0x00 , 0x01 , /* Error int1 */
0x00 , 0x00 , 0x00 , 0x02 , /* Error int2 */
0x00 , 0x00 , 0x00 , 0x00 , /* Error network pointer */
} ,
. header = { 0 , 0 , 0 , 0 , 0 , 0 } ,
} ;
memset ( & err , 0 , sizeof ( err ) ) ;
if ( virNetMessageDecodeLength ( & msg ) < 0 ) {
VIR_DEBUG ( " Failed to decode message header " ) ;
return - 1 ;
}
if ( msg . bufferOffset ! = 0x4 ) {
VIR_DEBUG ( " Expecting offset %zu got %zu " ,
( size_t ) 4 , msg . bufferOffset ) ;
return - 1 ;
}
if ( msg . bufferLength ! = 0x74 ) {
VIR_DEBUG ( " Expecting length %zu got %zu " ,
( size_t ) 0x74 , msg . bufferLength ) ;
return - 1 ;
}
if ( virNetMessageDecodeHeader ( & msg ) < 0 ) {
VIR_DEBUG ( " Failed to decode message header " ) ;
return - 1 ;
}
if ( msg . bufferOffset ! = 28 ) {
VIR_DEBUG ( " Expect message offset %zu got %zu " ,
msg . bufferOffset , ( size_t ) 28 ) ;
return - 1 ;
}
if ( msg . bufferLength ! = 0x74 ) {
VIR_DEBUG ( " Expecting length %zu got %zu " ,
( size_t ) 0x1c , msg . bufferLength ) ;
return - 1 ;
}
if ( virNetMessageDecodePayload ( & msg , ( xdrproc_t ) xdr_virNetMessageError , & err ) < 0 ) {
VIR_DEBUG ( " Failed to decode message payload " ) ;
return - 1 ;
}
if ( err . code ! = VIR_ERR_INTERNAL_ERROR ) {
VIR_DEBUG ( " Expect code %d got %d " ,
VIR_ERR_INTERNAL_ERROR , err . code ) ;
return - 1 ;
}
if ( err . domain ! = VIR_FROM_RPC ) {
VIR_DEBUG ( " Expect domain %d got %d " ,
VIR_ERR_RPC , err . domain ) ;
return - 1 ;
}
if ( err . message = = NULL | |
STRNEQ ( * err . message , " Hello World " ) ) {
VIR_DEBUG ( " Expect str1 'Hello World' got %s " ,
err . message ? * err . message : " (null) " ) ;
return - 1 ;
}
if ( err . dom ! = NULL ) {
VIR_DEBUG ( " Expect NULL dom " ) ;
return - 1 ;
}
if ( err . level ! = VIR_ERR_ERROR ) {
VIR_DEBUG ( " Expect leve %d got %d " ,
VIR_ERR_ERROR , err . level ) ;
return - 1 ;
}
if ( err . str1 = = NULL | |
STRNEQ ( * err . str1 , " One " ) ) {
VIR_DEBUG ( " Expect str1 'One' got %s " ,
err . str1 ? * err . str1 : " (null) " ) ;
return - 1 ;
}
if ( err . str2 = = NULL | |
STRNEQ ( * err . str2 , " Two " ) ) {
VIR_DEBUG ( " Expect str3 'Two' got %s " ,
err . str2 ? * err . str2 : " (null) " ) ;
return - 1 ;
}
if ( err . str3 = = NULL | |
STRNEQ ( * err . str3 , " Three " ) ) {
VIR_DEBUG ( " Expect str3 'Three' got %s " ,
err . str3 ? * err . str3 : " (null) " ) ;
return - 1 ;
}
if ( err . int1 ! = 1 ) {
VIR_DEBUG ( " Expect int1 1 got %d " ,
err . int1 ) ;
return - 1 ;
}
if ( err . int2 ! = 2 ) {
VIR_DEBUG ( " Expect int2 2 got %d " ,
err . int2 ) ;
return - 1 ;
}
if ( err . net ! = NULL ) {
VIR_DEBUG ( " Expect NULL network " ) ;
return - 1 ;
}
xdr_free ( ( xdrproc_t ) xdr_virNetMessageError , ( void * ) & err ) ;
return 0 ;
}
static int testMessagePayloadStreamEncode ( const void * args ATTRIBUTE_UNUSED )
{
char stream [ ] = " The quick brown fox jumps over the lazy dog " ;
static virNetMessage msg ;
static const char expect [ ] = {
0x00 , 0x00 , 0x00 , 0x47 , /* Length */
0x11 , 0x22 , 0x33 , 0x44 , /* Program */
0x00 , 0x00 , 0x00 , 0x01 , /* Version */
0x00 , 0x00 , 0x06 , 0x66 , /* Procedure */
0x00 , 0x00 , 0x00 , 0x03 , /* Type */
0x00 , 0x00 , 0x00 , 0x99 , /* Serial */
0x00 , 0x00 , 0x00 , 0x02 , /* Status */
' T ' , ' h ' , ' e ' , ' ' ,
' q ' , ' u ' , ' i ' , ' c ' ,
' k ' , ' ' , ' b ' , ' r ' ,
' o ' , ' w ' , ' n ' , ' ' ,
' f ' , ' o ' , ' x ' , ' ' ,
' j ' , ' u ' , ' m ' , ' p ' ,
' s ' , ' ' , ' o ' , ' v ' ,
' e ' , ' r ' , ' ' , ' t ' ,
' h ' , ' e ' , ' ' , ' l ' ,
' a ' , ' z ' , ' y ' , ' ' ,
' d ' , ' o ' , ' g ' ,
} ;
memset ( & msg , 0 , sizeof ( msg ) ) ;
msg . header . prog = 0x11223344 ;
msg . header . vers = 0x01 ;
msg . header . proc = 0x666 ;
msg . header . type = VIR_NET_STREAM ;
msg . header . serial = 0x99 ;
msg . header . status = VIR_NET_CONTINUE ;
if ( virNetMessageEncodeHeader ( & msg ) < 0 )
return - 1 ;
if ( virNetMessageEncodePayloadRaw ( & msg , stream , strlen ( stream ) ) < 0 )
return - 1 ;
if ( ARRAY_CARDINALITY ( expect ) ! = msg . bufferLength ) {
VIR_DEBUG ( " Expect message length %zu got %zu " ,
sizeof ( expect ) , msg . bufferLength ) ;
return - 1 ;
}
if ( msg . bufferOffset ! = 0 ) {
VIR_DEBUG ( " Expect message offset 0 got %zu " ,
msg . bufferOffset ) ;
return - 1 ;
}
if ( memcmp ( expect , msg . buffer , sizeof ( expect ) ) ! = 0 ) {
virtTestDifferenceBin ( stderr , expect , msg . buffer , sizeof ( expect ) ) ;
return - 1 ;
}
return 0 ;
}
static int
mymain ( void )
{
int ret = 0 ;
signal ( SIGPIPE , SIG_IGN ) ;
if ( virtTestRun ( " Message Header Encode " , 1 , testMessageHeaderEncode , NULL ) < 0 )
ret = - 1 ;
if ( virtTestRun ( " Message Header Decode " , 1 , testMessageHeaderDecode , NULL ) < 0 )
ret = - 1 ;
if ( virtTestRun ( " Message Payload Encode " , 1 , testMessagePayloadEncode , NULL ) < 0 )
ret = - 1 ;
if ( virtTestRun ( " Message Payload Decode " , 1 , testMessagePayloadDecode , NULL ) < 0 )
ret = - 1 ;
if ( virtTestRun ( " Message Payload Stream Encode " , 1 , testMessagePayloadStreamEncode , NULL ) < 0 )
ret = - 1 ;
2012-03-22 15:33:35 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
2010-12-06 20:03:22 +03:00
}
VIRT_TEST_MAIN ( mymain )