Commit 718a3145 authored by juga's avatar juga
Browse files

new: v3bwfile: Set measurements exclusion KeyValues

and return reason why the relay was excluded to be able to count
the relays excluded in the header.
Part of #28565.
parent 98443e0b
Loading
Loading
Loading
Loading
+39 −8
Original line number Diff line number Diff line
@@ -525,20 +525,51 @@ class V3BWLine(object):
                str(max(relay_recent_priority_list_counts))

        success_results = [r for r in results if isinstance(r, ResultSuccess)]

        # NOTE: The following 4 conditions exclude relays from the bandwidth
        # file when the measurements does not satisfy some rules, what makes
        # the relay non-`eligible`.
        # In BANDWIDTH_LINE_KEY_VALUES_MONITOR it is explained what they mean.
        # In BW_HEADER_KEYVALUES_RECENT_MEASUREMENTS_EXCLUDED it is also
        # explained the what it means the strings returned.
        # They rules were introduced in #28061 and #27338
        # In #28565 we introduce the KeyValues to know why they're excluded.
        # In #28563 we report these relays, but make Tor ignore them.
        # This might confirm #28042.

        number_excluded_error = len(results) - len(success_results)
        if number_excluded_error > 0:
            # then the number of error results is the number of results
            kwargs['relay_recent_measurements_excluded_error_count'] = \
                number_excluded_error
        if not success_results:
            return None
            return None, 'recent_measurements_excluded_error_count'

        results_away = \
            cls.results_away_each_other(success_results, secs_away)
        number_excluded_near = len(success_results) - len(results_away)
        if number_excluded_near > 0:
            kwargs['relay_recent_measurements_excluded_near_count'] = \
                len(success_results) - len(results_away)
        if not results_away:
            return None
            return None, 'recent_measurements_excluded_near_count'

        # log.debug("Results away from each other: %s",
        #           [unixts_to_isodt_str(r.time) for r in results_away])
        results_recent = cls.results_recent_than(results_away, secs_recent)
        number_excluded_old = len(results_away) - len(results_recent)
        if number_excluded_old > 0:
            kwargs['relay_recent_measurements_excluded_old_count'] = \
                number_excluded_old
        if not results_recent:
            return None
            return None, 'recent_measurements_excluded_old_count'

        if not len(results_recent) >= min_num:
            kwargs['relay_recent_measurements_excluded_few_count'] = \
                len(results_recent)
            # log.debug('The number of results is less than %s', min_num)
            return None
            return None, 'recent_measurements_excluded_few_count'

        rtt = cls.rtt_from_results(results_recent)
        if rtt:
            kwargs['rtt'] = rtt
@@ -560,7 +591,7 @@ class V3BWLine(object):
        kwargs['desc_bw_obs_mean'] = \
            cls.desc_bw_obs_mean_from_results(results_recent)
        bwl = cls(node_id, bw, **kwargs)
        return bwl
        return bwl, None

    @classmethod
    def from_data(cls, data, fingerprint):
@@ -594,7 +625,7 @@ class V3BWLine(object):
                return results
        # log.debug("Results are NOT away from each other in at least %ss: %s",
        #           secs_away, [unixts_to_isodt_str(r.time) for r in results])
        return None
        return []

    @staticmethod
    def results_recent_than(results, secs_recent=None):
@@ -769,8 +800,8 @@ class V3BWFile(object):
        state = State(state_fpath)
        for fp, values in results.items():
            # log.debug("Relay fp %s", fp)
            line = V3BWLine.from_results(values, secs_recent, secs_away,
                                         min_num)
            line, reason = V3BWLine.from_results(values, secs_recent,
                                                 secs_away, min_num)
            if line is not None:
                bw_lines_raw.append(line)
        if not bw_lines_raw:
+26 −1
Original line number Diff line number Diff line
@@ -61,6 +61,9 @@ raw_bwl_str = "bw=56 bw_mean=61423 bw_median=55656 "\
    "nick=A " \
    "node_id=$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "\
    "relay_recent_measurement_attempt_count=2 "\
    "relay_recent_measurement_exclusion_not_distanciated_count=0 "\
    "relay_recent_measurement_exclusion_not_recent_count=0 "\
    "relay_recent_measurement_exclusion_not_success_count=1 "\
    "relay_recent_priority_list_count=3 "\
    "rtt=456 success=1 " \
    "time=2018-04-17T14:09:07\n"
@@ -309,16 +312,31 @@ def test_results_away_each_other(datadir):
    results = load_result_file(str(datadir.join("results_away.txt")))
    # A has 4 results, 3 are success, 2 are 1 day away, 1 is 12h away
    values = results["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"]

    # There is one result excluded, but the relay is not excluded
    bwl, reason = V3BWLine.from_results(values, secs_away=secs_away, min_num=2)
    assert bwl.relay_recent_measurement_exclusion_error_count == 1
    assert reason is None

    success_results = [r for r in values if isinstance(r, ResultSuccess)]
    assert len(success_results) >= min_num
    results_away = V3BWLine.results_away_each_other(success_results, secs_away)
    assert len(results_away) == 3

    # B has 2 results, 12h away from each other
    values = results["BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]

    # Two measurements are excluded and there were only 2,
    # the relay is excluded
    bwl, reason = V3BWLine.from_results(values, secs_away=secs_away, min_num=2)
    # TODO ticket28563: uncomment
    # assert bwl.relay_recent_measurement_exclusion_near_count == 2
    assert reason == 'recent_measurement_exclusion_near_count'

    success_results = [r for r in values if isinstance(r, ResultSuccess)]
    assert len(success_results) >= min_num
    results_away = V3BWLine.results_away_each_other(success_results, secs_away)
    assert results_away is None
    assert not results_away
    secs_away = 43200  # 12h
    values = results["BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]
    success_results = [r for r in values if isinstance(r, ResultSuccess)]
@@ -327,6 +345,13 @@ def test_results_away_each_other(datadir):
    assert len(results_away) == 2
    # C has 1 result
    values = results["CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"]

    # There is only 1 result, the relay is excluded
    bwl, reason = V3BWLine.from_results(values, min_num=2)
    # TODO ticket28563: uncomment
    # assert bwl.recent_measurement_exclusion_few_count == 1
    assert reason == 'recent_measurement_exclusion_few_count'

    success_results = [r for r in values if isinstance(r, ResultSuccess)]
    assert len(success_results) < min_num