diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 50a25e01a..b6e9aeae6 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1,4 +1,5 @@ import os +import textwrap from functools import reduce from pathlib import Path from typing import Iterator, Optional @@ -22,6 +23,7 @@ export, find_plugin_functions, get_external_module_paths, + load_modules_from_paths, plugins, ) from dissect.target.target import Target @@ -789,3 +791,93 @@ def test_os_plugin___init_subclass__(subclass: type[OSPlugin], replaced: bool) - assert (os_docstring == subclass_docstring) is replaced if not replaced: assert subclass_docstring == f"Test docstring {method_name}" + + +@patch("dissect.target.plugin.PLUGINS", new_callable=dict) +def test_plugin_directory(mock_plugins: dict, tmp_path: Path) -> None: + code = """ + from dissect.target.plugin import Plugin, export + + class MyPlugin(Plugin): + __namespace__ = {!r} + + @export + def my_function(self): + return "My function" + """ + + (tmp_path / "myplugin").mkdir() + (tmp_path / "myplugin" / "__init__.py").write_text("") + (tmp_path / "myplugin" / "_plugin.py").write_text(textwrap.dedent(code.format(None))) + + (tmp_path / "mypluginns").mkdir() + (tmp_path / "mypluginns" / "__init__.py").write_text("") + (tmp_path / "mypluginns" / "_plugin.py").write_text(textwrap.dedent(code.format("myns"))) + + load_modules_from_paths([tmp_path]) + + assert mock_plugins["__functions__"][None] == { + "my_function": { + "myplugin.MyPlugin": FunctionDescriptor( + name="my_function", + namespace=None, + path="myplugin.my_function", + exported=True, + internal=False, + findable=True, + output="default", + method_name="my_function", + module="myplugin._plugin", + qualname="MyPlugin", + ) + }, + "myns": { + "mypluginns.MyPlugin": FunctionDescriptor( + name="myns", + namespace="myns", + path="mypluginns", + exported=True, + internal=False, + findable=True, + output=None, + method_name="__call__", + module="mypluginns._plugin", + qualname="MyPlugin", + ) + }, + "myns.my_function": { + "mypluginns.MyPlugin": FunctionDescriptor( + name="myns.my_function", + namespace="myns", + path="mypluginns.my_function", + exported=True, + internal=False, + findable=True, + output="default", + method_name="my_function", + module="mypluginns._plugin", + qualname="MyPlugin", + ) + }, + } + + assert mock_plugins["__plugins__"][None] == { + "myplugin.MyPlugin": PluginDescriptor( + module="myplugin._plugin", + qualname="MyPlugin", + namespace=None, + path="myplugin", + findable=True, + functions=["my_function"], + exports=["my_function"], + ), + "mypluginns.MyPlugin": PluginDescriptor( + module="mypluginns._plugin", + qualname="MyPlugin", + namespace="myns", + path="mypluginns", + findable=True, + functions=["my_function", "__call__"], + exports=["my_function", "__call__"], + ), + }