Example #1
0
static void
test_conn_download_status(void *arg)
{
  dir_connection_t *conn = NULL;
  dir_connection_t *conn2 = NULL;
  dir_connection_t *conn4 = NULL;
  connection_t *ap_conn = NULL;

  const struct testcase_t *tc = arg;
  consensus_flavor_t usable_flavor = (consensus_flavor_t)tc->setup_data;

  /* The "other flavor" trick only works if there are two flavors */
  tor_assert(N_CONSENSUS_FLAVORS == 2);
  consensus_flavor_t other_flavor = ((usable_flavor == FLAV_NS)
                                     ? FLAV_MICRODESC
                                     : FLAV_NS);
  const char *res = networkstatus_get_flavor_name(usable_flavor);
  const char *other_res = networkstatus_get_flavor_name(other_flavor);

  /* no connections */
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* one connection, not downloading */
  conn = test_conn_download_status_add_a_connection(res);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* one connection, downloading but not linked (not possible on a client,
   * but possible on a relay) */
  conn->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* one connection, downloading and linked, but not yet attached */
  ap_conn = test_conn_get_linked_connection(TO_CONN(conn),
                                            TEST_CONN_UNATTACHED_STATE);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

    /* one connection, downloading and linked and attached */
  ap_conn->state = TEST_CONN_ATTACHED_STATE;
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* one connection, linked and attached but not downloading */
  conn->base_.state = TEST_CONN_STATE;
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* two connections, both not downloading */
  conn2 = test_conn_download_status_add_a_connection(res);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 2);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* two connections, one downloading */
  conn->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 2);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);
  conn->base_.state = TEST_CONN_STATE;

  /* more connections, all not downloading */
  /* ignore the return value, it's free'd using the connection list */
  (void)test_conn_download_status_add_a_connection(res);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 0);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* more connections, one downloading */
  conn->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* more connections, two downloading (should never happen, but needs
   * to be tested for completeness) */
  conn2->base_.state = TEST_CONN_DL_STATE;
  /* ignore the return value, it's free'd using the connection list */
  (void)test_conn_get_linked_connection(TO_CONN(conn2),
                                        TEST_CONN_ATTACHED_STATE);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);
  conn->base_.state = TEST_CONN_STATE;

  /* more connections, a different one downloading */
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                         other_res) == 0);

  /* a connection for the other flavor (could happen if a client is set to
   * cache directory documents), one preferred flavor downloading
   */
  conn4 = test_conn_download_status_add_a_connection(other_res);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        other_res) == 1);

  /* a connection for the other flavor (could happen if a client is set to
   * cache directory documents), both flavors downloading
   */
  conn4->base_.state = TEST_CONN_DL_STATE;
  /* ignore the return value, it's free'd using the connection list */
  (void)test_conn_get_linked_connection(TO_CONN(conn4),
                                        TEST_CONN_ATTACHED_STATE);
  tt_assert(networkstatus_consensus_is_already_downloading(res) == 1);
  tt_assert(networkstatus_consensus_is_already_downloading(other_res) == 1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        res) == 3);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        other_res) == 1);

 done:
  /* the teardown function removes all the connections in the global list*/;
}
Example #2
0
static void
test_conn_download_status(void *arg)
{
  (void)arg;
  dir_connection_t *conn = NULL;
  dir_connection_t *conn2 = NULL;
  dir_connection_t *conn3 = NULL;

  /* no connections, no excess, not downloading */
  tt_assert(networkstatus_consensus_has_excess_connections() == 0);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 0);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 0);

  /* one connection, no excess, not downloading */
  conn = test_conn_download_status_add_a_connection();
  tt_assert(networkstatus_consensus_has_excess_connections() == 0);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 0);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 0);

  /* one connection, no excess, but downloading */
  conn->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_has_excess_connections() == 0);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 1);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);
  conn->base_.state = TEST_CONN_STATE;

  /* two connections, excess, but not downloading */
  conn2 = test_conn_download_status_add_a_connection();
  tt_assert(networkstatus_consensus_has_excess_connections() == 1);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 0);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 0);

  /* two connections, excess, downloading */
  conn2->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_has_excess_connections() == 1);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 1);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);
  conn2->base_.state = TEST_CONN_STATE;

  /* more connections, excess, but not downloading */
  conn3 = test_conn_download_status_add_a_connection();
  tt_assert(networkstatus_consensus_has_excess_connections() == 1);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 0);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 0);

  /* more connections, excess, downloading */
  conn3->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_has_excess_connections() == 1);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 1);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

  /* more connections, more downloading */
  conn2->base_.state = TEST_CONN_DL_STATE;
  tt_assert(networkstatus_consensus_has_excess_connections() == 1);
  tt_assert(networkstatus_consensus_is_downloading_usable_flavor() == 1);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

  /* now try closing the one that isn't downloading:
   * these tests won't work unless tor thinks it is bootstrapping */
  tt_assert(networkstatus_consensus_is_boostrapping(time(NULL)));

  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        TEST_CONN_RSRC) == 3);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);
  tt_assert(connection_dir_close_consensus_conn_if_extra(conn) == -1);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        TEST_CONN_RSRC) == 2);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

  /* now try closing one that is already closed - nothing happens */
  tt_assert(connection_dir_close_consensus_conn_if_extra(conn) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        TEST_CONN_RSRC) == 2);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

  /* now try closing one that is downloading - it stays open */
  tt_assert(connection_dir_close_consensus_conn_if_extra(conn2) == 0);
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        TEST_CONN_RSRC) == 2);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

  /* now try closing all excess connections */
  connection_dir_close_extra_consensus_conns();
  tt_assert(connection_dir_count_by_purpose_and_resource(
                                                        TEST_CONN_RSRC_PURPOSE,
                                                        TEST_CONN_RSRC) == 1);
  tt_assert(connection_dir_avoid_extra_connection_for_purpose(
                                                 TEST_CONN_RSRC_PURPOSE) == 1);

 done:
  /* the teardown function removes all the connections */;
}
Example #3
0
static void *
test_conn_get_rsrc_setup(const struct testcase_t *tc)
{
  (void)tc;
  return test_conn_download_status_add_a_connection(TEST_CONN_RSRC);
}