/*
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 .
*/
#include "replace.h"
#include
#include
#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; inum_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; inum_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; \
\
protocol_test_iterate_tag("%s %u\n", #NAME, cmd); \
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; \
\
protocol_test_iterate_tag("%s %u\n", #NAME, cmd); \
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);
static void event_protocol_test(void)
{
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