def install_three_tasks_test(self, proxy_getter): """Install with three tasks.""" observers = [] observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.InstallWithTasks.return_value = ["/A/1"] observers.append(observer) observer = Mock() observer.is_service_available = True observer.service_name = "B" observer.proxy.InstallWithTasks.return_value = ["/B/1", "/B/2"] observers.append(observer) task_proxy = Mock() task_proxy.Steps = 1 proxy_getter.return_value = task_proxy install_manager = InstallManager() install_manager.module_observers = observers main_task = install_manager.install_system_with_task() proxy_getter.assert_has_calls([ call("A", "/A/1"), call("B", "/B/1"), call("B", "/B/2") ]) self.assertIsInstance(main_task, SystemInstallationTask) self.assertEqual(main_task._subtasks, [task_proxy, task_proxy, task_proxy])
def install_three_tasks_test(self, proxy_getter): """Install with three tasks.""" observers = [] observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.InstallWithTasks.return_value = ["/A/1"] observers.append(observer) observer = Mock() observer.is_service_available = True observer.service_name = "B" observer.proxy.InstallWithTasks.return_value = ["/B/1", "/B/2"] observers.append(observer) task_proxy = Mock() task_proxy.Steps = 1 proxy_getter.return_value = task_proxy install_manager = InstallManager() install_manager.module_observers = observers main_task = install_manager.install_system_with_task() proxy_getter.assert_has_calls( [call("A", "/A/1"), call("B", "/B/1"), call("B", "/B/2")]) self.assertIsInstance(main_task, SystemInstallationTask) self.assertEqual(main_task._subtasks, [task_proxy, task_proxy, task_proxy])
def configure_runtime_test(self, proxy_getter): """Configure the runtime system with three tasks.""" observers = [] observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.ConfigureWithTasks.return_value = ["/A/1"] observers.append(observer) observer = Mock() observer.is_service_available = True observer.service_name = "B" observer.proxy.ConfigureWithTasks.return_value = ["/B/1", "/B/2"] observers.append(observer) task_proxy = Mock() task_proxy.Steps = 1 proxy_getter.return_value = task_proxy install_manager = InstallManager() install_manager.on_module_observers_changed(observers) main_task = install_manager.configure_runtime_with_task() proxy_getter.assert_has_calls([ call("A", "/A/1"), call("B", "/B/1"), call("B", "/B/2") ]) self.assertIsInstance(main_task, DBusMetaTask) self.assertEqual(main_task.name, "Configure the runtime system") self.assertEqual(main_task._subtasks, [task_proxy, task_proxy, task_proxy])
def test_list_services(self): sms = ServiceManagementService('secret', 'cert.pem') hs1 = Mock() hs1.service_name = 'juju-upgrade-foo' hs2 = Mock() hs2.service_name = 'juju-deploy-foo' services = [hs1, hs2] with patch.object(sms, 'list_hosted_services', autospec=True, return_value=services) as ls_mock: services = list_services(sms, 'juju-deploy-*', verbose=False) ls_mock.assert_called_once_with() self.assertEqual([hs2], services)
def test_unserialisable_headers(rabbit_manager, rabbit_config): vhost = rabbit_config["vhost"] container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = rabbit_config container.spawn_managed_thread = eventlet.spawn ctx_data = {"language": "en", "customheader": None} service = Mock() worker_ctx = CustomWorkerContext(container, service, DummyProvider("method"), data=ctx_data) publisher = Publisher(exchange=foobar_ex, queue=foobar_queue).bind(container, "publish") publisher.setup() publisher.start() service.publish = publisher.get_dependency(worker_ctx) service.publish("msg") messages = rabbit_manager.get_messages(vhost, foobar_queue.name) assert messages[0]["properties"]["headers"] == { "nameko.language": "en", "nameko.call_id_stack": ["service.method.0"], # no `customheader` }
def test_publish_to_queue(empty_config, maybe_declare, patch_publisher): container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.service_name = "srcservice" container.config = empty_config ctx_data = {"language": "en"} service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider("publish"), data=ctx_data) publisher = Publisher(queue=foobar_queue).bind(container, "publish") producer = Mock() connection = Mock() get_connection, get_producer = patch_publisher(publisher) get_connection.return_value = as_context_manager(connection) get_producer.return_value = as_context_manager(producer) # test declarations publisher.setup() maybe_declare.assert_called_once_with(foobar_queue, connection) # test publish msg = "msg" headers = {"nameko.language": "en", "nameko.call_id_stack": ["srcservice.publish.0"]} service.publish = publisher.get_dependency(worker_ctx) service.publish(msg, publish_kwarg="value") producer.publish.assert_called_once_with( msg, headers=headers, exchange=foobar_ex, retry=True, retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value" )
def test_dispatch_to_rabbit(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = rabbit_config service = Mock() worker_ctx = WorkerContext(container, service, None) dispatcher = EventDispatcher() dispatcher.bind("dispatch", container) dispatcher.prepare() dispatcher.start() # we should have an exchange but no queues exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) assert "srcservice.events" in [exchange['name'] for exchange in exchanges] assert queues == [] # manually add a queue to capture the events rabbit_manager.create_queue(vhost, "event-sink", auto_delete=True) rabbit_manager.create_binding(vhost, "srcservice.events", "event-sink", rt_key=ExampleEvent.type) dispatcher.inject(worker_ctx) service.dispatch(ExampleEvent("msg")) # test event receieved on manually added queue messages = rabbit_manager.get_messages(vhost, "event-sink") assert ['msg'] == [msg['payload'] for msg in messages]
def test_event_dispatcher(empty_config): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config service = Mock() worker_ctx = WorkerContext(container, service, "dispatch") event_dispatcher = EventDispatcher() event_dispatcher.bind("dispatch", container) path = 'nameko.messaging.PublishProvider.prepare' with patch(path, autospec=True) as prepare: # test start method event_dispatcher.prepare() assert event_dispatcher.exchange.name == "srcservice.events" assert prepare.called evt = Mock(type="eventtype", data="msg") event_dispatcher.inject(worker_ctx) producer = Mock() with patch.object( event_dispatcher, 'get_producer', autospec=True) as get_producer: get_producer.return_value = as_context_manager(producer) # test dispatch service.dispatch(evt) headers = event_dispatcher.get_message_headers(worker_ctx) producer.publish.assert_called_once_with( evt.data, exchange=event_dispatcher.exchange, headers=headers, routing_key=evt.type)
def test_unserialisable_headers(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = rabbit_config container.spawn_managed_thread = eventlet.spawn ctx_data = {'language': 'en', 'customheader': None} service = Mock() worker_ctx = CustomWorkerContext(container, service, DummyProvider('method'), data=ctx_data) publisher = PublishProvider(exchange=foobar_ex, queue=foobar_queue) publisher.bind("publish", container) publisher.prepare() publisher.start() publisher.inject(worker_ctx) service.publish("msg") messages = rabbit_manager.get_messages(vhost, foobar_queue.name) assert messages[0]['properties']['headers'] == { 'nameko.language': 'en', 'nameko.call_id_stack': ['service.method.0'], # no `customheader` }
def test_dispatch_to_rabbit(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.service_name = "srcservice" container.config = rabbit_config service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider()) dispatcher = EventDispatcher().bind(container, 'dispatch') dispatcher.setup() dispatcher.start() # we should have an exchange but no queues exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) assert "srcservice.events" in [exchange['name'] for exchange in exchanges] assert queues == [] # manually add a queue to capture the events rabbit_manager.create_queue(vhost, "event-sink", auto_delete=True) rabbit_manager.create_queue_binding( vhost, "srcservice.events", "event-sink", routing_key="eventtype") service.dispatch = dispatcher.get_dependency(worker_ctx) service.dispatch("eventtype", "msg") # test event receieved on manually added queue messages = rabbit_manager.get_messages(vhost, "event-sink") assert ['msg'] == [msg['payload'] for msg in messages]
def test_consume_provider(empty_config): container = Mock(spec=ServiceContainer) container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = empty_config worker_ctx = WorkerContext(container, None, DummyProvider()) spawn_worker = container.spawn_worker spawn_worker.return_value = worker_ctx queue_consumer = Mock() consume_provider = ConsumeProvider(queue=foobar_queue, requeue_on_error=False) consume_provider.queue_consumer = queue_consumer consume_provider.bind("name", container) message = Mock(headers={}) # test lifecycle consume_provider.prepare() queue_consumer.register_provider.assert_called_once_with(consume_provider) consume_provider.stop() queue_consumer.unregister_provider.assert_called_once_with( consume_provider) # test handling successful call queue_consumer.reset_mock() consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, 'result') queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call without requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = False consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, (Exception, Exception('Error'), "tb")) queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call with requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = True consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, (Exception, Exception('Error'), "tb")) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message) # test requeueing on ContainerBeingKilled (even without requeue_on_error) queue_consumer.reset_mock() consume_provider.requeue_on_error = False spawn_worker.side_effect = ContainerBeingKilled() consume_provider.handle_message("body", message) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message)
def test_publish_to_queue(empty_config, maybe_declare, patch_publisher): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config ctx_data = {'language': 'en'} service = Mock() worker_ctx = WorkerContext(container, service, "publish", data=ctx_data) publisher = PublishProvider(queue=foobar_queue) publisher.bind("publish", container) producer = Mock() connection = Mock() get_connection, get_producer = patch_publisher(publisher) get_connection.return_value = as_context_manager(connection) get_producer.return_value = as_context_manager(producer) # test declarations publisher.prepare() maybe_declare.assert_called_once_with(foobar_queue, connection) # test publish msg = "msg" headers = { 'nameko.language': 'en', 'nameko.call_id_stack': ['srcservice.publish.0'], } publisher.inject(worker_ctx) service.publish(msg) producer.publish.assert_called_once_with( msg, headers=headers, exchange=foobar_ex)
def test_unserialisable_headers(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = rabbit_config container.spawn_managed_thread = eventlet.spawn ctx_data = {'language': 'en', 'customheader': None} service = Mock() worker_ctx = CustomWorkerContext( container, service, 'method', data=ctx_data) publisher = PublishProvider(exchange=foobar_ex, queue=foobar_queue) publisher.bind("publish", container) publisher.prepare() publisher.start() publisher.inject(worker_ctx) service.publish("msg") messages = rabbit_manager.get_messages(vhost, foobar_queue.name) assert messages[0]['properties']['headers'] == { 'nameko.language': 'en', 'nameko.call_id_stack': ['service.method.0'], # no `customheader` }
def test_consume_from_rabbit(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.worker_ctx_cls = CustomWorkerContext container.service_name = "service" container.config = rabbit_config container.max_workers = 10 def spawn_thread(method, protected): return eventlet.spawn(method) container.spawn_managed_thread = spawn_thread worker_ctx = CustomWorkerContext(container, None, None) factory = DependencyFactory( ConsumeProvider, queue=foobar_queue, requeue_on_error=False) consumer = factory.create_and_bind_instance("injection_name", container) # prepare and start dependencies consumer.prepare() consumer.queue_consumer.prepare() consumer.start() consumer.queue_consumer.start() # test queue, exchange and binding created in rabbit exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name) assert "foobar_ex" in [exchange['name'] for exchange in exchanges] assert "foobar_queue" in [queue['name'] for queue in queues] assert "foobar_ex" in [binding['source'] for binding in bindings] # test message consumed from queue container.spawn_worker.return_value = worker_ctx headers = {'nameko.language': 'en', 'nameko.customheader': 'customvalue'} rabbit_manager.publish( vhost, foobar_ex.name, '', 'msg', properties=dict(headers=headers)) ctx_data = { 'language': 'en', 'customheader': 'customvalue', } with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method: method.assert_called_once_with( consumer, ('msg', ), {}, context_data=ctx_data, handle_result=ANY_PARTIAL) handle_result = method.call_args[1]['handle_result'] # ack message handle_result(worker_ctx, 'result') # stop will hang if the consumer hasn't acked or requeued messages with eventlet.timeout.Timeout(CONSUME_TIMEOUT): consumer.stop()
def test_event_dispatcher(empty_config): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider("dispatch")) event_dispatcher = EventDispatcher(retry_policy={'max_retries': 5}).bind( container, attr_name="dispatch") event_dispatcher.setup() service.dispatch = event_dispatcher.get_dependency(worker_ctx) from mock import ANY with patch('nameko.standalone.events.producers') as mock_producers: with mock_producers[ANY].acquire() as mock_producer: service.dispatch('eventtype', 'msg') headers = event_dispatcher.get_message_headers(worker_ctx) mock_producer.publish.assert_called_once_with( 'msg', exchange=ANY, headers=headers, routing_key='eventtype', retry=True, retry_policy={'max_retries': 5}) _, call_kwargs = mock_producer.publish.call_args exchange = call_kwargs['exchange'] assert exchange.name == 'srcservice.events'
def test_dispatch_to_rabbit(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = rabbit_config service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider()) dispatcher = EventDispatcher() dispatcher.bind("dispatch", container) dispatcher.prepare() dispatcher.start() # we should have an exchange but no queues exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) assert "srcservice.events" in [exchange['name'] for exchange in exchanges] assert queues == [] # manually add a queue to capture the events rabbit_manager.create_queue(vhost, "event-sink", auto_delete=True) rabbit_manager.create_binding(vhost, "srcservice.events", "event-sink", rt_key=ExampleEvent.type) dispatcher.inject(worker_ctx) service.dispatch(ExampleEvent("msg")) # test event receieved on manually added queue messages = rabbit_manager.get_messages(vhost, "event-sink") assert ['msg'] == [msg['payload'] for msg in messages]
def test_nova_rpc_provider(empty_config): rpc_consumer = Mock() message = Mock(headers={}) message_body = { 'method': 'method', 'args': { "arg": "arg_value" }, 'msg_id': 'msg_id', '_context_user_id': 'user_id' } class Service(object): def method(self, arg): pass container = Mock(spec=ServiceContainer) container.service_cls = Service container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = empty_config rpc_provider = NovaRpcProvider() rpc_provider.rpc_consumer = rpc_consumer rpc_provider.bind("method", container) container.spawn_worker.side_effect = ContainerBeingKilled() rpc_provider.handle_message(message_body, message) assert rpc_consumer.requeue_message.called
def test_publish_to_exchange(empty_config, maybe_declare, patch_publisher): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider("publish")) publisher = PublishProvider(exchange=foobar_ex) publisher.bind("publish", container) producer = Mock() connection = Mock() get_connection, get_producer = patch_publisher(publisher) get_connection.return_value = as_context_manager(connection) get_producer.return_value = as_context_manager(producer) # test declarations publisher.prepare() maybe_declare.assert_called_once_with(foobar_ex, connection) # test publish msg = "msg" publisher.inject(worker_ctx) service.publish(msg, publish_kwarg="value") headers = { 'nameko.call_id_stack': ['srcservice.publish.0'] } producer.publish.assert_called_once_with( msg, headers=headers, exchange=foobar_ex, retry=True, retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value")
def test_nova_rpc_provider(empty_config): rpc_consumer = Mock() message = Mock(headers={}) message_body = { 'method': 'method', 'args': {"arg": "arg_value"}, 'msg_id': 'msg_id', '_context_user_id': 'user_id' } class Service(object): def method(self, arg): pass container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.service_cls = Service container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = empty_config entrypoint = NovaRpc().bind(container, "method") entrypoint.setup() entrypoint.rpc_consumer = rpc_consumer container.spawn_worker.side_effect = ContainerBeingKilled() entrypoint.handle_message(message_body, message) assert rpc_consumer.requeue_message.called
def test_publish_to_exchange(empty_config, maybe_declare, patch_publisher): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config service = Mock() worker_ctx = WorkerContext(container, service, DummyProvider("publish")) publisher = PublishProvider(exchange=foobar_ex) publisher.bind("publish", container) producer = Mock() connection = Mock() get_connection, get_producer = patch_publisher(publisher) get_connection.return_value = as_context_manager(connection) get_producer.return_value = as_context_manager(producer) # test declarations publisher.prepare() maybe_declare.assert_called_once_with(foobar_ex, connection) # test publish msg = "msg" publisher.inject(worker_ctx) service.publish(msg, publish_kwarg="value") headers = {'nameko.call_id_stack': ['srcservice.publish.0']} producer.publish.assert_called_once_with(msg, headers=headers, exchange=foobar_ex, retry=True, retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value")
def test_stringify(): dep = DependencyProvider() assert str(dep).startswith('<DependencyProvider [unbound] at') container = Mock() container.service_name = 'foobar' dep.bind('spam', container) assert str(dep).startswith('<DependencyProvider [foobar.spam] at')
def test_stringify(): dep = DependencyProvider() assert str(dep).startswith("<DependencyProvider [unbound] at") container = Mock() container.service_name = "foobar" dep.bind("spam", container) assert str(dep).startswith("<DependencyProvider [foobar.spam] at")
def test_consume_provider(empty_config): container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = empty_config worker_ctx = WorkerContext(container, None, DummyProvider()) spawn_worker = container.spawn_worker spawn_worker.return_value = worker_ctx queue_consumer = Mock() consume_provider = Consumer(queue=foobar_queue, requeue_on_error=False).bind(container, "consume") consume_provider.queue_consumer = queue_consumer message = Mock(headers={}) # test lifecycle consume_provider.setup() queue_consumer.register_provider.assert_called_once_with(consume_provider) consume_provider.stop() queue_consumer.unregister_provider.assert_called_once_with(consume_provider) # test handling successful call queue_consumer.reset_mock() consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]["handle_result"] handle_result(worker_ctx, "result") queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call without requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = False consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]["handle_result"] handle_result(worker_ctx, None, (Exception, Exception("Error"), "tb")) queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call with requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = True consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]["handle_result"] handle_result(worker_ctx, None, (Exception, Exception("Error"), "tb")) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message) # test requeueing on ContainerBeingKilled (even without requeue_on_error) queue_consumer.reset_mock() consume_provider.requeue_on_error = False spawn_worker.side_effect = ContainerBeingKilled() consume_provider.handle_message("body", message) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message)
def test_service_policy_event_callback(self): # mock service policy event service_policy_event = Mock() service_policy_event.origin = 'policy_id' service_policy_event.service_name = 'UnitTestService' service_policy_event.op = 'test_op' # mock a container container = Mock() self.governance_controller.container = container # set it up so that service_name resolves neither to a service nor an agent container.proc_manager.is_local_service_process.return_value = False container.proc_manager.is_local_agent_process.return_value = False # add a pdp pdp = Mock() self.governance_controller.policy_decision_point_manager = pdp # check that the pdp is not called because service_name is neither a service nor an agent self.governance_controller.service_policy_event_callback(service_policy_event) self.assertEqual(pdp.called, False) ######### ######### # make the service_name a local service process container.proc_manager.is_local_service_process.return_value = True # set up mock policy client with rules policy_rules = 'policy_rules' pc = Mock() self.governance_controller.policy_client = pc self.governance_controller.system_actor_user_header = {} pc.get_active_service_access_policy_rules.return_value = policy_rules # set local process local_process = Mock() local_process.name = 'local_process' container.proc_manager.get_a_local_process.return_value = local_process # register process operation precondition self.governance_controller.register_process_operation_precondition(local_process, 'test_op', 'func1') # set up the active precondition op = Mock() op.op = 'test_op_2' op.preconditions = ['func2'] pc.get_active_process_operation_preconditions.return_value = [op] self.governance_controller.service_policy_event_callback(service_policy_event) # check that the service_policy_event_callback did not delete all registered preconditions (func1) on operation test_op self.assertEquals('test_op' in self.governance_controller.get_process_operation_dict(local_process.name), True) # and updated with the active one (func2) on test_op2 self.assertEquals('test_op_2' in self.governance_controller.get_process_operation_dict(local_process.name), True) # expect that policy rules are retrieved for resource pc.get_active_service_access_policy_rules.assert_called_with(service_name=service_policy_event.service_name, org_name=self.governance_controller.container_org_name, headers={}) pdp.load_service_policy_rules.assert_called_with(service_policy_event.service_name, policy_rules)
def test_entrypoint_str(): container = Mock() container.service_name = "sérvice" ext = Entrypoint() assert str(ext).startswith('<Entrypoint [unbound] at') bound = ext.bind(container, "føbar") assert str(bound).startswith("<Entrypoint [sérvice.føbar] at")
def test_dependency_str(): container = Mock() container.service_name = "sérvice" ext = DependencyProvider() assert str(ext).startswith('<DependencyProvider [unbound] at') bound = ext.bind(container, "føbar") assert str(bound).startswith("<DependencyProvider [sérvice.føbar] at")
def test_provider_interval_as_config_fallback(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = {} timer = TimerProvider(interval=1, config_key='spam-conf') timer.bind('foobar', container) timer.prepare() assert timer.interval == 1
def test_consume_from_rabbit(container_factory, rabbit_manager, rabbit_config): vhost = rabbit_config["vhost"] container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.worker_ctx_cls = CustomWorkerContext container.service_name = "service" container.config = rabbit_config container.max_workers = 10 def spawn_thread(method, protected): return eventlet.spawn(method) container.spawn_managed_thread = spawn_thread worker_ctx = CustomWorkerContext(container, None, DummyProvider()) consumer = Consumer(queue=foobar_queue, requeue_on_error=False).bind(container, "publish") # prepare and start extensions consumer.setup() consumer.queue_consumer.setup() consumer.start() consumer.queue_consumer.start() # test queue, exchange and binding created in rabbit exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name) assert "foobar_ex" in [exchange["name"] for exchange in exchanges] assert "foobar_queue" in [queue["name"] for queue in queues] assert "foobar_ex" in [binding["source"] for binding in bindings] # test message consumed from queue container.spawn_worker.return_value = worker_ctx headers = {"nameko.language": "en", "nameko.customheader": "customvalue"} rabbit_manager.publish(vhost, foobar_ex.name, "", "msg", properties=dict(headers=headers)) ctx_data = {"language": "en", "customheader": "customvalue"} with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method: method.assert_called_once_with(consumer, ("msg",), {}, context_data=ctx_data, handle_result=ANY_PARTIAL) handle_result = method.call_args[1]["handle_result"] # ack message handle_result(worker_ctx, "result") # stop will hang if the consumer hasn't acked or requeued messages with eventlet.timeout.Timeout(CONSUME_TIMEOUT): consumer.stop() consumer.queue_consumer.kill()
def test_provider_uses_config_for_interval(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = {'spam-conf': 10} container.spawn_managed_thread = eventlet.spawn timer = TimerProvider(interval=None, config_key='spam-conf') timer.bind('foobar', container) timer.prepare() assert timer.interval == 10
def test_consume_provider(empty_config): container = Mock(spec=ServiceContainer) container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = empty_config worker_ctx = WorkerContext(container, None, None) spawn_worker = container.spawn_worker spawn_worker.return_value = worker_ctx queue_consumer = Mock() consume_provider = ConsumeProvider(queue=foobar_queue, requeue_on_error=False) consume_provider.queue_consumer = queue_consumer consume_provider.bind("name", container) message = Mock(headers={}) # test lifecycle consume_provider.prepare() queue_consumer.register_provider.assert_called_once_with( consume_provider) consume_provider.stop() queue_consumer.unregister_provider.assert_called_once_with( consume_provider) # test handling successful call queue_consumer.reset_mock() consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, 'result') queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call without requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = False consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, Exception('Error')) queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call with requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = True consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, Exception('Error')) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message)
def install_with_no_tasks_test(self): """Install with no tasks.""" observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.InstallWithTasks.return_value = [] install_manager = InstallManager() install_manager.module_observers = [observer] main_task = install_manager.install_system_with_task() self.assertIsInstance(main_task, SystemInstallationTask) self.assertEqual(main_task._subtasks, [])
def test_stop_timer_immediatly(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = {} timer = TimerProvider(interval=5, config_key=None) timer.bind('foobar', container) timer.prepare() timer.start() eventlet.sleep(0.1) timer.stop() assert container.spawn_worker.call_count == 0 assert timer.gt.dead
def install_with_no_tasks_test(self): """Install with no tasks.""" observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.InstallWithTasks.return_value = [] install_manager = InstallManager() install_manager.on_module_observers_changed([observer]) main_task = install_manager.install_system_with_task() self.assertIsInstance(main_task, DBusMetaTask) self.assertEqual(main_task.name, "Install the system") self.assertEqual(main_task._subtasks, [])
def test_stop_timer_immediatly(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = {} timer = Timer(interval=5).bind(container, "method") timer.setup() timer.start() eventlet.sleep(0.1) timer.stop() assert container.spawn_worker.call_count == 0 assert timer.gt.dead
def test_reply_listener(get_rpc_exchange): container = Mock(spec=ServiceContainer) container.service_name = "exampleservice" exchange = Mock() get_rpc_exchange.return_value = exchange queue_consumer = Mock(spec=QueueConsumer) queue_consumer.bind("queue_consumer", container) reply_listener = ReplyListener() reply_listener.queue_consumer = queue_consumer reply_listener.bind("reply_listener", container) forced_uuid = uuid.uuid4().hex with patch('nameko.rpc.uuid', autospec=True) as patched_uuid: patched_uuid.uuid4.return_value = forced_uuid reply_listener.prepare() queue_consumer.prepare() queue = reply_listener.queue assert queue.name == "rpc.reply-exampleservice-{}".format(forced_uuid) assert queue.exchange == exchange assert queue.routing_key == forced_uuid queue_consumer.register_provider.assert_called_once_with(reply_listener) correlation_id = 1 reply_event = reply_listener.get_reply_event(correlation_id) assert reply_listener._reply_events == {1: reply_event} message = Mock() message.properties.get.return_value = correlation_id reply_listener.handle_message("msg", message) queue_consumer.ack_message.assert_called_once_with(message) assert reply_event.ready() assert reply_event.wait() == "msg" assert reply_listener._reply_events == {} with patch('nameko.rpc._log', autospec=True) as log: reply_listener.handle_message("msg", message) assert log.debug.call_args == call('Unknown correlation id: %s', correlation_id)
def test_reply_listener(get_rpc_exchange): container = Mock(spec=ServiceContainer) container.service_name = "exampleservice" exchange = Mock() get_rpc_exchange.return_value = exchange queue_consumer = Mock(spec=QueueConsumer) queue_consumer.bind("queue_consumer", container) reply_listener = ReplyListener() reply_listener.queue_consumer = queue_consumer reply_listener.bind("reply_listener", container) forced_uuid = uuid.uuid4().hex with patch('nameko.rpc.uuid', autospec=True) as patched_uuid: patched_uuid.uuid4.return_value = forced_uuid reply_listener.prepare() queue_consumer.prepare() queue = reply_listener.queue assert queue.name == "rpc.reply-exampleservice-{}".format(forced_uuid) assert queue.exchange == exchange assert queue.routing_key == forced_uuid queue_consumer.register_provider.assert_called_once_with(reply_listener) correlation_id = 1 reply_event = reply_listener.get_reply_event(correlation_id) assert reply_listener._reply_events == {1: reply_event} message = Mock() message.properties.get.return_value = correlation_id reply_listener.handle_message("msg", message) queue_consumer.ack_message.assert_called_once_with(message) assert reply_event.ready() assert reply_event.wait() == "msg" assert reply_listener._reply_events == {} with patch('nameko.rpc._log', autospec=True) as log: reply_listener.handle_message("msg", message) assert log.debug.call_args == call( 'Unknown correlation id: %s', correlation_id)
def test_kill_stops_timer(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.spawn_managed_thread = eventlet.spawn timer = Timer(interval=0).bind(container, "method") timer.setup() timer.start() with wait_for_call(1, container.spawn_worker): timer.kill() # unless the timer is dead, the following nap would cause a timer # to trigger eventlet.sleep(0.1) assert container.spawn_worker.call_count == 1
def test_event_handler(queue_consumer): container = Mock(spec=ServiceContainer) container.service_name = "destservice" # test default configuration event_handler = EventHandler("srcservice", "eventtype").bind( container, "foobar") event_handler.setup() assert event_handler.queue.durable is True assert event_handler.queue.routing_key == "eventtype" assert event_handler.queue.exchange.name == "srcservice.events" queue_consumer.register_provider.assert_called_once_with(event_handler) # test service pool handler event_handler = EventHandler("srcservice", "eventtype").bind( container, "foobar") event_handler.setup() assert (event_handler.queue.name == "evt-srcservice-eventtype--destservice.foobar") # test broadcast handler event_handler = EventHandler( "srcservice", "eventtype", handler_type=BROADCAST, reliable_delivery=False).bind(container, "foobar") event_handler.setup() assert event_handler.queue.name.startswith("evt-srcservice-eventtype-") # test singleton handler event_handler = EventHandler( "srcservice", "eventtype", handler_type=SINGLETON).bind( container, "foobar") event_handler.setup() assert event_handler.queue.name == "evt-srcservice-eventtype" # test reliable delivery event_handler = EventHandler("srcservice", "eventtype").bind( container, "foobar") event_handler.setup() assert event_handler.queue.auto_delete is False
def test_delete_service(self): sms = ServiceManagementService('secret', 'cert.pem') hosted_service = Mock(spec=HostedService) hosted_service.service_name = 'juju-bar' deployment = Mock(spec=Deployment) deployment.name = 'juju-bar-2' with patch.object(sms, 'delete_deployment', return_value='request') as dd_mock: with patch('winazure.wait_for_success', autospec=True) as ws_mock: with patch.object(sms, 'delete_hosted_service', autospec=True) as ds_mock: delete_service( sms, hosted_service, [deployment], pause=0, dry_run=False, verbose=False) dd_mock.assert_called_once_with('juju-bar', 'juju-bar-2') ws_mock.assert_called_once_with(sms, 'request', pause=0, verbose=False) ds_mock.assert_any_call('juju-bar')
def test_kill_stops_timer(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.spawn_managed_thread = eventlet.spawn timer = TimerProvider(interval=0, config_key=None) timer.bind('foobar', container) timer.prepare() timer.start() with wait_for_call(1, container.spawn_worker): timer.kill() # unless the timer is dead, the following nap would cause a timer # to trigger eventlet.sleep(0.1) assert container.spawn_worker.call_count == 1
def test_event_handler(queue_consumer): container = Mock(spec=ServiceContainer) container.service_name = "destservice" # test default configuration event_handler = EventHandler("srcservice", "eventtype").bind(container, "foobar") event_handler.setup() assert event_handler.queue.durable is True assert event_handler.queue.routing_key == "eventtype" assert event_handler.queue.exchange.name == "srcservice.events" queue_consumer.register_provider.assert_called_once_with(event_handler) # test service pool handler event_handler = EventHandler("srcservice", "eventtype").bind(container, "foobar") event_handler.setup() assert (event_handler.queue.name == "evt-srcservice-eventtype--destservice.foobar") # test broadcast handler event_handler = EventHandler("srcservice", "eventtype", handler_type=BROADCAST, reliable_delivery=False).bind(container, "foobar") event_handler.setup() assert event_handler.queue.name.startswith("evt-srcservice-eventtype-") # test singleton handler event_handler = EventHandler("srcservice", "eventtype", handler_type=SINGLETON).bind(container, "foobar") event_handler.setup() assert event_handler.queue.name == "evt-srcservice-eventtype" # test reliable delivery event_handler = EventHandler("srcservice", "eventtype").bind(container, "foobar") event_handler.setup() assert event_handler.queue.auto_delete is False
def test_cmd_rollback_to_unknown_ami(self, get_versions, cmd_set): '''Test cmd_rollback_to fails on missing ami_id in history''' ami_id = "ami-abcdefgh12345678" context = Mock(ef_version.EFVersionContext) context.env = "alpha0" context.key = "ami-id" context.limit = 10 context.service_name = "playheads" context.rollback_to = ami_id get_versions.return_value = self.versions with self.assertRaises(SystemExit) as e: ef_version.cmd_rollback_to(context) get_versions.assert_called_once_with(context) cmd_set.assert_not_called()
def install_one_task_test(self, proxy_getter): """Install with one task.""" observer = Mock() observer.is_service_available = True observer.service_name = "A" observer.proxy.InstallWithTasks.return_value = ["/A/1"] task_proxy = Mock() task_proxy.Steps = 1 proxy_getter.return_value = task_proxy install_manager = InstallManager() install_manager.module_observers = [observer] main_task = install_manager.install_system_with_task() proxy_getter.assert_called_once_with("A", "/A/1") self.assertIsInstance(main_task, SystemInstallationTask) self.assertEqual(main_task._subtasks, [task_proxy])
def test_rpc_consumer(get_rpc_exchange): container = Mock(spec=ServiceContainer) container.service_name = "exampleservice" container.service_cls = Mock(rpcmethod=lambda: None) exchange = Mock() get_rpc_exchange.return_value = exchange queue_consumer = Mock(spec=QueueConsumer) queue_consumer.bind("queue_consumer", container) consumer = RpcConsumer() consumer.queue_consumer = queue_consumer consumer.bind("rpc_consumer", container) provider = RpcProvider() provider.rpc_consumer = consumer provider.bind("rpcmethod", container) provider.prepare() consumer.prepare() queue_consumer.prepare() queue = consumer.queue assert queue.name == "rpc-exampleservice" assert queue.routing_key == "exampleservice.*" assert queue.exchange == exchange assert queue.durable queue_consumer.register_provider.assert_called_once_with(consumer) consumer.register_provider(provider) assert consumer._providers == set([provider]) routing_key = "exampleservice.rpcmethod" assert consumer.get_provider_for_method(routing_key) == provider routing_key = "exampleservice.invalidmethod" with pytest.raises(MethodNotFound): consumer.get_provider_for_method(routing_key) consumer.unregister_provider(provider) assert consumer._providers == set()
def test_delete_service(self): sms = ServiceManagementService('secret', 'cert.pem') hosted_service = Mock(spec=HostedService) hosted_service.service_name = 'juju-bar' deployment = Mock(spec=Deployment) deployment.name = 'juju-bar-2' with patch.object(sms, 'delete_deployment', return_value='request') as dd_mock: with patch('winazure.wait_for_success', autospec=True) as ws_mock: with patch.object(sms, 'delete_hosted_service', autospec=True) as ds_mock: delete_service(sms, hosted_service, [deployment], pause=0, dry_run=False, verbose=False) dd_mock.assert_called_once_with('juju-bar', 'juju-bar-2') ws_mock.assert_called_once_with(sms, 'request', pause=0, verbose=False) ds_mock.assert_any_call('juju-bar')
def test_publish_to_rabbit(rabbit_manager, rabbit_config): vhost = rabbit_config['vhost'] container = Mock(spec=ServiceContainer) container.service_name = "service" container.config = rabbit_config container.spawn_managed_thread = eventlet.spawn ctx_data = {'language': 'en', 'customheader': 'customvalue'} service = Mock() worker_ctx = CustomWorkerContext(container, service, DummyProvider('method'), data=ctx_data) publisher = PublishProvider(exchange=foobar_ex, queue=foobar_queue) publisher.bind("publish", container) # test queue, exchange and binding created in rabbit publisher.prepare() publisher.start() exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name) assert "foobar_ex" in [exchange['name'] for exchange in exchanges] assert "foobar_queue" in [queue['name'] for queue in queues] assert "foobar_ex" in [binding['source'] for binding in bindings] # test message published to queue publisher.inject(worker_ctx) service.publish("msg") messages = rabbit_manager.get_messages(vhost, foobar_queue.name) assert ['msg'] == [msg['payload'] for msg in messages] # test message headers assert messages[0]['properties']['headers'] == { 'nameko.language': 'en', 'nameko.customheader': 'customvalue', 'nameko.call_id_stack': ['service.method.0'], }
def test_publish_custom_headers(empty_config, maybe_declare, patch_publisher): container = Mock(spec=ServiceContainer) container.service_name = "srcservice" container.config = empty_config ctx_data = {'language': 'en', 'customheader': 'customvalue'} service = Mock() worker_ctx = CustomWorkerContext(container, service, DummyProvider('method'), data=ctx_data) publisher = PublishProvider(queue=foobar_queue) publisher.bind("publish", container) producer = Mock() connection = Mock() get_connection, get_producer = patch_publisher(publisher) get_connection.return_value = as_context_manager(connection) get_producer.return_value = as_context_manager(producer) # test declarations publisher.prepare() maybe_declare.assert_called_once_with(foobar_queue, connection) # test publish msg = "msg" headers = { 'nameko.language': 'en', 'nameko.customheader': 'customvalue', 'nameko.call_id_stack': ['srcservice.method.0'] } publisher.inject(worker_ctx) service.publish(msg, publish_kwarg="value") producer.publish.assert_called_once_with(msg, headers=headers, exchange=foobar_ex, retry=True, retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value")
def test_provider(): container = Mock(spec=ServiceContainer) container.service_name = "service" container.spawn_managed_thread = eventlet.spawn timer = Timer(interval=0.1).bind(container, "method") timer.setup() timer.start() assert timer.interval == 0.1 with wait_for_call(1, container.spawn_worker) as spawn_worker: with Timeout(1): timer.stop() # the timer should have stopped and should only have spawned # a single worker spawn_worker.assert_called_once_with(timer, (), {}) assert timer.gt.dead