diff --git a/api/debian/changelog b/api/debian/changelog index a13f205a..c8a58722 100644 --- a/api/debian/changelog +++ b/api/debian/changelog @@ -1,3 +1,9 @@ +ooni-api (1.0.89) unstable; urgency=medium + + * Start preparing for WebConnectivity v0.4 vs v0.5 A/B testing + + -- Simone Basso Tue, 20 Feb 2024 10:34:00 +0100 + ooni-api (1.0.88) unstable; urgency=medium * Add more logging diff --git a/api/ooniapi/probe_services.py b/api/ooniapi/probe_services.py index 49f1a3be..a5aa02b1 100644 --- a/api/ooniapi/probe_services.py +++ b/api/ooniapi/probe_services.py @@ -11,6 +11,7 @@ from urllib.request import urlopen import ipaddress import time +import os import ujson from flask import Blueprint, current_app, request, Response @@ -275,9 +276,15 @@ def check_in() -> Response: features={"torsf_enabled": True, "vanilla_tor_enabled": True} ) - # set webconnectivity_0.5 feature flag for some probes - octect = extract_probe_ipaddr_octect(1, 0) - if octect in (34, 239): + # WebConnectivity v0.4 vs v0.5 A/B testing. Try to avoid using the new version of + # the experiment in Cambodia and Belarus where there are upcoming elections. + # + # See https://github.com/ooni/probe/issues/2555#issuecomment-1906097413. + if ( + probe_cc not in ("BY", "KH") and + software_name == "ooniprobe-android-unattended" and + software_version == "3.8.6" + ): conf["features"]["webconnectivity_0.5"] = True conf["test_helpers"] = generate_test_helpers_conf() diff --git a/api/tests/integ/test_probe_services_nodb.py b/api/tests/integ/test_probe_services_nodb.py index c159660f..d772e9ab 100644 --- a/api/tests/integ/test_probe_services_nodb.py +++ b/api/tests/integ/test_probe_services_nodb.py @@ -246,6 +246,56 @@ def test_check_in_geoip(client, mocks): assert c["probe_network_name"] is not None +# See https://github.com/ooni/probe/issues/2555 for context. Delete when the A/B testing is done. +def test_check_in_abtesting_2555(client, mocks): + testcases = [{ + "name": "when the country is KH and the software name and version would match", + "inputs": { + "probe_cc": "KH", + "software_name": "ooniprobe-android-unattended", + "software_version": "3.8.6", + }, + "expect": False, + }, { + "name": "when the country is BY and the software name and version would match", + "inputs": { + "probe_cc": "BY", + "software_name": "ooniprobe-android-unattended", + "software_version": "3.8.6", + }, + "expect": False, + }, { + "name": "when the country is neither BY nor KH with unexpected software_name", + "inputs": { + "probe_cc": "IT", + "software_name": "ooniprobe-android", + "software_version": "3.8.6", + }, + "expect": False, + }, { + "name": "when the country is neither BY nor KH with unexpected software_version", + "inputs": { + "probe_cc": "IT", + "software_name": "ooniprobe-android-unattended", + "software_version": "3.8.4", + }, + "expect": False, + }, { + "name": "when the country is neither BY nor KH with correct software_version and software_version", + "inputs": { + "probe_cc": "IT", + "software_name": "ooniprobe-android-unattended", + "software_version": "3.8.6", + }, + "expect": True, + }] + for tc in testcases: + print("running", tc["name"]) + j = tc["inputs"] + c = client.post("/api/v1/check-in", json=j).json + assert c.get("conf", {}).get("features", {}).get("webconnectivity_0.5", False) == tc["expect"] + + # # Test /api/v1/collectors