コード例 #1
0
def test_observation_granularity():
    ct = ContactTracer(start_time=START_TIME)
    t1 = START_TIME + timedelta(minutes=20)
    t2 = START_TIME + timedelta(hours=6)
    ct.add_observation(EPHID1, t1)
    ct.add_observation(EPHID2, t2)

    # Verify that internal representation has batch granularity
    for time in ct.observations:
        assert time % SECONDS_PER_BATCH == 0
コード例 #2
0
def test_observation_granularity_after_update():
    ct = ContactTracer(start_time=START_TIME)
    t1 = START_TIME + timedelta(minutes=20)
    t2 = START_TIME + timedelta(hours=6)
    t3 = START_TIME + timedelta(days=1, hours=6)
    ct.add_observation(EPHID1, t1)
    ct.add_observation(EPHID2, t2)
    ct.next_day()
    ct.add_observation(EPHID2, t3)

    t4 = int((START_TIME + timedelta(days=1, hours=10)).timestamp())
    release_time = (t4 // SECONDS_PER_BATCH) * SECONDS_PER_BATCH
    batch = TracingDataBatch([], release_time=release_time)
    ct.housekeeping_after_batch(batch)

    # All observations should now be at day granularity
    for time in ct.observations:
        assert time % config.SECONDS_PER_DAY == 0
コード例 #3
0
def test_contact_tracing_retention():
    ct = ContactTracer(start_time=START_TIME)
    t1 = START_TIME + timedelta(minutes=20)
    t2 = START_TIME + timedelta(hours=6)
    ct.add_observation(EPHID1, t1)
    ct.add_observation(EPHID2, t2)
    recorded_times = ct.observations.keys()

    for _ in range(config.RETENTION_PERIOD + 1):
        ct.next_day()

    for time in recorded_times:
        assert time not in ct.observations
コード例 #4
0
def test_deleting_old_keys():
    ct = ContactTracer(start_time=START_TIME)
    ct.next_day()
    ct.next_day()

    assert len(ct.past_keys) > 0

    old_day_key = ct.current_day_key
    old_ephids = set(ct.current_ephids)

    # Get with side-effects: deleting old keys
    ct.get_tracing_information(START_TIME)

    # Should delete all old keys
    assert len(ct.past_keys) == 0

    # Should pick a new day key
    assert ct.current_day_key != old_day_key

    # And all EphIDs should have been regenerated
    assert len(set(ct.current_ephids).intersection(old_ephids)) == 0
コード例 #5
0
def main():
    alice = ContactTracer()
    bob = ContactTracer()

    ### Interaction ###

    process_single_day(alice, bob)
    process_single_day(alice, bob)

    # Compute interaction time and process another day
    interaction_time = datetime.fromtimestamp(alice.start_of_today)
    interaction_time += timedelta(hours=10)
    process_single_day(alice, bob, interaction_time)

    print("... skipping 3 days ...\n")
    for _ in range(4):
        alice.next_day()
        bob.next_day()

    ### Diagnosis and reporting ###

    report_day(alice.start_of_today)
    print("Bob is diagnosed with SARS-CoV-2")
    bob_contagious_start = datetime.fromtimestamp(bob.start_of_today - 7 * 86400)
    print(
        "Doctor establishes that Bob started being contagious at {}".format(
            bob_contagious_start
        )
    )

    print("\n[Bob -> Server] Bob sends:")
    tracing_info_bob = bob.get_tracing_information(bob_contagious_start)
    bob_contagious_start_epoch, bob_contagious_key = tracing_info_bob
    print(" * his key on {}: {}".format(bob_contagious_start, bob_contagious_key.hex()))
    print(
        " * the corresponding start time in epoch-seconds: {}\n".format(
            bob_contagious_start_epoch
        )
    )

    ### Contact tracing ###

    print("[Server] Compiles download batch\n")
    release_time = bob.start_of_today + 4 * SECONDS_PER_BATCH
    batch = TracingDataBatch([tracing_info_bob], release_time=release_time)

    print("[Server -> Alice] Alice receives batch")
    print("  * Alice checks if she was in contact with an infected person")

    if alice.matches_with_batch(batch) > 0:
        print("  * CORRECT: Alice's phone concludes she is at risk")
    else:
        print("  * ERROR: Alice's phone does not conclude she is at risk")

    print("\n[Alice] Runs housekeeping to update her observation store")
    alice.housekeeping_after_batch(batch)