예제 #1
0
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
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;
}
예제 #2
0
파일: test_iface.c 프로젝트: sbyx/hnetd
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);
	}
}
예제 #3
0
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
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
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
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();
}
예제 #5
0
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
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);
}
예제 #6
0
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
static void one_join(bool ok)
{
  smock_push("set_enable_ifname", dummy_ifname);
  smock_push_bool("set_enable_enabled", true);
  smock_push_bool("set_enable_result", ok);
}
예제 #7
0
파일: test_hncp_nio.c 프로젝트: dtaht/hnetd
static void destroy_hncp(hncp o)
{
  smock_push("uninit", NULL);
  hncp_destroy(o);
  smock_is_empty();
}