diff --git a/monkey/common/event_queue/pypubsub_event_queue.py b/monkey/common/event_queue/pypubsub_event_queue.py index dc4a3991d..87813311f 100644 --- a/monkey/common/event_queue/pypubsub_event_queue.py +++ b/monkey/common/event_queue/pypubsub_event_queue.py @@ -22,10 +22,12 @@ class PyPubSubEventQueue(IEventQueue): self, event_type: Type[AbstractEvent], subscriber: Callable[[AbstractEvent], None] ): # pypubsub.pub.subscribe needs a string as the topic/event name - self._pypubsub_publisher.subscribe(listener=subscriber, topicName=event_type.__name__) + event_type_topic = PyPubSubEventQueue._get_type_topic(event_type) + self._pypubsub_publisher.subscribe(listener=subscriber, topicName=event_type_topic) def subscribe_tag(self, tag: str, subscriber: Callable[[AbstractEvent], None]): - self._pypubsub_publisher.subscribe(listener=subscriber, topicName=tag) + tag_topic = PyPubSubEventQueue._get_tag_topic(tag) + self._pypubsub_publisher.subscribe(listener=subscriber, topicName=tag_topic) def publish(self, event: AbstractEvent): self._publish_to_all_events_topic(event) @@ -36,8 +38,20 @@ class PyPubSubEventQueue(IEventQueue): self._pypubsub_publisher.sendMessage(_INTERNAL_ALL_EVENT_TYPES_TOPIC, event=event) def _publish_to_type_topic(self, event: AbstractEvent): - self._pypubsub_publisher.sendMessage(event.__class__.__name__, event=event) + event_type_topic = PyPubSubEventQueue._get_type_topic(event.__class__) + self._pypubsub_publisher.sendMessage(event_type_topic, event=event) def _publish_to_tags_topics(self, event: AbstractEvent): for tag in event.tags: - self._pypubsub_publisher.sendMessage(tag, event=event) + tag_topic = PyPubSubEventQueue._get_tag_topic(tag) + self._pypubsub_publisher.sendMessage(tag_topic, event=event) + + # Appending a unique string to the topics for type and tags prevents bugs caused by collisions + # between type names and tag names. + @staticmethod + def _get_type_topic(event_type: Type[AbstractEvent]) -> str: + return f"{event_type.__name__}-type" + + @staticmethod + def _get_tag_topic(tag: str) -> str: + return f"{tag}-tag" diff --git a/monkey/tests/unit_tests/common/event_queue/test_pypubsub_event_queue.py b/monkey/tests/unit_tests/common/event_queue/test_pypubsub_event_queue.py index 1bd919133..449a7776a 100644 --- a/monkey/tests/unit_tests/common/event_queue/test_pypubsub_event_queue.py +++ b/monkey/tests/unit_tests/common/event_queue/test_pypubsub_event_queue.py @@ -99,3 +99,11 @@ def test_subscribe_tags_multiple_types(event_queue, subscriber): assert TestEvent1 in subscriber.call_types assert TestEvent2 in subscriber.call_types assert {EVENT_TAG_1, EVENT_TAG_2}.issubset(subscriber.call_tags) + + +def test_type_tag_collision(event_queue, subscriber): + event_queue.subscribe_type(TestEvent1, subscriber) + + event_queue.publish(TestEvent2(tags={TestEvent1.__name__})) + + assert subscriber.call_count == 0