From f1073958d4eb88ead7f6536941779ad18ee2c73a Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Tue, 20 Jul 2021 17:42:55 -0400 Subject: [PATCH] Add circular dependencies breaker tests --- .../test_dynamic_async_resources_py36.py | 30 +++++++++++++++++ tests/unit/containers/test_dynamic_py2_py3.py | 32 ++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/tests/unit/containers/test_dynamic_async_resources_py36.py b/tests/unit/containers/test_dynamic_async_resources_py36.py index a646b65b..a4a0caf7 100644 --- a/tests/unit/containers/test_dynamic_async_resources_py36.py +++ b/tests/unit/containers/test_dynamic_async_resources_py36.py @@ -79,3 +79,33 @@ class AsyncResourcesTest(AsyncTestCase): self._run(container.shutdown_resources()) self.assertEqual(initialized_resources, ['r1', 'r2', 'r3', 'r1', 'r2', 'r3']) self.assertEqual(shutdown_resources, ['r1', 'r2', 'r3', 'r1', 'r2', 'r3']) + + def test_shutdown_circular_dependencies_breaker(self): + async def _resource(name, **_): + yield name + + class Container(containers.DeclarativeContainer): + resource1 = providers.Resource( + _resource, + name='r1', + ) + resource2 = providers.Resource( + _resource, + name='r2', + r1=resource1, + ) + resource3 = providers.Resource( + _resource, + name='r3', + r2=resource2, + ) + + container = Container() + self._run(container.init_resources()) + + # Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...) + container.resource1.add_kwargs(r3=container.resource3) + + with self.assertRaises(RuntimeError) as context: + self._run(container.shutdown_resources()) + self.assertEqual(str(context.exception), 'Unable to resolve resources shutdown order') diff --git a/tests/unit/containers/test_dynamic_py2_py3.py b/tests/unit/containers/test_dynamic_py2_py3.py index 0b5d3ea3..fea4d489 100644 --- a/tests/unit/containers/test_dynamic_py2_py3.py +++ b/tests/unit/containers/test_dynamic_py2_py3.py @@ -192,7 +192,7 @@ class DeclarativeContainerInstanceTests(unittest.TestCase): self.assertEqual(container.overridden, tuple()) self.assertEqual(container.p11.overridden, tuple()) - def test_init_and_shutdown_ordering(self): + def test_init_and_shutdown_resources_ordering(self): """Test init and shutdown resources. Methods .init_resources() and .shutdown_resources() should respect resources dependencies. @@ -243,6 +243,36 @@ class DeclarativeContainerInstanceTests(unittest.TestCase): self.assertEqual(initialized_resources, ['r1', 'r2', 'r3', 'r1', 'r2', 'r3']) self.assertEqual(shutdown_resources, ['r1', 'r2', 'r3', 'r1', 'r2', 'r3']) + def test_shutdown_resources_circular_dependencies_breaker(self): + def _resource(name, **_): + yield name + + class Container(containers.DeclarativeContainer): + resource1 = providers.Resource( + _resource, + name='r1', + ) + resource2 = providers.Resource( + _resource, + name='r2', + r1=resource1, + ) + resource3 = providers.Resource( + _resource, + name='r3', + r2=resource2, + ) + + container = Container() + container.init_resources() + + # Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...) + container.resource1.add_kwargs(r3=container.resource3) + + with self.assertRaises(RuntimeError) as context: + container.shutdown_resources() + self.assertEqual(str(context.exception), 'Unable to resolve resources shutdown order') + def test_init_shutdown_nested_resources(self): def _init1(): _init1.init_counter += 1