def setUp(self): super(TestWildcardMessages, self).setUp() self.tenant_id_1 = 'a8f964d4-6631-11e5-a79f-525400cfc32a' self.tenant_id_2 = 'ef1a6e90-6631-11e5-83cb-525400cfc326' # Create some tenants for msg in [ event.Event( resource=event.Resource( driver=router.Router.RESOURCE_NAME, id='ABCD', tenant_id=self.tenant_id_1, ), crud=event.CREATE, body={'key': 'value'}, ), event.Event( resource=event.Resource( driver=router.Router.RESOURCE_NAME, id='EFGH', tenant_id=self.tenant_id_2), crud=event.CREATE, body={'key': 'value'}, )]: self.w.handle_message(msg.resource.tenant_id, msg)
def setUp(self): super(TestWildcardMessages, self).setUp() self.conf = mock.patch.object(vm_manager.cfg, 'CONF').start() self.conf.boot_timeout = 1 self.conf.akanda_mgt_service_port = 5000 self.conf.max_retries = 3 self.conf.management_prefix = 'fdca:3ba5:a17a:acda::/64' mock.patch('akanda.rug.worker.nova').start() mock.patch('akanda.rug.worker.quantum').start() self.addCleanup(mock.patch.stopall) self.w = worker.Worker(0, mock.Mock()) # Create some tenants for msg in [ event.Event( tenant_id='98dd9c41-d3ac-4fd6-8927-567afa0b8fc3', router_id='ABCD', crud=event.CREATE, body={'key': 'value'}, ), event.Event( tenant_id='ac194fc5-f317-412e-8611-fb290629f624', router_id='EFGH', crud=event.CREATE, body={'key': 'value'}, ) ]: self.w.handle_message(msg.tenant_id, msg)
def test_existing_resource_of_many(self): sms = {} for resource_id in ['5678', 'ABCD', 'EFGH']: r = event.Resource( tenant_id=self.tenant_id, id=resource_id, driver=router.Router.RESOURCE_NAME, ) msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, ) # First time creates... sm1 = self.trm.get_state_machines(msg, self.ctx)[0] sms[resource_id] = sm1 # Second time should return the same objects... r = event.Resource( id='5678', tenant_id=self.tenant_id, driver=router.Router.RESOURCE_NAME, ) msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, ) sm2 = self.trm.get_state_machines(msg, self.ctx)[0] self.assertIs(sm2, sms['5678'])
def _make_event_from_message(message): """Turn a raw message from the wire into an event.Event object """ if 'oslo.message' in message: # Unpack the RPC call body and discard the envelope message = rpc_common.deserialize_msg(message) tenant_id = _get_tenant_id_for_message(message) crud = event.UPDATE router_id = None if message.get('method') == 'router_deleted': crud = event.DELETE router_id = message.get('args', {}).get('router_id') else: event_type = message.get('event_type', '') # Router id is not always present, but look for it as though # it is to avoid duplicating this line a few times. router_id = message.get('payload', {}).get('router', {}).get('id') if event_type.startswith('routerstatus.update'): # We generate these events ourself, so ignore them. return None if event_type == 'router.create.end': crud = event.CREATE elif event_type == 'router.delete.end': crud = event.DELETE router_id = message.get('payload', {}).get('router_id') elif event_type in _INTERFACE_NOTIFICATIONS: crud = event.UPDATE router_id = message.get('payload', {}).get('router.interface', {}).get('id') elif event_type in _INTERESTING_NOTIFICATIONS: crud = event.UPDATE elif event_type.endswith('.end'): crud = event.UPDATE elif event_type.startswith('akanda.rug.command'): LOG.debug('received a command: %r', message.get('payload')) # If the message does not specify a tenant, send it to everyone pl = message.get('payload', {}) tenant_id = pl.get('tenant_id', '*') router_id = pl.get('router_id') crud = event.COMMAND if pl.get('command') == commands.POLL: return event.Event( tenant_id='*', router_id='*', crud=event.POLL, body={}, ) else: # LOG.debug('ignoring message %r', message) return None return event.Event(tenant_id, router_id, crud, message)
def testIgnoring(self): tmpdir = tempfile.mkdtemp() fullname = os.path.join(tmpdir, 'ac194fc5-f317-412e-8611-fb290629f624') with open(fullname, 'a'): os.utime(fullname, None) self.addCleanup(lambda: os.unlink(fullname) and os.rmdir(tmpdir)) w = worker.Worker(0, mock.Mock(), ignore_directory=tmpdir) tenant_id = '98dd9c41-d3ac-4fd6-8927-567afa0b8fc3' router_id = 'ac194fc5-f317-412e-8611-fb290629f624' msg = event.Event( tenant_id=tenant_id, router_id=router_id, crud=event.CREATE, body={'key': 'value'}, ) # Create the router manager and state machine so we can # replace the send_message() method with a mock. trm = w._get_trms(tenant_id)[0] sm = trm.get_state_machines(msg, worker.WorkerContext())[0] with mock.patch.object(sm, 'send_message') as meth: # The router id is being ignored, so the send_message() # method shouldn't ever be invoked. meth.side_effect = AssertionError('send_message was called') w.handle_message(tenant_id, msg)
def setUp(self): super(TestCreatingRouter, self).setUp() self.conf = mock.patch.object(vm_manager.cfg, 'CONF').start() self.conf.boot_timeout = 1 self.conf.akanda_mgt_service_port = 5000 self.conf.max_retries = 3 self.conf.management_prefix = 'fdca:3ba5:a17a:acda::/64' mock.patch('akanda.rug.worker.nova').start() mock.patch('akanda.rug.worker.quantum').start() self.addCleanup(mock.patch.stopall) self.w = worker.Worker(0, mock.Mock()) self.tenant_id = '98dd9c41-d3ac-4fd6-8927-567afa0b8fc3' self.router_id = 'ac194fc5-f317-412e-8611-fb290629f624' self.hostname = 'akanda' self.msg = event.Event( tenant_id=self.tenant_id, router_id=self.router_id, crud=event.CREATE, body={'key': 'value'}, ) self.w.handle_message(self.tenant_id, self.msg)
def test(self): w = worker.Worker(0, mock.Mock()) tenant_id = '98dd9c41-d3ac-4fd6-8927-567afa0b8fc3' router_id = 'ac194fc5-f317-412e-8611-fb290629f624' msg = event.Event( tenant_id=tenant_id, router_id=router_id, crud=event.CREATE, body={'key': 'value'}, ) # Create the router manager and state machine so we can # replace the update() method with a mock. trm = w._get_trms(tenant_id)[0] sm = trm.get_state_machines(msg, self.worker_context)[0] with mock.patch.object(sm, 'update') as meth: w.handle_message(tenant_id, msg) # Add a null message so the worker loop will exit. We have # to do this directly, because if we do it through # handle_message() that triggers shutdown logic that keeps # the loop from working properly. w.work_queue.put(None) # We aren't using threads (and we trust that threads do # work) so we just invoke the thread target ourselves to # pretend. used_context = w._thread_target() meth.assert_called_once_with(used_context)
def setUp(self): super(WorkerTestBase, self).setUp() cfg.CONF.boot_timeout = 1 cfg.CONF.akanda_mgt_service_port = 5000 cfg.CONF.max_retries = 3 cfg.CONF.management_prefix = 'fdca:3ba5:a17a:acda::/64' cfg.CONF.num_worker_threads = 0 self.fake_nova = mock.patch('akanda.rug.worker.nova').start() fake_neutron_obj = mock.patch.object( neutron, 'Neutron', autospec=True).start() fake_neutron_obj.get_ports_for_instance.return_value = ( 'mgt_port', ['ext_port', 'int_port']) fake_neutron_obj.get_router_for_tenant.return_value = ( FakeFetchedResource()) self.fake_neutron = mock.patch.object( neutron, 'Neutron', return_value=fake_neutron_obj).start() self.w = worker.Worker(mock.Mock()) self.addCleanup(mock.patch.stopall) self.target = self.tenant_id r = event.Resource( tenant_id=self.tenant_id, id=self.router_id, driver=router.Router.RESOURCE_NAME, ) self.msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, )
def test_all_resources(self): for i in range(5): rid = str(uuid.uuid4()) driver = fakes.fake_driver(rid) sm = state.Automaton(driver=driver, worker_context=self.ctx, resource_id=driver.id, tenant_id=self.tenant_id, delete_callback=None, bandwidth_callback=None, queue_warning_threshold=5, reboot_error_threshold=5) self.trm.state_machines[rid] = sm r = event.Resource( tenant_id=self.tenant_id, id='*', driver=router.Router.RESOURCE_NAME, ) msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, ) sms = self.trm.get_state_machines(msg, self.ctx) self.assertEqual(5, len(sms))
def test_report_status_dispatched(self): with mock.patch.object(self.w, 'report_status') as meth: self.w.handle_message( 'debug', event.Event('*', event.COMMAND, {'command': commands.WORKERS_DEBUG}) ) meth.assert_called_once_with()
def test_handle_message_report_status(self): with mock.patch('akanda.rug.worker.cfg.CONF') as conf: self.w.handle_message( 'debug', event.Event('*', event.COMMAND, {'command': commands.WORKERS_DEBUG}) ) self.assertTrue(conf.log_opt_values.called)
def router_deleted(self, ctxt, router_id): tenant_id = _get_tenant_id_for_message(ctxt) resource = event.Resource('router', router_id, tenant_id) crud = event.DELETE e = event.Event(resource, crud, None) self.notification_queue.put((e.resource.tenant_id, e))
def testManageNoLock(self): self.enable_debug(resource_id='this-resource-id') self.w.handle_message( '*', event.Event('*', event.COMMAND, {'command': commands.RESOURCE_MANAGE, 'resource_id': 'this-resource-id'}), ) self.assert_not_in_debug(resource_id='this-resource-id')
def testManage(self): self.enable_debug(tenant_id='this-tenant-id') self.w.handle_message( '*', event.Event('*', event.COMMAND, {'command': commands.TENANT_MANAGE, 'tenant_id': 'this-tenant-id'}), ) self.assert_not_in_debug(tenant_id='this-tenant-id')
def test_default_router(self): msg = event.Event( tenant_id='1234', router_id=None, crud=event.CREATE, body={'key': 'value'}, ) sm = self.trm.get_state_machines(msg, self.ctx)[0] self.assertEqual(sm.router_id, self.default_router.id) self.assertIn(self.default_router.id, self.trm.state_machines)
def test_new_router(self): msg = event.Event( tenant_id='1234', router_id='5678', crud=event.CREATE, body={'key': 'value'}, ) sm = self.trm.get_state_machines(msg, self.ctx)[0] self.assertEqual(sm.router_id, '5678') self.assertIn('5678', self.trm.state_machines)
def testWithDebugs(self): self.enable_debug(tenant_id='this-tenant-id') self.w.handle_message( '*', event.Event('*', event.COMMAND, {'command': commands.TENANT_DEBUG, 'tenant_id': 'this-tenant-id'}), ) is_debug, _ = self.dbapi.tenant_in_debug('this-tenant-id') self.assertTrue(is_debug)
def testManageUnlocked(self): self.enable_debug(resource_id='this-resource-id') lock = threading.Lock() self.w._resource_locks['this-resource-id'] = lock self.w.handle_message( '*', event.Event('*', event.COMMAND, {'command': commands.RESOURCE_MANAGE, 'resource_id': 'this-resource-id'}), ) self.assert_not_in_debug(resource_id='this-resource-id')
def test_deleter_callback(self): msg = event.Event( tenant_id='1234', router_id='5678', crud=event.CREATE, body={'key': 'value'}, ) sm = self.trm.get_state_machines(msg, self.ctx)[0] self.assertIn('5678', self.trm.state_machines) sm._do_delete() self.assertNotIn('5678', self.trm.state_machines)
def testWithDebugs(self): self.w.handle_message( '*', event.Event('*', event.COMMAND, {'command': commands.RESOURCE_DEBUG, 'resource_id': 'this-resource-id', 'reason': 'foo'}), ) self.enable_debug(resource_id='this-resource-id') self.assertIn(('this-resource-id', 'foo'), self.dbapi.resources_in_debug())
def testWithDebugs(self): self.w.handle_message( '*', event.Event( '*', '', event.COMMAND, { 'payload': { 'command': commands.TENANT_DEBUG, 'tenant_id': 'this-tenant-id' } }), ) self.assertEqual(set(['this-tenant-id']), self.w._debug_tenants)
def testWithDebugs(self): self.w.handle_message( '*', event.Event( '*', '', event.COMMAND, { 'payload': { 'command': commands.ROUTER_DEBUG, 'router_id': 'this-router-id' } }), ) self.assertEqual(set(['this-router-id']), self.w._debug_routers)
def test_existing_router_of_many(self): sms = {} for router_id in ['5678', 'ABCD', 'EFGH']: msg = event.Event( tenant_id='1234', router_id=router_id, crud=event.CREATE, body={'key': 'value'}, ) # First time creates... sm1 = self.trm.get_state_machines(msg, self.ctx)[0] sms[router_id] = sm1 # Second time should return the same objects... msg = event.Event( tenant_id='1234', router_id='5678', crud=event.CREATE, body={'key': 'value'}, ) sm2 = self.trm.get_state_machines(msg, self.ctx)[0] self.assertIs(sm2, sms['5678'])
def test_process_notification_arbitrary_end_event(self): payload = {'router': {'id': 'fake_router_id'}} r = event.Resource( driver=router.Router.RESOURCE_NAME, id='fake_router_id', tenant_id='fake_tenant_id') e = event.Event( resource=r, crud=event.UPDATE, body=payload, ) self._test_notification('foo.bar.end', payload, e)
def test_process_notification_router_delete(self): payload = {'router_id': 'fake_router_id'} r = event.Resource( driver=router.Router.RESOURCE_NAME, id='fake_router_id', tenant_id='fake_tenant_id') e = event.Event( resource=r, crud=event.DELETE, body=payload, ) self._test_notification('router.delete.end', payload, e)
def test(self, mock_cfg): mock_cfg.CONF = mock.MagicMock( log_opt_values=mock.MagicMock()) tenant_id = '*' resource_id = '*' msg = event.Event( resource=resource_id, crud=event.COMMAND, body={'command': commands.CONFIG_RELOAD} ) self.w.handle_message(tenant_id, msg) self.assertTrue(mock_cfg.CONF.called) self.assertTrue(mock_cfg.CONF.log_opt_values.called)
def test_get_state_machine_no_resoruce_id(self): r = event.Resource( tenant_id=self.tenant_id, id=None, driver=router.Router.RESOURCE_NAME, ) msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, ) self.assertRaises(tenant.InvalidIncomingMessage, self.trm.get_state_machines, msg, self.ctx)
def _health_inspector(period, scheduler): """Runs in the thread. """ while True: time.sleep(period) LOG.debug('waking up') e = event.Event( tenant_id='*', router_id='*', crud=event.POLL, body={}, ) scheduler.handle_message('*', e)
def testManageNoLock(self): self.w._debug_routers = set(['this-router-id']) self.w.handle_message( '*', event.Event( '*', '', event.COMMAND, { 'payload': { 'command': commands.ROUTER_MANAGE, 'router_id': 'this-router-id' } }), ) self.assertEqual(set(), self.w._debug_routers)
def test__should_process_no_router_id_no_router_found(self): self.fake_cache.get_by_tenant.return_value = None r = event.Resource( driver=router.Router.RESOURCE_NAME, id=None, tenant_id='fake_tenant_id', ) msg = event.Event( resource=r, crud=event.CREATE, body={'key': 'value'}, ) self.assertFalse(self.w._should_process(msg))