class TestRIPService1(unittest.TestCase): def setUp(self): self.lm1 = RouterLinkManager() self.dt1 = DatagramRouter( router_name=1, link_manager=self.lm1) self.sm1 = RouterServiceManager(self.dt1) self.rip_st1 = self.sm1.register_service(RIPService.protocol) self.rs1 = RIPService(1, self.lm1, self.rip_st1, update_period=0.3, inf_timeout=0.6, remove_timeout=1) def test_dynamic_routing(self): self.dt1.set_routing_table(self.rs1.dynamic_routing_table()) time.sleep(5) def test_dynamic_routing_transfer(self): self.dt1.set_routing_table(self.rs1.dynamic_routing_table()) #time.sleep(0.5) s10 = self.sm1.register_service(10) s15 = self.sm1.register_service(15) unreach_p10 = Packet(1, 2, "unreachable test (10)") s10.send(unreach_p10) p10_1 = Packet(1, 1, "test (10)") s10.send(p10_1) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s10.receive(block=False), None) p15_1 = Packet(1, 1, "test (15)") p10_2 = Packet(1, 1, "test 2 (10)") s10.send(p10_1) s15.send(p15_1) s10.send(p10_2) self.assertEqual(s15.receive(), p15_1) self.assertEqual(s15.receive(block=False), None) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s10.receive(), p10_2) self.assertEqual(s10.receive(block=False), None) text = "".join(map(chr, xrange(256))) p15_2 = Packet(1, 1, text * 10) s15.send(p15_2) s10.send(p10_1) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s15.receive(), p15_2) def tearDown(self): self.rs1.terminate() self.sm1.terminate() self.dt1.terminate()
class TestRIPServiceBasic(unittest.TestCase): def setUp(self): self.lm1 = RouterLinkManager() self.dt1 = DatagramRouter( router_name=1, link_manager=self.lm1) self.sm1 = RouterServiceManager(self.dt1) self.rip_st1 = self.sm1.register_service(RIPService.protocol) def test_constructor(self): rs1 = RIPService(1, self.lm1, self.rip_st1) rs1.terminate() def test_main(self): rs1 = RIPService(1, self.lm1, self.rip_st1) self.assertEqual(rs1.dynamic_routing_table().next_router(1), 1) self.assertEqual(rs1.dynamic_routing_table().next_router(2), None) rs1.terminate() def tearDown(self): self.sm1.terminate() self.dt1.terminate()
class TestRouterServiceManager1(unittest.TestCase): def setUp(self): self.lm1 = RouterLinkManager() self.dt1 = DatagramRouter( router_name=1, link_manager=self.lm1) self.sm1 = RouterServiceManager(self.dt1) def test_send_receive_data(self): self.s30 = self.sm1.register_service(30) text = "Some text text." self.s30.send_data(1, text) self.assertEqual(self.s30.receive_data(), (1, text)) self.assertEqual(self.s30.receive_data(False), None) def test_main(self): s10 = self.sm1.register_service(10) s15 = self.sm1.register_service(15) unreach_p10 = Packet(1, 2, "unreachable test (10)", 1) s10.send(unreach_p10) p10_1 = Packet(1, 1, "test (10)", 1) s10.send(p10_1) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s10.receive(block=False), None) p15_1 = Packet(1, 1, "test (15)", 1) p10_2 = Packet(1, 1, "test 2 (10)", 1) s10.send(p10_1) s15.send(p15_1) s10.send(p10_2) self.assertEqual(s15.receive(), p15_1) self.assertEqual(s15.receive(block=False), None) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s10.receive(), p10_2) self.assertEqual(s10.receive(block=False), None) text = "".join(map(chr, xrange(256))) p15_2 = Packet(1, 1, text * 10, 1) s15.send(p15_2) s10.send(p10_1) self.assertEqual(s10.receive(), p10_1) self.assertEqual(s15.receive(), p15_2) def tearDown(self): self.sm1.terminate() self.dt1.terminate()
class TestRouterServiceManagerBasic(unittest.TestCase): def setUp(self): self.lm1 = RouterLinkManager() self.dt1 = DatagramRouter( router_name=1, link_manager=self.lm1) def test_constructor(self): sm = RouterServiceManager(self.dt1) sm.terminate() def test_main(self): sm = RouterServiceManager(self.dt1) s10 = sm.register_service(10) sm.terminate() def tearDown(self): self.dt1.terminate()
class Router(object): def __init__(self, name): super(Router, self).__init__() assert router_name.is_valid(name) self._name = name self._link_manager = RouterLinkManager() self._datagram_router = DatagramRouter( router_name=self._name, link_manager=self._link_manager) self._service_manager = RouterServiceManager(self._datagram_router) self._rip_service_transmitter = \ self._service_manager.register_service(RIPService.protocol) self._rip_service = RIPService(self._name, self._link_manager, self._rip_service_transmitter) self._datagram_router.set_routing_table( self._rip_service.dynamic_routing_table()) # TODO def terminate(self): self._rip_service.terminate() self._service_manager.terminate() self._datagram_router.terminate() @property def name(self): return self._name @property def link_manager(self): return self._link_manager
class RouterItem(QGraphicsObject): def __init__(self, name, parent=None, enabled=True): super(RouterItem, self).__init__(parent) assert router_name.is_valid(name) self.name = name # TODO: Use @property self._logger = logging.getLogger("RouterItem.router={0}".format(self.name)) self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setZValue(1) # Circle color. self.color = palette.palette[self.name] # Circle radius. self.radius = 5.0 # Circle (width, height). self.size = QSizeF(2 * self.radius, 2 * self.radius) self.size_rect = QRectF(QPointF(-self.size.width() / 2.0, -self.size.height() / 2.0), self.size) self._last_paint_bounding_rect = QRectF(self.size_rect) # connected router -> link to it self._links = {} # packet -> protocol # self._packets_for_delivery = {} self._link_manager = RouterLinkManager() self._datagram_router = None self._service_manager = None self._rip_service_transmitter = None self._rip_service = None self.velocity = QPointF() self.max_mouse_move_velocity = 100 self._drag_points = deque(maxlen=10) self._enabled = False self.hide() self._start_networking() self.enabled = enabled update_rate = 20 # frames per second self._timer_id = self.startTimer(int(1000.0 / update_rate)) # self.destroyed.connect(self.on_destroy) # @pyqtSlot() # def on_destroy(self): # # FIXME: never called. # self._logger.info("{0}.on_destroy()".format(self)) # # self._stop_networking() def __del__(self): # super(RouterItem, self).__del__() print self, ".__del__()" # DEBUG self._stop_networking() @property def enabled(self): return self._enabled @enabled.setter def enabled(self, value): if self._enabled != bool(value): self._enabled = bool(value) if self._enabled: # Link up. self._router_up() else: # Link down. self._router_down() def _router_up(self): self.show() def _router_down(self): self.hide() def _start_networking(self): self._logger.info("{0}._start_networking()".format(self)) self._datagram_router = DatagramRouter(router_name=self.name, link_manager=self._link_manager) self._service_manager = RouterServiceManager(self._datagram_router) self._rip_service_transmitter = self._service_manager.register_service(RIPService.protocol) self._rip_service = RIPService(self.name, self._link_manager, self._rip_service_transmitter) self._datagram_router.set_routing_table(self._rip_service.dynamic_routing_table()) def _stop_networking(self): self._logger.info("{0}._stop_networking()".format(self)) self._rip_service.terminate() self._service_manager.terminate() self._datagram_router.terminate() self._datagram_router = None self._service_manager = None self._rip_service_transmitter = None self._rip_service = None @property def links(self): return self._links @property def link_manager(self): return self._link_manager @property def rip_service(self): return self._rip_service def link_to_router(self, name): for router, link in self._links.items(): if router.name == name: return link return None def boundingRect(self): adjust = 2 rect = QRectF(self._last_paint_bounding_rect) if config.display_router_connection_range: rect = rect.united( QRectF( -config.disconnection_distance, -config.disconnection_distance, config.disconnection_distance * 2, config.disconnection_distance * 2, ) ) return rect.adjusted(-adjust, -adjust, adjust, adjust) # TODO: Is circular shape really needed? def shape(self): path = QPainterPath() path.addEllipse(self.size_rect) return path def paint(self, painter, style_option, widget): painter.setPen(QPen(Qt.black, 0)) painter.setBrush(QBrush(self.color)) painter.drawEllipse(self.size_rect) self._last_paint_bounding_rect = QRectF(self.size_rect) if config.display_router_connection_range: painter.setPen(QPen(Qt.red, 0)) painter.setBrush(QBrush()) painter.drawEllipse(QPoint(), config.disconnection_distance, config.disconnection_distance) painter.setPen(QPen(Qt.green, 0)) painter.setBrush(QBrush()) painter.drawEllipse(QPoint(), config.connection_distance, config.connection_distance) self._last_paint_bounding_rect = self._last_paint_bounding_rect.united( QRectF( -config.disconnection_distance, -config.disconnection_distance, config.disconnection_distance * 2, config.disconnection_distance * 2, ) ) def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionHasChanged and self.scene(): self.adjust_links() # Value is the new position. pos = value.toPointF() pos_in_scene = self._return_to_scene(pos) if pos_in_scene != pos: # FIXME: Return value not respected in PyQt (this is a bug). self.setPos(pos_in_scene) return pos_in_scene return super(RouterItem, self).itemChange(change, value) def mousePressEvent(self, event): self._drag_points.clear() self.velocity = QPointF() # self._timer_id = self.startTimer(int(1000 / 10)) super(RouterItem, self).mousePressEvent(event) def mouseReleaseEvent(self, event): t = time.time() while self._drag_points and self._drag_points[0][0] + 0.1 < t: self._drag_points.popleft() if len(self._drag_points) >= 2: new_velocity = (self._drag_points[-1][1] - self._drag_points[0][1]) / ( self._drag_points[-1][0] - self._drag_points[0][0] ) l = QVector2D(new_velocity).length() if l > self.max_mouse_move_velocity: new_velocity *= self.max_mouse_move_velocity / l self.velocity = new_velocity super(RouterItem, self).mouseReleaseEvent(event) def mouseMoveEvent(self, event): self._drag_points.append((time.time(), event.scenePos())) super(RouterItem, self).mouseMoveEvent(event) def timerEvent(self, event): if not self.enabled: return # TODO if self._service_manager is None: return # for protocol, service_transmitter in \ # self._service_manager.services.items(): # while True: # try: # packet = service_transmitter.receive_queue.get(block=False) # except Queue.Empty: # break # # self._packets_for_delivery[packet] = protocol # # link = self.link_to_router(packet.delivered_from) # link.transmit_packet(protocol, packet) # def deliver_packet(self, packet, is_failed): # if not is_failed: # protocol = self._packets_for_delivery[packet] # service_transmitter = self._service_manager.services[protocol] # service_transmitter.actual_receive_queue.put(packet) # # self._logger.debug( # "Delivered packet (waiting queue len is {0}):\n" # " {1}".format(len(self._packets_for_delivery), packet)) # else: # self._logger.debug( # "Packet not delivered (waiting queue len is {0}):\n" # " {1}".format(len(self._packets_for_delivery), packet)) # # del self._packets_for_delivery[packet] def _return_to_scene(self, pos): new_pos = QPointF(pos) scene_rect = self.scene().sceneRect() scene_rect.adjust(self.radius, self.radius, -self.radius, -self.radius) assert scene_rect.isValid() if not scene_rect.contains(new_pos): # Keep the item inside the scene rect. new_pos.setX(min(scene_rect.right(), max(new_pos.x(), scene_rect.left()))) new_pos.setY(min(scene_rect.bottom(), max(new_pos.y(), scene_rect.top()))) assert scene_rect.contains(new_pos) return new_pos def add_link(self, link): self._links[link.link_end(self)] = link def adjust_links(self): for dest, link in self._links.iteritems(): link.adjust() def advance(self, dt): new_pos = self.pos() + self.velocity * dt * config.router_velocity_factor new_pos_in_scene = self._return_to_scene(new_pos) if new_pos.x() != new_pos_in_scene.x(): self.velocity.setX(-self.velocity.x()) if new_pos.y() != new_pos_in_scene.y(): self.velocity.setY(-self.velocity.y()) if self.pos() != new_pos_in_scene: self.setPos(new_pos_in_scene) # Returns is something changed. return self.velocity != 0 and dt != 0 def distance(self, other_router): return QLineF(self.mapFromItem(self, 0, 0), self.mapFromItem(other_router, 0, 0)).length()
class _TestRouterServiceManager2WithLosses(unittest.TestCase): def setUp(self): l1, l2 = FullDuplexLink(loss_func=LossFunc(0.001, 0.001, 0.001)) sft1 = SimpleFrameTransmitter(node=l1) sft2 = SimpleFrameTransmitter(node=l2) self.ft1 = FrameTransmitter(simple_frame_transmitter=sft1, debug_src=1, debug_dest=2) self.ft2 = FrameTransmitter(simple_frame_transmitter=sft2, debug_src=2, debug_dest=1) rlm1 = RouterLinkManager() rlm2 = RouterLinkManager() self.dr1 = DatagramRouter( router_name=1, link_manager=rlm1, routing_table=LocalRoutingTable(1, rlm1)) self.dr2 = DatagramRouter( router_name=2, link_manager=rlm2, routing_table=LocalRoutingTable(2, rlm2)) rlm1.add_link(2, self.ft1) rlm2.add_link(1, self.ft2) self.sm1 = RouterServiceManager(self.dr1) self.sm2 = RouterServiceManager(self.dr2) def test_transmit(self): s1_77 = self.sm1.register_service(77) s2_77 = self.sm2.register_service(77) d12 = Packet(1, 2, "test") s1_77.send(d12) self.assertEqual(s2_77.receive(), d12) s2_77.send(d12) self.assertEqual(s2_77.receive(), d12) s1_33 = self.sm1.register_service(33) s2_33 = self.sm2.register_service(33) d21 = Packet(2, 1, "test 2") s2_33.send(d21) self.assertEqual(s1_33.receive(), d21) s1_33.send(d21) self.assertEqual(s1_33.receive(), d21) text = "".join(map(chr, xrange(256))) d_big = Packet(1, 2, text * 5) s1_33.send(d_big) self.assertEqual(s2_33.receive(), d_big) d12_2 = Packet(1, 2, "test 2") d12_3 = Packet(1, 2, "test 3") s1_33.send(d12) s1_33.send(d12_2) self.assertEqual(s2_33.receive(), d12) s1_77.send(d12_3) self.assertEqual(s2_77.receive(), d12_3) self.assertEqual(s2_33.receive(), d12_2) def tearDown(self): self.sm1.terminate() self.sm2.terminate() self.dr1.terminate() self.dr2.terminate() self.ft1.terminate() self.ft2.terminate()
class TestRouterServiceManager2(unittest.TestCase): def setUp(self): l1, l2 = FullDuplexLink() sft1 = SimpleFrameTransmitter(node=l1) sft2 = SimpleFrameTransmitter(node=l2) self.ft1 = FrameTransmitter(simple_frame_transmitter=sft1, debug_src=1, debug_dest=2) self.ft2 = FrameTransmitter(simple_frame_transmitter=sft2, debug_src=2, debug_dest=1) rlm1 = RouterLinkManager() rlm2 = RouterLinkManager() self.dr1 = DatagramRouter( router_name=1, link_manager=rlm1, routing_table=LocalRoutingTable(1, rlm1)) self.dr2 = DatagramRouter( router_name=2, link_manager=rlm2, routing_table=LocalRoutingTable(2, rlm2)) rlm1.add_link(2, self.ft1) rlm2.add_link(1, self.ft2) self.sm1 = RouterServiceManager(self.dr1) self.sm2 = RouterServiceManager(self.dr2) self.s1_100 = self.sm1.register_service(100) self.s2_100 = self.sm2.register_service(100) def _test_transmit(self): s1_77 = self.sm1.register_service(77) s2_77 = self.sm2.register_service(77) d12 = Packet(1, 2, "test") s1_77.send(d12) self.assertEqual(s2_77.receive(), d12) s2_77.send(d12) self.assertEqual(s2_77.receive(), d12) s1_33 = self.sm1.register_service(33) s2_33 = self.sm2.register_service(33) d21 = Packet(2, 1, "test 2") s2_33.send(d21) self.assertEqual(s1_33.receive(), d21) s1_33.send(d21) self.assertEqual(s1_33.receive(), d21) text = "".join(map(chr, xrange(256))) d_big = Packet(1, 2, text * 5) s1_33.send(d_big) self.assertEqual(s2_33.receive(), d_big) d12_2 = Packet(1, 2, "test 2") d12_3 = Packet(1, 2, "test 3") s1_33.send(d12) s1_33.send(d12_2) self.assertEqual(s2_33.receive(), d12) s1_77.send(d12_3) self.assertEqual(s2_77.receive(), d12_3) self.assertEqual(s2_33.receive(), d12_2) def test_time(self): data = "test" self.s1_100.send_data(2, data) p = self.s2_100.receive() self.assertEqual(p.data, data) # TODO: Assume computer is not slow. self.assertLess(p.time, 5.0) self.assertGreaterEqual(p.time, 0) def tearDown(self): self.sm1.terminate() self.sm2.terminate() self.dr1.terminate() self.dr2.terminate() self.ft1.terminate() self.ft2.terminate()
class TestRIPService2(unittest.TestCase): def setUp(self): l1, l2 = FullDuplexLink() sft1 = SimpleFrameTransmitter(node=l1) sft2 = SimpleFrameTransmitter(node=l2) self.ft1 = FrameTransmitter(simple_frame_transmitter=sft1, debug_src=1, debug_dest=2) self.ft2 = FrameTransmitter(simple_frame_transmitter=sft2, debug_src=2, debug_dest=1) rlm1 = RouterLinkManager() rlm2 = RouterLinkManager() self.dr1 = DatagramRouter( router_name=1, link_manager=rlm1, routing_table=LocalRoutingTable(1, rlm1)) self.dr2 = DatagramRouter( router_name=2, link_manager=rlm2, routing_table=LocalRoutingTable(2, rlm2)) rlm1.add_link(2, self.ft1) rlm2.add_link(1, self.ft2) self.sm1 = RouterServiceManager(self.dr1) self.sm2 = RouterServiceManager(self.dr2) self.rip_st1 = self.sm1.register_service(RIPService.protocol) self.rip_st2 = self.sm2.register_service(RIPService.protocol) self.rs1 = RIPService(1, rlm1, self.rip_st1, update_period=0.5, inf_timeout=0.9, remove_timeout=1.6) self.rs2 = RIPService(2, rlm2, self.rip_st2, update_period=0.5, inf_timeout=0.9, remove_timeout=1.6) self.dr1.set_routing_table(self.rs1.dynamic_routing_table()) self.dr2.set_routing_table(self.rs2.dynamic_routing_table()) def test_transmit(self): s1_77 = self.sm1.register_service(77) s2_77 = self.sm2.register_service(77) d12 = Packet(1, 2, "test") s1_77.send(d12) self.assertEqual(s2_77.receive(), d12) s2_77.send(d12) self.assertEqual(s2_77.receive(), d12) s1_33 = self.sm1.register_service(33) s2_33 = self.sm2.register_service(33) d21 = Packet(2, 1, "test 2") s2_33.send(d21) self.assertEqual(s1_33.receive(), d21) s1_33.send(d21) self.assertEqual(s1_33.receive(), d21) text = "".join(map(chr, xrange(256))) d_big = Packet(1, 2, text * 5) s1_33.send(d_big) self.assertEqual(s2_33.receive(), d_big) d12_2 = Packet(1, 2, "test 2") d12_3 = Packet(1, 2, "test 3") s1_33.send(d12) s1_33.send(d12_2) self.assertEqual(s2_33.receive(), d12) s1_77.send(d12_3) self.assertEqual(s2_77.receive(), d12_3) self.assertEqual(s2_33.receive(), d12_2) def tearDown(self): self.rs1.terminate() self.rs2.terminate() self.sm1.terminate() self.sm2.terminate() self.dr1.terminate() self.dr2.terminate() self.ft1.terminate() self.ft2.terminate()