Пример #1
0
void sample(void)
{
  int r;

  L_DEBUG("debug");
  L_INFO("info");
  L_NOTICE("notice");
  L_WARN("warn");
  L_ERR("err");

  sput_fail_if(0, "0 isn't false!");
  sput_fail_unless(1, "1 isn't true!");

  /* Play with smock */
  sput_fail_unless(smock_empty(), "smock empty");
  smock_push_int("in", 1);
  sput_fail_unless(!smock_empty(), "smock not empty");
  smock_push_int("out", 2);
  smock_push_int("in", 3);
  smock_push_int("out", 6);
  r = dummy_callback(1);
  sput_fail_unless(r == 2, "dummy_callback broken");
  r = dummy_callback(3);
  sput_fail_unless(r == 6, "dummy_callback broken");
  /* In the end, we should be again gone. */
  sput_fail_unless(smock_empty(), "smock empty");
}
Пример #2
0
static hncp create_hncp(void)
{
  char buf[4] = "foo";

  /* Feed in fake hwaddr for eth0+eth1 (hardcoded, ugh) */
  smock_push("get_hwaddrs_buf", buf);
  smock_push_int("get_hwaddrs_len", sizeof(buf));

  /* io init succeeds */
  smock_push_bool("init_result", true);

  /* schedule happens _once_ */
  smock_push("schedule", NULL);

  hncp o = hncp_create();
  sput_fail_unless(o, "hncp_create -> hncp");
  smock_is_empty();

  /* clear the scheduled timeout - for now, we're empty slate anyway*/
  smock_push_int("time", 0);
  /* second one occurs from originating us (no caching due to 0 return value) */
  smock_push_int("time", 0);
  hncp_run(o);
  smock_is_empty();

  return o;
}
Пример #3
0
static void hncp_init_no_hwaddr(void)
{
  /* Feed in fake hwaddr for eth0+eth1 (hardcoded, ugh) */
  smock_push("get_hwaddrs_buf", NULL);
  smock_push_int("get_hwaddrs_len", 0);

  hncp o = hncp_create();
  sput_fail_unless(!o, "hncp_create -> !hncp");
  smock_is_empty();
}
Пример #4
0
static void hncp_rejoin_works(void)
{
  hncp o = create_hncp();
  int t = 123000;


  /* we'll try to join dummy_ifname; however, it fails. */
  smock_is_empty();
  one_join(false);
  smock_push_int("schedule", 0);
  smock_push_int("time", t);
  hncp_if_set_enabled(o, dummy_ifname, true);
  smock_is_empty();

  /* make sure next timeout before HNCP_REJOIN_INTERVAL just re-schedules. */
  t += HNCP_REJOIN_INTERVAL / 2;
  smock_push_int("time", t);
  smock_push_int("schedule", HNCP_REJOIN_INTERVAL / 2);
  hncp_run(o);
  smock_is_empty();

  /* now that the time _has_ expired, we should try joining.. fail again. */
  t += HNCP_REJOIN_INTERVAL / 2;
  smock_push_int("time", t);
  smock_push_int("schedule", HNCP_REJOIN_INTERVAL);
  one_join(false);
  hncp_run(o);
  smock_is_empty();

  /* again try after HNCP_REJOIN_INTERVAL, it should work. trickle
   * scheduling should require exactly one random call. */
  t += HNCP_REJOIN_INTERVAL;
  smock_push_int("time", t);
  smock_push_int("random", 0);
  smock_push_int("schedule", HNCP_TRICKLE_IMIN / 2);
  one_join(true);
  hncp_run(o);
  smock_is_empty();

  /* no unregisters at end, as we first kill io, and then flush
   * structures (socket kill should take care of it in any case). */
  destroy_hncp(o);
}
Пример #5
0
static void hncp_init_iofail(void)
{
  char buf[4] = "foo";

  /* Feed in fake hwaddr for eth0+eth1 (hardcoded, ugh) */
  smock_push("get_hwaddrs_buf", buf);
  smock_push_int("get_hwaddrs_len", sizeof(buf));

  /* io init succeeds */
  smock_push_bool("init_result", false);

  hncp o = hncp_create();
  sput_fail_unless(!o, "hncp_create -> !hncp");
  smock_is_empty();
}
Пример #6
0
void prefix_mock(__unused struct iface_user *u, __unused const char *ifname,
		__unused const struct prefix *prefix, __unused const struct prefix *excluded,
		hnetd_time_t valid_until, __unused hnetd_time_t preferred_until,
		__unused const void *dhcpv6_data, __unused size_t dhcpv6_len)
{
	if (valid_until > hnetd_time()) {
		smock_push("prefix_prefix", (void*)prefix);
		smock_push_int64("prefix_valid", valid_until);
		smock_push_int64("prefix_preferred", preferred_until);
		smock_push("dhcpv6_data", (void*)dhcpv6_data);
		smock_push_int("dhcpv6_len", dhcpv6_len);
	} else {
		smock_push_bool("prefix_remove", true);
	}
}
Пример #7
0
static void hncp_ok(void)
{
  hncp o = create_hncp();
  int t = 123000;
  int i;

  /* Pushing in a new subscriber should result in us being called. */
  smock_is_empty();
  smock_push_bool("node_callback", true);
  hncp_subscribe(o, &dummy_subscriber_1);
  hncp_subscribe(o, &dummy_subscriber_2);
  hncp_subscribe(o, &dummy_subscriber_3);
  hncp_subscribe(o, &dummy_subscriber_4);

  smock_is_empty();
  one_join(true);
  smock_push_int("schedule", 0);
  hncp_if_set_enabled(o, dummy_ifname, true);
  smock_is_empty();

  /* Ok. We're cooking with gas. */
  smock_push_int("time", t);
  smock_push_int("random", 0);
  smock_push_int("schedule", HNCP_TRICKLE_IMIN / 2);
  hncp_run(o);
  smock_is_empty();

  t += HNCP_TRICKLE_IMIN / 2 - 1;
  smock_push_int("time", t);
  smock_push_int("schedule", 1);
  hncp_run(o);
  smock_is_empty();

  t += 1;
  /* Ok. we get timestamp -> woah, need to do something. */
  smock_push_int("time", t);

  /* Should send stuff on an interface. */
  smock_push("sendto_ifname", dummy_ifname);
  smock_push("sendto_dst", &o->multicast_address);
  smock_push_int("sendto_return", 1);

  /* And schedule next one (=end of interval). */
  smock_push_int("schedule", HNCP_TRICKLE_IMIN / 2);
  hncp_run(o);
  smock_is_empty();

  /* overshoot what we were asked for.. shouldn't be a problem. */
  t += HNCP_TRICKLE_IMIN;
  smock_push_int("time", t);
  /* should be queueing next send, and now we go for 'max' value. */
  smock_push_int("random", 999);
  smock_push_int("schedule", 2 * HNCP_TRICKLE_IMIN * (1000 + 999) / 2000);
  hncp_run(o);
  smock_is_empty();

  /* run the clock until we hit HNCP_TRICKLE_IMAX/2 delay; or we run
   * out of iterations. */
  check_timing = false;
  check_send = false;
  check_random = false;
  want_send = 0;
  for (i = 0 ; i < 100 ; i++)
    {
      current_hnetd_time = t;
      want_schedule = 0;
      hncp_run(o);
      if (want_schedule >= (HNCP_TRICKLE_IMAX / 2))
        {
          sput_fail_unless(want_schedule <= HNCP_TRICKLE_IMAX, "reasonable timeout");
          break;
        }
      t += want_schedule;
      current_hnetd_time += want_schedule;
    }
  sput_fail_unless(want_send <= i / 2, "few sends");
  sput_fail_unless(i < 100, "did not encounter big enough delta");
  /* then, run for few more iterations, making sure we don't hit too long ones. */
  want_send = 0;
  for (i = 0 ; i < 10 ; i++)
    {
      current_hnetd_time = t;
      want_schedule = 0;
      hncp_run(o);
      sput_fail_unless(want_schedule <= HNCP_TRICKLE_IMAX, "reasonable timeout");
      t += want_schedule;
      current_hnetd_time += want_schedule;
    }
  sput_fail_unless(want_send > 0 && want_send <= i / 2, "few sends");
  check_timing = true;
  check_send = true;
  check_random = true;

  /* Ok, Trickle was in a stable state 'long' time. Make sure the
   * state resets once we push something new in. */
  struct tlv_attr ta;
  L_NOTICE("add tlv a");
#define TLV_ID_A 123
#define TLV_ID_B 125
#define TLV_ID_C 127
#define TLV_ID_D 124
  tlv_init(&ta, TLV_ID_A, 4);
  smock_push_int("schedule", 0);
  smock_push_int("local_tlv_callback", TLV_ID_A);
  hncp_add_tlv(o, &ta);
  smock_is_empty();

  L_NOTICE("add tlv b");
  tlv_init(&ta, TLV_ID_B, 4);
  /* should NOT cause extra schedule! */
  smock_push_int("local_tlv_callback", TLV_ID_B);
  hncp_add_tlv(o, &ta);
  smock_is_empty();

  L_NOTICE("running.");
  printf("last run starting\n");
  smock_push_int("time", t);
  smock_push_int("random", 0);
  smock_push_int("schedule", 0);

  /* Should get notification about two added TLVs. */
  smock_push_int("tlv_callback", TLV_ID_A);
  smock_push_int("tlv_callback", TLV_ID_B);
  smock_push_bool("republish_callback", true);
  hncp_run(o);
  smock_is_empty();

  /* Adding / removing last entry have special handling. So let's
   * test both by adding and removing tlv c (which > a, b). */

  /* Our interest in timing has waned by now though, so we disable
   * those checks. */
  check_timing = false;
  check_random = false;

  /* So, let's add one more TLV. Make sure we get notification about it. */
  L_NOTICE("add tlv c");
  tlv_init(&ta, TLV_ID_C, 4);
  smock_push_int("local_tlv_callback", TLV_ID_C);
  hncp_add_tlv(o, &ta);
  smock_is_empty();
  smock_push_int("tlv_callback", TLV_ID_C);
  smock_push_bool("republish_callback", true);
  hncp_run(o);
  smock_is_empty();

  /* Remove it. */
  L_NOTICE("remove tlv c");
  smock_push_int("local_tlv_callback", -TLV_ID_C);
  hncp_remove_tlv(o, &ta);
  smock_is_empty();
  smock_push_int("tlv_callback", -TLV_ID_C);
  smock_push_bool("republish_callback", true);
  hncp_run(o);
  smock_is_empty();

  /* Add TLV D in the middle. */
  L_NOTICE("add tlv d");
  tlv_init(&ta, TLV_ID_D, 4);
  smock_push_int("local_tlv_callback", TLV_ID_D);
  hncp_add_tlv(o, &ta);
  smock_is_empty();
  smock_push_int("tlv_callback", TLV_ID_D);
  smock_push_bool("republish_callback", true);
  hncp_run(o);
  smock_is_empty();

  /* Unsubscribing should result in callbacks too. */
  L_NOTICE("unsubscribe");
  smock_push_int("local_tlv_callback", -TLV_ID_A);
  smock_push_int("local_tlv_callback", -TLV_ID_D);
  smock_push_int("local_tlv_callback", -TLV_ID_B);
  smock_push_int("tlv_callback", -TLV_ID_A);
  smock_push_int("tlv_callback", -TLV_ID_D);
  smock_push_int("tlv_callback", -TLV_ID_B);
  smock_push_bool("node_callback", false);
  hncp_unsubscribe(o, &dummy_subscriber_1);
  hncp_unsubscribe(o, &dummy_subscriber_2);
  hncp_unsubscribe(o, &dummy_subscriber_3);
  hncp_unsubscribe(o, &dummy_subscriber_4);
  smock_is_empty();

  /* Re-enable checks */
  check_timing = true;
  check_random = true;

  /* no unregisters at end, as we first kill io, and then flush
   * structures (socket kill should take care of it in any case). */
  destroy_hncp(o);
}
Пример #8
0
static void dncp_io_basic_2()
{
  hncp_s h1, h2;
  dncp_s d1, d2;
  bool r;
  struct in6_addr a;
  char *msg = "foo";
  char *ifname = LOOPBACK_NAME;

  (void)uloop_init();
  memset(&h1, 0, sizeof(h1));
  memset(&h2, 0, sizeof(h2));
  memset(&d1, 0, sizeof(d1));
  memset(&d2, 0, sizeof(d2));
  h1.udp_port = 62000;
  h2.udp_port = 62001;
  h1.dncp = &d1;
  h2.dncp = &d2;
  d1.ext = &h1.ext;
  d2.ext = &h2.ext;
  r = hncp_io_init(&h1);
  sput_fail_unless(r, "dncp_io_init h1");
  r = hncp_io_init(&h2);
  sput_fail_unless(r, "dncp_io_init h2");

  /* Send a packet to ourselves */
  (void)inet_pton(AF_INET6, "::1", &a);
  struct sockaddr_in6 src = {
    .sin6_family = AF_INET6,
    .sin6_port = htons(h1.udp_port),
    .sin6_addr = a
#ifdef __APPLE__
    , .sin6_len = sizeof(struct sockaddr_in6)
#endif /* __APPLE__ */
  };
  struct sockaddr_in6 dst = {
    .sin6_family = AF_INET6,
    .sin6_port = htons(h2.udp_port),
    .sin6_addr = a
#ifdef __APPLE__
    , .sin6_len = sizeof(struct sockaddr_in6)
#endif /* __APPLE__ */
  };
  smock_push_int("dncp_poll_io_recvfrom", 3);
  smock_push_int("dncp_poll_io_recvfrom_src", &src);
  smock_push_int("dncp_poll_io_recvfrom_dst", &dst);
  smock_push_int("dncp_poll_io_recvfrom_buf", msg);
  smock_push_int("dncp_poll_io_recvfrom_ifname", ifname);
  h1.ext.cb.send(&h1.ext, dncp_find_ep_by_name(h1.dncp, "lo"),
                 NULL, &dst, msg, strlen(msg));
  pending_packets++;

  uloop_run();

  hncp_io_uninit(&h1);
  hncp_io_uninit(&h2);
}

int main(int argc, char **argv)
{
  setbuf(stdout, NULL); /* so that it's in sync with stderr when redirected */
  openlog("test_hncp_io", LOG_CONS | LOG_PERROR, LOG_DAEMON);
  sput_start_testing();
  sput_enter_suite("hncp_io"); /* optional */
  argc -= 1;
  argv += 1;

  sput_maybe_run_test(dncp_io_basic_2, do {} while(0));
  sput_leave_suite(); /* optional */
  sput_finish_testing();
  return sput_get_return_value();
}
Пример #9
0
void extdata_mock(__unused struct iface_user *u, __unused const char *ifname, __unused const void *dhcpv6_data, size_t dhcpv6_len)
{
	if (dhcpv6_len)
		smock_push_int("extdata", dhcpv6_len);
}