def test_cluster_eventual_same_risk_functional(self): """ scenario: single encounter that gets updated (should remain at one cluster), add a new encounter: it should not match the existing cluster due to diff risk """ encounter_tick_a = encounter_tick_b = 0 encounter_risk_level_a = update_risk_level_b = 7 encounter_risk_level_b = 1 update_tick_b = 1 assert encounter_tick_a <= self.max_tick assert encounter_tick_b <= update_tick_b <= self.max_tick o_a = ObservedRisk(encounter_tick=encounter_tick_a, encounter_risk_level=encounter_risk_level_a) o_b = ObservedRisk(encounter_tick=encounter_tick_b, encounter_risk_level=encounter_risk_level_b).update( update_tick=update_tick_b, update_risk_level=update_risk_level_b) self.message_context.insert_messages(observed_risks=o_a) self.message_context.insert_messages(observed_risks=o_b) cluster_manager = clu.SimplisticClusterManager( max_history_offset=self.message_context.max_history_offset) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), 2) self.assertEqual(cluster_manager.clusters[0].risk_level, encounter_risk_level_a)
def test_cluster_cleanup_outdated_functional(self): """ scenario: a new encounter is added that is waaay outdated; it should not create a cluster new manually added encounters that are outdated should also be ignored """ encounter_tick_a = 0 encounter_risk_level_a = 7 update_tick_a = 1 update_risk_level_a = 9 encounter_tick_b = 13 max_tick_day_offset = 3 encounter_risk_level_b = 15 assert encounter_tick_a <= update_tick_a < \ encounter_tick_b - max_tick_day_offset <= self.max_tick o_a = ObservedRisk(encounter_tick=encounter_tick_a, encounter_risk_level=encounter_risk_level_a).update( update_tick=update_tick_a, update_risk_level=update_risk_level_a) o_b = ObservedRisk(encounter_tick=encounter_tick_b, encounter_risk_level=encounter_risk_level_b) self.message_context.insert_messages(observed_risks=o_a) self.message_context.insert_messages(observed_risks=o_b) cluster_manager = clu.SimplisticClusterManager( max_history_offset=ObservedRisk.time_offset * max_tick_day_offset) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), 1) self.assertEqual(cluster_manager.clusters[0].risk_level, encounter_risk_level_b)
def test_same_day_visit_clusters_overlap(self): """ scenario: single day visits, and some visits will share the same cluster """ n_risk = 3 n_human = 5 encounter_tick = 0 encounter_risk_level = 7 assert n_human >= n_risk >= 1 assert encounter_tick <= self.max_tick # we will cheat and hard-code some initial 4-bit uids to make sure there is overlap for idx in range(n_human): self.message_context.insert_messages( ObservedRisk(encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level), tick_to_uid_map={encounter_tick: idx % n_risk}, ) cluster_manager = clu.SimplisticClusterManager( max_history_offset=self.message_context.max_history_offset, generate_backw_compat_embeddings=True, ) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), n_risk) self.assertEqual(cluster_manager.latest_refresh_timestamp, ObservedRisk.toff(encounter_tick)) expositions = cluster_manager._get_expositions_array() self.assertTrue(len(expositions) == n_risk and sum(expositions) == 0) embeddings = cluster_manager.get_embeddings_array() self.assertTrue( (embeddings[:, 1] == encounter_risk_level).all()) # risk level self.assertTrue((embeddings[:, 2] > 0).all() and (embeddings[:, 2] < n_risk).all()) # timestamp offset self.assertTrue((embeddings[:, 3] == encounter_tick).all())
def test_same_day_visit_clusters(self): """ single day visits, same risk for n visitors, should give one cluster """ n_human = 3 encounter_tick = 2 encounter_risk_level = 1 assert encounter_tick <= self.max_tick for idx in range(n_human): self.message_context.insert_messages( ObservedRisk(encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level), tick_to_uid_map={encounter_tick: idx}, ) cluster_manager = clu.SimplisticClusterManager( max_history_offset=self.message_context.max_history_offset, generate_backw_compat_embeddings=True, ) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(self.message_context.contact_messages), n_human) # three timesteps in book self.assertEqual(len(cluster_manager.clusters), n_human) self.assertEqual(cluster_manager.latest_refresh_timestamp, ObservedRisk.toff(encounter_tick)) expositions = cluster_manager._get_expositions_array() self.assertEqual(sum(expositions), 0) embeddings = cluster_manager.get_embeddings_array() self.assertEqual(len(embeddings), n_human) self.assertTrue( (embeddings[:, 1] == encounter_risk_level).all()) # risk level # message count self.assertTrue((sum(embeddings[:, 2]) == n_human).all()) self.assertTrue((embeddings[:, 3] == 0).all()) # timestamp offset
def test_cluster_same_risk_repeated_contact_functional(self): """ scenario: a same user with unchanging risk making a couple of contacts over days. With the message cluster expiring messages with older ticks than max_tick_day_offset, the remaining messages each constitute a distinct cluster """ encounter_ticks = [2, 5, 8] max_tick_day_offset = 5 encounter_risk_level = 0 assert all(t <= self.max_tick for t in encounter_ticks) o = [ ObservedRisk(encounter_tick=tick, encounter_risk_level=encounter_risk_level) for tick in encounter_ticks ] self.message_context.insert_messages(observed_risks=o) cluster_manager = clu.SimplisticClusterManager( max_history_offset=ObservedRisk.time_offset * max_tick_day_offset) cluster_manager.add_messages(self.message_context.contact_messages) cutoff_day = max(encounter_ticks) - max_tick_day_offset expected_ticks = { ObservedRisk.toff(t) for t in encounter_ticks if t >= cutoff_day } self.assertEqual(len(cluster_manager.clusters), len(expected_ticks)) clustered_first_update_time = \ {clu.first_update_time for clu in cluster_manager.clusters} self.assertEqual(clustered_first_update_time, expected_ticks)
def test_cluster_single_encounter_and_update_functional(self): """ functional test for SimplisticClusterManager, single encounter and update """ encounter_tick = 0 encounter_risk_level = 7 update_tick1 = 1 update_tick2 = 2 update_risk_level1 = 9 update_risk_level2 = 10 assert encounter_tick <= update_tick1 <= update_tick2 <= self.max_tick o = ObservedRisk( encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level ).update( # update_tick=update_tick1, # update_risk_level=update_risk_level1 # ).update( update_tick=update_tick2, update_risk_level=update_risk_level2) self.message_context.insert_messages(o) cluster_manager = clu.SimplisticClusterManager( max_history_offset=self.message_context.max_history_offset) print(self.message_context.contact_messages) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), 1) self.assertEqual(cluster_manager.clusters[0].risk_level, RiskLevelBoundsCheckedType(update_risk_level2))
def test_same_day_visit_diff_risk_clusters(self): """ 2nd scenario: single day visits, diff risk for n visitors, should give n cluster """ n_human = 3 encounter_tick = 0 assert encounter_tick <= self.max_tick assert n_human <= mu.risk_level_mask for idx in range(n_human): self.message_context.insert_messages( ObservedRisk(encounter_tick=encounter_tick, encounter_risk_level=idx), tick_to_uid_map={0: idx}, ) cluster_manager = clu.BlindClusterManager( max_history_offset=self.message_context.max_history_offset, generate_backw_compat_embeddings=True, ) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), n_human) self.assertEqual(cluster_manager.latest_refresh_timestamp, ObservedRisk.toff(encounter_tick)) expositions = cluster_manager._get_expositions_array() self.assertTrue(len(expositions) == n_human and sum(expositions) == 0) embeddings = cluster_manager.get_embeddings_array() self.assertEqual(len(embeddings), n_human) self.assertEqual(set(embeddings[:, 1]), set(range(n_human))) # risk level # message count self.assertTrue((sum(embeddings[:, 2]) == n_human).all()) self.assertTrue((embeddings[:, 3] == 0).all()) # timestamp offset
def test_same_day_visit_same_risk_clusters(self): """ first scenario: single day visits, same risk for n visitors, should give one cluster """ n_human = 3 encounter_tick = 2 encounter_risk_level = 1 assert encounter_tick <= self.max_tick for idx in range(n_human): self.message_context.insert_messages( ObservedRisk(encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level), tick_to_uid_map={0: idx}, ) cluster_manager = clu.BlindClusterManager( max_history_offset=self.message_context.max_history_offset, generate_backw_compat_embeddings=True, ) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), 1) self.assertEqual(cluster_manager.latest_refresh_timestamp, ObservedRisk.toff(encounter_tick)) embeddings = cluster_manager.get_embeddings_array() self.assertEqual(len(embeddings), 1) self.assertTrue( (embeddings[:, 1] == encounter_risk_level).all()) # risk level self.assertTrue((embeddings[:, 2] == n_human).all()) # message count self.assertTrue((embeddings[:, 3] == 0).all()) # timestamp offset
def test_cluster_single_encounter_functional(self): """ functional test for SimplisticClusterManager, single encounter """ encounter_tick = 0 encounter_risk_level = 7 assert encounter_tick <= self.max_tick o = ObservedRisk(encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level) self.message_context.insert_messages(o) cluster_manager = clu.SimplisticClusterManager( max_history_offset=self.message_context.max_history_offset) cluster_manager.add_messages(self.message_context.contact_messages) self.assertEqual(len(cluster_manager.clusters), 1) self.assertEqual(cluster_manager.clusters[0].risk_level, encounter_risk_level)
def test_insert_messages_smoke_test(self): # test arguments encounter_tick = 0 tick_to_uid_map = {encounter_tick: 10} encounter_risk_level = 14 update_tick = 30 update_risk_level = 3 # record an encounter observation and append an update on it o = ObservedRisk( encounter_tick=encounter_tick, encounter_risk_level=encounter_risk_level ).update(update_tick=update_tick, update_risk_level=update_risk_level) # compile the previous object into message history self.message_context.insert_messages( observed_risks=o, tick_to_uid_map=tick_to_uid_map ) encounter_time = ObservedRisk.start_time update_time = ObservedRisk.toff(update_tick) # define expected messages expected_update_message = mu.UpdateMessage( uid=tick_to_uid_map[encounter_tick], encounter_time=encounter_time, update_time=update_time, old_risk_level=encounter_risk_level, new_risk_level=update_risk_level, _real_encounter_time=encounter_time, _real_update_time=update_time, _sender_uid=0, _exposition_event=False, ) expected_encounter_message = mu.EncounterMessage( uid=tick_to_uid_map[encounter_tick], encounter_time=encounter_time, risk_level=encounter_risk_level, _real_encounter_time=encounter_time, _sender_uid=0, _exposition_event=False, ) self.assertEqual(self.message_context.contact_messages, [expected_encounter_message, expected_update_message])