diff --git a/src/core/ddsc/tests/test_oneliner.c b/src/core/ddsc/tests/test_oneliner.c index ecd0ca6..96c2fd3 100644 --- a/src/core/ddsc/tests/test_oneliner.c +++ b/src/core/ddsc/tests/test_oneliner.c @@ -213,7 +213,7 @@ static dds_return_t check_status_change_fields_are_0 (int ll, dds_entity_t ent) const char *d = lldesc[ll].desc; void *status = malloc (lldesc[ll].size); dds_return_t ret; - if ((ret = get_status (ll, ent, status)) <= 0) + if ((ret = get_status (ll, ent, status)) < 0) { free (status); return ret; @@ -1362,64 +1362,82 @@ static int checkstatus (struct oneliner_ctx *ctx, int ll, int ent, struct onelin { const void *p = advance (status, &off, *d); int i; - switch (*d) + if (peektok (argl, NULL) == '*') { - case 'n': - if (!nexttok_int (argl, &i) || i < 0) - return setresult (ctx, -1, "checkstatus: field %d expecting non-negative integer", field); - printf ("%s%"PRIu32" %d", sep, *(uint32_t *)p, i); fflush (stdout); - if (*(uint32_t *)p != (uint32_t)i) - return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIu32" expected %d", field, *(uint32_t *)p, i); - break; - case 'c': - if (!nexttok_int (argl, &i)) - return setresult (ctx, -1, "checkstatus: field %d expecting integer", field); - printf ("%s%"PRId32" %d", sep, *(int32_t *)p, i); fflush (stdout); - if (*(int32_t *)p != i) - return setresult (ctx, 0, "checkstatus: field %d has actual %"PRId32" expected %d", field, *(int32_t *)p, i); - break; - case 'P': - if (nexttok (argl, NULL) != TOK_NAME) - return setresult (ctx, -1, "checkstatus: field %d expecting policy name", field); - size_t polidx; - for (polidx = 0; polidx < sizeof (qostab) / sizeof (qostab[0]); polidx++) - if (strcmp (argl->v.n, qostab[polidx].abbrev) == 0) - break; - if (polidx == sizeof (qostab) / sizeof (qostab[0])) - return setresult (ctx, -1, "checkstatus: field %d expecting policy name", field); - printf ("%s%"PRIu32" %"PRIu32, sep, *(uint32_t *)p, (uint32_t) qostab[polidx].id); fflush (stdout); - if (*(uint32_t *)p != (uint32_t) qostab[polidx].id) - return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIu32" expected %d", field, *(uint32_t *)p, (int) qostab[polidx].id); - break; - case 'R': - if (nexttok (argl, NULL) != TOK_NAME) - return setresult (ctx, -1, "checkstatus: field %d expecting reason", field); - if (strcmp (argl->v.n, "i") == 0) i = (int) DDS_REJECTED_BY_INSTANCES_LIMIT; - else if (strcmp (argl->v.n, "s") == 0) i = (int) DDS_REJECTED_BY_SAMPLES_LIMIT; - else if (strcmp (argl->v.n, "spi") == 0) i = (int) DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT; - else return setresult (ctx, -1, "checkstatus: field %d expecting reason", field); - printf ("%s%d %d", sep, (int) *(dds_sample_rejected_status_kind *)p, i); fflush (stdout); - if (*(dds_sample_rejected_status_kind *)p != (dds_sample_rejected_status_kind) i) - return setresult (ctx, 0, "checkstatus: field %d has actual %d expected %d", field, (int) (*(dds_sample_rejected_status_kind *)p), i); - break; - case 'I': // instance handle is too complicated - break; - case 'E': { - int ent1 = -1; - dds_instance_handle_t esi1 = 0; - if (nexttok_if (argl, '*')) - ent1 = -1; - else if ((ent1 = parse_entity1 (argl, NULL)) < 0) - return setresult (ctx, -1, "checkstatus: field %d expecting * or entity name", field); - else if ((esi1 = lookup_insthandle (ctx, ent, ent1)) == 0) - return setresult (ctx, -1, "checkstatus: field %d instance handle lookup failed", field); - printf ("%s%"PRIx64" %"PRIx64, sep, *(dds_instance_handle_t *)p, esi1); fflush (stdout); - if (ent1 >= 0 && *(dds_instance_handle_t *)p != esi1) - return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIx64" expected %"PRIx64, field, *(dds_instance_handle_t *)p, esi1); - break; + (void) nexttok (argl, NULL); + switch (*d) + { + case 'n': printf ("%s%"PRIu32, sep, *(uint32_t *)p); break; + case 'c': printf ("%s%"PRId32, sep, *(int32_t *)p); break; + case 'P': printf ("%s%"PRIu32, sep, *(uint32_t *)p); break; + case 'R': printf ("%s%d", sep, (int) *(dds_sample_rejected_status_kind *)p); break; + case 'I': break; // instance handle is too complicated + case 'E': printf ("%s%"PRIx64, sep, *(dds_instance_handle_t *)p); break; + default: return DDS_RETCODE_BAD_PARAMETER; + } + printf (" *"); fflush (stdout); + } + else + { + switch (*d) + { + case 'n': + if (!nexttok_int (argl, &i) || i < 0) + return setresult (ctx, -1, "checkstatus: field %d expecting non-negative integer", field); + printf ("%s%"PRIu32" %d", sep, *(uint32_t *)p, i); fflush (stdout); + if (*(uint32_t *)p != (uint32_t)i) + return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIu32" expected %d", field, *(uint32_t *)p, i); + break; + case 'c': + if (!nexttok_int (argl, &i)) + return setresult (ctx, -1, "checkstatus: field %d expecting integer", field); + printf ("%s%"PRId32" %d", sep, *(int32_t *)p, i); fflush (stdout); + if (*(int32_t *)p != i) + return setresult (ctx, 0, "checkstatus: field %d has actual %"PRId32" expected %d", field, *(int32_t *)p, i); + break; + case 'P': + if (nexttok (argl, NULL) != TOK_NAME) + return setresult (ctx, -1, "checkstatus: field %d expecting policy name", field); + size_t polidx; + for (polidx = 0; polidx < sizeof (qostab) / sizeof (qostab[0]); polidx++) + if (strcmp (argl->v.n, qostab[polidx].abbrev) == 0) + break; + if (polidx == sizeof (qostab) / sizeof (qostab[0])) + return setresult (ctx, -1, "checkstatus: field %d expecting policy name", field); + printf ("%s%"PRIu32" %"PRIu32, sep, *(uint32_t *)p, (uint32_t) qostab[polidx].id); fflush (stdout); + if (*(uint32_t *)p != (uint32_t) qostab[polidx].id) + return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIu32" expected %d", field, *(uint32_t *)p, (int) qostab[polidx].id); + break; + case 'R': + if (nexttok (argl, NULL) != TOK_NAME) + return setresult (ctx, -1, "checkstatus: field %d expecting reason", field); + if (strcmp (argl->v.n, "i") == 0) i = (int) DDS_REJECTED_BY_INSTANCES_LIMIT; + else if (strcmp (argl->v.n, "s") == 0) i = (int) DDS_REJECTED_BY_SAMPLES_LIMIT; + else if (strcmp (argl->v.n, "spi") == 0) i = (int) DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT; + else return setresult (ctx, -1, "checkstatus: field %d expecting reason", field); + printf ("%s%d %d", sep, (int) *(dds_sample_rejected_status_kind *)p, i); fflush (stdout); + if (*(dds_sample_rejected_status_kind *)p != (dds_sample_rejected_status_kind) i) + return setresult (ctx, 0, "checkstatus: field %d has actual %d expected %d", field, (int) (*(dds_sample_rejected_status_kind *)p), i); + break; + case 'I': // instance handle is too complicated + break; + case 'E': { + int ent1 = -1; + dds_instance_handle_t esi1 = 0; + if (nexttok_if (argl, '*')) + ent1 = -1; + else if ((ent1 = parse_entity1 (argl, NULL)) < 0) + return setresult (ctx, -1, "checkstatus: field %d expecting * or entity name", field); + else if ((esi1 = lookup_insthandle (ctx, ent, ent1)) == 0) + return setresult (ctx, -1, "checkstatus: field %d instance handle lookup failed", field); + printf ("%s%"PRIx64" %"PRIx64, sep, *(dds_instance_handle_t *)p, esi1); fflush (stdout); + if (ent1 >= 0 && *(dds_instance_handle_t *)p != esi1) + return setresult (ctx, 0, "checkstatus: field %d has actual %"PRIx64" expected %"PRIx64, field, *(dds_instance_handle_t *)p, esi1); + break; + } + default: + return DDS_RETCODE_BAD_PARAMETER; } - default: - return DDS_RETCODE_BAD_PARAMETER; } sep = ", "; if (*d != 'I') @@ -1729,6 +1747,43 @@ static void dosetflags (struct oneliner_ctx *ctx) dds_entity_unpin (xwr); } +static void docheckstatus (struct oneliner_ctx *ctx) +{ + const int ll = parse_listener (ctx); + if (ll < 0) + error (ctx, "checkstatus: requires listener name"); + if (lldesc[ll].cb_status_off == 0) + error (ctx, "checkstatus: listener %s has no status", lldesc[ll].name); + struct oneliner_lex l1 = ctx->l; + if (*ctx->l.inp != '(') + error (ctx, "checkstatus: missing arguments"); + int tok; + while ((tok = nexttok (&ctx->l, NULL)) != EOF && tok != ')') + ; + const int ent = parse_entity (ctx); + if (ent < 0) + error (ctx, "check listener: requires an entity"); + if (ctx->es[ent] == 0) + make_entity (ctx, ent, NULL); + entname_t name; + printf ("status(%s %s): ", lldesc[ll].name, getentname (&name, ent)); + + void *status = malloc (lldesc[ll].size); + dds_return_t ret; + if ((ret = get_status (ll, ctx->es[ent], status)) < 0) + { + free (status); + error_dds (ctx, ret, "get_status failed"); + } + if (checkstatus (ctx, ll, ent, &l1, status) <= 0) + { + free (status); + longjmp (ctx->jb, 1); + } + free (status); + printf ("\n"); +} + static void dispatchcmd (struct oneliner_ctx *ctx) { static const struct { @@ -1737,6 +1792,7 @@ static void dispatchcmd (struct oneliner_ctx *ctx) } cs[] = { { "-", dodelete }, { "?", dowait }, + { "status", docheckstatus }, { "wr", dowr }, { "wrdisp", dowrdisp }, { "disp", dodisp }, diff --git a/src/core/ddsc/tests/test_oneliner.h b/src/core/ddsc/tests/test_oneliner.h index 60ab316..4ad2d74 100644 --- a/src/core/ddsc/tests/test_oneliner.h +++ b/src/core/ddsc/tests/test_oneliner.h @@ -144,6 +144,10 @@ * "i" for instances, "spi" for samples per instance) * sm see pm * + * A * can be substituted for any argument to indicate the value + * doesn't matter. (The value does get printed, so it can be a + * handy way to get quickly check the actual value in some cases). + * * | ?!LISTENER * * (Not listener) tests that LISTENER has not been invoked since @@ -171,6 +175,12 @@ * h suppress periodic heartbeats * d drop outgoing data * + * | status LISTENER(ARGS) ENTITY-NAME + * + * Compare the result of dds_get_L_status against ARGS for the + * specified entity, where L is corresponds to the event named by + * LISTENER. "da" and "dor" events are not allowed. + * * WRITE-LIKE ::= wr write * | wrdisp write-dispose * | disp dispose