Пример #1
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;
}
Пример #2
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);
}
Пример #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_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
void iface_test_new_unmanaged(void)
{
	iface_register_user(&user_mock);

	struct iface *iface = iface_create("test0", NULL, 0);
	sput_fail_unless(!!iface, "alloc unmanaged");

	struct iface *iface2 = iface_get("test0");
	sput_fail_unless(iface == iface2, "get after create");

	struct iface *iface3 = iface_create("test0", NULL, 0);
	sput_fail_unless(iface == iface3, "create after create");

	iface_remove(iface);
	sput_fail_unless(!iface_get("test0"), "delete");

	smock_is_empty();
	iface_unregister_user(&user_mock);
}
Пример #6
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);
}
Пример #7
0
static void destroy_hncp(hncp o)
{
  smock_push("uninit", NULL);
  hncp_destroy(o);
  smock_is_empty();
}
Пример #8
0
void iface_test_new_managed(void)
{
	struct in_addr v4source = {INADDR_LOOPBACK};
	iface_register_user(&user_mock);
	struct prefix p = {IN6ADDR_LOOPBACK_INIT, 0};
	char test[] = "test";

	struct iface *iface00 = iface_create("test00", "test00", 0);
	iface_update_ipv4_uplink(iface00);
	iface_set_ipv4_uplink(iface00, &v4source, 24);
	iface_commit_ipv4_uplink(iface00);
	/* smock_pull_bool_is("test00", false); */
        /* this was removed in the commit
           a5293745c235a057b6a477ffbd817937eaa9bc12 at 5/2015(!);
        */

	struct iface *iface = iface_create("test0", "test0", 0);
	iface->carrier = true;
	iface_discover_border(iface);

	sput_fail_unless(!!iface, "alloc managed");

	struct iface *iface2 = iface_get("test0");
	sput_fail_unless(iface == iface2, "get after create");

	struct iface *iface3 = iface_create("test0", "test0", 0);
	sput_fail_unless(iface == iface3, "create after create");

	/* smock_pull_bool_is("test0", false); */
        /* this was removed in the commit
           a5293745c235a057b6a477ffbd817937eaa9bc12 at 5/2015(!);
        */

	uloop_cancelled = false;
	uloop_run();
	smock_pull_bool_is("test0", true);

	iface_update_ipv4_uplink(iface);
	iface_set_ipv4_uplink(iface, &v4source, 24);
	iface_commit_ipv4_uplink(iface);
	smock_pull_bool_is("test0", false);

	iface_update_ipv4_uplink(iface);
	iface_commit_ipv4_uplink(iface);
	uloop_cancelled = false;
	uloop_run();
	smock_pull_bool_is("test0", true);

	iface_update_ipv6_uplink(iface);
	iface_add_delegated(iface, &p, NULL, HNETD_TIME_MAX, 0, test, sizeof(test));
	iface_commit_ipv6_uplink(iface);

	smock_pull_bool_is("test0", false);
	sput_fail_unless(!prefix_cmp(&p, (struct prefix *)smock_pull("prefix_prefix")), "prefix address");
	smock_pull_int64_is("prefix_valid", HNETD_TIME_MAX);
	smock_pull_int64_is("prefix_preferred", 0);
	sput_fail_unless(!strcmp(smock_pull("dhcpv6_data"), "test"), "dhcpv6_data");
	smock_pull_int_is("dhcpv6_len", sizeof(test));

	iface_update_ipv4_uplink(iface);
	iface_set_ipv4_uplink(iface, &v4source, 24);
	iface_commit_ipv4_uplink(iface);

	iface_update_ipv6_uplink(iface);
	iface_commit_ipv6_uplink(iface);
	smock_pull_bool_is("prefix_remove", true);

	iface_update_ipv4_uplink(iface);
	iface_commit_ipv4_uplink(iface);

	uloop_cancelled = false;
	uloop_run();
	smock_pull_bool_is("test0", true);

	iface_remove(iface);
	sput_fail_unless(!iface_get("test0"), "delete");
	smock_pull_bool_is("test0", false);
	smock_is_empty();
	iface_unregister_user(&user_mock);
}