2018-02-15 17:33:12 +11:00
/*
CTDB event daemon - protocol test
Copyright ( C ) Amitay Isaacs 2018
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "replace.h"
# include <talloc.h>
# include <assert.h>
# define EVENT_PROTOCOL_TEST
# include "event/event_protocol.c"
# include "tests/src/protocol_common_basic.h"
/*
* Functions to fill and verify event protocol structures
*/
static void fill_ctdb_event_script ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_script * p )
{
fill_ctdb_stringn ( mem_ctx , & p - > name ) ;
fill_ctdb_timeval ( & p - > begin ) ;
fill_ctdb_timeval ( & p - > end ) ;
p - > result = rand32i ( ) ;
fill_ctdb_stringn ( mem_ctx , & p - > output ) ;
}
static void verify_ctdb_event_script ( struct ctdb_event_script * p1 ,
struct ctdb_event_script * p2 )
{
verify_ctdb_stringn ( & p1 - > name , & p2 - > name ) ;
verify_ctdb_timeval ( & p1 - > begin , & p2 - > begin ) ;
verify_ctdb_timeval ( & p1 - > end , & p2 - > end ) ;
assert ( p1 - > result = = p2 - > result ) ;
verify_ctdb_stringn ( & p1 - > output , & p2 - > output ) ;
}
static void fill_ctdb_event_script_list ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_script_list * p )
{
int i ;
p - > num_scripts = rand_int ( 32 ) ;
if ( p - > num_scripts > 0 ) {
p - > script = talloc_array ( mem_ctx ,
struct ctdb_event_script ,
p - > num_scripts ) ;
assert ( p - > script ! = NULL ) ;
for ( i = 0 ; i < p - > num_scripts ; i + + ) {
fill_ctdb_event_script ( mem_ctx , & p - > script [ i ] ) ;
}
} else {
p - > script = NULL ;
}
}
static void verify_ctdb_event_script_list ( struct ctdb_event_script_list * p1 ,
struct ctdb_event_script_list * p2 )
{
int i ;
assert ( p1 - > num_scripts = = p2 - > num_scripts ) ;
for ( i = 0 ; i < p1 - > num_scripts ; i + + ) {
verify_ctdb_event_script ( & p1 - > script [ i ] , & p2 - > script [ i ] ) ;
}
}
static void fill_ctdb_event_request_run ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_request_run * p )
{
fill_ctdb_stringn ( mem_ctx , & p - > component ) ;
fill_ctdb_stringn ( mem_ctx , & p - > event ) ;
fill_ctdb_stringn ( mem_ctx , & p - > args ) ;
p - > timeout = rand32 ( ) ;
p - > flags = rand32 ( ) ;
}
static void verify_ctdb_event_request_run ( struct ctdb_event_request_run * p1 ,
struct ctdb_event_request_run * p2 )
{
verify_ctdb_stringn ( & p1 - > component , & p2 - > component ) ;
verify_ctdb_stringn ( & p1 - > event , & p2 - > event ) ;
verify_ctdb_stringn ( & p1 - > args , & p2 - > args ) ;
assert ( p1 - > timeout = = p2 - > timeout ) ;
assert ( p1 - > flags = = p2 - > flags ) ;
}
static void fill_ctdb_event_request_status ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_request_status * p )
{
fill_ctdb_stringn ( mem_ctx , & p - > component ) ;
fill_ctdb_stringn ( mem_ctx , & p - > event ) ;
}
static void verify_ctdb_event_request_status (
struct ctdb_event_request_status * p1 ,
struct ctdb_event_request_status * p2 )
{
verify_ctdb_stringn ( & p1 - > component , & p2 - > component ) ;
verify_ctdb_stringn ( & p1 - > event , & p2 - > event ) ;
}
static void fill_ctdb_event_request_script ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_request_script * p )
{
fill_ctdb_stringn ( mem_ctx , & p - > component ) ;
fill_ctdb_stringn ( mem_ctx , & p - > script ) ;
if ( rand_int ( 1 ) = = 0 ) {
p - > action = CTDB_EVENT_SCRIPT_DISABLE ;
} else {
p - > action = CTDB_EVENT_SCRIPT_ENABLE ;
}
}
static void fill_ctdb_event_reply_status ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_reply_status * p )
{
p - > summary = rand32i ( ) ;
p - > script_list = talloc ( mem_ctx , struct ctdb_event_script_list ) ;
assert ( p - > script_list ! = NULL ) ;
fill_ctdb_event_script_list ( mem_ctx , p - > script_list ) ;
}
static void verify_ctdb_event_reply_status ( struct ctdb_event_reply_status * p1 ,
struct ctdb_event_reply_status * p2 )
{
assert ( p1 - > summary = = p2 - > summary ) ;
verify_ctdb_event_script_list ( p1 - > script_list , p2 - > script_list ) ;
}
static void verify_ctdb_event_request_script (
struct ctdb_event_request_script * p1 ,
struct ctdb_event_request_script * p2 )
{
verify_ctdb_stringn ( & p1 - > component , & p2 - > component ) ;
verify_ctdb_stringn ( & p1 - > script , & p2 - > script ) ;
assert ( p1 - > action = = p2 - > action ) ;
}
static void fill_ctdb_event_request_data ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_request * p ,
uint32_t cmd )
{
p - > cmd = cmd ;
switch ( cmd ) {
case CTDB_EVENT_CMD_RUN :
p - > data . run = talloc ( mem_ctx , struct ctdb_event_request_run ) ;
assert ( p - > data . run ! = NULL ) ;
fill_ctdb_event_request_run ( mem_ctx , p - > data . run ) ;
break ;
case CTDB_EVENT_CMD_STATUS :
p - > data . status = talloc ( mem_ctx ,
struct ctdb_event_request_status ) ;
assert ( p - > data . status ! = NULL ) ;
fill_ctdb_event_request_status ( mem_ctx , p - > data . status ) ;
break ;
case CTDB_EVENT_CMD_SCRIPT :
p - > data . script = talloc ( mem_ctx ,
struct ctdb_event_request_script ) ;
assert ( p - > data . script ! = NULL ) ;
fill_ctdb_event_request_script ( mem_ctx , p - > data . script ) ;
break ;
default :
assert ( cmd > 0 & & cmd < CTDB_EVENT_CMD_MAX ) ;
}
}
static void verify_ctdb_event_request_data ( struct ctdb_event_request * p1 ,
struct ctdb_event_request * p2 )
{
assert ( p1 - > cmd = = p2 - > cmd ) ;
switch ( p1 - > cmd ) {
case CTDB_EVENT_CMD_RUN :
verify_ctdb_event_request_run ( p1 - > data . run , p2 - > data . run ) ;
break ;
case CTDB_EVENT_CMD_STATUS :
verify_ctdb_event_request_status ( p1 - > data . status ,
p2 - > data . status ) ;
break ;
case CTDB_EVENT_CMD_SCRIPT :
verify_ctdb_event_request_script ( p1 - > data . script ,
p2 - > data . script ) ;
break ;
default :
assert ( p1 - > cmd > 0 & & p1 - > cmd < CTDB_EVENT_CMD_MAX ) ;
}
}
static void fill_ctdb_event_reply_data ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_reply * p ,
uint32_t cmd )
{
p - > cmd = cmd ;
p - > result = rand32i ( ) ;
if ( p - > result ! = 0 ) {
return ;
}
switch ( cmd ) {
case CTDB_EVENT_CMD_STATUS :
p - > data . status = talloc ( mem_ctx ,
struct ctdb_event_reply_status ) ;
assert ( p - > data . status ! = NULL ) ;
fill_ctdb_event_reply_status ( mem_ctx , p - > data . status ) ;
break ;
default :
assert ( cmd > 0 & & cmd < CTDB_EVENT_CMD_MAX ) ;
}
}
static void verify_ctdb_event_reply_data ( struct ctdb_event_reply * p1 ,
struct ctdb_event_reply * p2 )
{
assert ( p1 - > cmd = = p2 - > cmd ) ;
assert ( p1 - > result = = p2 - > result ) ;
if ( p1 - > result ! = 0 ) {
return ;
}
switch ( p1 - > cmd ) {
case CTDB_EVENT_CMD_STATUS :
verify_ctdb_event_reply_status ( p1 - > data . status ,
p2 - > data . status ) ;
break ;
default :
assert ( p1 - > cmd > 0 & & p1 - > cmd < CTDB_EVENT_CMD_MAX ) ;
}
}
static void fill_ctdb_event_header ( struct ctdb_event_header * p )
{
p - > length = 0 ; /* updated by push functions */
p - > version = 0 ; /* updated by push functions */
p - > reqid = rand32 ( ) ;
}
static void verify_ctdb_event_header ( struct ctdb_event_header * p1 ,
struct ctdb_event_header * p2 )
{
assert ( p1 - > length = = p2 - > length ) ;
assert ( p1 - > version = = p2 - > version ) ;
assert ( p1 - > reqid = = p2 - > reqid ) ;
}
static void fill_ctdb_event_request ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_request * p ,
uint32_t cmd )
{
fill_ctdb_event_request_data ( mem_ctx , p , cmd ) ;
}
static void verify_ctdb_event_request ( struct ctdb_event_request * p1 ,
struct ctdb_event_request * p2 )
{
verify_ctdb_event_request_data ( p1 , p2 ) ;
}
static void fill_ctdb_event_reply ( TALLOC_CTX * mem_ctx ,
struct ctdb_event_reply * p ,
uint32_t cmd )
{
fill_ctdb_event_reply_data ( mem_ctx , p , cmd ) ;
}
static void verify_ctdb_event_reply ( struct ctdb_event_reply * p1 ,
struct ctdb_event_reply * p2 )
{
verify_ctdb_event_reply_data ( p1 , p2 ) ;
}
# define EVENT_PROTOCOL1_TEST(TYPE, NAME) \
static void TEST_FUNC ( NAME ) ( uint32_t cmd ) \
{ \
TALLOC_CTX * mem_ctx ; \
TYPE c1 , * c2 ; \
uint8_t * buf ; \
size_t buflen , np ; \
int ret ; \
\
2022-01-04 12:19:49 +11:00
protocol_test_iterate_tag ( " %s %u \n " , # NAME , cmd ) ; \
2018-02-15 17:33:12 +11:00
mem_ctx = talloc_new ( NULL ) ; \
assert ( mem_ctx ! = NULL ) ; \
FILL_FUNC ( NAME ) ( mem_ctx , & c1 , cmd ) ; \
buflen = LEN_FUNC ( NAME ) ( & c1 ) ; \
buf = talloc_size ( mem_ctx , buflen ) ; \
assert ( buf ! = NULL ) ; \
np = 0 ; \
PUSH_FUNC ( NAME ) ( & c1 , buf , & np ) ; \
assert ( np = = buflen ) ; \
np = 0 ; \
ret = PULL_FUNC ( NAME ) ( buf , buflen , mem_ctx , & c2 , & np ) ; \
assert ( ret = = 0 ) ; \
assert ( np = = buflen ) ; \
VERIFY_FUNC ( NAME ) ( & c1 , c2 ) ; \
talloc_free ( mem_ctx ) ; \
}
# define EVENT_PROTOCOL2_TEST(TYPE, NAME) \
static void TEST_FUNC ( NAME ) ( uint32_t cmd ) \
{ \
TALLOC_CTX * mem_ctx ; \
struct ctdb_event_header h1 , h2 ; \
TYPE c1 , * c2 ; \
uint8_t * buf ; \
size_t buflen , len ; \
int ret ; \
\
2022-01-04 12:19:49 +11:00
protocol_test_iterate_tag ( " %s %u \n " , # NAME , cmd ) ; \
2018-02-15 17:33:12 +11:00
mem_ctx = talloc_new ( NULL ) ; \
assert ( mem_ctx ! = NULL ) ; \
fill_ctdb_event_header ( & h1 ) ; \
FILL_FUNC ( NAME ) ( mem_ctx , & c1 , cmd ) ; \
buflen = LEN_FUNC ( NAME ) ( & h1 , & c1 ) ; \
buf = talloc_size ( mem_ctx , buflen ) ; \
assert ( buf ! = NULL ) ; \
len = 0 ; \
ret = PUSH_FUNC ( NAME ) ( & h1 , & c1 , buf , & len ) ; \
assert ( ret = = EMSGSIZE ) ; \
assert ( len = = buflen ) ; \
ret = PUSH_FUNC ( NAME ) ( & h1 , & c1 , buf , & buflen ) ; \
assert ( ret = = 0 ) ; \
ret = PULL_FUNC ( NAME ) ( buf , buflen , & h2 , mem_ctx , & c2 ) ; \
assert ( ret = = 0 ) ; \
verify_ctdb_event_header ( & h1 , & h2 ) ; \
VERIFY_FUNC ( NAME ) ( & c1 , c2 ) ; \
talloc_free ( mem_ctx ) ; \
}
PROTOCOL_TYPE3_TEST ( struct ctdb_event_script , ctdb_event_script ) ;
PROTOCOL_TYPE3_TEST ( struct ctdb_event_script_list , ctdb_event_script_list ) ;
PROTOCOL_TYPE3_TEST ( struct ctdb_event_request_run , ctdb_event_request_run ) ;
PROTOCOL_TYPE3_TEST ( struct ctdb_event_request_status ,
ctdb_event_request_status ) ;
PROTOCOL_TYPE3_TEST ( struct ctdb_event_request_script ,
ctdb_event_request_script ) ;
PROTOCOL_TYPE3_TEST ( struct ctdb_event_reply_status , ctdb_event_reply_status ) ;
EVENT_PROTOCOL1_TEST ( struct ctdb_event_request , ctdb_event_request_data ) ;
EVENT_PROTOCOL1_TEST ( struct ctdb_event_reply , ctdb_event_reply_data ) ;
EVENT_PROTOCOL2_TEST ( struct ctdb_event_request , ctdb_event_request ) ;
EVENT_PROTOCOL2_TEST ( struct ctdb_event_reply , ctdb_event_reply ) ;
2022-01-04 12:19:49 +11:00
static void event_protocol_test ( void )
2018-02-15 17:33:12 +11:00
{
uint32_t cmd ;
TEST_FUNC ( ctdb_event_script ) ( ) ;
TEST_FUNC ( ctdb_event_script_list ) ( ) ;
TEST_FUNC ( ctdb_event_request_run ) ( ) ;
TEST_FUNC ( ctdb_event_request_status ) ( ) ;
TEST_FUNC ( ctdb_event_request_script ) ( ) ;
TEST_FUNC ( ctdb_event_reply_status ) ( ) ;
for ( cmd = 1 ; cmd < CTDB_EVENT_CMD_MAX ; cmd + + ) {
TEST_FUNC ( ctdb_event_request_data ) ( cmd ) ;
}
for ( cmd = 1 ; cmd < CTDB_EVENT_CMD_MAX ; cmd + + ) {
TEST_FUNC ( ctdb_event_reply_data ) ( cmd ) ;
}
for ( cmd = 1 ; cmd < CTDB_EVENT_CMD_MAX ; cmd + + ) {
TEST_FUNC ( ctdb_event_request ) ( cmd ) ;
}
for ( cmd = 1 ; cmd < CTDB_EVENT_CMD_MAX ; cmd + + ) {
TEST_FUNC ( ctdb_event_reply ) ( cmd ) ;
}
2022-01-04 12:19:49 +11:00
}
2018-02-15 17:33:12 +11:00
2022-01-04 12:19:49 +11:00
int main ( int argc , const char * * argv )
{
protocol_test_iterate ( argc , argv , event_protocol_test ) ;
2018-02-15 17:33:12 +11:00
return 0 ;
}