Example #1
0
/* Test waking up a connection that is idle */
static void test_connection_wake(test_t *t) {
  test_proactor_t tps[] =  { test_proactor(t, open_wake_handler), test_proactor(t,  listen_handler) };
  pn_proactor_t *client = tps[0].proactor;
  pn_listener_t *l = test_listen(&tps[1], "");

  pn_connection_t *c = pn_connection();
  pn_incref(c);                 /* Keep a reference for wake() after free */
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  TEST_CHECK(t, pn_proactor_get(client) == NULL); /* Should be idle */
  pn_connection_wake(c);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_WAKE, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps)); /* Both ends */
  /* The pn_connection_t is still valid so wake is legal but a no-op */
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_EVENT_NONE, TEST_PROACTORS_GET(tps)); /* No more wake */

  /* Verify we don't get a wake after close even if they happen together */
  pn_connection_t *c2 = pn_connection();
  pn_proactor_connect2(client, c2, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  pn_connection_wake(c2);
  pn_proactor_disconnect(client, NULL);
  pn_connection_wake(c2);

  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, test_proactors_run(&tps[0], 1));
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, test_proactors_run(&tps[0], 1));
  TEST_ETYPE_EQUAL(t, PN_EVENT_NONE, test_proactors_get(&tps[0], 1)); /* No late wake */

  TEST_PROACTORS_DESTROY(tps);
  /* The pn_connection_t is still valid so wake is legal but a no-op */
  pn_connection_wake(c);
  pn_decref(c);
}
Example #2
0
/* Test that INACTIVE event is generated when last connections/listeners closes. */
static void test_inactive(test_t *t) {
  test_proactor_t tps[] =  { test_proactor(t, open_wake_handler), test_proactor(t, listen_handler) };
  pn_proactor_t *client = tps[0].proactor, *server = tps[1].proactor;

  /* Listen, connect, disconnect */
  pn_listener_t *l = test_listen(&tps[1], "");
  pn_connection_t *c = pn_connection();
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  pn_connection_wake(c);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_WAKE, TEST_PROACTORS_RUN(tps));
  /* Expect TRANSPORT_CLOSED from client and server, INACTIVE from client */
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Immediate timer generates INACTIVE on client (no connections) */
  pn_proactor_set_timeout(client, 0);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_TIMEOUT, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Connect, set-timer, disconnect */
  pn_proactor_set_timeout(client, 1000000);
  c = pn_connection();
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  pn_connection_wake(c);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_WAKE, TEST_PROACTORS_RUN(tps));
  /* Expect TRANSPORT_CLOSED from client and server */
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  /* No INACTIVE till timer is cancelled */
  TEST_CHECK(t, pn_proactor_get(server) == NULL);
  pn_proactor_cancel_timeout(client);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Server won't be INACTIVE until listener is closed */
  TEST_CHECK(t, pn_proactor_get(server) == NULL);
  pn_listener_close(l);
  TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  TEST_PROACTORS_DESTROY(tps);
}
Example #3
0
/* Test sending/receiving a message in chunks */
static void test_message_stream(test_t *t) {
  test_proactor_t tps[] ={
    test_proactor(t, message_stream_handler),
    test_proactor(t, message_stream_handler)
  };
  pn_proactor_t *client = tps[0].proactor;
  pn_listener_t *l = test_listen(&tps[1], "");
  struct message_stream_context ctx = { 0 };
  tps[0].handler.context = &ctx;
  tps[1].handler.context = &ctx;

  /* Encode a large (not very) message to send in chunks */
  char *body = (char*)malloc(BODY);
  memset(body, 'x', BODY);
  pn_message_t *m = pn_message();
  pn_data_put_binary(pn_message_body(m), pn_bytes(BODY, body));
  free(body);
  ctx.size = message_encode(m, &ctx.send_buf);
  pn_message_free(m);

  pn_connection_t *c = pn_connection();
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  pn_session_t *ssn = pn_session(c);
  pn_session_open(ssn);
  pn_link_t *snd = pn_sender(ssn, "x");
  pn_link_open(snd);
  TEST_PROACTORS_RUN_UNTIL(tps, PN_LINK_FLOW);

  /* Send and receive the message in chunks */
  do {
    pn_connection_wake(c);      /* Initiate send/receive of one chunk */
    do {                        /* May be multiple receives for one send */
      TEST_PROACTORS_RUN_UNTIL(tps, PN_DELIVERY);
    } while (ctx.received < ctx.sent);
  } while (!ctx.complete);
  TEST_CHECK(t, ctx.received == ctx.size);
  TEST_CHECK(t, ctx.sent == ctx.size);
  TEST_CHECK(t, !memcmp(ctx.send_buf.start, ctx.recv_buf.start, ctx.size));

  free(ctx.send_buf.start);
  free(ctx.recv_buf.start);
  TEST_PROACTORS_DESTROY(tps);
}
Example #4
0
void connection::wake() const {
    pn_connection_wake(pn_object());
}