Beispiel #1
0
void rpctest_begin_cb (flux_t h, flux_msg_watcher_t *w,
                       const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    flux_rpc_t *r;

    errno = 0;
    ok (!(r = flux_rpc (h, NULL, NULL, FLUX_NODEID_ANY, 0))
        && errno == EINVAL,
        "flux_rpc with NULL topic fails with EINVAL");

    /* working no-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.hello", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when none is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    ok (flux_rpc_get (r, NULL, NULL) == 0,
        "flux_rpc_get works");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (unexpected payload) - will be picked up in _get() */
    ok ((r = flux_rpc (h, "rpctest.hello", "foo", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when none is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (missing payload) - will be picked up in _get() */
    errno = 0;
    ok ((r = flux_rpc (h, "rpctest.echo", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when payload is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* working with-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.echo", "foo", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    json_str = NULL;
    ok (flux_rpc_get (r, NULL, &json_str) == 0
        && json_str && !strcmp (json_str, "foo"),
        "flux_rpc_get works and returned expected payload");
    flux_rpc_destroy (r);

    flux_reactor_stop (h);
}
Beispiel #2
0
static void then_cb (flux_rpc_t *r, void *arg)
{
    flux_t h = arg;
    const char *json_str;

    ok (flux_rpc_check (r) == true,
        "flux_rpc_check says get won't block in then callback");
    json_str = NULL;
    ok (flux_rpc_get (r, NULL, &json_str) == 0
        && json_str && !strcmp (json_str, "xxx"),
        "flux_rpc_get works and returned expected payload in then callback");
    flux_reactor_stop (h);
}
Beispiel #3
0
int main (int argc, char *argv[])
{
    flux_msg_t *msg;
    flux_t h;

    plan (33);

    (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0);
    ok ((h = flux_open ("loop://", FLUX_O_COPROC)) != NULL,
        "opened loop connector");
    if (!h)
        BAIL_OUT ("can't continue without loop handle");
    flux_fatal_set (h, fatal_err, NULL);

    ok (flux_msg_watcher_addvec (h, htab, NULL) == 0,
        "registered message handlers");
    /* test continues in rpctest_begin_cb() so that rpc calls
     * can sleep while we answer them
     */
    ok ((msg = flux_request_encode ("rpctest.begin", NULL)) != NULL,
        "encoded rpctest.begin request OK");
    ok (flux_send (h, msg, 0) == 0,
        "sent rpctest.begin request");
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_msg_destroy (msg);

    /* test _then:  Slightly tricky.
     * Send request.  We're not in a coproc ctx here in main(), so there
     * will be no response, therefore, check will be false.  Register
     * continuation, start reactor.  Response will be received, continuation
     * will be invoked. Continuation stops the reactor.
    */
    flux_rpc_t *r;
    ok ((r = flux_rpc (h, "rpctest.echo", "xxx", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    /* reg/unreg _then a couple times for fun */
    ok (flux_rpc_then (r, NULL, 0) == 0,
        "flux_rpc_then with NULL cb works");
    ok (flux_rpc_then (r, then_cb, h) == 0,
        "flux_rpc_then works after NULL");
    ok (flux_rpc_then (r, NULL, 0) == 0,
        "flux_rpc_then with NULL cb after non-NULL works");
    ok (flux_rpc_then (r, then_cb, h) == 0,
        "flux_rpc_then works");
    /* enough of that */
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_rpc_destroy (r);

    /* Test a _then corner case:
     * If _check() is called before _then(), a message may have been cached
     * in the flux_rpc_t.  rpctest_thenbug_cb creates this condition.
     * Next, _then continuation is installed, but will reactor call it?
     * This will hang if rpc implementation doesn't return a cached message
     * back to the handle in _then().  Else, continuation will stop reactor.
     */
    ok ((thenbug_r = flux_rpc (h, "rpctest.echo", "xxx",
        FLUX_NODEID_ANY, 0)) != NULL,
        "thenbug: sent echo request");
    do {
        if (!(msg = flux_request_encode ("rpctest.thenbug", NULL))
                  || flux_send (h, msg, 0) < 0
                  || flux_reactor_start (h) < 0) {
            flux_msg_destroy (msg);
            break;
        }
        flux_msg_destroy (msg);
    } while (!flux_rpc_check (thenbug_r));
    ok (true,
        "thenbug: check says message ready");
    ok (flux_rpc_then (thenbug_r, then_cb, h) == 0,
        "thenbug: registered then - hangs on failure");
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_rpc_destroy (thenbug_r);

    flux_msg_watcher_delvec (h, htab);
    flux_close (h);
    done_testing();
    return (0);
}
Beispiel #4
0
void rpctest_thenbug_cb (flux_t h, flux_msg_watcher_t *w,
                         const flux_msg_t *msg, void *arg)
{
    (void)flux_rpc_check (thenbug_r);
    flux_reactor_stop (h);
}
Beispiel #5
0
void rpctest_begin_cb (flux_t *h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    flux_rpc_t *r;

    errno = 0;
    ok (!(r = flux_rpc (h, NULL, NULL, FLUX_NODEID_ANY, 0))
        && errno == EINVAL,
        "flux_rpc with NULL topic fails with EINVAL");

    /* working no-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.hello", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when none is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    ok (flux_rpc_get (r, NULL) == 0,
        "flux_rpc_get works");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (unexpected payload) - will be picked up in _get() */
    ok ((r = flux_rpc (h, "rpctest.hello", "{}", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when none is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (missing payload) - will be picked up in _get() */
    errno = 0;
    ok ((r = flux_rpc (h, "rpctest.echo", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when payload is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* working with-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.echo", "{}", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    json_str = NULL;
    ok (flux_rpc_get (r, &json_str) == 0
        && json_str && !strcmp (json_str, "{}"),
        "flux_rpc_get works and returned expected payload");
    flux_rpc_destroy (r);

    /* working with-payload RPC (raw) */
    char *d, data[] = "aaaaaaaaaaaaaaaaaaaa";
    int l, len = strlen (data);
    ok ((r = flux_rpc_raw (h, "rpctest.rawecho", data, len,
                          FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc_raw with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    json_str = NULL;
    ok (flux_rpc_get_raw (r, &d, &l) == 0
        && d != NULL && l == len && memcmp (data, d, len) == 0,
        "flux_rpc_get_raw works and returned expected payload");
    flux_rpc_destroy (r);

    /* use newish pack/unpack payload interfaces */
    int i = 0;
    ok ((r = flux_rpcf (h, "rpctest.incr", FLUX_NODEID_ANY, 0,
                        "{s:i}", "n", 107)) != NULL,
        "flux_rpcf works");
    ok (flux_rpc_getf (r, "{s:i}", "n", &i) == 0,
        "flux_rpc_getf works");
    ok (i == 108,
        "and service returned incremented value");
    flux_rpc_destroy (r);

    flux_reactor_stop (flux_get_reactor (h));
}
Beispiel #6
0
void rpctest_thenbug_cb (flux_t *h, flux_msg_handler_t *w,
                         const flux_msg_t *msg, void *arg)
{
    (void)flux_rpc_check (thenbug_r);
    flux_reactor_stop (flux_get_reactor (h));
}
Beispiel #7
0
int rpctest_begin_cb (flux_t h, int type, zmsg_t **zmsg, void *arg)
{
    uint32_t nodeid;
    int i, errors;
    int old_count;
    flux_rpc_t *r;
    const char *json_str;

    errno = 0;
    ok (!(r = flux_rpc_multi (h, NULL, "foo", "all", 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with NULL topic fails with EINVAL");
    errno = 0;
    ok (!(r = flux_rpc_multi (h, "bar", "foo", NULL, 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with NULL nodeset fails with EINVAL");
    errno = 0;
    ok (!(r = flux_rpc_multi (h, "bar", "foo", "xyz", 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with bad nodeset fails with EINVAL");

    /* working no-payload RPC */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL,
        "flux_rpc_multi [0] with no payload when none is expected works");
    if (!r)
        BAIL_OUT ("can't continue without successful rpc call");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    ok (flux_rpc_get (r, NULL, NULL) == 0,
        "flux_rpc_get works");
    ok (hello_count == old_count + 1,
        "rpc was called once");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (unexpected payload) - picked up in _get() */
    ok ((r = flux_rpc_multi (h, "rpctest.hello", "foo", "all", 0)) != NULL,
        "flux_rpc_multi [0] with unexpected payload works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* fake that we have a larger session */
    fake_size = 128;
    char s[16];
    uint32_t size = 0;
    snprintf (s, sizeof (s), "%u", fake_size);
    flux_attr_fake (h, "size", s, FLUX_ATTRFLAG_IMMUTABLE);
    flux_get_size (h, &size);
    cmp_ok (size, "==", fake_size,
        "successfully faked flux_get_size() of %d", fake_size);

    /* repeat working no-payload RPC test (now with 128 nodes) */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL,
        "flux_rpc_multi [0-%d] with no payload when none is expected works",
        fake_size - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < fake_size; i++)
        if (flux_rpc_get (r, NULL, NULL) < 0)
            errors++;
    ok (errors == 0,
        "flux_rpc_get succeded %d times", fake_size);

    cmp_ok (hello_count - old_count, "==", fake_size,
        "rpc was called %d times", fake_size);
    flux_rpc_destroy (r);

    /* same with a subset */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] with no payload when none is expected works",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < 64; i++)
        if (flux_rpc_get (r, &nodeid, NULL) < 0 || nodeid != i)
            errors++;
    ok (errors == 0,
        "flux_rpc_get succeded %d times, with correct nodeid map", 64);

    cmp_ok (hello_count - old_count, "==", 64,
        "rpc was called %d times", 64);
    flux_rpc_destroy (r);

    /* same with echo payload */
    ok ((r = flux_rpc_multi (h, "rpctest.echo", "foo", "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] ok",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < 64; i++) {
        if (flux_rpc_get (r, NULL, &json_str) < 0
                || !json_str || strcmp (json_str, "foo") != 0)
            errors++;
    }
    ok (errors == 0,
        "flux_rpc_get succeded %d times, with correct return payload", 64);
    flux_rpc_destroy (r);

    /* detect partial failure without mresponse */
    nodeid_fake_error = 20;
    ok ((r = flux_rpc_multi (h, "rpctest.nodeid", NULL, "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] ok",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    for (i = 0; i < 64; i++) {
        if (flux_rpc_get (r, &nodeid, &json_str) < 0)
            break;
    }
    ok (i == 20 && errno == EPERM,
        "flux_rpc_get correctly reports single error");
    flux_rpc_destroy (r);

    /* test _then (still at fake session size of 128) */
    ok ((then_r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-127]", 0)) != NULL,
        "flux_rpc_multi [0-127] ok");
    ok (flux_rpc_then (then_r, then_cb, h) == 0,
        "flux_rpc_then works");
    /* then_cb stops reactor; results reported, then_r destroyed in main() */

    return 0;
}