diff --git a/tests/adapter/test_rpc.py b/tests/adapter/test_rpc.py new file mode 100644 index 0000000..baf27f9 --- /dev/null +++ b/tests/adapter/test_rpc.py @@ -0,0 +1,160 @@ +import importlib +import asyncio +import sys +from amqp.service.amq_message_handler import DataMessageHandler + +# Create a dummy package and module for demonstration +# You would typically have these in separate files/directories +# e.g., my_package/ +# __init__.py +# my_module.py + +# For this self-contained example, we'll create them dynamically in memory +# In a real application, 'my_package' would be a proper installed package or in sys.path + +# --- Dummy Package/Module Setup --- +# Define a simple module string +dummy_module_content = """ +import asyncio + +# Global function +def greet_sync(name: str) -> str: + return f"Hello, {name} (sync global)!" + +async def greet_async(name: str) -> str: + await asyncio.sleep(0.05) # Simulate async work + return f"Hello, {name} (async global)!" + +# A simple class +class MyService: + def __init__(self): + self.service_name = "MyAwesomeService" + + def process_data_sync(self, data: str, count: int) -> str: + return f"Service '{self.service_name}' processed '{data}' {count} times (sync method)." + + async def process_data_async(self, data: str, delay: float) -> str: + await asyncio.sleep(delay) # Simulate async work + return f"Service '{self.service_name}' processed '{data}' after {delay}s (async method)." + + def _private_method(self): + return "This is a private method." +""" + +# Dynamically create a module object +spec = importlib.util.spec_from_loader("my_package.my_module", loader=None) +if spec is None: + raise ImportError("Could not create module spec for my_package.my_module") + +my_module = importlib.util.module_from_spec(spec) +exec(dummy_module_content, my_module.__dict__) +sys.modules["my_package"] = my_module # Add to sys.modules for importlib to find + +# --- Running the Demos --- +async def main(): + print("\n--- Demo: Invoking Global Synchronous Function ---") + try: + result = await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="__global__", + function_name="greet_sync", + kwargs={"name": "Alice"} + ) + print(f"Demo Result: {result}\n") + except Exception as e: + print(f"Demo Failed: {e}\n") + + print("\n--- Demo: Invoking Global Asynchronous Function ---") + try: + result = await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="__global__", + function_name="greet_async", + kwargs={"name": "Bob"} + ) + print(f"Demo Result: {result}\n") + except Exception as e: + print(f"Demo Failed: {e}\n") + + print("\n--- Demo: Invoking Class Synchronous Method ---") + try: + result = await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="MyService", + function_name="process_data_sync", + kwargs={"data": "report", "count": 3} + ) + print(f"Demo Result: {result}\n") + except Exception as e: + print(f"Demo Failed: {e}\n") + + print("\n--- Demo: Invoking Class Asynchronous Method ---") + try: + result = await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="MyService", + function_name="process_data_async", + kwargs={"data": "metrics", "delay": 0.1} + ) + print(f"Demo Result: {result}\n") + except Exception as e: + print(f"Demo Failed: {e}\n") + + print("\n--- Demo: Error - Package Not Found ---") + try: + await DataMessageHandler.invoke_command( + package_name="non_existent_package", + class_name="__global__", + function_name="some_func", + kwargs={} + ) + except ModuleNotFoundError: + print("Demo Handled: ModuleNotFoundError as expected.\n") + except Exception as e: + print(f"Demo Failed Unexpectedly: {e}\n") + + print("\n--- Demo: Error - Class Not Found ---") + try: + await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="NonExistentClass", + function_name="some_method", + kwargs={} + ) + except AttributeError: + print("Demo Handled: AttributeError (Class Not Found) as expected.\n") + except Exception as e: + print(f"Demo Failed Unexpectedly: {e}\n") + + print("\n--- Demo: Error - Function/Method Not Found ---") + try: + await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="MyService", + function_name="non_existent_method", + kwargs={} + ) + except AttributeError: + print("Demo Handled: AttributeError (Function/Method Not Found) as expected.\n") + except Exception as e: + print(f"Demo Failed Unexpectedly: {e}\n") + + print("\n--- Demo: Error - Private Method (AttributeError) ---") + try: + await DataMessageHandler.invoke_command( + package_name="my_package.my_module", + class_name="MyService", + function_name="_private_method", # Python convention, but still accessible via getattr + kwargs={} + ) + print("Demo Result: Successfully called _private_method (Python allows this via getattr).\n") + except Exception as e: + print(f"Demo Failed: {e}\n") + + +if __name__ == "__main__": + import sys + import importlib.util + + # Run the main asynchronous demo + asyncio.run(main())