static void checkArrD(const char *pv, long elen, double a, double b, double c, double d) { double buf[4]; double expect[4]; long nReq = NELEMENTS(buf), i; unsigned match; DBADDR addr; expect[0] = a; expect[1] = b; expect[2] = c; expect[3] = d; if (dbNameToAddr(pv, &addr)) testAbort("Unknown PV '%s'", pv); if (dbGet(&addr, DBR_DOUBLE, buf, NULL, &nReq, NULL)) testAbort("Failed to get '%s'", pv); match = elen==nReq; for (i=0; i<nReq && i<elen; i++) { match &= fabs(buf[i]-expect[i])<0.01; } testOk(match, "dbGet(\"%s\") matches", pv); if (elen!=nReq) testDiag("lengths don't match %ld != %ld", elen, nReq); for (i=0; i<nReq && i<elen; i++) { if (fabs(buf[i]-expect[i])>=0.01) testDiag("[%ld] -> %f != %f", i, expect[i], buf[i]); } }
/* Program exit func */ static void seqg_exit(SS_ID seqg_env) { # line 43 "../local.st" testOk(seqg_var->i == 1, "global i==%d", seqg_var->i); # line 44 "../local.st" seq_test_done(); }
static void acceptNewClient ( void *pParam ) { osiSocklen_t addrSize; struct sockaddr_in addr; int status; addrSize = sizeof ( addr ); insock = epicsSocketAccept ( sock, (struct sockaddr *)&addr, &addrSize ); testOk(insock != INVALID_SOCKET && addrSize >= sizeof (addr), "Accepted new client"); status = fdmgr_add_callback(pfdctx, insock, fdi_read, readFromClient, NULL); testOk(status >= 0, "Client read configured"); }
static void * allocPvt(void) { myStruct *my = (myStruct*) calloc(1, sizeof(myStruct)); if (!puser1) { puser1 = my; testOk(e1 & e_alloc, "allocPvt (1) called"); c1 |= e_alloc; } else if (!puser2) { puser2 = my; testOk(e2 & e_alloc, "allocPvt (2) called"); c2 |= e_alloc; } clearStruct (my); return my; }
/* Action function for state "check_msg" in state set "check" */ static void seqg_action_check_1_check_msg(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 107 "../opttVar.st" seqg_var->seqg_vars_check.xp = seqg_var->seqg_vars_check.expected; # line 108 "../opttVar.st" testPass("one more time..."); # line 109 "../opttVar.st" seqg_var->seqg_vars_check.repeat = 0; } return; case 1: { } return; case 2: { # line 114 "../opttVar.st" testOk(strcmp(*seqg_var->seqg_vars_check.xp, seqg_var->msg) == 0, "msg=%s", seqg_var->msg); # line 115 "../opttVar.st" seqg_var->seqg_vars_check.xp++; } return; } }
/* Action function for state "zero" in state set "main" */ static void A_main_0_zero(SS_ID ssId, struct UserVar *pVar, int transNum, int *pNextState) { switch(transNum) { case 0: { } return; case 1: { # line 37 "../change.st" testOk(pVar->UserVar_main.x == 0, "state=zero, x=%d", pVar->UserVar_main.x); # line 38 "../change.st" pVar->UserVar_main.x = rand() % 10 - 5; # line 39 "../change.st" testDiag("new random x=%d", pVar->UserVar_main.x); # line 40 "../change.st" pVar->UserVar_main.n++; # line 41 "../change.st" if (pVar->UserVar_main.x > 0) { {*pNextState = 1; return;} } else # line 43 "../change.st" if (pVar->UserVar_main.x < 0) { {*pNextState = 2; return;} } } return; } }
static void checkArrI(const char *pv, long elen, epicsInt32 a, epicsInt32 b, epicsInt32 c, epicsInt32 d) { epicsInt32 buf[4]; epicsInt32 expect[4]; long nReq = NELEMENTS(buf), i; unsigned match; DBADDR addr; expect[0] = a; expect[1] = b; expect[2] = c; expect[3] = d; if (dbNameToAddr(pv, &addr)) testAbort("Unknown PV '%s'", pv); if (dbGet(&addr, DBR_LONG, buf, NULL, &nReq, NULL)) testAbort("Failed to get '%s'", pv); match = elen==nReq; for (i=0; i<nReq && i<elen; i++) { match &= buf[i]==expect[i]; } testOk(match, "dbGet(\"%s\") matches", pv); if (elen!=nReq) testDiag("lengths don't match %ld != %ld", elen, nReq); for (i=0; i<nReq && i<elen; i++) { if(buf[i]!=expect[i]) testDiag("[%ld] -> %d != %d", i, (int)expect[i], (int)buf[i]); } }
static long initRec1(waveformRecord *prec) { testDiag("init_record(%s)", prec->name); testOk(prec->nord==0, "NORD %d==0", (int)prec->nord); iran |= 2; return 0; }
static void * allocPvtFail(void) { if (!puser1) { testOk(e1 & e_alloc, "allocPvt (1) called"); c1 |= e_alloc; } return NULL; }
epicsShareFunc void testRestore(void) { aoRecord *rec0; waveformRecord *rec1; testDiag("test Restore"); initHookRegister(hookPass0); initHookRegister(hookPass1); testdbPrepare(); testdbReadDatabase("asTestIoc.dbd", NULL, NULL); /* since this test has device support it must appear in a * DLL for windows dynamic builds. * However, the rRDD function is in the executable, * and not accessible here. So use iocsh. * For rtems/vxworks the test harness clears * iocsh registrations, so iocsh can't work here. */ #if defined(__rtems__) || defined(vxWorks) asTestIoc_registerRecordDeviceDriver(pdbbase); #else iocshCmd("asTestIoc_registerRecordDeviceDriver(pdbbase)"); #endif testdbReadDatabase("asTest.db", NULL, NULL); rec0 = (aoRecord*)testdbRecordPtr("rec0"); rec1 = (waveformRecord*)testdbRecordPtr("rec1"); eltc(0); testIocInitOk(); eltc(1); testDiag("Post initialization"); testOk1(iran==3); testOk1(rec0->val==4); testOk1(rec1->nord==5); { double *buf = rec1->bptr; testOk(buf[0]==1, "buf[0] %f==1", buf[0]); testOk1(buf[1]==2); testOk1(buf[2]==3); testOk1(buf[3]==4); testOk1(buf[4]==5); } testIocShutdownOk(); /* recSup doesn't cleanup after itself */ free(rec1->bptr); testdbCleanup(); }
static int checkGetString(DBENTRY *pent, const char *expect) { dbCommon *prec = pent->precnode->precord; const char *actual = dbGetString(pent); int ret = strcmp(actual, expect); testOk(ret==0, "dbGetString(\"%s.%s\") -> '%s' == '%s'", prec->name, pent->pflddes->name, actual, expect); return ret; }
static void createAndOpen(const char *chan, const char *json, const char *type, dbChannel**pch, short no) { ELLNODE *node; char name[80]; strncpy(name, chan, sizeof(name)-1); strncat(name, json, sizeof(name)-strlen(name)-1); testOk(!!(*pch = dbChannelCreate(name)), "dbChannel with plugin arr %s created", type); testOk((ellCount(&(*pch)->filters) == no), "channel has %d filter(s) in filter list", no); testOk(!(dbChannelOpen(*pch)), "dbChannel with plugin arr opened"); node = ellFirst(&(*pch)->pre_chain); (void) CONTAINER(node, chFilter, pre_node); testOk((ellCount(&(*pch)->pre_chain) == 0), "arr has no filter in pre chain"); node = ellFirst(&(*pch)->post_chain); (void) CONTAINER(node, chFilter, post_node); testOk((ellCount(&(*pch)->post_chain) == no), "arr has %d filter(s) in post chain", no); }
/* Action function for state "last" in state set "start" */ static void seqg_action_start_0_last(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 36 "../local.st" testOk(seqg_var->seqg_vars_start.i == 2, "state set local i==%d", seqg_var->seqg_vars_start.i); } return; } }
static void channelRegisterPost(dbChannel *chan, void *user, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) { myStruct *my = (myStruct*)user; if (my == puser1) { testOk(e1 & e_reg_post, "register_post (1) called"); testOk(!(c2 & e_reg_post), "register_post (2) was not called before register_post (1)"); c1 |= e_reg_post; } else if (my == puser2) { testOk(e2 & e_reg_post, "register_post (2) called"); testOk(!(e1 & e_reg_post) || c1 & e_reg_post, "register_post (1) was called before register_post (2)"); c2 |= e_reg_post; } else { testFail("register_post: user pointer invalid"); testSkip(1, "Can't check order of register_post(1)/register_post(2)"); } testOk(!(e1 & e_reg_pre) || c1 & e_reg_pre, "register_pre (1) was called before register_post (%c)", inst(user)); testOk(!(e2 & e_reg_pre) || c2 & e_reg_pre, "register_pre (2) was called before register_post (%c)", inst(user)); my->offpost = offset++; probe->field_type++; *cb_out = post; *arg_out = user; }
static void testAValExpr(const char* expr, double* args, double** aargs, double* expected, int length) { unsigned char rpn[255]; short err; double val; double aval[12]; epicsUInt32 amask; if (aCalcPostfix(expr, rpn, &err)) { testDiag("postfix: %s in expression '%s'", aCalcErrorStr(err), expr); return; } if (aCalcPerform(args, 12, aargs, 12, 12, &val, aval, rpn, 12, &amask)) { testDiag("calcPerform: error evaluating '%s'", expr); return; } bool pass = true; int i = 0; for (i = 0; i < length; i += 1) { if (finite(expected[i]) && finite(aval[i])) { if (fabs(expected[i] - aval[i]) > 1e-8) { pass = false; break; } } else if (isnan(expected[i]) && !isnan(aval[i])) { pass = false; break; } else if (aval[i] != expected[i]) { pass = false; break; } } if(!testOk(pass, "%s", expr)) { testDiag("Expected aval[%d]: %f, Got: %f", i, expected[i], aval[i]); } }
static void hookPass1(initHookState state) { DBENTRY entry; DBADDR addr; if(state!=initHookAfterInitDatabase) return; testDiag("initHookAfterInitDatabase"); dbInitEntry(pdbbase, &entry); if(dbFindRecord(&entry, "rec0.VAL")==0) { aoRecord *prec = entry.precnode->precord; testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val); testOk1(dbPutString(&entry, "4")==0); testOk(prec->val==4, "VAL %d==4", (int)prec->val); } else{ testFail("Missing rec0"); testSkip(1, "missing record"); } /* Can't restore links in pass 1 */ if(dbNameToAddr("rec1.VAL", &addr)) { testFail("missing rec1"); testSkip(3, "missing record"); } else { struct rset *prset = dbGetRset(&addr); dbfType ftype = addr.field_type; long count=-1, offset=-1, maxcount = addr.no_elements; testOk1(prset && prset->get_array_info && prset->put_array_info); testOk1((*prset->get_array_info)(&addr, &count, &offset)==0); /* count is ignored */ testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0); testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0); } dbFinishEntry(&entry); }
/* Action function for state "get" in state set "read_anon_sync" */ static void seqg_action_read_anon_sync_3_get(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 155 "../pvGet.st" seq_efSet(seqg_env, ef_read_anon_sync); } return; case 1: { # line 158 "../pvGet.st" epicsMutexMustLock(mutex); # line 159 "../pvGet.st" seqg_var->seqg_vars_read_anon_sync.expected = shared; # line 160 "../pvGet.st" seq_pvGetTmo(seqg_env, 0/*anon*/, SYNC, DEFAULT_TIMEOUT); # line 161 "../pvGet.st" epicsMutexUnlock(mutex); # line 163 "../pvGet.st" testOk(seqg_var->seqg_vars_read_anon_sync.expected == seqg_var->anon, "synchronous get: expected=%d==%d=anon", seqg_var->seqg_vars_read_anon_sync.expected, seqg_var->anon); # line 164 "../pvGet.st" epicsThreadSleep(0.1); # line 165 "../pvGet.st" epicsMutexMustLock(mutex); # line 166 "../pvGet.st" seqg_var->seqg_vars_read_anon_sync.expected = shared; # line 167 "../pvGet.st" seq_pvGetTmo(seqg_env, 0/*anon*/, SYNC, DEFAULT_TIMEOUT); # line 168 "../pvGet.st" epicsMutexUnlock(mutex); # line 170 "../pvGet.st" testOk(seqg_var->seqg_vars_read_anon_sync.expected == seqg_var->anon, "repeat get after delay: expected=%d==%d=anon", seqg_var->seqg_vars_read_anon_sync.expected, seqg_var->anon); } return; } }
/* Action function for state "get" in state set "read_named_sync" */ static void seqg_action_read_named_sync_2_get(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 119 "../pvGet.st" seq_efSet(seqg_env, ef_read_named_sync); } return; case 1: { # line 122 "../pvGet.st" epicsMutexMustLock(mutex); # line 123 "../pvGet.st" seqg_var->seqg_vars_read_named_sync.expected = shared; # line 124 "../pvGet.st" seq_pvGetTmo(seqg_env, 2/*named*/, SYNC, DEFAULT_TIMEOUT); # line 125 "../pvGet.st" epicsMutexUnlock(mutex); # line 127 "../pvGet.st" testOk(seqg_var->seqg_vars_read_named_sync.expected == seqg_var->seqg_vars_read_named_sync.named, "synchronous get: expected=%d==%d=named", seqg_var->seqg_vars_read_named_sync.expected, seqg_var->seqg_vars_read_named_sync.named); # line 128 "../pvGet.st" epicsThreadSleep(0.1); # line 129 "../pvGet.st" epicsMutexMustLock(mutex); # line 130 "../pvGet.st" seqg_var->seqg_vars_read_named_sync.expected = shared; # line 131 "../pvGet.st" seq_pvGetTmo(seqg_env, 2/*named*/, SYNC, DEFAULT_TIMEOUT); # line 132 "../pvGet.st" epicsMutexUnlock(mutex); # line 134 "../pvGet.st" testOk(seqg_var->seqg_vars_read_named_sync.expected == seqg_var->seqg_vars_read_named_sync.named, "repeat get after delay: expected=%d==%d=named", seqg_var->seqg_vars_read_named_sync.expected, seqg_var->seqg_vars_read_named_sync.named); } return; } }
/* Action function for state "wait" in state set "read_anon_sync" */ static void seqg_action_read_anon_sync_3_wait(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 176 "../pvGet.st" testOk(seqg_var->seqg_vars_read_anon_sync.expected == seqg_var->anon, "after sync: expected=%d==%d=anon", seqg_var->seqg_vars_read_anon_sync.expected, seqg_var->anon); # line 177 "../pvGet.st" seqg_var->seqg_vars_read_anon_sync.n++; } return; } }
/* Action function for state "wait" in state set "read_named_sync" */ static void seqg_action_read_named_sync_2_wait(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 140 "../pvGet.st" testOk(seqg_var->seqg_vars_read_named_sync.expected == seqg_var->seqg_vars_read_named_sync.named, "after sync: expected=%d==%d=named", seqg_var->seqg_vars_read_named_sync.expected, seqg_var->seqg_vars_read_named_sync.named); # line 141 "../pvGet.st" seqg_var->seqg_vars_read_named_sync.n++; } return; } }
extern "C" void mutexThread(void * arg) { info *pinfo = (info *)arg; testDiag("mutexThread %d starting", pinfo->threadnum); while (pinfo->quit--) { epicsMutexLockStatus status = epicsMutexLock(pinfo->mutex); testOk(status == epicsMutexLockOK, "mutexThread %d epicsMutexLock returned %d", pinfo->threadnum, (int)status); epicsThreadSleep(.1); epicsMutexUnlock(pinfo->mutex); epicsThreadSleep(.9); } testDiag("mutexThread %d exiting", pinfo->threadnum); return; }
/* Action function for state "idle" in state set "ss2" */ static void seqg_action_ss2_1_idle(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 42 "../safeModeNotAssigned.st" if (seqg_var->seqg_vars_ss2.seqg_vars_idle.i < 10) { # line 43 "../safeModeNotAssigned.st" testOk(seqg_var->v == 0, "ss2: v=%d==0", seqg_var->v); } # line 45 "../safeModeNotAssigned.st" seqg_var->seqg_vars_ss2.seqg_vars_idle.i++; } return; } }
void testChars(void) { int i; char input[2] = {0, 0}; char escaped[20]; char result[20]; size_t s, t, needed; for (i = 255; i >= 0; --i) { input[0] = i; needed = epicsStrnEscapedFromRawSize(input, 1); s = epicsStrnEscapedFromRaw(escaped, sizeof(escaped), input, 1); t = epicsStrnRawFromEscaped(result, sizeof(result), escaped, s); testOk(needed == s && t == 1 && result[0] == input[0] && result[1] == 0, "escaped char 0x%2.2x -> \"%s\" (%d) -> 0x%2.2x", input[0] & 0xff, escaped, (int) needed, result[0] & 0xff); } }
/* Action function for state "first" in state set "start" */ static void seqg_action_start_0_first(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 28 "../local.st" testOk(seqg_var->seqg_vars_start.seqg_vars_first.i >= 3, "state local i == %d >= 3", seqg_var->seqg_vars_start.seqg_vars_first.i); # line 29 "../local.st" seqg_var->seqg_vars_start.seqg_vars_first.i = seqg_var->seqg_vars_start.seqg_vars_first.i + 1; } return; case 1: { } return; } }
static void testValExpr(const char* expr, double* args, double** aargs, double expected) { unsigned char rpn[255]; short err; double val; double aval[1]; epicsUInt32 amask; if (aCalcPostfix(expr, rpn, &err)) { testDiag("postfix: %s in expression '%s'", aCalcErrorStr(err), expr); return; } if (aCalcPerform(args, 12, aargs, 12, 3, &val, aval, rpn, 1, &amask)) { testDiag("calcPerform: error evaluating '%s'", expr); return; } bool pass; if (finite(expected) && finite(val)) { pass = fabs(expected - val) < 1e-8; } else if (isnan(expected)) { pass = (bool) isnan(val); } else { pass = (val == expected); } if(!testOk(pass, "%s", expr)) { testDiag("Expected: %f, Got: %f", expected, val); } }
static void check(const char *str, const char *expect) { char *got = macEnvExpand(str); int pass = -1; if (expect && !got) { testDiag("Got NULL, expected \"%s\".\n", expect); pass = 0; } else if (!expect && got) { testDiag("Got \"%s\", expected NULL.\n", got); pass = 0; } else if (expect && got && strcmp(got, expect)) { testDiag("Got \"%s\", expected \"%s\".\n", got, expect); pass = 0; } testOk(pass, "%s", str); }
/* Action function for state "idle" in state set "ss1" */ static void seqg_action_ss1_0_idle(SS_ID seqg_env, int seqg_trn, int *seqg_pnst) { switch(seqg_trn) { case 0: { # line 25 "../safeModeNotAssigned.st" testOk(seqg_var->v == seqg_var->seqg_vars_ss1.i, "ss1: v=%d==%d=i", seqg_var->v, seqg_var->seqg_vars_ss1.i); # line 26 "../safeModeNotAssigned.st" seqg_var->v++; # line 27 "../safeModeNotAssigned.st" seqg_var->seqg_vars_ss1.i++; } return; case 1: { } return; } }
static db_field_log * post(void *user, dbChannel *chan, db_field_log *pLog) { myStruct *my = (myStruct*)user; dbfl_freeFunc *dtor = NULL; if (my == puser1) { testOk(e1 & e_post, "post (1) called"); testOk(!(c2 & e_post), "post (2) was not called before post (1)"); c1 |= e_post; dtor = dbfl_free1; } else if (my == puser2) { testOk(e2 & e_post, "post (2) called"); testOk(!(e1 & e_post) || c1 & e_post, "post (1) was called before post (2)"); c2 |= e_post; dtor = dbfl_free2; } else { testFail("post: user pointer invalid"); testSkip(1, "Can't check order of post(1)/post(2)"); } testOk(!(e1 & e_pre) || c1 & e_pre, "pre (1) was called before post (%c)", inst(user)); testOk(!(e2 & e_pre) || c2 & e_pre, "pre (2) was called before post (%c)", inst(user)); if (!testOk(pLog->field_type == TYPE_START + my->offpost, "post (%c) got field log of expected type", inst(user))) testDiag("expected: %d, got %d", TYPE_START + my->offpost, pLog->field_type); pLog->field_type++; if (my->offpost == 0) { /* The first one registers a dtor and saves pfl */ pLog->u.r.dtor = dtor; dtorpfl = pLog; } if (my->offpost == drop) { testDiag("post (%c) is dropping the field log", inst(user)); return NULL; } return pLog; }
static void readFromClient(void *pParam) { char recvbuf[1024]; int recvLength; memset(recvbuf, 0, 1024); recvLength = recv(insock, recvbuf, 1024, 0); if (recvLength > 0) { strcat(prefixmsgbuffer, recvbuf); /* If we have received all of the messages. */ if (strstr(prefixmsgbuffer, "DONE") != NULL) { size_t msglen = strlen(prefixexpectedmsg); int prefixcmp = strncmp(prefixexpectedmsg, prefixmsgbuffer, msglen); if (!testOk(prefixcmp == 0, "prefix matches")) { testDiag("Expected '%s'\n", prefixexpectedmsg); testDiag("Obtained '%s'\n", prefixmsgbuffer); } } } }
/* Start one thread per CPU which will all try lock * the same spinlock. They break as soon as one * fails to take the lock. */ static void verifyTryLock() { int N, i; struct verifyTryLock verify; N = epicsThreadGetCPUs(); if(N==1) { testSkip(1, "verifyTryLock() only for SMP systems"); return; } verify.flag = 0; verify.spin = epicsSpinMustCreate(); testDiag("Starting %d spinners", N); verify.ents = calloc(N, sizeof(*verify.ents)); for(i=0; i<N; i++) { verify.ents[i].main = &verify; verify.ents[i].done = epicsEventMustCreate(epicsEventEmpty); epicsThreadMustCreate("verifyTryLockThread", 40, epicsThreadGetStackSize(epicsThreadStackSmall), verifyTryLockThread, &verify.ents[i]); } testDiag("All started"); for(i=0; i<N; i++) { epicsEventMustWait(verify.ents[i].done); epicsEventDestroy(verify.ents[i].done); } testDiag("All done"); testOk(verify.flag==1, "epicsTryLock returns %d (expect 1)", verify.flag); epicsSpinDestroy(verify.spin); free(verify.ents); }