def testGetFactoryContext(self): """ Tests the _get_factory_context() method """ class DummyClass(object): pass class ChildClass(DummyClass): pass # Assert the field doesn't exist yet self.assertRaises(AttributeError, getattr, DummyClass, constants.IPOPO_FACTORY_CONTEXT) # Convert the parent into a component DummyClass = decorators.ComponentFactory("dummy-factory")( decorators.Requires("field", "req")(DummyClass)) # Get the context class_context = decorators.get_factory_context(DummyClass) self.assertIsNotNone(decorators.get_factory_context(DummyClass), "Invalid factory context") # The child has a copy of the parent context child_context = decorators.get_factory_context(ChildClass) self.assertIsNot(child_context, class_context, "The child must have a copy of the context")
def testGetFactoryContext(self): """ Tests the _get_factory_context() method """ class DummyClass(object): pass class ChildClass(DummyClass): pass # Assert the field doesn't exist yet self.assertRaises(AttributeError, getattr, DummyClass, constants.IPOPO_FACTORY_CONTEXT) # Convert the parent into a component DummyClass = decorators.ComponentFactory("dummy-factory")( decorators.Requires("field", "req") (DummyClass)) # Get the context class_context = decorators.get_factory_context(DummyClass) self.assertIsNotNone(decorators.get_factory_context(DummyClass), "Invalid factory context") # The child has a copy of the parent context child_context = decorators.get_factory_context(ChildClass) self.assertIsNot(child_context, class_context, "The child must have a copy of the context")
def __call__(self, clazz): """ Stores the configuration of the handler in the component factory context Do not forget to return the given class if no exception is raised :param clazz: Manipulated class :return: The (manipulated) class """ # Ensure that the decorator is applied on a class if not inspect.isclass(clazz): raise TypeError( "@Logger can decorate only classes, not '{0}'".format( type(clazz).__name__)) # Retrieve the Factory context context = decorators.get_factory_context(clazz) if context.completed: # Do nothing if the class has already been manipulated _logger.warning("@Logger: Already manipulated class: %s", decorators.get_method_description(clazz)) return clazz # Store the handler information context.set_handler(constants.HANDLER_LOGGER, self._field) # Inject the logger field in the class setattr(clazz, self._field, None) return clazz
def __call__(self, clazz): """ Stores the configuration of the handler in the component factory context Do not forget to return the given class if no exception is raised :param clazz: Manipulated class :return: The (manipulated) class """ # Ensure that the decorator is applied on a class if not inspect.isclass(clazz): raise TypeError( "@Logger can decorate only classes, not '{0}'".format( type(clazz).__name__ ) ) # Retrieve the Factory context context = decorators.get_factory_context(clazz) if context.completed: # Do nothing if the class has already been manipulated _logger.warning( "@Logger: Already manipulated class: %s", decorators.get_method_description(clazz), ) return clazz # Store the handler information context.set_handler(constants.HANDLER_LOGGER, self._field) # Inject the logger field in the class setattr(clazz, self._field, None) return clazz
def testComponentFactory(self): """ Tests the @decorators.ComponentFactory decorator """ instance_name = "test" @decorators.Instantiate(instance_name) class DummyClass(object): pass class ChildClass(DummyClass): pass def method(): pass # Invalid target for invalid in (None, method, 123): self.assertRaises(TypeError, decorators.ComponentFactory("test"), invalid) # Transform the class into a component decorators.ComponentFactory()(DummyClass) # No name -> generated one parent_context = decorators.get_factory_context(DummyClass) self.assertEqual(parent_context.name, "DummyClassFactory", "Invalid generated name") # Transform the child class decorators.ComponentFactory()(ChildClass) child_context = decorators.get_factory_context(ChildClass) # Ensure the instantiation was not removed after inheritance self.assertIn(instance_name, parent_context.get_instances(), "Instance disappeared of parent") # Ensure the instantiation was not inherited self.assertNotIn(instance_name, child_context.get_instances(), "Instance kept in child")
def testComponentFactory(self): """ Tests the @decorators.ComponentFactory decorator """ instance_name = "test" @decorators.Instantiate(instance_name) class DummyClass(object): pass class ChildClass(DummyClass): pass def method(): pass # Invalid target for invalid in (None, method, 123): self.assertRaises(TypeError, decorators.ComponentFactory("test"), invalid) # Transform the class into a component decorators.ComponentFactory()(DummyClass) # No name -> generated one parent_context = decorators.get_factory_context(DummyClass) self.assertEqual(parent_context.name, "DummyClassFactory", "Invalid generated name") # Transform the child class decorators.ComponentFactory()(ChildClass) child_context = decorators.get_factory_context(ChildClass) # Ensure the instantiation was not removed after inheritance self.assertIn(instance_name, parent_context.get_instances(), "Instance disappeared of parent") # Ensure the instantiation was not inherited self.assertNotIn(instance_name, child_context.get_instances(), "Instance kept in child")
def test_no_rebind(self): """ Tests the @RequiresBest handler without immediate_rebind """ # Modify the component factory module = install_bundle(self.framework) context = get_factory_context(module.RequiresBestComponentFactory) configs = context.get_handler(RequiresBest.HANDLER_ID) configs["service"].immediate_rebind = False self.__internal_test(module, [IPopoEvent.INVALIDATED, IPopoEvent.UNBOUND, IPopoEvent.BOUND, IPopoEvent.VALIDATED])
def test_immediate_rebind(self): """ Tests the @RequiresVarFilter handler with immediate_rebind """ # Modify component factories module = install_bundle(self.framework) for clazz in (module.RequiresVarFilterComponentFactory, module.RequiresVarFilterAggregateComponentFactory): context = get_factory_context(clazz) configs = context.get_handler(RequiresVarFilter.HANDLER_ID) configs["service"].immediate_rebind = True self.__internal_test(module, [IPopoEvent.UNBOUND, IPopoEvent.BOUND])
def test_immediate_rebind(self): """ Tests the @RequiresVarFilter handler with immediate_rebind """ # Modify component factories module = install_bundle(self.framework) for clazz in (module.RequiresVarFilterComponentFactory, module.RequiresVarFilterAggregateComponentFactory): context = get_factory_context(clazz) configs = context.get_handler(RequiresVarFilter.HANDLER_ID) configs["service"].immediate_rebind = True self.__internal_test(module, [IPopoEvent.UNBOUND, IPopoEvent.BOUND])
def testInstantiate(self): """ Tests the @Instantiate decorator """ class DummyClass(object): pass def method(): pass # Empty name for empty in ("", " "): self.assertRaises(ValueError, decorators.Instantiate, empty) # Invalid name type for invalid in (None, [], tuple(), 123): self.assertRaises(TypeError, decorators.Instantiate, invalid) # Invalid properties type for invalid in ("props", [1, 2], tuple((1, 2, 3)), 123): self.assertRaises(TypeError, decorators.Instantiate, "test", invalid) # Invalid target for invalid in (None, method, 123): self.assertRaises(TypeError, decorators.Instantiate("test"), invalid) # 1st injection decorators.Instantiate("test", {"id": 1})(DummyClass) # 2nd injection: nothing happens log_off() decorators.Instantiate("test", {"id": 2})(DummyClass) log_on() # Get the factory context context = decorators.get_factory_context(DummyClass) instances = context.get_instances() self.assertEqual(instances["test"]["id"], 1, "Instance properties have been overridden")
def testInstantiate(self): """ Tests the @Instantiate decorator """ class DummyClass(object): pass def method(): pass # Empty name for empty in ("", " "): self.assertRaises(ValueError, decorators.Instantiate, empty) # Invalid name type for invalid in (None, [], tuple(), 123): self.assertRaises(TypeError, decorators.Instantiate, invalid) # Invalid properties type for invalid in ("props", [1, 2], tuple((1, 2, 3)), 123): self.assertRaises(TypeError, decorators.Instantiate, "test", invalid) # Invalid target for invalid in (None, method, 123): self.assertRaises(TypeError, decorators.Instantiate("test"), invalid) # 1st injection decorators.Instantiate("test", {"id": 1})(DummyClass) # 2nd injection: nothing happens log_off() decorators.Instantiate("test", {"id": 2})(DummyClass) log_on() # Get the factory context context = decorators.get_factory_context(DummyClass) instances = context.get_instances() self.assertEqual(instances["test"]["id"], 1, "Instance properties have been overridden")
def test_temporal_lifecycle(self): """ Tests the component life cycle """ module = install_bundle(self.framework) context = self.framework.get_bundle_context() assert isinstance(context, BundleContext) # Assert that the service is not yet available self.assertIsNone(context.get_service_reference(IEchoService), "Service is already registered") # Import TemporalException here, or the type will be different from the # one loaded by the framework. from pelix.ipopo.handlers.temporal import TemporalException # Get the value from the configuration of the handler factory_context = get_factory_context(module.TemporalComponentFactory) configs = factory_context.get_handler(Temporal.HANDLER_ID) timeout = configs["service"][1] # Instantiate the component consumer = self.ipopo.instantiate(module.FACTORY_TEMPORAL, NAME_A) # Component must be invalid self.assertListEqual([IPopoEvent.INSTANTIATED], consumer.states) consumer.reset() # Instantiate a service svc1 = Dummy() reg1 = context.register_service(IEchoService, svc1, {}) # The consumer must have been validated self.assertListEqual([IPopoEvent.BOUND, IPopoEvent.VALIDATED], consumer.states) consumer.reset() # Make a call self.assertEqual(consumer.call(), svc1.method()) # Register service 2 svc2 = Dummy() reg2 = context.register_service(IEchoService, svc2, {}) # No modification self.assertListEqual([], consumer.states) consumer.reset() # Unregister service 1 reg1.unregister() self.assertListEqual([IPopoEvent.UNBOUND, IPopoEvent.BOUND], consumer.states) self.assertEqual(consumer.call(), svc2.method()) consumer.reset() # Unregister service 2 reg2.unregister() # No modification yet self.assertListEqual([], consumer.states) consumer.reset() # Register a new service svc3 = Dummy() reg3 = context.register_service(IEchoService, svc3, {}) # Service must have been injected before invalidation self.assertListEqual([IPopoEvent.UNBOUND, IPopoEvent.BOUND], consumer.states) self.assertEqual(consumer.call(), svc3.method()) consumer.reset() # Unregister service 3 reg3.unregister() # No modification yet self.assertListEqual([], consumer.states) consumer.reset() start = time.time() try: # Try to call the method consumer.call() except TemporalException: # OK ! pass else: self.fail("No temporal exception raised during call") end = time.time() # Check timeout self.assertLess(end - start, timeout * 2.) self.assertGreater(end - start, timeout / 2.) # Wait a little time.sleep(.2) # Check state self.assertListEqual([IPopoEvent.INVALIDATED, IPopoEvent.UNBOUND], consumer.states) consumer.reset()
def test_temporal_lifecycle(self): """ Tests the component life cycle """ module = install_bundle(self.framework) context = self.framework.get_bundle_context() assert isinstance(context, BundleContext) # Assert that the service is not yet available self.assertIsNone(context.get_service_reference(IEchoService), "Service is already registered") # Import TemporalException here, or the type will be different from the # one loaded by the framework. from pelix.ipopo.handlers.temporal import TemporalException # Get the value from the configuration of the handler factory_context = get_factory_context(module.TemporalComponentFactory) configs = factory_context.get_handler(Temporal.HANDLER_ID) timeout = configs["service"][1] # Instantiate the component consumer = self.ipopo.instantiate(module.FACTORY_TEMPORAL, NAME_A) # Component must be invalid self.assertListEqual([IPopoEvent.INSTANTIATED], consumer.states) consumer.reset() # Instantiate a service svc1 = Dummy() reg1 = context.register_service(IEchoService, svc1, {}) # The consumer must have been validated self.assertListEqual([IPopoEvent.BOUND, IPopoEvent.VALIDATED], consumer.states) consumer.reset() # Make a call self.assertEqual(consumer.call(), svc1.method()) # Register service 2 svc2 = Dummy() reg2 = context.register_service(IEchoService, svc2, {}) # No modification self.assertListEqual([], consumer.states) consumer.reset() # Unregister service 1 reg1.unregister() self.assertListEqual([IPopoEvent.UNBOUND, IPopoEvent.BOUND], consumer.states) self.assertEqual(consumer.call(), svc2.method()) consumer.reset() # Unregister service 2 reg2.unregister() # No modification yet self.assertListEqual([], consumer.states) consumer.reset() # Register a new service svc3 = Dummy() reg3 = context.register_service(IEchoService, svc3, {}) # Service must have been injected before invalidation self.assertListEqual([IPopoEvent.UNBOUND, IPopoEvent.BOUND], consumer.states) self.assertEqual(consumer.call(), svc3.method()) consumer.reset() # Unregister service 3 reg3.unregister() # No modification yet self.assertListEqual([], consumer.states) consumer.reset() start = time.time() try: # Try to call the method consumer.call() except TemporalException: # OK ! pass else: self.fail("No temporal exception raised during call") end = time.time() # Check timeout self.assertLess(end-start, timeout * 2.) self.assertGreater(end-start, timeout / 2.) # Wait a little time.sleep(.2) # Check state self.assertListEqual([IPopoEvent.INVALIDATED, IPopoEvent.UNBOUND], consumer.states) consumer.reset()