From 1fd6decf91deacc4ab121e896800008caa7550f0 Mon Sep 17 00:00:00 2001 From: Salad Dais Date: Fri, 11 Jun 2021 19:44:53 +0000 Subject: [PATCH] Add integration tests for addon (un)loading --- tests/proxy/integration/test_addons.py | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/proxy/integration/test_addons.py b/tests/proxy/integration/test_addons.py index 4e1052c..fd11edb 100644 --- a/tests/proxy/integration/test_addons.py +++ b/tests/proxy/integration/test_addons.py @@ -1,5 +1,10 @@ from __future__ import annotations +import asyncio +import sys +from pathlib import Path +from tempfile import TemporaryDirectory + from hippolyzer.lib.base.message.message import Block, Message from hippolyzer.lib.proxy import addon_ctx from hippolyzer.lib.proxy.addon_utils import ( @@ -29,14 +34,47 @@ class MockAddon(BaseAddon): show_message(bar) +PARENT_ADDON_SOURCE = """ +from hippolyzer.lib.proxy.addon_utils import BaseAddon + +class ParentAddon(BaseAddon): + baz = None + + @classmethod + def foo(cls): + cls.baz = 1 + +addons = [ParentAddon()] +""" + +CHILD_ADDON_SOURCE = """ +from hippolyzer.lib.proxy.addon_utils import BaseAddon +from hippolyzer.lib.proxy.addons import AddonManager + +import parent_addon + +AddonManager.hot_reload(parent_addon) + +class ChildAddon(BaseAddon): + def handle_init(self, session_manager): + parent_addon.ParentAddon.foo() + +addons = [ChildAddon()] +""" + + class AddonIntegrationTests(BaseProxyTest): def setUp(self) -> None: super().setUp() self.addon = MockAddon() AddonManager.init([], self.session_manager, [self.addon], swallow_addon_exceptions=False) + self.temp_dir = TemporaryDirectory(prefix="addon_test_sources") + self.child_path = Path(self.temp_dir.name) / "child_addon.py" + self.parent_path = Path(self.temp_dir.name) / "parent_addon.py" def tearDown(self) -> None: AddonManager.shutdown() + self.temp_dir.cleanup() def _fake_command(self, command: str) -> None: msg = Message( @@ -76,3 +114,28 @@ class AddonIntegrationTests(BaseProxyTest): # Should have sent out the two injected packets for inbound and outbound chat # But not the original chatfromviewer from our command. self.assertEqual(len(self.transport.packets), 2) + + async def test_loading_addons(self): + with open(self.parent_path, "w") as f: + f.write(PARENT_ADDON_SOURCE) + with open(self.child_path, "w") as f: + f.write(CHILD_ADDON_SOURCE) + AddonManager.load_addon_from_path(str(self.parent_path), reload=True) + AddonManager.load_addon_from_path(str(self.child_path), reload=True) + # Wait for the init hooks to run + await asyncio.sleep(0.001) + # Should be able to import this by name now + import parent_addon # noqa + # ChildAddon calls a classmethod that mutates this + self.assertEqual(1, parent_addon.ParentAddon.baz) + + async def test_unloading_addons(self): + with open(self.parent_path, "w") as f: + f.write(PARENT_ADDON_SOURCE) + AddonManager.load_addon_from_path(str(self.parent_path), reload=True) + # Wait for the init hooks to run + await asyncio.sleep(0.001) + # Should be able to import this by name now + AddonManager.unload_addon_from_path(str(self.parent_path), reload=True) + await asyncio.sleep(0.001) + self.assertNotIn('hippolyzer.user_addon_parent_addon', sys.modules)