def test__does_not_remove_fresh_entries(self): uuid_now = str(uuid1()) queue = OrderedDict() queue[uuid_now] = {} self.assertThat(queue, HasLength(1)) age_out_uuid_queue(queue) self.assertThat(queue, HasLength(1))
def test__removes_entries_from_the_distant_past(self): uuid_from_the_past = '00000000-0000-1000-aaaa-aaaaaaaaaaaa' queue = OrderedDict() queue[uuid_from_the_past] = {} self.assertThat(queue, HasLength(1)) age_out_uuid_queue(queue) self.assertThat(queue, HasLength(0))
def test__removes_entries_from_the_far_future(self): uuid_from_the_future = "ffffffff-ffff-1fff-0000-000000000000" queue = OrderedDict() queue[uuid_from_the_future] = {} self.assertThat(queue, HasLength(1)) age_out_uuid_queue(queue) self.assertThat(queue, HasLength(0))
def test__removes_entries_from_the_future(self): uuid_from_the_future = factory.make_UUID_with_timestamp(time.time() + 123.0) queue = OrderedDict() queue[uuid_from_the_future] = {} self.assertThat(queue, HasLength(1)) age_out_uuid_queue(queue) self.assertThat(queue, HasLength(0))
def test__keeps_entries_from_the_reasonable_past(self): uuid_from_the_past = factory.make_UUID_with_timestamp(time.time() - 60.0) queue = OrderedDict() queue[uuid_from_the_past] = {} self.assertThat(queue, HasLength(1)) age_out_uuid_queue(queue) self.assertThat(queue, HasLength(1))
def remember_beacon_and_check_duplicate(self, rx_uuid, beacon_json): """Records an incoming beacon based on its UUID and JSON. Organizes incoming beacons in the `rx_queue` by creating a list of beacons received [on different interfaces] per UUID. :param rx_uuid: The UUID of the incoming beacon. :param beacon_json: The incoming beacon (in JSON format). :return: True if the beacon was a duplicate, otherwise False. """ duplicate_received = False # Need to age out before doing anything else; we don't want to match # a duplicate packet and then delete it immediately after. age_out_uuid_queue(self.rx_queue) rx_packets_for_uuid = self.rx_queue.get(rx_uuid, []) if len(rx_packets_for_uuid) > 0: duplicate_received = True rx_packets_for_uuid.append(beacon_json) self.rx_queue[rx_uuid] = rx_packets_for_uuid return duplicate_received
def send_beacon(self, beacon, destination_address): """Send a beacon to the specified destination. :param beacon: The `BeaconPayload` namedtuple to send. Must have a `payload` ivar containing a 'uuid' element. :param destination_address: The UDP/IP (destination, port) tuple. IPv4 addresses must be in IPv4-mapped IPv6 format. :return: True if the beacon was sent, False otherwise. """ try: self.transport.write(beacon.bytes, destination_address) # If the packet cannot be sent for whatever reason, OSError will # be raised, and we won't record sending a beacon we didn't # actually send. self.tx_queue[beacon.payload['uuid']] = beacon age_out_uuid_queue(self.tx_queue) return True except OSError as e: if self.debug is True: log.msg("Error while sending beacon to %r: %s" % (destination_address, e)) return False