Major reorganization:

Removed all Main.cpp files, use the macro in testMain.h instead and
defaulted all argc/argv parameters.
Converted all real test programs to use epicsUnitTest.h.
Moved performance measurements from epicsThreadTest to epicsThreadPerform.
Moved epicsOkToBlockTest tests into epicsThreadTest.
On a host arch,  make test  inside the O.arch directory runs all tests.
This commit is contained in:
Andrew Johnson
2006-11-09 22:38:41 +00:00
parent d8b9856252
commit 6c19051727
46 changed files with 1239 additions and 1533 deletions

View File

@@ -1,11 +1,10 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Id$
@@ -18,12 +17,17 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <epicsMessageQueue.h>
#include <epicsThread.h>
#include <epicsExit.h>
#include <epicsAssert.h>
const char *msg1 = "1234567890This is a very long message.";
#include "epicsMessageQueue.h"
#include "epicsThread.h"
#include "epicsExit.h"
#include "epicsEvent.h"
#include "epicsAssert.h"
#include "epicsUnitTest.h"
#include "testMain.h"
static const char *msg1 = "1234567890This is a very long message.";
static int testExit = 0;
/*
* In Numerical Recipes in C: The Art of Scientific Computing (William H.
@@ -47,11 +51,27 @@ badReceiver(void *arg)
{
epicsMessageQueue *q = (epicsMessageQueue *)arg;
char cbuf[80];
int len;
cbuf[0] = '\0';
assert((q->receive(cbuf, 1) == -1) && (cbuf[0] == '\0'));
epicsThreadSleep(5.0);
assert((q->receive(cbuf, 1) == -1) && (cbuf[0] == '\0'));
len = q->receive(cbuf, 1);
if (len < 0 && cbuf[0] == '\0')
testPass("receive into undersized buffer returned error (%d)", len);
else if (len == 1 && cbuf[0] == *msg1)
testPass("receive into undersized buffer truncated message");
else
testFail("receive into undersized buffer returned %d", len);
epicsThreadSleep(3.0);
cbuf[0] = '\0';
len = q->receive(cbuf, 1);
if (len < 0 && cbuf[0] == '\0')
testPass("receive into undersized buffer returned error (%d)", len);
else if (len == 1 && cbuf[0] == *msg1)
testPass("receive into undersized buffer truncated message");
else
testFail("receive into undersized buffer returned %d", len);
}
extern "C" void
@@ -62,27 +82,29 @@ receiver(void *arg)
int expectmsg[4];
int len;
int sender, msgNum;
int errors = 0;
for (sender = 1 ; sender <= 4 ; sender++)
expectmsg[sender-1] = 1;
for (;;) {
while (!testExit) {
cbuf[0] = '\0';
len = q->receive(cbuf, sizeof cbuf);
if ((sscanf(cbuf, "Sender %d -- %d", &sender, &msgNum) == 2)
&& (sender >= 1)
&& (sender <= 4)) {
if (expectmsg[sender-1] != msgNum)
printf("%s received %d '%.*s' -- expected %d\n", epicsThreadGetNameSelf(), len, len, cbuf, expectmsg[sender-1]);
if (expectmsg[sender-1] != msgNum) {
++errors;
testDiag("%s received %d '%.*s' -- expected %d", epicsThreadGetNameSelf(), len, len, cbuf, expectmsg[sender-1]);
}
expectmsg[sender-1] = msgNum + 1;
epicsThreadSleep(0.001 * (randBelow(20)));
}
else {
for (sender = 1 ; sender <= 4 ; sender++) {
if (expectmsg[sender-1] > 1)
printf("Sender %d -- %d messages\n", sender, expectmsg[sender-1]-1);
}
}
}
for (sender = 1 ; sender <= 4 ; sender++) {
if (expectmsg[sender-1] > 1)
testDiag("Sender %d -- %d messages", sender, expectmsg[sender-1]-1);
}
testOk1(errors == 0);
}
extern "C" void
@@ -93,7 +115,7 @@ sender(void *arg)
int len;
int i = 0;
for (;;) {
while (!testExit) {
len = sprintf(cbuf, "%s -- %d.", epicsThreadGetNameSelf(), ++i);
while (q->trySend((void *)cbuf, len) < 0)
epicsThreadSleep(0.005 * (randBelow(5)));
@@ -101,8 +123,9 @@ sender(void *arg)
}
}
extern "C" void epicsMessageQueueTest(void *parm)
extern "C" void messageQueueTest(void *parm)
{
epicsEventId *pfinished = (epicsEventId *) parm;
unsigned int i;
char cbuf[80];
int len;
@@ -112,143 +135,141 @@ extern "C" void epicsMessageQueueTest(void *parm)
epicsMessageQueue *q1 = new epicsMessageQueue(4, 20);
printf ("Simple single-thread tests.\n");
testDiag("Simple single-thread tests:");
i = 0;
used = 0;
assert(q1->pending() == 0);
testOk1(q1->pending() == 0);
while (q1->trySend((void *)msg1, i ) == 0) {
i++;
assert(q1->pending() == i);
printf("Should have %d pending -- ", ++used);
q1->show();
testOk(q1->pending() == i, "q1->pending() == %d", i);
}
assert(q1->pending() == 4);
testOk1(q1->pending() == 4);
want = 0;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 3);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 3);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
want++;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 2);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 2);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
q1->trySend((void *)msg1, i++);
want++;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 2);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 2);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
q1->trySend((void *)msg1, i++);
assert(q1->pending() == 3);
testOk1(q1->pending() == 3);
i = 3;
while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) {
assert(q1->pending() == --i);
--i;
testOk(q1->pending() == i, "q1->pending() == %d", i);
want++;
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
if (!testOk1((len == want) & (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
}
assert(q1->pending() == 0);
testOk1(q1->pending() == 0);
printf ("Test sender timeout.\n");
testDiag("Test sender timeout:");
i = 0;
used = 0;
assert(q1->pending() == 0);
testOk1(q1->pending() == 0);
while (q1->send((void *)msg1, i, 1.0 ) == 0) {
i++;
assert(q1->pending() == i);
printf("Should have %d pending -- ", ++used);
q1->show();
testOk(q1->pending() == i, "q1->pending() == %d", i);
}
assert(q1->pending() == 4);
testOk1(q1->pending() == 4);
want = 0;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 3);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 3);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
want++;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 2);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 2);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
q1->send((void *)msg1, i++, 1.0);
want++;
len = q1->receive(cbuf, sizeof cbuf);
assert(q1->pending() == 2);
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
testOk1(q1->pending() == 2);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
q1->send((void *)msg1, i++, 1.0);
assert(q1->pending() == 3);
testOk1(q1->pending() == 3);
i = 3;
while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) {
assert(q1->pending() == --i);
--i;
testOk(q1->pending() == i, "q1->pending() == %d", i);
want++;
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
}
assert(q1->pending() == 0);
testOk1(q1->pending() == 0);
printf ("Test receiver with timeout.\n");
testDiag("Test receiver with timeout:");
for (i = 0 ; i < 4 ; i++)
assert (q1->send((void *)msg1, i, 1.0) == 0);
assert(q1->pending() == 4);
testOk1 (q1->send((void *)msg1, i, 1.0) == 0);
testOk1(q1->pending() == 4);
for (i = 0 ; i < 4 ; i++)
assert (q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i);
assert(q1->pending() == 0);
assert (q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0);
assert(q1->pending() == 0);
testOk(q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i,
"q1->receive(...) == %d", i);
testOk1(q1->pending() == 0);
testOk1(q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0);
testOk1(q1->pending() == 0);
printf("Single receiver with invalid size, single sender tests.\n");
testDiag("Single receiver with invalid size, single sender tests:");
epicsThreadCreate("Bad Receiver", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), badReceiver, q1);
epicsThreadSleep(5.0);
assert (q1->send((void *)msg1, 10) == 0); /* Send with waiting receiver */
epicsThreadSleep(1.0);
testOk(q1->send((void *)msg1, 10) == 0, "Send with waiting receiver");
epicsThreadSleep(2.0);
testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver");
epicsThreadSleep(2.0);
assert (q1->send((void *)msg1, 10) == 0); /* Send with no receiver */
epicsThreadSleep(10.0);
printf("Single receiver, single sender tests.\n");
testDiag("Single receiver, single sender tests:");
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityHigh);
epicsThreadCreate("Receiver one", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), receiver, q1);
for (pass = 1 ; pass <= 3 ; pass++) {
switch (pass) {
case 1:
printf ("Systems with priority-based scheduler should send only\n"
"4 or 5 messages (sender priority > receiver priority).\n");
break;
case 2:
printf ("Systems with strict priority-based scheduler should send\n"
"10 messages (sender priority < receiver priority).\n");
break;
case 3:
printf ("All systems should send 10 messages (sender pauses\n"
"after sending each message).\n");
break;
}
epicsThreadSleep(1.0);
for (i = 0 ; i < 10 ; i++) {
if (q1->trySend((void *)msg1, i) < 0)
break;
if (pass >= 3)
epicsThreadSleep(0.5);
}
printf ("Sent %d messages.\n", i);
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityLow);
switch (pass) {
case 1:
if (i<6)
testDiag(" priority-based scheduler, sent %d messages", i);
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityLow);
break;
case 2:
if (i<10)
testDiag(" scheduler not strict priority, sent %d messages", i);
else
testDiag(" strict priority scheduler, sent 10 messages");
break;
case 3:
testOk(i == 10, "%d of 10 messages sent with sender pauses", i);
break;
}
epicsThreadSleep(1.0);
}
/*
* Single receiver, multiple sender tests
*/
printf("Single receiver, multiple sender tests.\n");
printf("The following test takes 5 minutes to run and has succeeded\nif nothing appears between here....\n");
testDiag("Single receiver, multiple sender tests:");
testDiag("This test takes 5 minutes...");
epicsThreadCreate("Sender 1", epicsThreadPriorityLow, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
epicsThreadCreate("Sender 2", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
epicsThreadCreate("Sender 3", epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
@@ -256,10 +277,22 @@ extern "C" void epicsMessageQueueTest(void *parm)
epicsThreadSleep(300.0);
/*
* Force out summaries
*/
printf("......and here.\n");
q1->trySend((void *)msg1, 0);
testExit = 1;
epicsThreadSleep(1.0);
epicsEventSignal(*pfinished);
}
MAIN(epicsMessageQueueTest)
{
testPlan(58);
epicsEventId finished = epicsEventMustCreate(epicsEventEmpty);
epicsThreadCreate("messageQueueTest", epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackMedium),
messageQueueTest, (void *) &finished);
epicsEventWait(finished);
return testDone();
}