def test_all_channels_send(self): c1_sub = MagicMock() c2_sub = MagicMock() all_sub = MagicMock() p = MultitopicPublisher() #subscribe c1_sub_subs = p.subscribe(c1_sub, "c1") c2_sub_subs = p.subscribe(c2_sub, "c2") all_sub_subs = p.subscribe(all_sub, MultitopicPublisher.ALL_TOPICS) #send message to ALL_TOPICS p.send(1,MultitopicPublisher.ALL_TOPICS) c1_sub.assert_called_with(1) c2_sub.assert_called_with(1) all_sub.assert_called_with(1) self.assertEqual(c1_sub.call_count, 1) self.assertEqual(c2_sub.call_count, 1) self.assertEqual(all_sub.call_count, 1) #send message to ALL_TOPICS p.send(2, MultitopicPublisher.ALL_TOPICS) c1_sub.assert_called_with(2) c2_sub.assert_called_with(2) all_sub.assert_called_with(2) self.assertEqual(c1_sub.call_count, 2) self.assertEqual(c2_sub.call_count, 2) self.assertEqual(all_sub.call_count, 2)
def test_random(self): iterations = 100 n_subscribers = 100 n_topics = 10 def join_prob_iter(i): '''probability of a subscriber joining, vs leaving, for a given iteration number''' return max(0.0, min(1.0, 1 - i / float(iterations) )) #start at 100%, end at 0% topics = ["c_"+str(n) for n in range(10)] messages = ["m_"+str(n) for n in range(100)] subscribers = [MagicMock() for x in range(n_subscribers)] unjoined = set(subscribers) joined = set() p = MultitopicPublisher() topic_subs = defaultdict(set) sub_topic = {} subscriptions = {} #keyed by subscriber n_received_messages = defaultdict(lambda:0) # keyed by subscriber for iteration in range(iterations): self.assertEqual(p.num_subscriptions, len(joined)) join = random.random() < join_prob_iter(iteration) leave = not join if join and len(unjoined)>0: join_topic = random.choice(topics) join_sub = random.choice(tuple(unjoined)) assert not join_sub in joined assert not join_sub in subscriptions subscription = p.subscribe(join_sub, join_topic) subscriptions[join_sub] = subscription topic_subs[join_topic].add(join_sub) sub_topic[join_sub] = join_topic unjoined.remove(join_sub) joined.add(join_sub) if leave and len(joined)>0: leave_sub = random.choice(tuple(joined)) leave_topic = sub_topic[leave_sub] subscriptions[leave_sub].stop() subscriptions.pop(leave_sub) sub_topic[leave_sub] = None unjoined.add(leave_sub) joined.remove(leave_sub) topic_subs[leave_topic].remove(leave_sub) topic = random.choice(topics) message = random.choice(messages) p.send(message, topic) current_topic_subs = topic_subs[topic] for subscribed_sub in current_topic_subs: n_received_messages[subscribed_sub]+=1 subscribed_sub.assert_called_with(message) for sub in subscribers: self.assertEqual(sub.call_count, n_received_messages[sub])
def test_simple(self): c1_sub1 = MagicMock() c1_sub2 = MagicMock() c2_sub1 = MagicMock() p = MultitopicPublisher() self.assertEqual(p.active, False) #send messages to random topics p.send(9, "c1") p.send(9, "c2") p.send(9, "something") p.send(9, "mytopic") #subscribe to c1 c1_sub1_subs = p.subscribe(c1_sub1, "c1") self.assertEqual(p.active, True) c1_sub2_subs = p.subscribe(c1_sub2, "c1") #send message to c1 p.send(1, "c1") c1_sub1.assert_called_with(1) c1_sub2.assert_called_with(1) self.assertEqual(c2_sub1.call_count, 0) #subscribe to c2 c2_sub1_subs = p.subscribe(c2_sub1, "c2") #send message to c2 p.send(2, "c2") c1_sub1.assert_called_with(1) c1_sub2.assert_called_with(1) c2_sub1.assert_called_with(2) self.assertEqual(c1_sub1.call_count, 1) self.assertEqual(c1_sub2.call_count, 1) self.assertEqual(c2_sub1.call_count, 1) #unsubscribe to c2 c2_sub1_subs.stop() self.assertEqual(p.active, True) #send message to c2 p.send(3, "c2") c1_sub1.assert_called_with(1) c1_sub2.assert_called_with(1) c2_sub1.assert_called_with(2) self.assertEqual(c1_sub1.call_count, 1) self.assertEqual(c1_sub2.call_count, 1) self.assertEqual(c2_sub1.call_count, 1) #unsubscribe to c1_sub2 c1_sub2_subs.stop() self.assertEqual(p.active, True) #send message to c1 p.send(4, "c1") c1_sub1.assert_called_with(4) c1_sub2.assert_called_with(1) c2_sub1.assert_called_with(2) self.assertEqual(c1_sub1.call_count, 2) self.assertEqual(c1_sub2.call_count, 1) self.assertEqual(c2_sub1.call_count, 1) #unsubscribe to c1_sub1 c1_sub1_subs.stop() self.assertEqual(p.active, False) #send message to c1 p.send(5, "c1") c1_sub1.assert_called_with(4) c1_sub2.assert_called_with(1) c2_sub1.assert_called_with(2) self.assertEqual(c1_sub1.call_count, 2) self.assertEqual(c1_sub2.call_count, 1) self.assertEqual(c2_sub1.call_count, 1) self.assertEqual(p.active, False)