Skip to content

Commit

Permalink
Implement final loni generation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
hellais committed Nov 18, 2023
1 parent bea7811 commit 54df5a5
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 36 deletions.
213 changes: 178 additions & 35 deletions oonidata/analysis/website_experiment_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@
log = logging.getLogger("oonidata.analysis")

Check warning on line 9 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L9

Added line #L9 was not covered by tests


class LoniValue(NamedTuple):
ok_value: float
down: Dict[str, float]
blocked: Dict[str, float]
blocking_scope: Optional[str]


def map_analysis_to_target_name(analysis):

Check warning on line 12 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L12

Added line #L12 was not covered by tests
# Poormans mapping to target name
# TODO(arturo) we eventually want to look these up in some sort of database that groups together related domains
Expand Down Expand Up @@ -60,10 +53,21 @@ def sum(self) -> float:
return s

Check warning on line 53 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L49-L53

Added lines #L49 - L53 were not covered by tests


@dataclass
class LoNI:
ok_final: float

Check warning on line 58 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L56-L58

Added lines #L56 - L58 were not covered by tests

ok: OutcomeSpace
down: OutcomeSpace
blocked: OutcomeSpace
blocking_scope: Optional[str]

Check warning on line 63 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L60-L63

Added lines #L60 - L63 were not covered by tests


def calculate_web_loni(

Check warning on line 66 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L66

Added line #L66 was not covered by tests
web_analysis: WebAnalysis,
) -> Tuple[LoniValue, List[str]]:
) -> Tuple[LoNI, List[str]]:
ok_value = 0
ok = OutcomeSpace()
down = OutcomeSpace()
blocked = OutcomeSpace()

Check warning on line 72 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L69-L72

Added lines #L69 - L72 were not covered by tests

Expand Down Expand Up @@ -332,6 +336,7 @@ def calculate_web_loni(
# final analysis to blocked and down dictionaries.
blocked.dns = OutcomeStatus(key=blocked_key, value=blocked_value)
down.dns = OutcomeStatus(key=down_key, value=down_value)
ok.dns = OutcomeStatus(key="dns", value=ok_value)
assert (

Check warning on line 340 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L337-L340

Added lines #L337 - L340 were not covered by tests
blocked.sum() + down.sum() + ok_value == 1
), f"{blocked} + {down} + {ok_value} != 1"
Expand All @@ -343,10 +348,11 @@ def calculate_web_loni(
# TODO(arturo): do we want to have different thresholds here?
analysis_transcript.append("ok_value < 0.5")
return (

Check warning on line 350 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L349-L350

Added lines #L349 - L350 were not covered by tests
LoniValue(
ok_value=ok_value,
blocked=blocked.to_dict(),
down=down.to_dict(),
LoNI(
ok_final=ok_value,
ok=ok,
blocked=blocked,
down=down,
blocking_scope=blocking_scope,
),
analysis_transcript,
Expand Down Expand Up @@ -421,6 +427,8 @@ def calculate_web_loni(

blocked.tcp = OutcomeStatus(key=blocked_key, value=blocked_value * ok_value)
down.tcp = OutcomeStatus(key=down_key, value=down_value * ok_value)

Check warning on line 429 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L428-L429

Added lines #L428 - L429 were not covered by tests
# TODO(arturo): double check this is correct
ok.tcp = OutcomeStatus(key="tcp", value=1 - (blocked.sum() + down.sum()))

Check warning on line 431 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L431

Added line #L431 was not covered by tests

old_ok_value = ok_value
ok_value = 1 - (blocked.sum() + down.sum())
Expand All @@ -437,10 +445,11 @@ def calculate_web_loni(
f"ok_value < 0.5 # OK went from {old_ok_value} -> {ok_value}"
)
return (

Check warning on line 447 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L447

Added line #L447 was not covered by tests
LoniValue(
ok_value=ok_value,
blocked=blocked.to_dict(),
down=down.to_dict(),
LoNI(
ok_final=ok_value,
ok=ok,
blocked=blocked,
down=down,
blocking_scope=blocking_scope,
),
analysis_transcript,
Expand Down Expand Up @@ -528,6 +537,8 @@ def calculate_web_loni(

blocked.tls = OutcomeStatus(key=blocked_key, value=blocked_value * ok_value)
down.tls = OutcomeStatus(key=down_key, value=down_value * ok_value)

Check warning on line 539 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L538-L539

Added lines #L538 - L539 were not covered by tests
# TODO(arturo): double check this is correct
ok.tls = OutcomeStatus(key="tls", value=1 - (blocked.sum() + down.sum()))

Check warning on line 541 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L541

Added line #L541 was not covered by tests

old_ok_value = ok_value
ok_value = 1 - (blocked.sum() + down.sum())
Expand All @@ -542,10 +553,11 @@ def calculate_web_loni(
f"ok_value < 0.5 # OK went from {old_ok_value} -> {ok_value}"
)
return (

Check warning on line 555 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L555

Added line #L555 was not covered by tests
LoniValue(
ok_value=ok_value,
blocked=blocked.to_dict(),
down=down.to_dict(),
LoNI(
ok_final=ok_value,
ok=ok,
blocked=blocked,
down=down,
blocking_scope=blocking_scope,
),
analysis_transcript,
Expand Down Expand Up @@ -707,11 +719,15 @@ def calculate_web_loni(
)
blocked.tls = OutcomeStatus(key=blocked_key, value=blocked_value * ok_value)
down.tls = OutcomeStatus(key=down_key, value=down_value * ok_value)

Check warning on line 721 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L720-L721

Added lines #L720 - L721 were not covered by tests
# TODO(arturo): double check this is correct
ok.tls = OutcomeStatus(key="tls", value=1 - (blocked.sum() + down.sum()))

Check warning on line 723 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L723

Added line #L723 was not covered by tests
else:
blocked.http = OutcomeStatus(

Check warning on line 725 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L725

Added line #L725 was not covered by tests
key=blocked_key, value=blocked_value * ok_value
)
down.http = OutcomeStatus(key=down_key, value=down_value * ok_value)

Check warning on line 728 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L728

Added line #L728 was not covered by tests
# TODO(arturo): double check this is correct
ok.http = OutcomeStatus(key="http", value=1 - (blocked.sum() + down.sum()))

Check warning on line 730 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L730

Added line #L730 was not covered by tests

old_ok_value = ok_value
ok_value = 1 - (blocked.sum() + down.sum())
Expand All @@ -720,10 +736,11 @@ def calculate_web_loni(
), f"{blocked} + {down} + {ok_value} != 1"

return (

Check warning on line 738 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L738

Added line #L738 was not covered by tests
LoniValue(
ok_value=ok_value,
blocked=blocked.to_dict(),
down=down.to_dict(),
LoNI(
ok_final=ok_value,
ok=ok,
blocked=blocked,
down=down,
blocking_scope=blocking_scope,
),
analysis_transcript,
Expand All @@ -750,21 +767,145 @@ def make_website_experiment_results(
target_domain_name = first_analysis.target_domain_name
target_detail = first_analysis.target_detail

Check warning on line 768 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L764-L768

Added lines #L764 - L768 were not covered by tests

loni_ok_value = 0
analysis_transcript_list = []
loni_list = []
loni_blocked_list = []
loni_down_list = []
loni_ok_list = []
for wa in web_analysis:
loni, analysis_transcript = calculate_web_loni(wa)
analysis_transcript_list.append(analysis_transcript)
loni_list.append(loni)
loni_blocked_list.append(loni.blocked)
loni_down_list.append(loni.down)
loni_ok_list.append(loni.ok)

Check warning on line 781 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L770-L781

Added lines #L770 - L781 were not covered by tests

final_blocked = OutcomeSpace()
final_down = OutcomeSpace()
final_ok = OutcomeSpace()
ok_value = 0
blocking_scope = None

Check warning on line 787 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L783-L787

Added lines #L783 - L787 were not covered by tests

# TODO(arturo): this section needs to be formalized and verified a bit more
# in depth. Currently it's just a prototype to start seeing how the data
# looks like.

loni_down_keys = []
loni_down_values = []
### FINAL DNS
max_dns_blocked = max(

Check warning on line 794 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L794

Added line #L794 was not covered by tests
map(lambda x: x.dns, loni_blocked_list), key=lambda d: d.value if d else 0
)
max_dns_down = max(

Check warning on line 797 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L797

Added line #L797 was not covered by tests
map(lambda x: x.dns, loni_down_list), key=lambda d: d.value if d else 0
)
min_dns_ok = min(

Check warning on line 800 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L800

Added line #L800 was not covered by tests
map(lambda x: x.dns, loni_ok_list), key=lambda d: d.value if d else 0
)
ok_value = min_dns_ok
final_ok.dns = OutcomeStatus(key="dns", value=min_dns_ok)
final_blocked.dns = OutcomeStatus(key=max_dns_blocked.key, value=max_dns_blocked)
final_down.dns = OutcomeStatus(

Check warning on line 806 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L803-L806

Added lines #L803 - L806 were not covered by tests
# TODO(arturo): this is overestimating blocking.
key=max_dns_down.key,
value=1 - (min_dns_ok + max_dns_blocked),
)
if max_dns_blocked.blocking_scope:
blocking_scope = max_dns_blocked.blocking_scope

Check warning on line 812 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L811-L812

Added lines #L811 - L812 were not covered by tests

loni_blocked_keys = []
loni_blocked_values = []
### FINAL TCP
max_tcp_blocked = max(

Check warning on line 815 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L815

Added line #L815 was not covered by tests
map(lambda x: x.tcp, loni_blocked_list), key=lambda d: d.value if d else 0
)
max_tcp_down = max(

Check warning on line 818 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L818

Added line #L818 was not covered by tests
map(lambda x: x.tcp, loni_down_list), key=lambda d: d.value if d else 0
)
min_tcp_ok = min(

Check warning on line 821 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L821

Added line #L821 was not covered by tests
map(lambda x: x.tcp, loni_ok_list), key=lambda d: d.value if d else 0
)
final_blocked.tcp = OutcomeStatus(

Check warning on line 824 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L824

Added line #L824 was not covered by tests
key=max_tcp_blocked.key, value=max_tcp_blocked.value * ok_value
)
final_down.tcp = OutcomeStatus(

Check warning on line 827 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L827

Added line #L827 was not covered by tests
key=max_tcp_down.value,
value=1 - (min_tcp_ok.value + max_tcp_blocked.value) * ok_value,
)
final_ok.tcp = OutcomeStatus(key="tcp", value=min_tcp_ok.value)

Check warning on line 831 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L831

Added line #L831 was not covered by tests

analysis_transcript = []
old_ok_value = ok_value
ok_value = 1 - (final_blocked.sum() + final_down.sum())
log.info(f"TCP done {old_ok_value} -> {ok_value}")

Check warning on line 835 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L833-L835

Added lines #L833 - L835 were not covered by tests

is_anomaly = None
is_confirmed = None
### FINAL TLS
max_tls_blocked = max(

Check warning on line 838 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L838

Added line #L838 was not covered by tests
map(lambda x: x.tls, loni_blocked_list), key=lambda d: d.value if d else 0
)
max_tls_down = max(

Check warning on line 841 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L841

Added line #L841 was not covered by tests
map(lambda x: x.tls, loni_down_list), key=lambda d: d.value if d else 0
)
min_tls_ok = min(

Check warning on line 844 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L844

Added line #L844 was not covered by tests
map(lambda x: x.tls, loni_ok_list), key=lambda d: d.value if d else 0
)
final_blocked.tls = OutcomeStatus(

Check warning on line 847 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L847

Added line #L847 was not covered by tests
key=max_tls_blocked.key, value=max_tls_blocked.value * ok_value
)
final_down.tls = OutcomeStatus(

Check warning on line 850 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L850

Added line #L850 was not covered by tests
key=max_tls_down.value,
value=1 - (min_tls_ok.value + max_tls_blocked.value) * ok_value,
)
final_ok.tls = OutcomeStatus(key="http", value=min_tls_ok.value)
old_ok_value = ok_value
ok_value = 1 - (final_blocked.sum() + final_down.sum())
log.info(f"TLS done {old_ok_value} -> {ok_value}")

Check warning on line 857 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L854-L857

Added lines #L854 - L857 were not covered by tests

for wa in web_analysis:
loni = calculate_web_loni(wa)
### FINAL HTTP
max_http_blocked = max(

Check warning on line 860 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L860

Added line #L860 was not covered by tests
map(lambda x: x.http, loni_blocked_list), key=lambda d: d.value if d else 0
)
max_http_down = max(

Check warning on line 863 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L863

Added line #L863 was not covered by tests
map(lambda x: x.http, loni_down_list), key=lambda d: d.value if d else 0
)
min_http_ok = min(

Check warning on line 866 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L866

Added line #L866 was not covered by tests
map(lambda x: x.http, loni_ok_list), key=lambda d: d.value if d else 0
)
final_blocked.http = OutcomeStatus(

Check warning on line 869 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L869

Added line #L869 was not covered by tests
key=max_http_blocked.key, value=max_http_blocked.value * ok_value
)
final_down.http = OutcomeStatus(

Check warning on line 872 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L872

Added line #L872 was not covered by tests
key=max_http_down.value,
value=1 - (min_http_ok.value + max_http_blocked.value) * ok_value,
)
final_ok.http = OutcomeStatus(key="http", value=min_http_ok.value)
if max_http_blocked.blocking_scope:
if blocking_scope is not None:
log.warning(f"overwriting blocking_scope key: {blocking_scope}")
blocking_scope = max_http_blocked.blocking_scope

Check warning on line 880 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L876-L880

Added lines #L876 - L880 were not covered by tests

old_ok_value = ok_value
ok_value = 1 - (final_blocked.sum() + final_down.sum())
log.info(f"HTTP done {old_ok_value} -> {ok_value}")

Check warning on line 884 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L882-L884

Added lines #L882 - L884 were not covered by tests

final_loni = LoNI(

Check warning on line 886 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L886

Added line #L886 was not covered by tests
ok_final=ok_value,
ok=final_ok,
down=final_down,
blocked=final_blocked,
blocking_scope=blocking_scope,
)

loni_ok_value = final_loni.ok_final

Check warning on line 894 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L894

Added line #L894 was not covered by tests

loni_down = final_loni.down.to_dict()
loni_down_keys, loni_down_values = list(loni_down.keys()), list(loni_down.values())

Check warning on line 897 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L896-L897

Added lines #L896 - L897 were not covered by tests

loni_blocked = final_loni.down.to_dict()
loni_blocked_keys, loni_blocked_values = list(loni_blocked.keys()), list(

Check warning on line 900 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L899-L900

Added lines #L899 - L900 were not covered by tests
loni_blocked.values()
)

loni_ok = final_loni.ok.to_dict()
loni_ok_keys, loni_ok_values = list(loni_ok.keys()), list(loni_ok.values())

Check warning on line 905 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L904-L905

Added lines #L904 - L905 were not covered by tests

is_anomaly = loni_ok_value < 0.6
is_confirmed = final_loni.blocked.sum() > 0.9

Check warning on line 908 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L907-L908

Added lines #L907 - L908 were not covered by tests

er = ExperimentResultInstant(

Check warning on line 910 in oonidata/analysis/website_experiment_results.py

View check run for this annotation

Codecov / codecov/patch

oonidata/analysis/website_experiment_results.py#L910

Added line #L910 was not covered by tests
experiment_result_id=experiment_result_id,
Expand Down Expand Up @@ -792,7 +933,9 @@ def make_website_experiment_results(
loni_down_values=loni_down_values,
loni_blocked_keys=loni_blocked_keys,
loni_blocked_values=loni_blocked_values,
analysis_transcript=analysis_transcript,
loni_ok_keys=loni_ok_keys,
loni_ok_values=loni_ok_values,
analysis_transcript_list=analysis_transcript_list,
measurement_count=1,
observation_count=len(web_analysis),
vp_count=1,
Expand Down
5 changes: 4 additions & 1 deletion oonidata/models/experiment_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,12 @@ class ExperimentResultInstant:
loni_blocked_keys: List[str]
loni_blocked_values: List[float]

loni_ok_keys: List[str]
loni_ok_values: List[float]

# Inside this string we include a representation of the logic that lead us
# to produce the above loni values
analysis_transcript: Optional[List[str]]
analysis_transcript_list: Optional[List[List[str]]]

# Number of measurements used to produce this experiment result
measurement_count: int
Expand Down

0 comments on commit 54df5a5

Please sign in to comment.