static void
generate_events (void)
{
  struct lwes_emitter *emitter;

  /* create emitter */
  emitter = lwes_emitter_create (TEST_LLOG_ADDRESS,
                                 TEST_LLOG_INTERFACE,
                                 atoi (TEST_LLOG_PORT),
                                 0,
                                 60);

  MY_ASSERT (emitter != NULL);

  event1 (emitter);

  lwes_emitter_destroy (emitter);
}
static void emitter    (const char *ip, const int port, const char *iface)
{
  struct lwes_emitter *emitter;
  struct lwes_event *event;
  struct lwes_event_type_db *db = NULL;

/*  db = lwes_event_type_db_create ( (char*)esffile );
 * assert ( db != NULL );
 */

  /* test null safety */
  assert ( lwes_emitter_emit(NULL, NULL) == -1 );

  /* emit without heartbeat */
  emitter = lwes_emitter_create (ip, iface, port, 0, 60);
  assert ( emitter != NULL );
  assert (lwes_net_get_ttl (&(emitter->connection)) == 3);
  event  = lwes_event_create (db, eventname);
  assert ( event != NULL );

  assert ( lwes_event_set_STRING   (event, key01, value01) == 1 );
  assert ( lwes_event_set_BOOLEAN  (event, key02, value02) == 2 );
  assert ( lwes_event_set_IP_ADDR  (event, key03, value03) == 3 );
  assert ( lwes_event_set_U_INT_16 (event, key04, value04) == 4 );
  assert ( lwes_event_set_INT_16   (event, key05, value05) == 5 );
  assert ( lwes_event_set_U_INT_32 (event, key06, value06) == 6 );
  assert ( lwes_event_set_INT_32   (event, key07, value07) == 7 );
  assert ( lwes_event_set_U_INT_64 (event, key08, value08) == 8 );
  assert ( lwes_event_set_INT_64   (event, key09, value09) == 9 );

  assert ( lwes_emitter_emit(emitter,event) == 0 );

  lwes_event_destroy(event);
  lwes_emitter_destroy(emitter);
/*  lwes_event_type_db_destroy(db); */

  /* emit with heartbeat */
  emitter = lwes_emitter_create (ip, iface, port, 1, 2);
  assert ( emitter != NULL );
  event  = lwes_event_create (db, eventname);
  assert ( event != NULL );

  assert ( lwes_event_set_STRING   (event, key01, value01) == 1 );
  assert ( lwes_event_set_BOOLEAN  (event, key02, value02) == 2 );
  assert ( lwes_event_set_IP_ADDR  (event, key03, value03) == 3 );
  assert ( lwes_event_set_U_INT_16 (event, key04, value04) == 4 );
  assert ( lwes_event_set_INT_16   (event, key05, value05) == 5 );
  assert ( lwes_event_set_U_INT_32 (event, key06, value06) == 6 );
  assert ( lwes_event_set_INT_32   (event, key07, value07) == 7 );
  assert ( lwes_event_set_U_INT_64 (event, key08, value08) == 8 );
  assert ( lwes_event_set_INT_64   (event, key09, value09) == 9 );

  /* emit one */
  assert ( lwes_emitter_emit(emitter,event) == 0 );

  /* then pretend it's the future so we get a heartbeat */
  time_future = 10;
  assert ( lwes_emitter_emit(emitter,event) == 0 );
  time_future = 0;

  lwes_event_destroy(event);

  /* pretend its really really far in the future to see that freq is
     capped */
  time_future = 100000;
  lwes_emitter_destroy(emitter);
  time_future = 0;
}
void test_emitter_failures (void)
{
  /* open failures */
  {
    /* 1: malloc failure for emitter */
    malloc_count = 0;
    null_at      = 1;
    assert (lwes_emitter_create ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, 0, 60)
            == NULL);
    /* 2: lwes_net_open failure */
    lwes_net_open_error = 1;
    assert (lwes_emitter_create ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, 0, 60)
            == NULL);
    lwes_net_open_error = 0;

    /* 3: lwes_net_set_ttl failure */
    lwes_net_set_ttl_error = 1;
    assert (lwes_emitter_create ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, 0, 60)
            == NULL);
    lwes_net_set_ttl_error = 0;

    /* 4: malloc failure for msg buffer */
    malloc_count = 0;
    null_at      = 2;
    assert (lwes_emitter_create ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, 0, 60)
            == NULL);
  }

  /* Test emit failures */
  {
    struct lwes_emitter *emitter;
    struct lwes_event *event;

    emitter = lwes_emitter_create ((char *) mcast_ip,
                                   (char *) mcast_iface,
                                   (int) mcast_port, 0, 60);
    assert (emitter != NULL);
    event  = lwes_event_create (NULL, eventname);
    assert ( event != NULL );

    lwes_event_to_bytes_error = 1;
    assert (lwes_emitter_emit (emitter, event) == -1);
    lwes_event_to_bytes_error = 0;

    lwes_net_send_bytes_error = 1;
    assert (lwes_emitter_emit (emitter, event) == -2);
    lwes_net_send_bytes_error = 0;
    lwes_event_destroy (event);
    lwes_emitter_destroy (emitter);
  }

  /* Test emitto failures */
  {
    struct lwes_emitter *emitter;
    struct lwes_event *event;

    emitter = lwes_emitter_create ((char *) mcast_ip,
                                   (char *) mcast_iface,
                                   (int) mcast_port, 0, 60);
    assert (emitter != NULL);
    event  = lwes_event_create (NULL, eventname);
    assert ( event != NULL );

    lwes_event_to_bytes_error = 1;
    assert (lwes_emitter_emitto ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, emitter, event) == -1);
    lwes_event_to_bytes_error = 0;

    lwes_net_sendto_bytes_error = 1;
    assert (lwes_emitter_emitto ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, emitter, event) == -2);
    lwes_net_sendto_bytes_error = 0;

    assert (lwes_emitter_emitto ((char *) mcast_ip,
                                 (char *) mcast_iface,
                                 (int) mcast_port, NULL, event) == -1);

    lwes_event_destroy (event);
    lwes_emitter_destroy (emitter);
  }

  /* emitter shouldn't be able to emit an event with no name */
  {
    struct lwes_emitter *emitter;
    struct lwes_event *event;

    emitter = lwes_emitter_create ((char *) mcast_ip,
                                   (char *) mcast_iface,
                                   (int) mcast_port,
                                   0,
                                   10);
    assert (emitter != NULL);

    event  = lwes_event_create_no_name (NULL);
    assert (event != NULL);

    /* recv first, so we are listening */
    assert (lwes_emitter_emit (emitter, event) < 0);
    lwes_event_destroy (event);
    lwes_emitter_destroy (emitter);
  }
}
void test_event_name_peek (void)
{
  /* successful event name peek */
  {
    struct lwes_listener *listener;
    struct lwes_emitter *emitter;
    struct lwes_event *event;
    struct lwes_event *event2;
    LWES_BYTE bytes[MAX_MSG_SIZE];
    int n;
    LWES_SHORT_STRING name1 = (LWES_SHORT_STRING)"TypeChecker";
    LWES_SHORT_STRING name2 = (LWES_SHORT_STRING)"Type";
    LWES_SHORT_STRING name3 = (LWES_SHORT_STRING)"CheckerType";

    emitter = lwes_emitter_create ((char *) mcast_ip,
                                   (char *) mcast_iface,
                                   (int) mcast_port,
                                   0,
                                   10);
    assert (emitter != NULL);

    listener = lwes_listener_create ((char *) mcast_ip,
                                     (char *) mcast_iface,
                                     (int) mcast_port);
    assert (listener != NULL);

    event  = lwes_event_create (NULL, name1);
    assert (event != NULL);

    event2 = lwes_event_create_no_name (NULL);
    assert (event2 != NULL);

    /* recv first, so we are listening */
    assert (lwes_listener_recv_by (listener, event, 10) != 0);
    /* now emit */
    assert (lwes_emitter_emit (emitter, event) == 0);
    /* get the bytes */
    assert ((n = lwes_listener_recv_bytes_by
                   (listener, bytes, MAX_MSG_SIZE, 1000)) > 0);

    /* check that the exact name matches */
    assert (lwes_listener_event_has_name (bytes, n, name1) == 0);

    /* but not the subname */
    assert (lwes_listener_event_has_name (bytes, n, name2) != 0);

    /* same lengths will also fail */
    assert (lwes_listener_event_has_name (bytes, n, name3) != 0);

    lwes_event_destroy (event);
    lwes_event_destroy (event2);
    lwes_listener_destroy (listener);
    lwes_emitter_destroy (emitter);
  }

  /* failure at event name peek */
  {
    LWES_BYTE bytes[MAX_MSG_SIZE];

    /* NULL bytes */
    assert (lwes_listener_event_has_name (NULL, 10, eventname) != 0);

    /* zero length */
    assert (lwes_listener_event_has_name (bytes, 0, eventname) != 0);

    /* NULL event name */
    assert (lwes_listener_event_has_name (bytes, 10, NULL) != 0);
  }
}
void test_listener_failures (void)
{
  /* open failures */
  {
    /* 1: malloc failure for listener */
    malloc_count = 0;
    null_at      = 1;
    assert (lwes_listener_create ((char *) mcast_ip,
                                  (char *) mcast_iface,
                                  (int) mcast_port) == NULL);
    /* 2: malloc failure for buffer */
    malloc_count = 0;
    null_at      = 2;
    assert (lwes_listener_create ((char *) mcast_ip,
                                  (char *) mcast_iface,
                                  (int) mcast_port) == NULL);
    /* 3: malloc failure for dtmp */
    malloc_count = 0;
    null_at      = 3;
    assert (lwes_listener_create ((char *) mcast_ip,
                                  (char *) mcast_iface,
                                  (int) mcast_port) == NULL);
    /* 4: lwes_net_open failure */
    lwes_net_open_error = 1;
    assert (lwes_listener_create ((char *) mcast_ip,
                                  (char *) mcast_iface,
                                  (int) mcast_port) == NULL);
    lwes_net_open_error = 0;
  }

  /* recv failures */
  {
    struct lwes_listener *listener;
    struct lwes_event *event;
    struct lwes_event_type_db *db = NULL;

    listener = lwes_listener_create ((char *) mcast_ip,
                                     (char *) mcast_iface,
                                     (int) mcast_port);
    assert (listener != NULL);
    event  = lwes_event_create_no_name ( db );
    assert (event != NULL);

    lwes_net_recv_bytes_error = 1;
    assert (lwes_listener_recv (listener, event) != 0);
    lwes_net_recv_bytes_error = 0;

    lwes_event_destroy(event);

    lwes_listener_destroy(listener);
  }

  /* recv_by timeout failure */
  {
    struct lwes_listener *listener;
    struct lwes_event *event;
    struct lwes_event_type_db *db = NULL;

    listener = lwes_listener_create ((char *) mcast_ip,
                                     (char *) mcast_iface,
                                     (int) mcast_port);
    assert (listener != NULL);
    event  = lwes_event_create_no_name ( db );
    assert (event != NULL);

    assert (lwes_listener_recv_by (listener, event, 2000) != 0);

    lwes_event_destroy(event);

    lwes_listener_destroy(listener);
  }

  /* add_headers failures */
  {
    struct lwes_listener *listener;
    struct lwes_emitter *emitter;
    struct lwes_event *event;
    struct lwes_event *event2;
    LWES_BYTE bytes[MAX_MSG_SIZE];
    int n;
    size_t m;

    emitter = lwes_emitter_create ((char *) mcast_ip,
                                   (char *) mcast_iface,
                                   (int) mcast_port,
                                   0,
                                   10);
    assert (emitter != NULL);

    listener = lwes_listener_create ((char *) mcast_ip,
                                     (char *) mcast_iface,
                                     (int) mcast_port);
    assert (listener != NULL);

    event  = lwes_event_create (NULL, eventname);
    assert (event != NULL);

    event2 = lwes_event_create_no_name (NULL);
    assert (event2 != NULL);

    /* recv first, so we are listening */
    assert (lwes_listener_recv_by (listener, event, 10) != 0);
    /* now emit */
    assert (lwes_emitter_emit (emitter, event) == 0);
    /* get the bytes */
    assert ((n = lwes_listener_recv_bytes_by
                   (listener, bytes, MAX_MSG_SIZE, 1000)) > 0);


    /* fail to add headers for various reasons */
    m = n;

    /*  1 2  3  4  5  6  7  8  9 10 11 12 13 14 */
    /* 08 T  y  p  e  C  h  e  c  k  e  r 00 00 */
    /* reason 1: truncated event name */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 5, &m) == -1);

    /* reason 2: truncated num attrs */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 12, &m) == -2);


    /* reason 3: error adding receipt time */

    /* 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 */
    /* 00 R  e  c  e  i  p  t  T  i  m  e  00 00 00 00 00 00 00 00 00 */

    /* first with string marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 14, &m) == -3);
    /* then with type token marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 26, &m) == -3);
    /* finally with type marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 28, &m) == -3);

    /* reason 4: error adding Sender IP */

    /* 36 37 38 39 40 41 42 43 44 45 46 47 48 49 */
    /* 00  S  e  n  d  e  r  I  P 00 00 00 00 00 */

    /* first with string marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 35, &m) == -4);
    /* then with type token marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 44, &m) == -4);
    /* finally with type marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 45, &m) == -4);

    /* reason 5: error adding Sender Port */

    /* 50 51 52 53 54 55 56 57 58 59 60 61 62 63 */
    /* 00  S  e  n  d  e  r  P  o  r  t 00 00 00 */
    /* first with string marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 49, &m) == -5);
    /* then with type token marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 60, &m) == -5);
    /* finally with type marshall */
    assert (lwes_listener_add_header_fields
              (listener, bytes, 61, &m) == -5);

    /* reason 6: error reencoding number of attributes */
    marshall_U_INT_16_fail_at = 2;
    marshall_U_INT_16_count = 0;
    assert (lwes_listener_add_header_fields
              (listener, bytes, 500, &m) == -6);

    marshall_U_INT_16_fail_at = 0;

    /* one final test for coverage get it to fail when process event calls
       add header fields */

    marshall_U_INT_16_fail_at = 2;
    marshall_U_INT_16_count = 0;

    /* emit again */
    assert (lwes_emitter_emit (emitter, event) == 0);
    /* get the bytes */
    assert ((n = lwes_listener_recv_by
                   (listener, event2, 1000)) < 0);
    marshall_U_INT_16_fail_at = 0;

    lwes_event_destroy (event);
    lwes_event_destroy (event2);
    lwes_listener_destroy (listener);
    lwes_emitter_destroy (emitter);
  }
}
static void emitter_to  (const char *ip,
                         const int port,
                         const char *iface,
                         const char *n_ip,
                         const int n_port,
                         const char *n_iface)
{
  struct lwes_emitter *emitter;
  struct lwes_event *event;
  struct lwes_event_type_db *db = NULL;

/* db = lwes_event_type_db_create ( (char*)esffile );
 * assert ( db != NULL );
 */

  /* emit without heartbeat */
  emitter = lwes_emitter_create (ip, iface, port, 0, 60);
  assert (emitter != NULL);
  assert (lwes_net_get_ttl (&(emitter->connection)) == 3);
  event  = lwes_event_create (db, eventname);
  assert (event != NULL);

  assert (lwes_event_set_STRING   (event, key01, value01) == 1);
  assert (lwes_event_set_BOOLEAN  (event, key02, value02) == 2 );
  assert (lwes_event_set_IP_ADDR  (event, key03, value03) == 3);
  assert (lwes_event_set_U_INT_16 (event, key04, value04) == 4);
  assert (lwes_event_set_INT_16   (event, key05, value05) == 5);
  assert (lwes_event_set_U_INT_32 (event, key06, value06) == 6);
  assert (lwes_event_set_INT_32   (event, key07, value07) == 7);
  assert (lwes_event_set_U_INT_64 (event, key08, value08) == 8);
  assert (lwes_event_set_INT_64   (event, key09, value09) == 9);

  assert (lwes_emitter_emitto ((char *) n_ip,
                               (char *) n_iface,
                               (int)    n_port,
                               emitter,
                               event) == 0);

  lwes_event_destroy(event);
  lwes_emitter_destroy(emitter);
/*  lwes_event_type_db_destroy(db); */

  /* emit with heartbeat */
  emitter = lwes_emitter_create (ip, iface, port, 1, 2);
  assert (emitter != NULL);
  event  = lwes_event_create (db, eventname);
  assert (event != NULL);

  assert (lwes_event_set_STRING   (event, key01, value01) == 1);
  assert (lwes_event_set_BOOLEAN  (event, key02, value02) == 2);
  assert (lwes_event_set_IP_ADDR  (event, key03, value03) == 3);
  assert (lwes_event_set_U_INT_16 (event, key04, value04) == 4);
  assert (lwes_event_set_INT_16   (event, key05, value05) == 5);
  assert (lwes_event_set_U_INT_32 (event, key06, value06) == 6);
  assert (lwes_event_set_INT_32   (event, key07, value07) == 7);
  assert (lwes_event_set_U_INT_64 (event, key08, value08) == 8);
  assert (lwes_event_set_INT_64   (event, key09, value09) == 9);

  assert (lwes_emitter_emitto ((char *) n_ip,
                               (char *) n_iface,
                               (int)    n_port,
                               emitter,
                               event) == 0);

  /* pretend its the future */
  time_future = 10;

  assert (lwes_emitter_emitto ((char *) n_ip,
                               (char *) n_iface,
                               (int)    n_port,
                               emitter,
                               event) == 0);

  lwes_event_destroy (event);

  /* pretend its the past to test the other edge case for freqency */
  time_past = 2000;
  lwes_emitter_destroy (emitter);
  time_past = 0;
}
Example #7
0
int main(int argc, char **argv)
{
  gzFile file;
  const char *filename;
  char header[22];
  unsigned char buf[65535];

  const char *args = "n:o:r:tdh";
  int number = 0;            /* (n) total number to emit */
  struct lwes_emitter *emitter = NULL; /* (o) where to send the events */
  int rate = 0;              /* (r) number per second for emission */
  bool use_timings = false;  /* (t) using timings from file */
  bool repeat = false;       /* (d) rerun journals over and over */

  int ret = 0;
  LWES_INT_64 start  = 0LL;
  LWES_INT_64 stop   = 0LL;

  /* turn off error messages, I'll handle them */
  opterr = 0;
  while (1)
    {
      char c = getopt (argc, argv, args);

      if (c == -1)
        {
          break;
        }
      switch (c)
        {
          case 'n':
            number = atoi(optarg);
            break;

          case 'r':
            rate = atoi(optarg);
            break;

          case 'o':
            emitter = handle_transport_arg (optarg);
            if (emitter == NULL)
              {
                fprintf (stderr, "ERROR: problem with emitter\n");
                ret = 1;
                goto cleanup;
              }
            break;

          case 't':
            use_timings = true;
            break;

          case 'd':
            repeat = true;
            break;

          case 'h':
            fprintf (stderr, "%s", help);
            ret = 1;
            goto cleanup;

          default:
            fprintf (stderr,
                     "WARNING: unrecognized command line option -%c\n",
                     optopt);
        }
    }

  if (optind >= argc)
    {
      fprintf (stderr, "ERROR: journal file is required\n");
      ret = 1;
      goto cleanup;
    }

  /* setup sigint/sigkill/sigpipe handler */
  setup_sig_handler();
  start = currentTimeMillisLongLong ();

  int start_index = optind;
  int num_files = argc - optind;
  int offset = 0;
  int total_count = 0;
  int this_second_count = 0;
  unsigned long long delay_micros = rate > 0 ? 1000000 / rate : 0;

  bool done = false;
  while (! done)
    {
      /* deal with multiple files and repeating */
      filename = argv[start_index + offset];
      if (! repeat && offset == (num_files - 1))
        {
          done = true; /* last file and we are not repeating,
                          so done after it's processed */
        }
      offset = (offset + 1) % num_files; /* skip to next file if available */

      file = gzopen (filename, "rb");
      struct timeval start_emit_time;
      micro_now (&start_emit_time);
      struct timeval current_emit_time = { 0, 0 };
      struct timeval previous_emit_time = { 0, 0 };
      unsigned long long time_between_emit_events = 0ULL;
      unsigned long long start_file_timestamp = 0ULL;
      unsigned long long end_file_timestamp = 0ULL;
      int file_count = 0;
      unsigned long long time_to_sleep = 0ULL;

      /* read a header from the file */
      while (gzread (file, header, 22) == 22)
        {
          unsigned short size = header_payload_length (header);
          unsigned long long cur_file_timestamp =
            (unsigned long long)(header_receipt_time (header));
          if (start_file_timestamp == 0ULL)
            {
              start_file_timestamp = cur_file_timestamp;
            }
          end_file_timestamp = cur_file_timestamp;

          /* read an event from the file */
          if (gzread (file, buf, size) != size)
            {
              fprintf (stderr, "ERROR: failure reading journal\n");
              done = true;
              ret=1;
              break;
            }

          /* keep track of the current emit time */
          micro_now (&current_emit_time);

          /* if we are using timings determine how long to sleep before
           * emitting the next event */
          if (use_timings)
            {
              unsigned long long time_between_file_events = 0ULL;

              time_between_file_events =
                (cur_file_timestamp - start_file_timestamp) * 1000ULL;
              time_between_emit_events =
                micro_timediff (&start_emit_time, &current_emit_time);

              time_to_sleep =
                time_between_file_events > time_between_emit_events
                ? time_between_file_events - time_between_emit_events
                : 0ULL;

              /* sleep some number of microseconds */
              if (time_to_sleep > 0)
                {
                  usleep (time_to_sleep);
                }
            }

          /* if we are trying to meet a rate, determine how long to sleep
           * before next call
           */
          if (rate > 0)
            {
              if (previous_emit_time.tv_sec != 0)
                {
                  /* the difference in micros alway includes the time slept,
                   * so to figure out how much time we should sleep we subtract
                   * the previous slept time from how much time it's actually
                   * been since the last emit.  In other words sleep time plus
                   * processing time should equal delay_ms
                   */

                  unsigned long long diff =
                    micro_timediff (&previous_emit_time, &current_emit_time)
                    - time_to_sleep;
                  time_to_sleep =
                    delay_micros > diff
                    ? delay_micros - diff
                    : 0ULL;
                  if (time_to_sleep > 0)
                    {
                      usleep (time_to_sleep);
                    }
                }
            }

          /* then emit the event */
          if (lwes_emitter_emit_bytes (emitter, buf, size) != size)
            {
              fprintf (stderr, "ERROR: failure emitting\n");
              done = true;
              ret=1;
              break;
            }

          /* keep track of some counts */
          file_count++;
          total_count++;
          this_second_count++;
          previous_emit_time = current_emit_time;

          /* if we are emitting a limited number we will be done if we hit
           * that number
           */
          if (number > 0 && number == total_count)
            {
              done = true;
              ret=2;
              break;
            }
          if (gbl_sig)
            {
              done = true;
              ret=3;
              break;
            }
        }
      gzclose (file);
      fprintf (stderr,
               "emitted %d events from %s representing %lld file time "
               "in %llu milliseconds\n",
               file_count, filename,
               (end_file_timestamp - start_file_timestamp),
               micro_timediff (&start_emit_time, &current_emit_time) / 1000ULL);
    }
  /* if we hit the count limit (2) it is not an error */
  if (ret == 2)
    {
      ret = 0;
    }
  stop = currentTimeMillisLongLong ();
  fprintf (stderr, "emitted %d events in %lld milliseconds\n",
           total_count, (stop - start));
cleanup:
  if (emitter != NULL)
    {
      lwes_emitter_destroy (emitter);
    }
  exit (ret);
}
int main (int   argc,
          char *argv[])
{
  const char *mcast_ip    = "224.1.1.11";
  const char *mcast_iface = NULL;
  int         mcast_port  = 12345;
  int         number      = 1;
  int         pad         = 0;
  int         seconds     = 1;
  int         pause       = 0;
  int         even        = 0;

  struct lwes_emitter * emitter;
  struct lwes_event *event;
  char *pad_string;

  /* turn off error messages, I'll handle them */
  opterr = 0;
  while (1)
    {
      char c = getopt (argc, argv, "m:p:i:n:s:x:b:eh");

      if (c == -1)
        {
          break;
        }

      switch (c)
        {
          case 'b':
            pause = atoi(optarg);

            break;

          case 'm':
            mcast_ip = optarg;

            break;

          case 'p':
            mcast_port = atoi(optarg);

            break;

          case 'n':
            number = atoi(optarg);

            break;

          case 's':
            seconds = atoi(optarg);
            break;

          case 'e':
            even = 1;
            break;

          case 'h':
            fprintf (stderr, "%s", help);

            return 1;

          case 'i':
            mcast_iface = optarg;

            break;

          case 'x':
            pad = atoi(optarg);
            break;

          default:
            fprintf (stderr,
                     "error: unrecognized command line option -%c\n", 
                     optopt);

            return 1;
        }
    }

  pad_string = NULL;
  if (pad > 0)
    {
      pad_string = malloc(pad+1);
      if (pad_string == NULL)
        {
          fprintf (stderr,
                   "Unable to allocate %d bytes for pad string\n",
                   pad);
          exit(1);
        }
      else
        {
          memset(pad_string, 'X', pad);
          pad_string[pad] = '\0';
        }
    }

  emitter = lwes_emitter_create ( (LWES_SHORT_STRING) mcast_ip,
                                  (LWES_SHORT_STRING) mcast_iface,
                                  (LWES_U_INT_32)     mcast_port,
                                  0,
                                  10 );

  assert (emitter != NULL);

  {
    int i,s,n;
    LWES_INT_64 start  = 0LL;
    LWES_INT_64 stop   = 0LL;

    for (s = 0, n = 0; s < seconds; ++s)
      {
        start = currentTimeMillisLongLong ();
        stop  = start;
        for (i = 0; i < number; ++i, ++n)
          {
            event  = lwes_event_create (NULL, "MyEvent");
            assert (event != NULL);

            assert
              (lwes_event_set_STRING   (event, "field", "hello world") == 1 );
            assert
              (lwes_event_set_INT_32   (event, "count", i) == 2);
            assert
              (lwes_event_set_INT_32   (event, "run", s) == 3);
            assert
              (lwes_event_set_STRING (event, "prog_id","12345") == 4);
            assert
              (lwes_event_set_INT_16 (event,"num", 2) == 5);
            assert
              (lwes_event_set_STRING (event,"k0", "a-key.count") == 6);
            assert
              (lwes_event_set_INT_16 (event,"v0", 1) == 7);
            assert
              (lwes_event_set_STRING (event,"k1", "b-key.count") == 8);
            assert
              (lwes_event_set_INT_16 (event,"v1", 2) == 9);
            assert
              (lwes_event_set_U_INT_64(event, "global_count", n) == 10);
            assert
              (lwes_event_set_INT_64 (event,"SentTime", stop) == 11);
            if (pad>0) {
              assert(lwes_event_set_STRING (event,"pad",pad_string) == 12);
            }

            assert (lwes_emitter_emit (emitter, event) == 0);

            lwes_event_destroy(event);
            stop = currentTimeMillisLongLong ();

            /* if we are going over our total time, bail out */
            if ((stop - start) >= 1000)
              {
                printf ("Was only able to emit %7d in 1 sec\n",i);
                break;
              }
            
            /* if we are attempting to send events evenly throughout
            the second, consider pausing briefly to get back on
            schedule */
            if (even)
              {
                const int delay_ms = (i*1000/number) - (stop-start);
                if (delay_ms > 0)
                  {
                    usleep (delay_ms*1000);
                  }
              }
          }
        {
          const int delay_ms = (1000 - (stop - start))*1000;
          if (delay_ms > 0) usleep (delay_ms);
        }
        {
          char timebuff[20];
          /* HH/MM/SS DD/MM/YYYY  */
          /* 12345678901234567890 */
          time_t start_time = time (NULL);

          strftime (timebuff, 20, "%H:%M:%S %d/%m/%Y", localtime (&start_time));

          printf ("%s : %7d\n", timebuff, i);
        }

        sleep (pause);
      }
    lwes_emitter_destroy(emitter);
    if (pad_string!=NULL) free(pad_string);
  }

  return 0;
}