def test_ping_cycle(self): scenarios = [[[SimpleCapability(str(CapabilityRegister.AGENT))], 1], [[], 1], [[SimpleCapability(str(CapabilityRegister.POOL))], 0], [[SimpleCapability("MadeUpCapability")], 0]] for scenario in scenarios: reqd_cap, expected_notification = scenario logging.info( "\n\nTesting Ping Cycle with capabilities [{}]\n\n".format( str(reqd_cap))) sa = SimpleAgent( 'test agent', start_state=State.S0, end_state=State.S1, capacity=1, task_consumption_policy=GreedyTaskConsumptionPolicy(), trace=True) time.sleep(.5) ping_srcsink = DummySrcSink("PingSrcSink", ping_topic=sa.topic) ping_workref = ping_srcsink.send_ping( required_capabilities=reqd_cap) time.sleep(1) self.assertEqual(expected_notification, len(ping_srcsink.ping_notifications)) if expected_notification > 0: self.assertEqual( ping_workref.id, ping_srcsink.ping_notifications[0].sender_work_ref.id) pub.unsubAll() return
def test_ping_cycle(self): _ = SimpleEther("TestEther1") scenarios = [[[SimpleCapability(str(CapabilityRegister.POOL))], 1], [[], 1], [[SimpleCapability(str(CapabilityRegister.AGENT))], 0], [[SimpleCapability("MadeUpCapability")], 0]] for scenario in scenarios: reqd_cap, expected_notification = scenario logging.info( "\n\nTesting Ping Cycle with capabilities [{}]\n\n".format( str(reqd_cap))) ping_srcsink = DummySrcSink("PingSrcSink") task_pool = SimpleTaskPool('Task Pool 1') time.sleep(.25) ping_workref = ping_srcsink.send_ping( required_capabilities=reqd_cap) time.sleep(1) self.assertEqual(expected_notification, len(ping_srcsink.ping_notifications)) if expected_notification > 0: self.assertEqual( ping_workref.id, ping_srcsink.ping_notifications[0].sender_work_ref.id) pub.unsubAll() del task_pool del ping_srcsink return
def test_get_with_capabilities_multi_ss(self): ss_list = list() for i in range(10): ss_list.append(DummySrcSink("DummySrcSink-{}".format(i))) # Confirm empty at create time. test_address_book = AddressBook() self.assertEqual(0, len(test_address_book.get())) # Confirm nothing matches empty address book in terms of capabilities for ss in ss_list: self.assertEqual( None, test_address_book.get_with_capabilities(ss.capabilities)) # Add to the AddressBook with a time delay so the address timestamps are clearly different. # The last one added should always bethe one returned as it the last in time. for ss in ss_list: time.sleep(0.1) test_address_book.update(ss) self.assertEqual( ss, test_address_book.get_with_capabilities(ss.capabilities)[0]) # Check everything is in the addressBook addr_bk = test_address_book.get() for ss in ss_list: self.assertTrue(ss in addr_bk) # Wait 5 seconds and then ask for items newer than 10 seconds - should be none delay = 2 time.sleep(delay) ss_last = ss_list[-1] self.assertEqual( None, test_address_book.get_with_capabilities(ss_last.capabilities, max_age_in_seconds=delay - 0.1)) self.assertEqual( ss_last, test_address_book.get_with_capabilities(ss_last.capabilities, max_age_in_seconds=100)[0]) # Add one more and make sure it comes back ss_new = DummySrcSink("DummySrcSink-new") test_address_book.update(ss_new) self.assertEqual( ss_new, test_address_book.get_with_capabilities( ss_new.capabilities, max_age_in_seconds=None)[0]) self.assertEqual( ss_new, test_address_book.get_with_capabilities(ss_new.capabilities, max_age_in_seconds=0.5)[0]) return
def run_ether_do_pub(self, scenario: List): """ We publish a SrcSink to the back-plane and verify that all other ethers respond with their address. """ reqd_cap, expected = scenario ether_tx1 = SimpleEther("TestEtherTx1") # We will publish to private topic and check it replicates ether_rx1 = SimpleEther("TestEtherRx1") # We will see if it gets the replicated ping. ether_rx2 = SimpleEther("TestEtherRx2") # We will see if it gets the replicated ping. ethers = [ether_tx1, ether_rx1, ether_rx2] # Force in some SrcSinks with capabilities via protected methods just for testing ds1 = DummySrcSink(name="DS1", capability=SimpleCapability(capability_name=self.capability_1)) ds2 = DummySrcSink(name="DS2", capability=SimpleCapability(capability_name=self.capability_2)) ether_rx1._update_addressbook(srcsink=ds1) ether_rx2._update_addressbook(srcsink=ds2) ping = SimpleSrcSinkPing(sender_srcsink=ether_tx1, required_capabilities=reqd_cap) # Pub to Private pub.sendMessage(topicName=Ether.back_plane_topic(), notification=ping) # Publish direct to Ether private topic time.sleep(1) # Wait for 1 sec to ensure the activity time triggers. for ether in ethers: ether.stop() # The sender of the ping request should have all the addresses on the ether ether = ether_tx1 logging.info("Checking {}".format(ether.name)) srcsink_topics = list(x.topic for x in ether.get_addressbook()) if expected == 3: self.assertEqual(expected, len(srcsink_topics)) # We expect all topics self.assertTrue(ether_rx1.topic in srcsink_topics) self.assertTrue(ether_rx2.topic in srcsink_topics) self.assertTrue(ds1.topic in srcsink_topics) # The SrcSink with reqd capability else: self.assertEqual(expected, len(srcsink_topics)) # We expect all topics + the tx self.assertTrue(ether_rx1.topic in srcsink_topics) # The topic should be in the set self.assertTrue(ether_rx2.topic in srcsink_topics) # The topic should be in the set self.assertTrue(ether_tx1.topic in srcsink_topics) # The topic should be in the set self.assertTrue(ds1.topic in srcsink_topics) # The SrcSink with reqd capability self.assertTrue(ds2.topic in srcsink_topics) # The SrcSink with reqd capability for ether in ethers: del ether del ds1 del ds2 return
def test_ping_back_plane(self): """ Test the case where we have multiple Ether entities and multiple SrcSinkPings. We send the SrcSinkPing to the back-plane topic *once* but all of the Ether objects should get the ping. """ num_diff_ping_sources = 10 # Topic should be registered even if the ether does not have a matching ping capabilities ethers = list() for i in range(5): ethers.append(SimpleEther("TestEther{}".format(i))) srcsinks = list() for i in range(num_diff_ping_sources): srcsink = DummySrcSink("DummySrcSink-{}".format(i)) srcsinks.append(srcsink) ping = SimpleSrcSinkPing(sender_srcsink=srcsink, required_capabilities=TestEther.NO_CAPABILITIES_REQUIRED, ) # Publish to back plane topic, single message should go to all ethers on backplane. pub.sendMessage(topicName=Ether.back_plane_topic(), notification=ping) for ether in ethers: srcsink_topics = list(x.topic for x in ether.get_addressbook()) self.assertEqual(num_diff_ping_sources, len(srcsink_topics)) # Num topic = num diff ones sent for srcsink in srcsinks: self.assertTrue(srcsink.topic in srcsink_topics) # Every ether should have every topic return
def test_ping_single_srcsink(self): """ Test all the methods of injecting a SrcSinkPing into a single Ether entity. """ # Topic should be registered even if the ether does not have a matching ping capabilities required_capabilities = [TestEther.NO_CAPABILITIES_REQUIRED, [SimpleCapability("ArbitraryCapability")]] for reqd_cap in required_capabilities: for i in range(3): srcsink = DummySrcSink("DummySrcSink-2") ether = SimpleEther("TestEther1") ping = SimpleSrcSinkPing(sender_srcsink=srcsink, required_capabilities=reqd_cap) if i == 0: ether(ping) # Invoke as callable elif i == 1: pub.sendMessage(topicName=ether.topic, notification=ping) # Publish direct to Ether private topic else: pub.sendMessage(topicName=Ether.back_plane_topic(), notification=ping) # Publish to back plane topic srcsink_topics = list(x.topic for x in ether.get_addressbook()) self.assertEqual(1, len(srcsink_topics)) # We expect a single topic only self.assertTrue(srcsink.topic in srcsink_topics) # The topic should be in the set recorded by the ether return
def test_simple_task_injection(self): effort = 3 capacity = 1 source_name = "Dummy-Test-Source-Inject" SimpleTask.process_start_state(State.S0) SimpleTask.process_end_state(State.S1) for i in range(3): logging.info( "\n\n- - - - - T E S T C A S E {} - - - -\n\n".format(i)) test_task = SimpleTask(effort=effort) test_srcsink = DummySrcSink(source_name) test_agent = SimpleAgent( 'agent {}'.format(i), start_state=State.S0, end_state=State.S1, capacity=capacity, task_consumption_policy=GreedyTaskConsumptionPolicy(), trace=True) test_notification = SimpleWorkNotificationDo(UniqueWorkRef( suffix=source_name, prefix=str(test_task.id)), originator=test_agent, source=test_srcsink, task=test_task) time.sleep(1) if i == 0: # Publish to agent via it's private topic. # test_agent(test_notification) pub.sendMessage(topicName=test_agent.topic, notification=test_notification) elif i == 1: # Direct Injection. test_agent._do_work(test_notification) else: # With Agent as callable test_agent(test_notification) time.sleep(1) tlid = SimpleAgent.trace_log_id("_do_work", type(test_notification), test_notification.work_ref) self.assertEqual(test_agent.trace_log[tlid], effort) tlid = SimpleAgent.trace_log_id("_do_notification", type(test_notification), test_notification.work_ref) self.assertTrue(tlid not in test_agent.trace_log) self.assertEqual(test_task.lead_time, int(ceil(effort / capacity))) work_done = test_agent.work_done self.assertEqual(1, len(work_done)) self.assertEqual(test_task.id, work_done[0].task.id) return
def test_basics(self): test_srcsink = DummySrcSink("DummySrcSink-1") test_address_book = AddressBook() self.assertEqual(0, len(test_address_book.get())) test_address_book.update(test_srcsink) self.assertEqual(1, len(test_address_book.get())) self.assertTrue(test_srcsink in test_address_book.get()) return
def test_get_with_capabilities_single_ss(self): test_srcsink = DummySrcSink("DummySrcSink-1") test_address_book = AddressBook() self.assertEqual( None, test_address_book.get_with_capabilities(test_srcsink.capabilities)) test_address_book.update(test_srcsink) self.assertEqual( test_srcsink, test_address_book.get_with_capabilities( test_srcsink.capabilities)[0]) return
def test_handlers(self): task_pool = SimpleTaskPool('Task Pool 1') SimpleTask.process_start_state(State.S0) SimpleTask.process_end_state(State.S1) test_task = SimpleTask(effort=1, start_state=State.S0) uwr = UniqueWorkRef("Dummy1", "Dummy2") src = DummySrcSink("Source") orig = DummySrcSink("originator") scenarios = [ SimpleWorkNotificationDo(uwr, test_task, orig, src), SimpleWorkNotificationFinalise(uwr, test_task, orig, src) ] try: for scenario in scenarios: task_pool(scenario) except Exception as e: self.fail("Un expected exception {}".format(str(e))) return
def test_get_with_capabilities_partial_matches(self): test_address_book = AddressBook() cap1 = SimpleCapability("Cap1") cap2 = SimpleCapability("Cap2") cap3 = SimpleCapability("Cap3") cap4 = SimpleCapability("Cap4") capx = SimpleCapability("Cap?") ss1 = DummySrcSink("DummySrcSink-1") ss1.capabilities = [cap1] ss2 = DummySrcSink("DummySrcSink-2") ss2.capabilities = [cap1, cap2] ss3 = DummySrcSink("DummySrcSink-3") ss3.capabilities = [cap1, cap2, cap3] ss4 = DummySrcSink("DummySrcSink-4") ss4.capabilities = [cap2, cap4] test_address_book.update(ss1) time.sleep(.01) test_address_book.update(ss2) time.sleep(.01) test_address_book.update(ss3) time.sleep(.01) test_address_book.update(ss4) scenarios = [ [1, [cap1, capx], 1.0, [None], 1], [2, [cap1, cap2, cap3], 1.0, [ss3], 1], [3, [cap1, cap2], 1.0, [ss3], 1], # As ss-3 also has Cap1, Cap2 and was created last [4, [capx], 0.0, [ss4], 1], # Zero => match any so will return last one created [5, [capx], 0.3142, [None], 1], [6, [capx], 1.0, [None], 1], [7, [cap1], 1.0, [ss3], 1], [8, [cap1, cap2], 1.0, [ss3], 1], [9, [cap1, cap2], 0.5, [ss4], 1], [10, [cap1], 1.0, [ss3, ss2], 2], [11, [cap1], 1.0, [ss3, ss2, ss1], 3], [12, [cap1], 1.0, [ss3, ss2, ss1], 4], [13, [cap1], 0.0, [ss4, ss3, ss2, ss1], 4], [14, [cap1], 1.0, [ss3, ss2, ss1], 5], [15, [cap1], 1.0, [ss3, ss2, ss1], 500], [16, [cap4, capx], 1.0, [None], 10], [17, [cap4, capx], 0.5, [ss4], 10], [18, [cap3, cap4, capx], 1.0, [None], 10], [19, [cap3, cap4, capx], 0.33, [ss4, ss3], 10] ] for scenario in scenarios: case_num, caps, threshold, expected, n = scenario logging.info( "test_get_with_capabilities_partial_matches case {}".format( case_num)) res = test_address_book.get_with_capabilities( required_capabilities=caps, match_threshold=threshold, n=n) if res is None: self.assertEqual(expected[0], res) self.assertEqual(len(expected), 1) else: self.assertEqual(len(expected), len(res)) # Should have same num results. for i in range(len(expected)): # Order dependent equality. self.assertEqual(expected[i], res[i]) logging.info("case {} passed OK".format(case_num)) return