def testA2_differentNLRIDifferentSource(self): # 2 sources A and B advertise and withdraw routes for different NLRI. # Mock objects self.trackerWorker._newBestRoute = mock.Mock() self.trackerWorker._bestRouteRemoved = mock.Mock() # 2 sources: A and B workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') # Source A advertises a route for NLRI1 routeNlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source B advertises a route for NLRI2 routeNlri2B = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI2, [RT1, RT2], workerB, NH1, 100) # Source A withdraws the route for NLRI1 self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source B withdraws the route for NLRI2 self._newRouteEvent( RouteEvent.WITHDRAW, NLRI2, [RT1, RT2], workerB, NH1, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved self.assertEqual(2, self.trackerWorker._newBestRoute.call_count, '2 newBestRoute calls: 1 for NLRI1 and 1 for NLRI2') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, routeNlri1A.routeEntry), (NLRI2, routeNlri2B.routeEntry)]) self.assertEqual(2, self.trackerWorker._bestRouteRemoved.call_count, '2 bestRouteRemoved calls: 1 for NLRI1 and 1 for ' 'NLRI2') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, routeNlri1A.routeEntry, True), (NLRI2, routeNlri2B.routeEntry, True)])
def __init__(self, bgpManager, name, peerAddress): # call super Thread.__init__(self) self.setDaemon(True) self.name = "BGP-%s" % peerAddress Worker.__init__(self, bgpManager, self.name) self.bgpManager = bgpManager self.peerAddress = peerAddress # its up to subclasses to call setHoldTime again to set holdtime based # on value advertized by peer self._setHoldTime(DEFAULT_HOLDTIME) # used to stop receiveThread self._stopLoops = Event() # used to track that we've been told to stop: self.shouldStop = False self.sendKATimer = None self.KAReceptionTimer = None LookingGlassLocalLogger.__init__( self, self.peerAddress.replace(".", "-")) self.fsm = FSM(self) self.log.debug("Init %s", self.name) self.enqueue(Init)
def testC3_selectNewBestRouteAmongSeveral(self): # When current best route is withdrawn, the new best route should be # selected among several routes self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 3 sources: A, B and C workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') workerC = Worker('BGPManager', 'Worker-C') # Source A advertises a route1 for NLRI1 self._append_call("RE1") route1Nlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises a route2 for NLRI1. Route1 is better than Route2 self._append_call("RE2") route2Nrli1B = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source C advertises a route3 for NLRI1. Route2 is better than Route3 self._append_call("RE3") route3Nrli1C = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerC, NH1, 100) # Source A withdraws route1 for NLRI1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B withdraws route2 for NLRI1 self._append_call("RE5") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source C withdraws route3 for NLRI1 self._append_call("RE6") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerC, NH1, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", "RE4", NBR, BRR, "RE5", NBR, BRR, "RE6", BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 3, self.trackerWorker._newBestRoute.call_count, '3 new newBestRoute calls for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1A.routeEntry), (NLRI1, route2Nrli1B.routeEntry), (NLRI1, route3Nrli1C.routeEntry)]) self.assertEqual( 3, self.trackerWorker._bestRouteRemoved.call_count, '3 bestRouteRemoved calls for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1A.routeEntry, False), (NLRI1, route2Nrli1B.routeEntry, False), (NLRI1, route3Nrli1C.routeEntry, True)])
def __init__(self, bgpManager, workerName, compareRoutes=compareNoECMP): Worker.__init__(self, bgpManager, workerName) LookingGlassLocalLogger.__init__(self) # dict: entry -> list of routes: self.trackedEntry2routes = dict() # dict: entry -> set of bestRoutes: self.trackedEntry2bestRoutes = dict() self._compareRoutes = compareRoutes
def testE2_replaceBRisNotNBR(self): # Advertise a route that replaces the best route but does not become # the new best route self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 2 sources : A and B workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') # Source A advertises a route1 for NLRI1 self._append_call("RE1") route1Nlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises a route2. Route1 is better than Route2 self._append_call("RE2") route2Nrli1B = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source A advertises a route3 for NLRI1. Route3 replaces Route1. # Route2 is better than route3. self._append_call("RE3") route3Nrli1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100, route1Nlri1A.routeEntry) # Source B withdraws route2 for NLRI1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerB, NH1, 200) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", NBR, BRR, "RE4", NBR, BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 3, self.trackerWorker._newBestRoute.call_count, '3 new newBestRoute calls for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1A.routeEntry), (NLRI1, route2Nrli1B.routeEntry), (NLRI1, route3Nrli1A.routeEntry)]) self.assertEqual( 2, self.trackerWorker._bestRouteRemoved.call_count, '2 bestRouteRemoved calls for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1A.routeEntry, False), (NLRI1, route2Nrli1B.routeEntry, False)])
def testA1_differentNLRISameSource(self): # A source A advertises and withdraws routes for different NLRI. # Mock objects self.trackerWorker._newBestRoute = mock.Mock() self.trackerWorker._bestRouteRemoved = mock.Mock() # Only 1 source A workerA = Worker('BGPManager', 'Worker-A') # Source A advertises a route for NLRI1 routeNlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source A advertises a route for NLRI2 routeNlri2A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI2, [RT1, RT2], workerA, NH1, 100) # Source A withdraws the route for NLRI1 self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source A withdraws the route for NLRI2 self._newRouteEvent( RouteEvent.WITHDRAW, NLRI2, [RT1, RT2], workerA, NH1, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved self.assertEqual(2, self.trackerWorker._newBestRoute.call_count, '2 new best routes: 1 for NLRI1 and 1 for NLRI2') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, routeNlri1A.routeEntry), (NLRI2, routeNlri2A.routeEntry)]) self.assertEqual(2, self.trackerWorker._bestRouteRemoved.call_count, '2 old routes removed: 1 for NLRI1 and 1 for NLRI2') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, routeNlri1A.routeEntry, True), (NLRI2, routeNlri2A.routeEntry, True)])
def testC1_route1BestRoute(self): # Route1 is the best route # Mock objects self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 2 sources : A and B workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') # Source A advertises a route1 for NLRI1 self._append_call("RE1") route1Nlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises a route2 for NLRI1 with different attributes. # Route1 is better than Route2 self._append_call("RE2") route2Nrli1B = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source A withdraws route1 for NLRI1 self._append_call("RE3") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B withdraws route2 for NLRI1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerB, NH1, 200) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", NBR, BRR, "RE4", BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 2, self.trackerWorker._newBestRoute.call_count, '2 new newBestRoute calls for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1A.routeEntry), (NLRI1, route2Nrli1B.routeEntry)]) self.assertEqual( 2, self.trackerWorker._bestRouteRemoved.call_count, '2 bestRouteRemoved calls for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1A.routeEntry, False), (NLRI1, route2Nrli1B.routeEntry, True)])
def testB2_isNotTheCurrentBestRoute(self): # The route which is advertised by an other source is not the current # best route but will become the best route self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 3 sources: A, B and C workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') workerC = Worker('BGPManager', 'Worker-C') # Source A advertises route1 for NLRI1 self._append_call("RE1") route1Nlri1 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises route2 for NLRI1 : route1 is better than route2 self._append_call("RE2") route2Nlri1 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source C advertises also route2 self._append_call("RE3") self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerC, NH1, 200) # Source A withdraws route1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 300) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", "RE4", NBR, BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 2, self.trackerWorker._newBestRoute.call_count, '2 new best route call for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1.routeEntry), (NLRI1, route2Nlri1.routeEntry)]) self.assertEqual( 1, self.trackerWorker._bestRouteRemoved.call_count, '1 bestRouteRemoved call for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1.routeEntry, False)])
def testE5_replaceBRisNBREqual(self): # Same as E3, but the route that replaces our current best compares # equally to the two initially less preferred routes, and becomes best # route with them self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 3 sources: A, B and C workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') workerC = Worker('BGPManager', 'Worker-C') # Source A advertises route1 for NLRI1 self._append_call("RE1") route1 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises route2 for NLRI1 : route1 is better than route2 self._append_call("RE2") route2 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source C advertises also route2 self._append_call("RE3") route3 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerC, NH2, 200) # Source A advertises route3 which replaces route1 self._append_call("RE4") route4 = self._newRouteEvent(RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH3, 200, route1.routeEntry) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", "RE4", NBR, NBR, NBR, BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1.routeEntry), (NLRI1, route2.routeEntry), (NLRI1, route3.routeEntry), (NLRI1, route4.routeEntry)]) # FIXME: the order of route2, route3, route4 is not important in the # test above, we should test independently of the order self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1.routeEntry, False)])
def testE3_replaceBRisNotNBR(self): # Advertise a route that replaces the best route but does not become # the new best route self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 3 sources: A, B and C workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') workerC = Worker('BGPManager', 'Worker-C') # Source A advertises route1 for NLRI1 self._append_call("RE1") route1Nlri1 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 300) # Source B advertises route2 for NLRI1 : route1 is better than route2 self._append_call("RE2") route2Nlri1 = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 200) # Source C advertises also route2 self._append_call("RE3") self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerC, NH1, 200) # Source A advertises route3 which replaces route1 self._append_call("RE4") self._newRouteEvent(RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100, route1Nlri1.routeEntry) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", "RE3", "RE4", NBR, BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 2, self.trackerWorker._newBestRoute.call_count, '2 new best route call for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1.routeEntry), (NLRI1, route2Nlri1.routeEntry)]) self.assertEqual( 1, self.trackerWorker._bestRouteRemoved.call_count, '1 bestRouteRemoved call for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1.routeEntry)])
def testB1_isTheCurrentBestRoute(self): # The route which is advertised by another source is the current best # route self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 2 sources: A and B workerA = Worker('BGPManager', 'Worker-A') workerB = Worker('BGPManager', 'Worker-B') # Source A advertises a route for NLRI1 self._append_call("RE1") routeNlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source B advertises the same route for NLRI1 self._append_call("RE2") routeNlri1B = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerB, NH1, 100) # Source A withdraws the route for NLRI1 self._append_call("RE3") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source B withdraws the route for NLRI1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerB, NH1, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved self.assertEqual( 1, self.trackerWorker._newBestRoute.call_count, '1 new best route call for NLRI1') self._checkCalls( self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, routeNlri1A.routeEntry)]) self.assertEqual( 1, self.trackerWorker._bestRouteRemoved.call_count, '1 bestRouteRemoved call for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, routeNlri1B.routeEntry, True)]) expectedCalls = ["RE1", NBR, "RE2", "RE3", "RE4", BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence')
def testD1_ECMPRoutes(self): # ECMP routes are routes advertised by the same worker with the same # LP and different NH self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 1 source: A workerA = Worker('BGPManager', 'Worker-A') # Source A advertises a route1 for NLRI1 self._append_call("RE1") route1Nlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source A advertises a route2 for NLRI1. route2 is equal to route1 # with compareRoutes, but the next_hop are different self._append_call("RE2") route2Nrli1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH2, 100) # Source A withdraws route1 for NLRI1 self._append_call("RE3") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source A withdraws route2 for NLRI1 self._append_call("RE4") self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH2, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", NBR, "RE3", BRR, "RE4", BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 2, self.trackerWorker._newBestRoute.call_count, '2 new newBestRoute calls for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1A.routeEntry), (NLRI1, route2Nrli1A.routeEntry)]) self.assertEqual( 2, self.trackerWorker._bestRouteRemoved.call_count, '2 bestRouteRemoved calls for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1A.routeEntry, False), (NLRI1, route2Nrli1A.routeEntry, True)])
def testA4_withdrawNLRINotKnown(self): # A source A withdraws a route that does not exist. self.trackerWorker._newBestRoute = mock.Mock() self.trackerWorker._bestRouteRemoved = mock.Mock() # 1 source: A workerA = Worker('BGPManager', 'Worker-A') # Source A withdraws a route for NLRI1 which is not known by # trackerWorker self._newRouteEvent( RouteEvent.WITHDRAW, NLRI1, [RT1, RT2], workerA, NH1, 100) # Check calls to _newBestRoute and _bestRouteRemoved self.assertEqual(0, self.trackerWorker._newBestRoute.call_count, 'newBestRoute should not have been called') self.assertEqual(0, self.trackerWorker._bestRouteRemoved.call_count, 'bestRouteRemoved should not have been called')
def testA3_sameNLRISameSource(self): # A source A advertises the same route for the same NLRI # Mock objects self.trackerWorker._newBestRoute = mock.Mock() self.trackerWorker._bestRouteRemoved = mock.Mock() # 1 source: A workerA = Worker('BGPManager', 'Worker-A') # Source A advertises a route for NLRI1 routeNlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Source A advertises the same route for NLRI1 self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved self.assertEqual(1, self.trackerWorker._newBestRoute.call_count, 'expected 1 newBestRoute call for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, routeNlri1A.routeEntry), (NLRI1, routeNlri1A.routeEntry)])
def testE1_replaceBRisNBR(self): # Advertise a route that replaces the best route and becomes the new # best route self.trackerWorker._newBestRoute = mock.Mock( side_effect=self._callList(NBR)) self.trackerWorker._bestRouteRemoved = mock.Mock( side_effect=self._callList(BRR)) # 1 source: A workerA = Worker('BGPManager', 'Worker-A') # Source A advertises a route1 for NLRI1 self._append_call("RE1") route1Nlri1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 200) # Source A advertises a route2 for NLRI1. Route1 is better than Route2 # BUT Route2 replaces Route1 self._append_call("RE2") route2Nrli1A = self._newRouteEvent( RouteEvent.ADVERTISE, NLRI1, [RT1, RT2], workerA, NH1, 100, route1Nlri1A.routeEntry) # Check calls and arguments list to _newBestRoute and _bestRouteRemoved expectedCalls = ["RE1", NBR, "RE2", NBR, BRR] self.assertEqual(expectedCalls, self._calls, 'Wrong call sequence') self.assertEqual( 2, self.trackerWorker._newBestRoute.call_count, '2 new newBestRoute calls for NLRI1') self._checkCalls(self.trackerWorker._newBestRoute.call_args_list, [(NLRI1, route1Nlri1A.routeEntry), (NLRI1, route2Nrli1A.routeEntry)]) self.assertEqual( 1, self.trackerWorker._bestRouteRemoved.call_count, '1 bestRouteRemoved call for NLRI1') self._checkCalls( self.trackerWorker._bestRouteRemoved.call_args_list, [(NLRI1, route1Nlri1A.routeEntry, False)])
def stop(self): Worker.stop(self) self._stopLoops.set() self.shouldStop = True