Tweak timeout handling of authentication tests

* Compute the time at which the handshake must have completed from the
  initial timeout specification, rather than using it as a timeout for
  the individual steps of the handshake
* If the handshake fails because an expected message is not present,
  print this, including whether the timeout occured because the message
  queue was empty or because the expected message could not be found in
  a non-empty queue.
* Replace the 0.5s per-step timeout to a single 2s timeout.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-05-16 08:38:58 +02:00 committed by eboasson
parent 2ef17d0200
commit be7f7af741
6 changed files with 122 additions and 55 deletions

View file

@ -700,7 +700,7 @@ static void test_encoding_mismatch(
struct Handshake *hs_list;
int nhs;
validate_handshake (DDS_DOMAINID, false, NULL, &hs_list, &nhs, DDS_MSECS(500));
validate_handshake (DDS_DOMAINID, false, NULL, &hs_list, &nhs, DDS_SECS(2));
CU_ASSERT_EQUAL_FATAL (exp_hs_fail, nhs < 1);
handshake_list_fini (hs_list, nhs);
@ -799,7 +799,7 @@ static void test_readwrite_protection (
if (!exp_pub_pp_fail && !exp_sub_pp_fail)
{
dds_entity_t pub, sub, pub_tp, sub_tp, wr, rd;
validate_handshake_nofail (DDS_DOMAINID, DDS_MSECS(500));
validate_handshake_nofail (DDS_DOMAINID, DDS_SECS(2));
rd_wr_init_fail (g_participant[0], &pub, &pub_tp, &wr, g_participant[1], &sub, &sub_tp, &rd, topic_name, exp_pub_tp_fail, exp_wr_fail, exp_sub_tp_fail, exp_rd_fail);
if (!exp_pub_tp_fail && !exp_wr_fail && !exp_sub_tp_fail && !exp_rd_fail)
sync_writer_to_readers (g_participant[0], wr, exp_sync_fail ? 0 : 1, DDS_SECS(1));

View file

@ -446,11 +446,11 @@ static struct dds_security_authentication_impl * get_impl_for_domain(dds_domaini
return NULL;
}
struct message * test_authentication_plugin_take_msg(dds_domainid_t domain_id, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_duration_t timeout)
enum take_message_result test_authentication_plugin_take_msg(dds_domainid_t domain_id, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_time_t abstimeout, struct message **msg)
{
struct dds_security_authentication_impl *impl = get_impl_for_domain(domain_id);
assert(impl);
return take_message(&impl->msg_queue, kind, lidHandle, ridHandle, hsHandle, timeout);
return take_message(&impl->msg_queue, kind, lidHandle, ridHandle, hsHandle, abstimeout, msg);
}
void test_authentication_plugin_release_msg(struct message *msg)

View file

@ -33,7 +33,7 @@ SECURITY_EXPORT int finalize_test_authentication_missing_func(void *context);
SECURITY_EXPORT int init_test_authentication_init_error(const char *argument, void **context, struct ddsi_domaingv *gv);
SECURITY_EXPORT int finalize_test_authentication_init_error(void *context);
SECURITY_EXPORT struct message * test_authentication_plugin_take_msg(dds_domainid_t domain_id, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_duration_t timeout);
SECURITY_EXPORT enum take_message_result test_authentication_plugin_take_msg(dds_domainid_t domain_id, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_time_t abstimeout, struct message **msg);
SECURITY_EXPORT void test_authentication_plugin_release_msg(struct message *msg);
#endif /* SECURITY_CORE_TEST_AUTHENTICATION_WRAPPER_H_ */

View file

@ -95,25 +95,26 @@ int message_matched(struct message *msg, message_kind_t kind, DDS_Security_Ident
(!hsHandle || msg->hsHandle == hsHandle);
}
struct message * take_message(struct message_queue *queue, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_duration_t timeout)
enum take_message_result take_message(struct message_queue *queue, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_time_t abstimeout, struct message **msg)
{
struct message *msg = NULL, *cur, *prev;
int r = 1;
struct message *cur, *prev;
enum take_message_result ret = TAKE_MESSAGE_OK;
*msg = NULL;
ddsrt_mutex_lock(&queue->lock);
do
{
cur = queue->head;
prev = NULL;
while (cur && !msg)
while (cur && *msg == NULL)
{
if (message_matched(cur, kind, lidHandle, ridHandle, hsHandle))
{
msg = cur;
*msg = cur;
if (prev)
prev->next = msg->next;
prev->next = cur->next;
else
queue->head = msg->next;
if (queue->tail == msg)
queue->head = cur->next;
if (queue->tail == cur)
queue->tail = prev;
}
else
@ -122,13 +123,13 @@ struct message * take_message(struct message_queue *queue, message_kind_t kind,
cur = cur->next;
}
}
if (!msg)
if (*msg == NULL)
{
if (!ddsrt_cond_waitfor(&queue->cond, &queue->lock, timeout))
r = 0;
if (!ddsrt_cond_waituntil(&queue->cond, &queue->lock, abstimeout))
ret = queue->head ? TAKE_MESSAGE_TIMEOUT_NONEMPTY : TAKE_MESSAGE_TIMEOUT_EMPTY;
}
} while (r && !msg);
} while (ret == TAKE_MESSAGE_OK && *msg == NULL);
ddsrt_mutex_unlock(&queue->lock);
return msg;
return ret;
}

View file

@ -46,6 +46,12 @@ struct message_queue {
struct message *tail;
};
enum take_message_result {
TAKE_MESSAGE_OK, /* message found */
TAKE_MESSAGE_TIMEOUT_EMPTY, /* no message found, queue is empty */
TAKE_MESSAGE_TIMEOUT_NONEMPTY /* no message found, queue is not empty */
};
struct dds_security_authentication_impl;
void insert_message(struct message_queue *queue, struct message *msg);
@ -56,7 +62,7 @@ void delete_message(struct message *msg);
void init_message_queue(struct message_queue *queue);
void deinit_message_queue(struct message_queue *queue);
int message_matched(struct message *msg, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle);
struct message * take_message(struct message_queue *queue, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_duration_t timeout);
enum take_message_result take_message(struct message_queue *queue, message_kind_t kind, DDS_Security_IdentityHandle lidHandle, DDS_Security_IdentityHandle ridHandle, DDS_Security_IdentityHandle hsHandle, dds_time_t abstimeout, struct message **msg);
#endif /* SECURITY_CORE_PLUGIN_WRAPPER_MSG_Q_H_ */

View file

@ -149,11 +149,12 @@ static int find_handshake (DDS_Security_HandshakeHandle handle)
return -1;
}
static void handle_process_message (dds_domainid_t domain_id, DDS_Security_IdentityHandle handshake, dds_duration_t timeout)
static void handle_process_message (dds_domainid_t domain_id, DDS_Security_IdentityHandle handshake, dds_time_t abstimeout)
{
struct message *msg;
if ((msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_PROCESS_HANDSHAKE, 0, 0, handshake, timeout)))
switch (test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_PROCESS_HANDSHAKE, 0, 0, handshake, abstimeout, &msg))
{
case TAKE_MESSAGE_OK: {
int idx;
if ((idx = find_handshake (msg->hsHandle)) >= 0)
{
@ -162,45 +163,78 @@ static void handle_process_message (dds_domainid_t domain_id, DDS_Security_Ident
handshakeList[idx].err_msg = ddsrt_strdup (msg->err_msg);
}
test_authentication_plugin_release_msg (msg);
break;
}
case TAKE_MESSAGE_TIMEOUT_EMPTY: {
print_test_msg ("handle_process_message: timed out on empty queue\n");
break;
}
case TAKE_MESSAGE_TIMEOUT_NONEMPTY: {
print_test_msg ("handle_process_message: timed out on non-empty queue\n");
break;
}
}
}
static void handle_begin_handshake_request (dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, dds_duration_t timeout)
static void handle_begin_handshake_request (dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, dds_time_t abstimeout)
{
struct message *msg;
print_test_msg ("handle begin handshake request %"PRId64"<->%"PRId64"\n", lid, rid);
if ((msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REQUEST, lid, rid, 0, timeout)))
switch (test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REQUEST, lid, rid, 0, abstimeout, &msg))
{
case TAKE_MESSAGE_OK: {
hs->handle = msg->hsHandle;
hs->handshakeResult = msg->result;
if (msg->result != DDS_SECURITY_VALIDATION_FAILED)
handle_process_message (domain_id, msg->hsHandle, timeout);
handle_process_message (domain_id, msg->hsHandle, abstimeout);
else
hs->err_msg = ddsrt_strdup (msg->err_msg);
test_authentication_plugin_release_msg (msg);
break;
}
case TAKE_MESSAGE_TIMEOUT_EMPTY: {
print_test_msg ("handle_begin_handshake_request: timed out on empty queue\n");
break;
}
case TAKE_MESSAGE_TIMEOUT_NONEMPTY: {
print_test_msg ("handle_begin_handshake_request: timed out on non-empty queue\n");
break;
}
}
}
static void handle_begin_handshake_reply (dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, dds_duration_t timeout)
static void handle_begin_handshake_reply (dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, dds_time_t abstimeout)
{
struct message *msg;
print_test_msg ("handle begin handshake reply %"PRId64"<->%"PRId64"\n", lid, rid);
if ((msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REPLY, lid, rid, 0, timeout)))
switch (test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REPLY, lid, rid, 0, abstimeout, &msg))
{
case TAKE_MESSAGE_OK: {
hs->handle = msg->hsHandle;
hs->handshakeResult = msg->result;
if (msg->result != DDS_SECURITY_VALIDATION_FAILED)
handle_process_message (domain_id, msg->hsHandle, timeout);
handle_process_message (domain_id, msg->hsHandle, abstimeout);
else
hs->err_msg = ddsrt_strdup (msg->err_msg);
test_authentication_plugin_release_msg (msg);
break;
}
case TAKE_MESSAGE_TIMEOUT_EMPTY: {
print_test_msg ("handle_begin_handshake_reply: timed out on empty queue\n");
break;
}
case TAKE_MESSAGE_TIMEOUT_NONEMPTY: {
print_test_msg ("handle_begin_handshake_reply: timed out on non-empty queue\n");
break;
}
}
}
static void handle_validate_remote_identity (dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, int count, dds_duration_t timeout)
static void handle_validate_remote_identity (dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, int count, dds_time_t abstimeout)
{
enum take_message_result res = TAKE_MESSAGE_OK;
struct message *msg;
while (count-- > 0 && (msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, timeout)))
while (count-- > 0 && (res = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, abstimeout, &msg)) == TAKE_MESSAGE_OK)
{
struct Handshake *hs;
add_remote_identity (msg->ridHandle, &msg->rguid);
@ -208,12 +242,12 @@ static void handle_validate_remote_identity (dds_domainid_t domain_id, DDS_Secur
if (msg->result == DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST)
{
hs->node_type = HSN_REQUESTER;
handle_begin_handshake_request (domain_id, hs, lid, msg->ridHandle, timeout);
handle_begin_handshake_request (domain_id, hs, lid, msg->ridHandle, abstimeout);
}
else if (msg->result == DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE)
{
hs->node_type = HSN_REPLIER;
handle_begin_handshake_reply (domain_id, hs, lid, msg->ridHandle, timeout);
handle_begin_handshake_reply (domain_id, hs, lid, msg->ridHandle, abstimeout);
}
else
{
@ -221,11 +255,34 @@ static void handle_validate_remote_identity (dds_domainid_t domain_id, DDS_Secur
}
test_authentication_plugin_release_msg (msg);
}
switch (res)
{
case TAKE_MESSAGE_OK:
break;
case TAKE_MESSAGE_TIMEOUT_EMPTY:
print_test_msg ("handle_validate_remote_identity: timed out on empty queue\n");
break;
case TAKE_MESSAGE_TIMEOUT_NONEMPTY:
print_test_msg ("handle_validate_remote_identity: timed out on non-empty queue\n");
break;
}
}
static void handle_validate_local_identity (dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, dds_duration_t timeout)
static void handle_validate_local_identity (dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, dds_time_t abstimeout)
{
struct message *msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, timeout);
struct message *msg;
switch (test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, abstimeout, &msg))
{
case TAKE_MESSAGE_OK:
break;
case TAKE_MESSAGE_TIMEOUT_EMPTY:
print_test_msg ("handle_validate_local_identity: timed out on empty queue\n");
break;
case TAKE_MESSAGE_TIMEOUT_NONEMPTY:
print_test_msg ("handle_validate_local_identity: timed out on non-empty queue\n");
break;
}
CU_ASSERT_FATAL (msg != NULL);
CU_ASSERT_FATAL ((msg->result == DDS_SECURITY_VALIDATION_OK) != exp_localid_fail);
if (exp_localid_fail && exp_localid_msg)
@ -234,12 +291,15 @@ static void handle_validate_local_identity (dds_domainid_t domain_id, bool exp_l
CU_ASSERT_FATAL (msg->err_msg && strstr (msg->err_msg, exp_localid_msg) != NULL);
}
else
{
add_local_identity (msg->lidHandle, &msg->lguid);
}
test_authentication_plugin_release_msg (msg);
}
void validate_handshake (dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, struct Handshake *hs_list[], int *nhs, dds_duration_t timeout)
{
dds_time_t abstimeout = dds_time() + timeout;
clear_stores ();
if (nhs)
@ -247,10 +307,10 @@ void validate_handshake (dds_domainid_t domain_id, bool exp_localid_fail, const
if (hs_list)
*hs_list = NULL;
handle_validate_local_identity (domain_id, exp_localid_fail, exp_localid_msg, timeout);
handle_validate_local_identity (domain_id, exp_localid_fail, exp_localid_msg, abstimeout);
if (!exp_localid_fail)
{
handle_validate_remote_identity (domain_id, localIdentityList[0].handle, 1, timeout);
handle_validate_remote_identity (domain_id, localIdentityList[0].handle, 1, abstimeout);
for (int n = 0; n < numHandshake; n++)
{
struct Handshake *hs = &handshakeList[n];