int zre_log_msg_test (bool verbose) { printf (" * zre_log_msg: "); // @selftest // Simple create/destroy test zre_log_msg_t *self = zre_log_msg_new (0); assert (self); zre_log_msg_destroy (&self); // Create pair of sockets we can send through zctx_t *ctx = zctx_new (); assert (ctx); void *output = zsocket_new (ctx, ZMQ_DEALER); assert (output); zsocket_bind (output, "inproc://selftest"); void *input = zsocket_new (ctx, ZMQ_ROUTER); assert (input); zsocket_connect (input, "inproc://selftest"); // Encode/send/decode and verify each message type self = zre_log_msg_new (ZRE_LOG_MSG_LOG); zre_log_msg_set_level (self, 123); zre_log_msg_set_event (self, 123); zre_log_msg_set_node (self, 123); zre_log_msg_set_peer (self, 123); zre_log_msg_set_time (self, 123); zre_log_msg_set_data (self, "Life is short but Now lasts for ever"); zre_log_msg_send (&self, output); self = zre_log_msg_recv (input); assert (self); assert (zre_log_msg_level (self) == 123); assert (zre_log_msg_event (self) == 123); assert (zre_log_msg_node (self) == 123); assert (zre_log_msg_peer (self) == 123); assert (zre_log_msg_time (self) == 123); assert (streq (zre_log_msg_data (self), "Life is short but Now lasts for ever")); zre_log_msg_destroy (&self); zctx_destroy (&ctx); // @end printf ("OK\n"); return 0; }
zre_log_msg_t * zre_log_msg_decode (zmsg_t **msg_p) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zre_log_msg_t *self = zre_log_msg_new (0); // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 2)) goto empty; // Invalid signature // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: GET_NUMBER1 (self->level); GET_NUMBER1 (self->event); GET_NUMBER2 (self->node); GET_NUMBER2 (self->peer); GET_NUMBER8 (self->time); GET_STRING (self->data); break; default: goto malformed; } // Successful return zframe_destroy (&frame); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zre_log_msg_destroy (&self); return (NULL); }
void zyre_log_test (bool verbose) { printf (" * zyre_log: "); // @selftest zctx_t *ctx = zctx_new (); // Get all incoming log messages void *collector = zsocket_new (ctx, ZMQ_SUB); zsocket_bind (collector, "tcp://127.0.0.1:5555"); zsocket_set_subscribe (collector, ""); // Create a log instance to send log messages zyre_log_t *log = zyre_log_new (ctx, "this is me"); zyre_log_connect (log, "tcp://127.0.0.1:5555"); // Workaround for issue 270; give time for connect to // happen and subscriptions to go to pub socket; 200 // msec should be enough for under valgrind on a slow PC zpoller_t *poller = zpoller_new (collector, NULL); zpoller_wait (poller, 200); // Send some messages zyre_log_info (log, ZRE_LOG_MSG_EVENT_JOIN, NULL, "this is you"); zyre_log_info (log, ZRE_LOG_MSG_EVENT_EXIT, "Pizza time", "this is you"); zyre_log_warning (log, "this is you", "Time flies like an %s", "arrow"); zyre_log_error (log, "this is you", "Fruit flies like a %s", "banana"); int count = 0; while (count < 4) { zre_log_msg_t *msg = zre_log_msg_recv (collector); assert (msg); if (verbose) zre_log_msg_dump (msg); zre_log_msg_destroy (&msg); count++; } zpoller_destroy (&poller); zyre_log_destroy (&log); zctx_destroy (&ctx); // @end printf ("OK\n"); }
static void s_print_log_msg (void *collector) { zre_log_msg_t *msg = zre_log_msg_recv (collector); if (!msg) return; // Interrupted time_t curtime = zre_log_msg_time (msg); char *event = NULL; switch (zre_log_msg_event (msg)) { case ZRE_LOG_MSG_EVENT_JOIN: event = "Join group"; break; case ZRE_LOG_MSG_EVENT_LEAVE: event = "Leave group"; break; case ZRE_LOG_MSG_EVENT_ENTER: event = "Peer enters"; break; case ZRE_LOG_MSG_EVENT_EXIT: event = "Peer exits"; break; } struct tm *loctime = localtime (&curtime); char timestr [20]; strftime (timestr, 20, "%y-%m-%d %H:%M:%S ", loctime); printf ("%s I: [%04X] [%04X] - %s %s\n", timestr, zre_log_msg_node (msg), zre_log_msg_peer (msg), event, zre_log_msg_data (msg)); zre_log_msg_destroy (&msg); }
int zre_log_msg_send (zre_log_msg_t **self_p, void *output) { assert (output); assert (self_p); assert (*self_p); // Calculate size of serialized data zre_log_msg_t *self = *self_p; size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZRE_LOG_MSG_LOG: // level is a 1-byte integer frame_size += 1; // event is a 1-byte integer frame_size += 1; // node is a 2-byte integer frame_size += 2; // peer is a 2-byte integer frame_size += 2; // time is a 8-byte integer frame_size += 8; // data is a string with 1-byte length frame_size++; // Size is one octet if (self->data) frame_size += strlen (self->data); break; default: printf ("E: bad message type '%d', not sent\n", self->id); // No recovery, this is a fatal application error assert (false); } // Now serialize message into the frame zframe_t *frame = zframe_new (NULL, frame_size); self->needle = zframe_data (frame); size_t string_size; int frame_flags = 0; PUT_NUMBER2 (0xAAA0 | 2); PUT_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: PUT_NUMBER1 (self->level); PUT_NUMBER1 (self->event); PUT_NUMBER2 (self->node); PUT_NUMBER2 (self->peer); PUT_NUMBER8 (self->time); if (self->data) { PUT_STRING (self->data); } else PUT_NUMBER1 (0); // Empty string break; } // If we're sending to a ROUTER, we send the address first if (zsocket_type (output) == ZMQ_ROUTER) { assert (self->address); if (zframe_send (&self->address, output, ZFRAME_MORE)) { zframe_destroy (&frame); zre_log_msg_destroy (self_p); return -1; } } // Now send the data frame if (zframe_send (&frame, output, frame_flags)) { zframe_destroy (&frame); zre_log_msg_destroy (self_p); return -1; } // Destroy zre_log_msg object zre_log_msg_destroy (self_p); return 0; }
zre_log_msg_t * zre_log_msg_recv (void *input) { assert (input); zre_log_msg_t *self = zre_log_msg_new (0); zframe_t *frame = NULL; size_t string_size; size_t list_size; size_t hash_size; // Read valid message frame from socket; we loop over any // garbage data we might receive from badly-connected peers while (true) { // If we're reading from a ROUTER socket, get address if (zsocket_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->address); self->address = zframe_recv (input); if (!self->address) goto empty; // Interrupted if (!zsocket_rcvmore (input)) goto malformed; } // Read and parse command in frame frame = zframe_recv (input); if (!frame) goto empty; // Interrupted // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature == (0xAAA0 | 2)) break; // Valid signature // Protocol assertion, drop message while (zsocket_rcvmore (input)) { zframe_destroy (&frame); frame = zframe_recv (input); } zframe_destroy (&frame); } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: GET_NUMBER1 (self->level); GET_NUMBER1 (self->event); GET_NUMBER2 (self->node); GET_NUMBER2 (self->peer); GET_NUMBER8 (self->time); free (self->data); GET_STRING (self->data); break; default: goto malformed; } // Successful return zframe_destroy (&frame); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zre_log_msg_destroy (&self); return (NULL); }
int zre_log_msg_test (bool verbose) { printf (" * zre_log_msg: "); // @selftest // Simple create/destroy test zre_log_msg_t *self = zre_log_msg_new (0); assert (self); zre_log_msg_destroy (&self); // Create pair of sockets we can send through zsock_t *input = zsock_new (ZMQ_ROUTER); assert (input); zsock_connect (input, "inproc://selftest"); zsock_t *output = zsock_new (ZMQ_DEALER); assert (output); zsock_bind (output, "inproc://selftest"); // Encode/send/decode and verify each message type int instance; zre_log_msg_t *copy; self = zre_log_msg_new (ZRE_LOG_MSG_LOG); // Check that _dup works on empty message copy = zre_log_msg_dup (self); assert (copy); zre_log_msg_destroy (©); zre_log_msg_set_level (self, 123); zre_log_msg_set_event (self, 123); zre_log_msg_set_node (self, 123); zre_log_msg_set_peer (self, 123); zre_log_msg_set_time (self, 123); zre_log_msg_set_data (self, "Life is short but Now lasts for ever"); // Send twice from same object zre_log_msg_send_again (self, output); zre_log_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_log_msg_recv (input); assert (self); assert (zre_log_msg_routing_id (self)); assert (zre_log_msg_level (self) == 123); assert (zre_log_msg_event (self) == 123); assert (zre_log_msg_node (self) == 123); assert (zre_log_msg_peer (self) == 123); assert (zre_log_msg_time (self) == 123); assert (streq (zre_log_msg_data (self), "Life is short but Now lasts for ever")); zre_log_msg_destroy (&self); } zsock_destroy (&input); zsock_destroy (&output); // @end printf ("OK\n"); return 0; }
zmsg_t * zre_log_msg_encode (zre_log_msg_t **self_p) { assert (self_p); assert (*self_p); zre_log_msg_t *self = *self_p; zmsg_t *msg = zmsg_new (); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZRE_LOG_MSG_LOG: // level is a 1-byte integer frame_size += 1; // event is a 1-byte integer frame_size += 1; // node is a 2-byte integer frame_size += 2; // peer is a 2-byte integer frame_size += 2; // time is a 8-byte integer frame_size += 8; // data is a string with 1-byte length frame_size++; // Size is one octet if (self->data) frame_size += strlen (self->data); break; default: printf ("E: bad message type '%d', not sent\n", self->id); // No recovery, this is a fatal application error assert (false); } // Now serialize message into the frame zframe_t *frame = zframe_new (NULL, frame_size); self->needle = zframe_data (frame); PUT_NUMBER2 (0xAAA0 | 2); PUT_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: PUT_NUMBER1 (self->level); PUT_NUMBER1 (self->event); PUT_NUMBER2 (self->node); PUT_NUMBER2 (self->peer); PUT_NUMBER8 (self->time); if (self->data) { PUT_STRING (self->data); } else PUT_NUMBER1 (0); // Empty string break; } // Now send the data frame if (zmsg_append (msg, &frame)) { zmsg_destroy (&msg); zre_log_msg_destroy (self_p); return NULL; } // Destroy zre_log_msg object zre_log_msg_destroy (self_p); return msg; }