def test_send_to_non_existent_node(self): """ Fail gracefully if there is nowhere to route the message """ message = Message('foo', 1) message.route(self.ucla) assert message.route_nodes == None, message.route_nodes
def test_send_back_from_non_peer(self): """Test send back from non peer""" message = Message('ucla', 1) self.sri.add_link(Link(self.ucla, 1)) self.utah.add_link(Link(self.sri, 1)) message.send(self.utah) assert message.location().name == 'ucla', message.location
def test_keep_messages_on_host(self): """ If a node is a host rather than an IMP then we want the message lights to stay on once the message has arrived """ m = Message('sri', 1) m2 = Message('sri', 1) m3 = Message('sri', 1) m4 = Message('sri', 1) self.sri_host.add_message(m) self.sri_host.process() self.sri_host.process() assert self.sri_host.buffer_contents(0) == [ None, None, m ], self.sri_host.buffer_contents(0) self.sri_host.add_message(m2) self.sri_host.process() assert self.sri_host.buffer_contents(0) == [ None, m2, m ], self.sri_host.buffer_contents(0) self.sri_host.add_message(m3) assert self.sri_host.buffer_contents(0) == [ m3, m2, m ], self.sri_host.buffer_contents(0) self.sri_host.process() self.sri_host.add_message(m4) assert self.sri_host.buffer_contents(0) == [ m4, m3, m2 ], self.sri_host.buffer_contents(0)
def test_send_with_two_routes(self): """Test send with two routes""" ucsb = Node('ucsb') self.ucla.add_link(Link(ucsb, 1)) ucsb.add_link(Link(self.sri, 1)) message = Message('utah', 1) message.send(self.ucla) assert message.location().name == 'utah', message.location
def test_send_by_least_busy_route(self): """Test send by least busy route""" ucsb = Node('ucsb') self.ucla.add_link(Link(ucsb, 1)) ucsb.add_link(Link(self.sri, 1)) self.ucla.links['sri'].weight = 10 message = Message('utah', 1) message.send(self.ucla) assert message.route_nodes == [self.utah, self.sri, ucsb, self.ucla]
def test_combine_both_buffers_in_display(self): """ The display should show messages travelling in both directions """ display = MagicMock() self.ucla.display = display message = Message('utah', 1) self.ucla.add_message(message) message_2 = Message('utah', 2) self.ucla.add_message(message_2, 1) self.ucla.display.update.assert_called_with('ucla', [1, None, 2])
def test_get_messages(self): messages = [Message('foo', 1), Message('foo', 2), Message('foo', 3)] self.ucla.add_message(messages[0]) self.ucla.add_message(messages[1], 1) self.ucla.process() self.ucla.add_message(messages[2]) for message in self.ucla.messages(): assert message in messages assert messages[0] in self.ucla.messages(0) assert messages[1] in self.ucla.messages(1)
def test_add_message_to_buffer_when_full(self): """ Adding a message to the buffer when it is full will fail Want some way of showing this so we can update the display accordingly - e.g. turn the LEDs red. Sending node can then decide to route the message a different way. """ message = Message('ucla', 1) message.route(self.ucla) assert self.ucla.add_message(message) == True assert self.ucla.add_message(message) == False
def test_move_message_through_buffer(self): """ A message moves from left to right through the buffer as messages to its right are processed. """ message = Message('utah', 1) self.ucla.add_message(message) message_2 = Message('utah', 2) self.ucla.add_message(message_2, 1) self.ucla.process() assert self.ucla.buffer_contents(0) == [None, message, None ], self.ucla.buffer_contents(0) assert self.ucla.buffer_contents(1) == [None, message_2, None ], self.ucla.buffer_contents(1)
def test_ascii_version_of_node(self): """ To make it easier to inspect the network we want to be able to see what the contents of each node's buffers is """ self.ucla.add_message(Message('foo', 1)) assert self.ucla.ascii_art() == "[1--][---]", self.ucla.ascii_art()
def test_message_gets_sent_when_leaves_buffer(self): """ When a message gets to the end of the buffer it should be sent to the next node on its route Unless this is the last node on the route... """ self.ucla.add_link(Link(self.sri, 0)) message = Message('sri', 1) message.route(self.ucla) self.sri.add_message = MagicMock() self.ucla.add_message(message) for _ in range(self.ucla.buffer_length): self.ucla.process() assert self.sri.add_message.call_count == 1 assert self.ucla.buffer_contents(0) == [None, None, None ], self.ucla.buffer_contents(0)
def test_add_message_to_buffer(self): """ Add a message to the three slot buffer on the node. The slots correspond to LEDS on the IMP models. """ message = Message('utah', 1) self.ucla.add_message(message) assert self.ucla.buffer_contents(0) == [message, None, None ], self.ucla.buffer_contents(0)
def test_process_messages(): net = Network([{ 'from': 'ucla', 'to': 'sri', 'weight': 1, 'r2l': False, 'bidirectional': True }, { 'from': 'ucsb', 'to': 'sri', 'weight': 1, 'r2l': False, 'bidirectional': True }]) net.nodes['ucla'].add_message(Message('sri', 1)) net.nodes['ucsb'].add_message(Message('sri', 2)) for i in range(5): net.process() assert net.ascii_art( ) == 'ucla:[---][---] sri:[-21][---] ucsb:[---][---]', net.ascii_art()
def test_dont_go_round_in_circles(self): """ If there is a route back to the origin, check we don't end up going round in circles """ NODES = ['ucla', 'ucsb', 'sri', 'utah'] LINKS = [('ucla', 'sri', 1), ('ucla', 'ucsb', 1), ('ucsb', 'sri', 1), ('sri', 'utah', 1), ('utah', 'sri', 1), ('sri', 'ucsb', 1), ('sri', 'ucla', 1), ('ucsb', 'ucla', 1)] network = {} for node in NODES: network[node] = Node(node) for link in LINKS: network[link[0]].add_link(Link(network[link[1]], link[2])) message = Message('utah', 1) message.route(network['ucla']) assert message.route_nodes[0] == network['utah']
def test_add_message_to_rl_buffer(self): """ When we have messages going in opposite directions the effect is a bit meh if they always go right to left on the node. So I'm adding a second buffer for messages going the other way which can then be ORed together onto the LEDs. """ message = Message('utah', 1) self.ucla.add_message(message, 1) assert self.ucla.buffer_contents(1) == [message, None, None ], self.ucla.buffer_contents(1)
def test_ascii_art(): """ ASCII art representation of the network state """ net = Network([{ 'from': 'ucla', 'to': 'sri', 'weight': 1, 'r2l': False, 'bidirectional': True }, { 'from': 'ucsb', 'to': 'sri', 'weight': 1, 'r2l': False, 'bidirectional': True }]) net.nodes['ucla'].add_message(Message('sri', 1)) net.nodes['ucsb'].add_message(Message('sri', 1)) assert net.ascii_art( ) == 'ucla:[1--][---] sri:[---][---] ucsb:[1--][---]', net.ascii_art()
def test_link_to_rl_buffer(self): """ Links can indicate whether messages sent via them should be added to the right to left or the left to right buffer. """ message = Message('sri', 1) self.sri.add_message = MagicMock() self.ucla.add_link(Link(self.sri, 0, True)) self.ucla.add_message(message) for _ in range(self.ucla.buffer_length): self.ucla.process() self.sri.add_message.assert_called_with(message, 1)
def test_message_leaves_destination_node(self): """ Messages should be passed off (to the host?) once they reach their destination """ message = Message('ucla', 1) self.ucla.add_message(message) for _ in range(self.ucla.buffer_length): self.ucla.process() assert self.ucla.buffer_contents(0) == [None, None, None ], self.ucla.buffer_contents(0) assert message.route_nodes is not None
def test_step_message_along_route(self): """ In order to display the progress of a message on Blinkenlights etc we want to be able to move the message along the route a step (node/light) at a time updating the display as we go """ message = Message('utah', 1) message.route(self.ucla) message.step() location = message.location() assert location.name == 'sri'
def test_process_message(): """ So that the lights representing messages appear to move one light at a time we don't want them to get processed twice in one go. e.g. if a message bound for utah is on ucla [_ _ M] and it gets processed off to sri [M _ _] if ucla is does its processing before sri then when it's sri's turn then it will move again [_ M _] and the message will appear to have jumped two steps and not one """ net = Network([{ 'from': 'ucla', 'to': 'sri', 'weight': 1, 'r2l': False, 'bidirectional': True }]) net.nodes['ucla'].add_message(Message('sri', 1)) for i in range(5): net.process() assert net.nodes['sri'].ascii_art( ) == '[--1][---]', net.nodes['sri'].ascii_art()
def test_ascii_representation_of_message(self): message = Message('utah', 1) assert message.ascii_art() == '1'
'r2l': False, 'bidirectional': True }, { 'from': 'sri', 'to': 'utah', 'weight': 1, 'r2l': False, 'bidirectional': True }], TRANS) NETWORK.nodes['sds'].host = True input("Send L") input("Are you sure?") M = Message('sds', 5) NETWORK.nodes['sig7'].add_message(M) sleep(.4) for i in range(4): print(i) NETWORK.process() sleep(.4) NETWORK.process() sleep(.4) NETWORK.process() sleep(.4) input("Send O") input("Are you sure?") M = Message('sds', 5)
def test_send_message_to_origin(self): """Test a node can send a message to itself""" message = Message('ucla', 1) message.send(self.ucla) assert message.location().name == 'ucla', message.location
def test_send_message_to_non_peer(self): """Test send message to non peer""" message = Message('utah', 1) message.send(self.ucla) assert message.location().name == 'utah', message.location
def test_send_message_to_peer(self): """Test send message to peer""" message = Message('sri', 1) message.send(self.ucla) assert message.location().name == 'sri', message.location