Browse Source

test: Improve our rotation and build descriptor tests

Because of the latest changes on when we rotate, longer lifetime of
descriptors and no more overlap period, the tests needed to be improved to
test more functionnalities.

Signed-off-by: David Goulet <dgoulet@torproject.org>
David Goulet 6 years ago
parent
commit
6c6ba07517
1 changed files with 96 additions and 25 deletions
  1. 96 25
      src/test/test_hs_service.c

+ 96 - 25
src/test/test_hs_service.c

@@ -937,14 +937,16 @@ static void
 test_rotate_descriptors(void *arg)
 {
   int ret;
-  time_t next_rotation_time;
+  time_t next_rotation_time, now = time(NULL);
   hs_service_t *service;
   hs_service_descriptor_t *desc_next;
-  hs_service_intro_point_t *ip;
 
   (void) arg;
 
+  dummy_state = tor_malloc_zero(sizeof(or_state_t));
+
   hs_init();
+  MOCK(get_or_state, get_or_state_replacement);
   MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
   MOCK(networkstatus_get_live_consensus,
        mock_networkstatus_get_live_consensus);
@@ -961,8 +963,14 @@ test_rotate_descriptors(void *arg)
   /* Create a service with a default descriptor and state. It's added to the
    * global map. */
   service = helper_create_service();
-  ip = helper_create_service_ip();
-  service_intro_point_add(service->desc_current->intro_points.map, ip);
+  service_descriptor_free(service->desc_current);
+  service->desc_current = NULL;
+  /* This triggers a build for both descriptors. The time now is only used in
+   * the descriptor certificate which is important to be now else the decoding
+   * will complain that the cert has expired if we use valid_after. */
+  build_all_descriptors(now);
+  tt_assert(service->desc_current);
+  tt_assert(service->desc_next);
 
   /* Tweak our service next rotation time so we can use a custom time. */
   service->state.next_rotation_time = next_rotation_time =
@@ -973,8 +981,13 @@ test_rotate_descriptors(void *arg)
   rotate_all_descriptors(mock_ns.valid_after);
   tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   tt_assert(service->desc_current);
-  tt_int_op(digest256map_size(service->desc_current->intro_points.map),
-            OP_EQ, 1);
+  tt_assert(service->desc_next);
+  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
+            hs_get_previous_time_period_num(0));
+  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
+            hs_get_time_period_num(0));
+  /* Keep a reference so we can compare it after rotation to the current. */
+  desc_next = service->desc_next;
 
   /* Going right after a new SRV. */
   ret = parse_rfc1123_time("Sat, 27 Oct 1985 01:00:00 UTC",
@@ -984,8 +997,6 @@ test_rotate_descriptors(void *arg)
                            &mock_ns.fresh_until);
   tt_int_op(ret, OP_EQ, 0);
 
-  desc_next = service_descriptor_new();
-  service->desc_next = desc_next;
   /* Note down what to expect for the next rotation time which is 01:00 + 23h
    * meaning 00:00:00. */
   next_rotation_time = mock_ns.valid_after + (23 * 60 * 60);
@@ -994,20 +1005,25 @@ test_rotate_descriptors(void *arg)
   rotate_all_descriptors(mock_ns.valid_after);
   tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
-  tt_int_op(digest256map_size(service->desc_current->intro_points.map),
-            OP_EQ, 0);
   tt_assert(service->desc_next == NULL);
 
   /* A second time should do nothing. */
   rotate_all_descriptors(mock_ns.valid_after);
   tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
-  tt_int_op(digest256map_size(service->desc_current->intro_points.map),
-            OP_EQ, 0);
   tt_assert(service->desc_next == NULL);
 
+  build_all_descriptors(now);
+  tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
+  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
+            hs_get_time_period_num(0));
+  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
+            hs_get_next_time_period_num(0));
+  tt_assert(service->desc_next);
+
  done:
   hs_free_all();
+  UNMOCK(get_or_state);
   UNMOCK(circuit_mark_for_close_);
   UNMOCK(networkstatus_get_live_consensus);
 }
@@ -1027,6 +1043,7 @@ test_build_update_descriptors(void *arg)
   (void) arg;
 
   hs_init();
+
   MOCK(get_or_state,
        get_or_state_replacement);
   MOCK(networkstatus_get_live_consensus,
@@ -1036,30 +1053,28 @@ test_build_update_descriptors(void *arg)
 
   ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
                            &mock_ns.valid_after);
+  tt_int_op(ret, OP_EQ, 0);
   ret = parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
                            &mock_ns.fresh_until);
   tt_int_op(ret, OP_EQ, 0);
 
-  uint64_t period_num = hs_get_time_period_num(0);
-  uint64_t next_period_num = hs_get_next_time_period_num(0);
-
   /* Create a service without a current descriptor to trigger a build. */
-  service = hs_service_new(get_options());
+  service = helper_create_service();
   tt_assert(service);
-  service->config.version = HS_VERSION_THREE;
-  ed25519_secret_key_generate(&service->keys.identity_sk, 0);
-  ed25519_public_key_generate(&service->keys.identity_pk,
-                              &service->keys.identity_sk);
-  /* Register service to global map. */
-  ret = register_service(get_hs_service_map(), service);
-  tt_int_op(ret, OP_EQ, 0);
+  /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
+  service_descriptor_free(service->desc_current);
+  service->desc_current = NULL;
 
+  /* We have a fresh service so this should trigger a build for both
+   * descriptors for specific time period that we'll test. */
   build_all_descriptors(now);
   /* Check *current* descriptor. */
   tt_assert(service->desc_current);
   tt_assert(service->desc_current->desc);
   tt_assert(service->desc_current->intro_points.map);
-  tt_u64_op(service->desc_current->time_period_num, OP_EQ, period_num);
+  /* The current time period is the one expected when starting at 03:00. */
+  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
+            hs_get_time_period_num(0));
   /* This should be untouched, the update descriptor process changes it. */
   tt_u64_op(service->desc_current->next_upload_time, OP_EQ, 0);
 
@@ -1068,7 +1083,8 @@ test_build_update_descriptors(void *arg)
   tt_assert(service->desc_next->desc);
   tt_assert(service->desc_next->intro_points.map);
   tt_assert(service->desc_current != service->desc_next);
-  tt_u64_op(service->desc_next->time_period_num, OP_EQ, next_period_num);
+  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
+            hs_get_next_time_period_num(0));
   /* This should be untouched, the update descriptor process changes it. */
   tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
 
@@ -1168,6 +1184,61 @@ test_build_update_descriptors(void *arg)
   tt_u64_op(ip_cur->time_to_expire, OP_LE, now +
             INTRO_POINT_LIFETIME_MAX_SECONDS);
 
+  /* Now, we will try to set up a service after a new time period has started
+   * and see if it behaves as expected. */
+
+  ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
+                           &mock_ns.valid_after);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
+                           &mock_ns.fresh_until);
+  tt_int_op(ret, OP_EQ, 0);
+
+  /* Create a service without a current descriptor to trigger a build. */
+  service = helper_create_service();
+  tt_assert(service);
+  /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
+  service_descriptor_free(service->desc_current);
+  service->desc_current = NULL;
+
+  /* We have a fresh service so this should trigger a build for both
+   * descriptors for specific time period that we'll test. */
+  build_all_descriptors(now);
+  /* Check *current* descriptor. */
+  tt_assert(service->desc_current);
+  tt_assert(service->desc_current->desc);
+  tt_assert(service->desc_current->intro_points.map);
+  /* This should be for the previous time period. */
+  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
+            hs_get_previous_time_period_num(0));
+  /* This should be untouched, the update descriptor process changes it. */
+  tt_u64_op(service->desc_current->next_upload_time, OP_EQ, 0);
+
+  /* Check *next* descriptor. */
+  tt_assert(service->desc_next);
+  tt_assert(service->desc_next->desc);
+  tt_assert(service->desc_next->intro_points.map);
+  tt_assert(service->desc_current != service->desc_next);
+  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
+            hs_get_time_period_num(0));
+  /* This should be untouched, the update descriptor process changes it. */
+  tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
+
+  /* Let's remove the next descriptor to simulate a rotation. */
+  service_descriptor_free(service->desc_next);
+  service->desc_next = NULL;
+
+  build_all_descriptors(now);
+  /* Check *next* descriptor. */
+  tt_assert(service->desc_next);
+  tt_assert(service->desc_next->desc);
+  tt_assert(service->desc_next->intro_points.map);
+  tt_assert(service->desc_current != service->desc_next);
+  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
+            hs_get_next_time_period_num(0));
+  /* This should be untouched, the update descriptor process changes it. */
+  tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
+
  done:
   hs_free_all();
   nodelist_free_all();