|  | @@ -746,6 +746,17 @@ generate_ri_from_rs(const vote_routerstatus_t *vrs)
 | 
	
		
			
				|  |  |      strlen(r->cache_info.signed_descriptor_body);
 | 
	
		
			
				|  |  |    r->exit_policy = smartlist_new();
 | 
	
		
			
				|  |  |    r->cache_info.published_on = ++published + time(NULL);
 | 
	
		
			
				|  |  | +  if (rs->has_bandwidth) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * Multiply by 1000 because the routerinfo_t and the routerstatus_t
 | 
	
		
			
				|  |  | +     * seem to use different units (*sigh*) and because we seem stuck on
 | 
	
		
			
				|  |  | +     * icky and perverse decimal kilobytes (*double sigh*) - see
 | 
	
		
			
				|  |  | +     * router_get_advertised_bandwidth_capped() of routerlist.c and
 | 
	
		
			
				|  |  | +     * routerstatus_format_entry() of dirserv.c.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    r->bandwidthrate = rs->bandwidth * 1000;
 | 
	
		
			
				|  |  | +    r->bandwidthcapacity = rs->bandwidth * 1000;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |    return r;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1684,6 +1695,384 @@ test_dir_random_weighted(void *testdata)
 | 
	
		
			
				|  |  |    ;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/* Function pointers for test_dir_clip_unmeasured_bw() */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Generate a routerstatus for clip_unmeasured_bw test; based on the
 | 
	
		
			
				|  |  | + * v3_networkstatus ones.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static vote_routerstatus_t *
 | 
	
		
			
				|  |  | +gen_routerstatus_for_umbw(int idx, time_t now)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  vote_routerstatus_t *vrs;
 | 
	
		
			
				|  |  | +  routerstatus_t *rs;
 | 
	
		
			
				|  |  | +  tor_addr_t addr_ipv6;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  switch (idx) {
 | 
	
		
			
				|  |  | +    case 0:
 | 
	
		
			
				|  |  | +      /* Generate the first routerstatus. */
 | 
	
		
			
				|  |  | +      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
 | 
	
		
			
				|  |  | +      rs = &vrs->status;
 | 
	
		
			
				|  |  | +      vrs->version = tor_strdup("0.1.2.14");
 | 
	
		
			
				|  |  | +      rs->published_on = now-1500;
 | 
	
		
			
				|  |  | +      strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
 | 
	
		
			
				|  |  | +      memset(rs->identity_digest, 3, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      memset(rs->descriptor_digest, 78, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      rs->addr = 0x99008801;
 | 
	
		
			
				|  |  | +      rs->or_port = 443;
 | 
	
		
			
				|  |  | +      rs->dir_port = 8000;
 | 
	
		
			
				|  |  | +      /* all flags but running cleared */
 | 
	
		
			
				|  |  | +      rs->is_flagged_running = 1;
 | 
	
		
			
				|  |  | +      /*
 | 
	
		
			
				|  |  | +       * This one has measured bandwidth below the clip cutoff, and
 | 
	
		
			
				|  |  | +       * so shouldn't be clipped; we'll have to test that it isn't
 | 
	
		
			
				|  |  | +       * later.
 | 
	
		
			
				|  |  | +       */
 | 
	
		
			
				|  |  | +      rs->has_measured_bw = 1;
 | 
	
		
			
				|  |  | +      rs->has_bandwidth = 1;
 | 
	
		
			
				|  |  | +      rs->measured_bw = rs->bandwidth = DEFAULT_MAX_UNMEASURED_BW / 2;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    case 1:
 | 
	
		
			
				|  |  | +      /* Generate the second routerstatus. */
 | 
	
		
			
				|  |  | +      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
 | 
	
		
			
				|  |  | +      rs = &vrs->status;
 | 
	
		
			
				|  |  | +      vrs->version = tor_strdup("0.2.0.5");
 | 
	
		
			
				|  |  | +      rs->published_on = now-1000;
 | 
	
		
			
				|  |  | +      strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
 | 
	
		
			
				|  |  | +      memset(rs->identity_digest, 5, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      memset(rs->descriptor_digest, 77, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      rs->addr = 0x99009901;
 | 
	
		
			
				|  |  | +      rs->or_port = 443;
 | 
	
		
			
				|  |  | +      rs->dir_port = 0;
 | 
	
		
			
				|  |  | +      tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
 | 
	
		
			
				|  |  | +      tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
 | 
	
		
			
				|  |  | +      rs->ipv6_orport = 4711;
 | 
	
		
			
				|  |  | +      rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
 | 
	
		
			
				|  |  | +        rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
 | 
	
		
			
				|  |  | +      /*
 | 
	
		
			
				|  |  | +       * This one has measured bandwidth above the clip cutoff, and
 | 
	
		
			
				|  |  | +       * so shouldn't be clipped; we'll have to test that it isn't
 | 
	
		
			
				|  |  | +       * later.
 | 
	
		
			
				|  |  | +       */
 | 
	
		
			
				|  |  | +      rs->has_measured_bw = 1;
 | 
	
		
			
				|  |  | +      rs->has_bandwidth = 1;
 | 
	
		
			
				|  |  | +      rs->measured_bw = rs->bandwidth = 2 * DEFAULT_MAX_UNMEASURED_BW;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    case 2:
 | 
	
		
			
				|  |  | +      /* Generate the third routerstatus. */
 | 
	
		
			
				|  |  | +      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
 | 
	
		
			
				|  |  | +      rs = &vrs->status;
 | 
	
		
			
				|  |  | +      vrs->version = tor_strdup("0.1.0.3");
 | 
	
		
			
				|  |  | +      rs->published_on = now-1000;
 | 
	
		
			
				|  |  | +      strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
 | 
	
		
			
				|  |  | +      memset(rs->identity_digest, 0x33, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      memset(rs->descriptor_digest, 79, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      rs->addr = 0xAA009901;
 | 
	
		
			
				|  |  | +      rs->or_port = 400;
 | 
	
		
			
				|  |  | +      rs->dir_port = 9999;
 | 
	
		
			
				|  |  | +      rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
 | 
	
		
			
				|  |  | +        rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
 | 
	
		
			
				|  |  | +        rs->is_possible_guard = 1;
 | 
	
		
			
				|  |  | +      /*
 | 
	
		
			
				|  |  | +       * This one has unmeasured bandwidth above the clip cutoff, and
 | 
	
		
			
				|  |  | +       * so should be clipped; we'll have to test that it isn't
 | 
	
		
			
				|  |  | +       * later.
 | 
	
		
			
				|  |  | +       */
 | 
	
		
			
				|  |  | +      rs->has_measured_bw = 0;
 | 
	
		
			
				|  |  | +      rs->has_bandwidth = 1;
 | 
	
		
			
				|  |  | +      rs->measured_bw = 0;
 | 
	
		
			
				|  |  | +      rs->bandwidth = 2 * DEFAULT_MAX_UNMEASURED_BW;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    case 3:
 | 
	
		
			
				|  |  | +      /* Generate a fourth routerstatus that is not running. */
 | 
	
		
			
				|  |  | +      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
 | 
	
		
			
				|  |  | +      rs = &vrs->status;
 | 
	
		
			
				|  |  | +      vrs->version = tor_strdup("0.1.6.3");
 | 
	
		
			
				|  |  | +      rs->published_on = now-1000;
 | 
	
		
			
				|  |  | +      strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
 | 
	
		
			
				|  |  | +      memset(rs->identity_digest, 0x34, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      memset(rs->descriptor_digest, 47, DIGEST_LEN);
 | 
	
		
			
				|  |  | +      rs->addr = 0xC0000203;
 | 
	
		
			
				|  |  | +      rs->or_port = 500;
 | 
	
		
			
				|  |  | +      rs->dir_port = 1999;
 | 
	
		
			
				|  |  | +      /* all flags but running cleared */
 | 
	
		
			
				|  |  | +      rs->is_flagged_running = 1;
 | 
	
		
			
				|  |  | +      /*
 | 
	
		
			
				|  |  | +       * This one has unmeasured bandwidth below the clip cutoff, and
 | 
	
		
			
				|  |  | +       * so shouldn't be clipped; we'll have to test that it isn't
 | 
	
		
			
				|  |  | +       * later.
 | 
	
		
			
				|  |  | +       */
 | 
	
		
			
				|  |  | +      rs->has_measured_bw = 0;
 | 
	
		
			
				|  |  | +      rs->has_bandwidth = 1;
 | 
	
		
			
				|  |  | +      rs->measured_bw = 0;
 | 
	
		
			
				|  |  | +      rs->bandwidth = DEFAULT_MAX_UNMEASURED_BW / 2;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    case 4:
 | 
	
		
			
				|  |  | +      /* No more for this test; return NULL */
 | 
	
		
			
				|  |  | +      vrs = NULL;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    default:
 | 
	
		
			
				|  |  | +      /* Shouldn't happen */
 | 
	
		
			
				|  |  | +      test_assert(0);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + done:
 | 
	
		
			
				|  |  | +  return vrs;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/** Apply tweaks to the vote list for each voter; for the umbw test this is
 | 
	
		
			
				|  |  | + * just adding the right consensus methods to let clipping happen */
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  test_assert(v);
 | 
	
		
			
				|  |  | +  (void)voter;
 | 
	
		
			
				|  |  | +  (void)now;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  test_assert(v->supported_methods);
 | 
	
		
			
				|  |  | +  smartlist_clear(v->supported_methods);
 | 
	
		
			
				|  |  | +  /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW */
 | 
	
		
			
				|  |  | +  smartlist_split_string(v->supported_methods,
 | 
	
		
			
				|  |  | +                         "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17",
 | 
	
		
			
				|  |  | +                         NULL, 0, -1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + done:
 | 
	
		
			
				|  |  | +  return;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Test a parsed vote_routerstatus_t for umbw test.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  routerstatus_t *rs;
 | 
	
		
			
				|  |  | +  tor_addr_t addr_ipv6;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  (void)voter;
 | 
	
		
			
				|  |  | +  test_assert(vrs);
 | 
	
		
			
				|  |  | +  rs = &(vrs->status);
 | 
	
		
			
				|  |  | +  test_assert(rs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* Split out by digests to test */
 | 
	
		
			
				|  |  | +  if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
 | 
	
		
			
				|  |  | +                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
 | 
	
		
			
				|  |  | +                DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * Check the first routerstatus - measured bandwidth below the clip
 | 
	
		
			
				|  |  | +     * cutoff.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_streq(vrs->version, "0.1.2.14");
 | 
	
		
			
				|  |  | +    test_eq(rs->published_on, now-1500);
 | 
	
		
			
				|  |  | +    test_streq(rs->nickname, "router2");
 | 
	
		
			
				|  |  | +    test_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +               "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
 | 
	
		
			
				|  |  | +               "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
 | 
	
		
			
				|  |  | +               DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_eq(rs->addr, 0x99008801);
 | 
	
		
			
				|  |  | +    test_eq(rs->or_port, 443);
 | 
	
		
			
				|  |  | +    test_eq(rs->dir_port, 8000);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_measured_bw);
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                       "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
 | 
	
		
			
				|  |  | +                       "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
 | 
	
		
			
				|  |  | +                       DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * Check the second routerstatus - measured bandwidth above the clip
 | 
	
		
			
				|  |  | +     * cutoff.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_streq(vrs->version, "0.2.0.5");
 | 
	
		
			
				|  |  | +    test_eq(rs->published_on, now-1000);
 | 
	
		
			
				|  |  | +    test_streq(rs->nickname, "router1");
 | 
	
		
			
				|  |  | +    test_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +               "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
 | 
	
		
			
				|  |  | +               "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
 | 
	
		
			
				|  |  | +               DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_eq(rs->addr, 0x99009901);
 | 
	
		
			
				|  |  | +    test_eq(rs->or_port, 443);
 | 
	
		
			
				|  |  | +    test_eq(rs->dir_port, 0);
 | 
	
		
			
				|  |  | +    tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
 | 
	
		
			
				|  |  | +    test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
 | 
	
		
			
				|  |  | +    test_eq(rs->ipv6_orport, 4711);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_measured_bw);
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW * 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, DEFAULT_MAX_UNMEASURED_BW * 2);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                       "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
 | 
	
		
			
				|  |  | +                       "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
 | 
	
		
			
				|  |  | +                       DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * Check the third routerstatus - unmeasured bandwidth above the clip
 | 
	
		
			
				|  |  | +     * cutoff; this one should be clipped later on in the consensus, but
 | 
	
		
			
				|  |  | +     * appears unclipped in the vote.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(!(rs->has_measured_bw));
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW * 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, 0);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                       "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
 | 
	
		
			
				|  |  | +                       "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
 | 
	
		
			
				|  |  | +                       DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * Check the fourth routerstatus - unmeasured bandwidth below the clip
 | 
	
		
			
				|  |  | +     * cutoff; this one should not be clipped.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(!(rs->has_measured_bw));
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, 0);
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    test_assert(0);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + done:
 | 
	
		
			
				|  |  | +  return;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Test a consensus for v3_networkstatus_test
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +test_consensus_for_umbw(networkstatus_t *con, time_t now)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  (void)now;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  test_assert(con);
 | 
	
		
			
				|  |  | +  test_assert(!con->cert);
 | 
	
		
			
				|  |  | +  /* test_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW); */
 | 
	
		
			
				|  |  | +  test_assert(con->consensus_method >= 16);
 | 
	
		
			
				|  |  | +  test_eq(4, smartlist_len(con->routerstatus_list));
 | 
	
		
			
				|  |  | +  /* There should be four listed routers; all voters saw the same in this */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + done:
 | 
	
		
			
				|  |  | +  return;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Test a router list entry for umbw test
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  tor_addr_t addr_ipv6;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  test_assert(rs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* There should be four listed routers, as constructed above */
 | 
	
		
			
				|  |  | +  if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
 | 
	
		
			
				|  |  | +                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
 | 
	
		
			
				|  |  | +                DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    test_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +               "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
 | 
	
		
			
				|  |  | +               "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
 | 
	
		
			
				|  |  | +               DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_authority);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_exit);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_fast);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_possible_guard);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_stable);
 | 
	
		
			
				|  |  | +    /* (If it wasn't running it wouldn't be here) */
 | 
	
		
			
				|  |  | +    test_assert(rs->is_flagged_running);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_v2_dir);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_valid);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_named);
 | 
	
		
			
				|  |  | +    /* This one should have measured bandwidth below the clip cutoff */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_measured_bw);
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                       "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
 | 
	
		
			
				|  |  | +                       "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
 | 
	
		
			
				|  |  | +                       DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'.  */
 | 
	
		
			
				|  |  | +    test_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +               "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
 | 
	
		
			
				|  |  | +               "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
 | 
	
		
			
				|  |  | +               DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_streq(rs->nickname, "router1");
 | 
	
		
			
				|  |  | +    test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
 | 
	
		
			
				|  |  | +    test_eq(rs->published_on, now-1000);
 | 
	
		
			
				|  |  | +    test_eq(rs->addr, 0x99009901);
 | 
	
		
			
				|  |  | +    test_eq(rs->or_port, 443);
 | 
	
		
			
				|  |  | +    test_eq(rs->dir_port, 0);
 | 
	
		
			
				|  |  | +    tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
 | 
	
		
			
				|  |  | +    test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
 | 
	
		
			
				|  |  | +    test_eq(rs->ipv6_orport, 4711);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_authority);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_exit);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_fast);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_possible_guard);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_stable);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_flagged_running);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_v2_dir);
 | 
	
		
			
				|  |  | +    test_assert(rs->is_valid);
 | 
	
		
			
				|  |  | +    test_assert(!rs->is_named);
 | 
	
		
			
				|  |  | +    /* This one should have measured bandwidth above the clip cutoff */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(rs->has_measured_bw);
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW * 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, DEFAULT_MAX_UNMEASURED_BW * 2);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
 | 
	
		
			
				|  |  | +                "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
 | 
	
		
			
				|  |  | +                DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * This one should have unmeasured bandwidth above the clip cutoff,
 | 
	
		
			
				|  |  | +     * and so should be clipped
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(!(rs->has_measured_bw));
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, 0);
 | 
	
		
			
				|  |  | +  } else if (tor_memeq(rs->identity_digest,
 | 
	
		
			
				|  |  | +                "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
 | 
	
		
			
				|  |  | +                "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
 | 
	
		
			
				|  |  | +                DIGEST_LEN)) {
 | 
	
		
			
				|  |  | +    /*
 | 
	
		
			
				|  |  | +     * This one should have unmeasured bandwidth below the clip cutoff,
 | 
	
		
			
				|  |  | +     * and so should not be clipped
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    test_assert(rs->has_bandwidth);
 | 
	
		
			
				|  |  | +    test_assert(!(rs->has_measured_bw));
 | 
	
		
			
				|  |  | +    test_eq(rs->bandwidth, DEFAULT_MAX_UNMEASURED_BW / 2);
 | 
	
		
			
				|  |  | +    test_eq(rs->measured_bw, 0);
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    /* Weren't expecting this... */
 | 
	
		
			
				|  |  | +    test_assert(0);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + done:
 | 
	
		
			
				|  |  | +  return;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Compute a consensus involving clipping unmeasured bandwidth with consensus
 | 
	
		
			
				|  |  | + * method 17; this uses the same test_a_networkstatus() function that the
 | 
	
		
			
				|  |  | + * v3_networkstatus test uses.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +test_dir_clip_unmeasured_bw(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  test_a_networkstatus(gen_routerstatus_for_umbw,
 | 
	
		
			
				|  |  | +                       vote_tweaks_for_umbw,
 | 
	
		
			
				|  |  | +                       test_vrs_for_umbw,
 | 
	
		
			
				|  |  | +                       test_consensus_for_umbw,
 | 
	
		
			
				|  |  | +                       test_routerstatus_for_umbw);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #define DIR_LEGACY(name)                                                   \
 | 
	
		
			
				|  |  |    { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1701,6 +2090,7 @@ struct testcase_t dir_tests[] = {
 | 
	
		
			
				|  |  |    DIR_LEGACY(v3_networkstatus),
 | 
	
		
			
				|  |  |    DIR(random_weighted),
 | 
	
		
			
				|  |  |    DIR(scale_bw),
 | 
	
		
			
				|  |  | +  DIR_LEGACY(clip_unmeasured_bw),
 | 
	
		
			
				|  |  |    END_OF_TESTCASES
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 |