143 lines
4.3 KiB
C
143 lines
4.3 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2008 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 is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
/* ringBytesTest.c */
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
|
|
#include "epicsThread.h"
|
|
#include "epicsRingBytes.h"
|
|
#include "errlog.h"
|
|
#include "epicsEvent.h"
|
|
#include "epicsUnitTest.h"
|
|
#include "testMain.h"
|
|
|
|
#define RINGSIZE 10
|
|
|
|
static char msg[] = "This is a very long string to be sent through the ring. "
|
|
"It will take multiple transmissions, you know.";
|
|
|
|
typedef struct info {
|
|
epicsEventId consumerEvent;
|
|
epicsRingBytesId ring;
|
|
}info;
|
|
|
|
static void check(epicsRingBytesId ring, int expectedFree)
|
|
{
|
|
int expectedUsed = RINGSIZE - expectedFree;
|
|
int expectedEmpty = (expectedUsed == 0);
|
|
int expectedFull = (expectedFree == 0);
|
|
int nFree = epicsRingBytesFreeBytes(ring);
|
|
int nUsed = epicsRingBytesUsedBytes(ring);
|
|
int isEmpty = epicsRingBytesIsEmpty(ring);
|
|
int isFull = epicsRingBytesIsFull(ring);
|
|
|
|
testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree);
|
|
testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed);
|
|
testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty);
|
|
testOk(isFull == expectedFull, "Full: %d == %d", isFull, expectedFull);
|
|
}
|
|
|
|
static void consumer(void *arg)
|
|
{
|
|
info *pinfo = (info *)arg;
|
|
char getMsg[sizeof(msg) + RINGSIZE];
|
|
int i = 0;
|
|
int n;
|
|
|
|
testDiag("Consumer starting");
|
|
while(1) {
|
|
epicsEventMustWait(pinfo->consumerEvent);
|
|
n = epicsRingBytesGet(pinfo->ring, getMsg+i, RINGSIZE);
|
|
testOk(n != 0, "Read from ring");
|
|
i += n;
|
|
if (i >= sizeof(msg))
|
|
break;
|
|
}
|
|
testOk(i==sizeof(msg), "Correct number of bytes received %d==%d", i, (int)sizeof(msg));
|
|
testOk(strcmp(msg, getMsg) == 0, "Message received");
|
|
}
|
|
|
|
MAIN(ringBytesTest)
|
|
{
|
|
int i, n;
|
|
info *pinfo;
|
|
epicsEventId consumerEvent;
|
|
char put[RINGSIZE+1];
|
|
char get[RINGSIZE+1];
|
|
epicsRingBytesId ring;
|
|
|
|
testPlan(242);
|
|
|
|
pinfo = calloc(1,sizeof(info));
|
|
if (!pinfo) {
|
|
testAbort("calloc failed");
|
|
}
|
|
pinfo->consumerEvent = consumerEvent = epicsEventCreate(epicsEventEmpty);
|
|
if (!consumerEvent) {
|
|
testAbort("epicsEventCreate failed");
|
|
}
|
|
|
|
pinfo->ring = ring = epicsRingBytesCreate(RINGSIZE);
|
|
if (!ring) {
|
|
testAbort("epicsRingBytesCreate failed");
|
|
}
|
|
check(ring, RINGSIZE);
|
|
|
|
for (i = 0 ; i < sizeof(put) ; i++)
|
|
put[i] = i;
|
|
for(i = 0 ; i < RINGSIZE ; i++) {
|
|
n = epicsRingBytesPut(ring, put, i);
|
|
testOk(n==i, "ring put %d", i);
|
|
check(ring, RINGSIZE-i);
|
|
n = epicsRingBytesGet(ring, get, i);
|
|
testOk(n==i, "ring get %d", i);
|
|
check(ring, RINGSIZE);
|
|
testOk(memcmp(put,get,i)==0, "get matches write");
|
|
}
|
|
|
|
for(i = 0 ; i < RINGSIZE ; i++) {
|
|
n = epicsRingBytesPut(ring, put+i, 1);
|
|
testOk(n==1, "ring put 1, %d", i);
|
|
check(ring, RINGSIZE-1-i);
|
|
}
|
|
n = epicsRingBytesPut(ring, put+RINGSIZE, 1);
|
|
testOk(n==0, "put to full ring");
|
|
check(ring, 0);
|
|
for(i = 0 ; i < RINGSIZE ; i++) {
|
|
n = epicsRingBytesGet(ring, get+i, 1);
|
|
testOk(n==1, "ring get 1, %d", i);
|
|
check(ring, 1+i);
|
|
}
|
|
testOk(memcmp(put,get,RINGSIZE)==0, "get matches write");
|
|
n = epicsRingBytesGet(ring, get+RINGSIZE, 1);
|
|
testOk(n==0, "get from empty ring");
|
|
check(ring, RINGSIZE);
|
|
|
|
epicsThreadCreate("consumer", 50,
|
|
epicsThreadGetStackSize(epicsThreadStackSmall), consumer, pinfo);
|
|
epicsThreadSleep(0.1);
|
|
|
|
for (i = 0; i < sizeof(msg) ; ) {
|
|
n = epicsRingBytesPut(ring, msg+i, sizeof(msg)-i);
|
|
epicsEventSignal(consumerEvent);
|
|
epicsThreadSleep(0.2);
|
|
i += n;
|
|
}
|
|
epicsThreadSleep(0.2);
|
|
check(ring, RINGSIZE);
|
|
|
|
return testDone();
|
|
}
|