Merge "[eventlet-removal] DHCP: move RPC init to service.start phase"
This commit is contained in:
@@ -121,13 +121,9 @@ class DhcpAgent(manager.Manager):
|
||||
opt_value=self.conf.resync_throttle)
|
||||
self._periodic_resync_event = threading.Event()
|
||||
self.cache = NetworkCache()
|
||||
self.dhcp_driver_cls = importutils.import_class(self.conf.dhcp_driver)
|
||||
self.plugin_rpc = DhcpPluginApi(topics.PLUGIN, self.conf.host)
|
||||
# create dhcp dir to store dhcp info
|
||||
dhcp_dir = os.path.dirname("/%s/dhcp/" % self.conf.state_path)
|
||||
fileutils.ensure_tree(dhcp_dir, mode=0o755)
|
||||
self.dhcp_version = self.dhcp_driver_cls.check_version()
|
||||
self._populate_networks_cache()
|
||||
# keep track of mappings between networks and routers for
|
||||
# metadata processing
|
||||
self._metadata_routers = {} # {network_id: router_id}
|
||||
@@ -153,6 +149,12 @@ class DhcpAgent(manager.Manager):
|
||||
self.restarted_metadata_proxy_set = set()
|
||||
|
||||
def init_host(self):
|
||||
super().init_host()
|
||||
|
||||
self.dhcp_driver_cls = importutils.import_class(self.conf.dhcp_driver)
|
||||
self.plugin_rpc = DhcpPluginApi(topics.PLUGIN, self.conf.host)
|
||||
self.dhcp_version = self.dhcp_driver_cls.check_version()
|
||||
self._populate_networks_cache()
|
||||
self.sync_state()
|
||||
|
||||
def _populate_networks_cache(self):
|
||||
@@ -1060,11 +1062,15 @@ class NetworkCache:
|
||||
class DhcpAgentWithStateReport(DhcpAgent):
|
||||
def __init__(self, host=None, conf=None):
|
||||
super().__init__(host=host, conf=conf)
|
||||
self.host = host
|
||||
|
||||
def init_host(self):
|
||||
super().init_host()
|
||||
self.state_rpc = agent_rpc.PluginReportStateAPI(topics.REPORTS)
|
||||
self.failed_report_state = False
|
||||
self.agent_state = {
|
||||
'binary': constants.AGENT_PROCESS_DHCP,
|
||||
'host': host,
|
||||
'host': self.host,
|
||||
'availability_zone': self.conf.AGENT.availability_zone,
|
||||
'topic': topics.DHCP_AGENT,
|
||||
'configurations': {
|
||||
|
||||
@@ -86,6 +86,7 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
|
||||
mock.patch('neutron.agent.rpc.PluginReportStateAPI').start()
|
||||
self.conf.set_override('check_child_processes_interval', 1, 'AGENT')
|
||||
self.agent = agent.DhcpAgentWithStateReport('localhost')
|
||||
self.agent.init_host()
|
||||
|
||||
self.ovs_driver = interface.OVSInterfaceDriver(self.conf)
|
||||
mock.patch('neutron.agent.common.ovs_lib.'
|
||||
|
||||
@@ -364,6 +364,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
common_config.init(sys.argv[1:])
|
||||
agent_mgr = dhcp_agent.DhcpAgentWithStateReport(
|
||||
'testhost')
|
||||
agent_mgr.init_host()
|
||||
eventlet.greenthread.sleep(1)
|
||||
agent_mgr.after_start()
|
||||
mock_periodic_resync.assert_called_once_with(agent_mgr)
|
||||
@@ -376,6 +377,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
def test_run_completes_single_pass(self):
|
||||
with mock.patch(DEVICE_MANAGER):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
attrs_to_mock = {
|
||||
a: mock.DEFAULT for a in
|
||||
['periodic_resync', 'start_ready_ports_loop',
|
||||
@@ -392,6 +394,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
network = mock.MagicMock()
|
||||
network.id = '1'
|
||||
dhcp = dhcp_agent.DhcpAgent(cfg.CONF)
|
||||
dhcp.init_host()
|
||||
self.assertTrue(dhcp.call_driver('foo', network))
|
||||
self.driver.assert_called_once_with(cfg.CONF,
|
||||
mock.ANY,
|
||||
@@ -416,6 +419,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
segments=[seg1, seg0])
|
||||
|
||||
agent = dhcp_agent.DhcpAgent(cfg.CONF)
|
||||
agent.init_host()
|
||||
with mock.patch.object(agent,
|
||||
'_call_driver') as _call_driver:
|
||||
self.assertTrue(agent.call_driver('enable', network))
|
||||
@@ -428,6 +432,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
def test_call_driver_no_network(self):
|
||||
network = None
|
||||
dhcp = dhcp_agent.DhcpAgent(cfg.CONF)
|
||||
dhcp.init_host()
|
||||
self.assertIsNone(dhcp.call_driver('foo', network))
|
||||
|
||||
def _test_call_driver_failure(self, exc=None,
|
||||
@@ -436,6 +441,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
network.id = '1'
|
||||
self.driver.return_value.foo.side_effect = exc or Exception
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(dhcp,
|
||||
'schedule_resync') as schedule_resync:
|
||||
self.assertIsNone(dhcp.call_driver('foo', network))
|
||||
@@ -475,6 +481,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
network = mock.MagicMock()
|
||||
self.driver().get_metadata_bind_interface.return_value = 'iface0'
|
||||
agent = dhcp_agent.DhcpAgent(cfg.CONF)
|
||||
agent.init_host()
|
||||
self.assertEqual(
|
||||
'iface0',
|
||||
agent.call_driver('get_metadata_bind_interface', network))
|
||||
@@ -486,6 +493,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
network.subnets[0] = fake_subnet1
|
||||
self.driver().get_metadata_bind_interface.return_value = 'iface0'
|
||||
agent = dhcp_agent.DhcpAgent(cfg.CONF)
|
||||
agent.init_host()
|
||||
self.assertEqual(
|
||||
'iface0',
|
||||
agent.call_driver('get_metadata_bind_interface', network))
|
||||
@@ -498,22 +506,23 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
mock_plugin.get_active_networks_info.return_value = active_networks
|
||||
plug.return_value = mock_plugin
|
||||
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp_obj = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp_obj.init_host()
|
||||
|
||||
attrs_to_mock = {a: mock.DEFAULT
|
||||
for a in ['disable_dhcp_helper', 'cache',
|
||||
'safe_configure_dhcp_for_network']}
|
||||
|
||||
with mock.patch.multiple(dhcp, **attrs_to_mock) as mocks:
|
||||
with mock.patch.multiple(dhcp_obj, **attrs_to_mock) as mocks:
|
||||
mocks['cache'].get_network_ids.return_value = known_net_ids
|
||||
mocks['cache'].get_port_ids.return_value = range(4)
|
||||
dhcp.sync_state()
|
||||
dhcp_obj.sync_state()
|
||||
|
||||
diff = set(known_net_ids) - set(active_net_ids)
|
||||
exp_disable = [mock.call(net_id) for net_id in diff]
|
||||
mocks['cache'].assert_has_calls([mock.call.get_network_ids()])
|
||||
mocks['disable_dhcp_helper'].assert_has_calls(exp_disable)
|
||||
self.assertEqual(set(range(4)), dhcp.dhcp_ready_ports)
|
||||
self.assertEqual(set(range(4)), dhcp_obj.dhcp_ready_ports)
|
||||
|
||||
def test_sync_state_initial(self):
|
||||
self._test_sync_state_helper([], ['a'])
|
||||
@@ -529,7 +538,11 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
active_net_ids = ['1', '2', '3', '4', '5']
|
||||
known_net_ids = ['1', '2', '3', '4', '5']
|
||||
self._test_sync_state_helper(known_net_ids, active_net_ids)
|
||||
mock_wait.assert_called_once()
|
||||
# As init_host called before the mocks take effect there are
|
||||
# a 1st call for wait with TypeErrors (sync_state is executed and
|
||||
# expects network objects via RPC)
|
||||
wait_calls = [mock.call(mock.ANY), mock.call(mock.ANY)]
|
||||
mock_wait.assert_has_calls(wait_calls)
|
||||
|
||||
def test_sync_state_for_all_networks_plugin_error(self):
|
||||
with mock.patch(DHCP_PLUGIN) as plug:
|
||||
@@ -539,6 +552,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
with mock.patch.object(dhcp_agent.LOG, 'exception') as log:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(dhcp,
|
||||
'schedule_resync') as schedule_resync:
|
||||
dhcp.sync_state()
|
||||
@@ -555,6 +569,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
with mock.patch.object(dhcp_agent.LOG, 'exception') as log:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(dhcp,
|
||||
'schedule_resync') as schedule_resync:
|
||||
dhcp.sync_state(['foo_network'])
|
||||
@@ -564,18 +579,21 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_periodic_resync(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(dhcp_agent.eventlet, 'spawn') as spawn:
|
||||
dhcp.periodic_resync()
|
||||
spawn.assert_called_once_with(dhcp._periodic_resync_helper)
|
||||
|
||||
def test_start_ready_ports_loop(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(dhcp_agent.eventlet, 'spawn') as spawn:
|
||||
dhcp.start_ready_ports_loop()
|
||||
spawn.assert_called_once_with(dhcp._dhcp_ready_ports_loop)
|
||||
|
||||
def test__dhcp_ready_ports_doesnt_log_exception_on_timeout(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.dhcp_ready_ports = set(range(4))
|
||||
|
||||
with mock.patch.object(dhcp.plugin_rpc, 'dhcp_ready_on_ports',
|
||||
@@ -590,6 +608,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test__dhcp_ready_ports_loop(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.dhcp_ready_ports = set(range(4))
|
||||
|
||||
with mock.patch.object(dhcp.plugin_rpc, 'dhcp_ready_on_ports',
|
||||
@@ -604,6 +623,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_dhcp_ready_ports_loop_with_limit_ports_per_call(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
sync_max = dhcp_agent.DHCP_READY_PORTS_SYNC_MAX
|
||||
port_count = sync_max + 1
|
||||
dhcp.dhcp_ready_ports = set(range(port_count))
|
||||
@@ -630,6 +650,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_dhcp_ready_ports_loop_with_limit_ports_per_call_prio(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
sync_max = dhcp_agent.DHCP_READY_PORTS_SYNC_MAX
|
||||
port_count = 4
|
||||
# port set ranges must be unique to differentiate results
|
||||
@@ -679,6 +700,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_configure_dhcp_for_network(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(
|
||||
dhcp, 'update_isolated_metadata_proxy') as ump, \
|
||||
mock.patch.object(
|
||||
@@ -691,6 +713,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_configure_dhcp_for_network_no_subnets_with_dhcp_enabled(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(
|
||||
dhcp, 'update_isolated_metadata_proxy') as ump, \
|
||||
mock.patch.object(
|
||||
@@ -705,6 +728,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
def test_safe_configure_dhcp_for_network(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(
|
||||
dhcp, 'update_isolated_metadata_proxy') as ump, \
|
||||
mock.patch.object(
|
||||
@@ -718,6 +742,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
def test_safe_configure_dhcp_for_network_exception(self):
|
||||
# This should return without raising an exception
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
with mock.patch.object(
|
||||
dhcp, 'configure_dhcp_for_network',
|
||||
side_effect=RuntimeError):
|
||||
@@ -732,6 +757,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
'IpAddrCommand.wait_until_address_ready') as mock_wait:
|
||||
mock_wait.return_value = True
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.update_isolated_metadata_proxy = mock.Mock()
|
||||
self.assertEqual(set(), dhcp.dhcp_ready_ports)
|
||||
dhcp.configure_dhcp_for_network(fake_network)
|
||||
@@ -744,6 +770,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
with mock.patch.object(metadata_driver,
|
||||
'MetadataDriver') as md_cls:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.configure_dhcp_for_network(fake_network)
|
||||
md_cls.spawn_monitored_metadata_proxy.assert_called_once_with(
|
||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY,
|
||||
@@ -761,6 +788,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
with mock.patch.object(metadata_driver,
|
||||
'MetadataDriver') as md_cls:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.configure_dhcp_for_network(fake_network)
|
||||
md_cls.destroy_monitored_metadata_proxy.assert_called_once_with(
|
||||
mock.ANY, fake_network.id, mock.ANY, fake_network.namespace)
|
||||
@@ -770,21 +798,36 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
network_id=fake_network.id)
|
||||
|
||||
def test_report_state_revival_logic(self):
|
||||
dhcp = dhcp_agent.DhcpAgentWithStateReport(HOSTNAME)
|
||||
with mock.patch.object(dhcp.state_rpc,
|
||||
'report_state') as report_state,\
|
||||
mock.patch.object(dhcp, "run"):
|
||||
report_state.return_value = agent_consts.AGENT_ALIVE
|
||||
dhcp._report_state()
|
||||
self.assertEqual({}, dhcp.needs_resync_reasons)
|
||||
dhcp_ = dhcp_agent.DhcpAgentWithStateReport(HOSTNAME)
|
||||
networks = [{'id': '1'}, {'id': '2'}]
|
||||
dhcp_.init_host()
|
||||
|
||||
report_state.return_value = agent_consts.AGENT_REVIVED
|
||||
dhcp._report_state()
|
||||
self.assertEqual(dhcp.needs_resync_reasons[None],
|
||||
['Agent has just been revived'])
|
||||
with mock.patch.object(
|
||||
dhcp_.plugin_rpc, 'get_active_networks_info',
|
||||
return_value=[dhcp.NetModel(n) for n in networks]):
|
||||
with mock.patch.object(dhcp_.state_rpc,
|
||||
'report_state') as report_state,\
|
||||
mock.patch.object(dhcp_, "run"):
|
||||
|
||||
dhcp_.sync_state()
|
||||
|
||||
report_state.return_value = agent_consts.AGENT_ALIVE
|
||||
dhcp_._report_state()
|
||||
|
||||
# Only MessagingTimeout is in the list as init_host
|
||||
# was called before the mock
|
||||
self.assertIn(None, dhcp_.needs_resync_reasons.keys())
|
||||
|
||||
report_state.return_value = agent_consts.AGENT_REVIVED
|
||||
dhcp_._report_state()
|
||||
# The 1st item in the list is the MessagingTimeout,
|
||||
# the 2nd one is the actual msg
|
||||
self.assertEqual(dhcp_.needs_resync_reasons[None][1],
|
||||
'Agent has just been revived')
|
||||
|
||||
def test_periodic_resync_helper(self):
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
resync_reasons = collections.OrderedDict(
|
||||
(('a', 'reason1'), ('b', 'reason2')))
|
||||
dhcp.needs_resync_reasons = resync_reasons
|
||||
@@ -798,6 +841,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
def test_periodic_resync_helper_with_event(self):
|
||||
with mock.patch.object(dhcp_agent.LOG, 'debug') as log:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
dhcp.schedule_resync('reason1', 'a')
|
||||
dhcp.schedule_resync('reason1', 'b')
|
||||
reasons = list(dhcp.needs_resync_reasons.keys())
|
||||
@@ -815,6 +859,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
|
||||
with mock.patch.object(dhcp_agent.LOG, 'debug') as log:
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
|
||||
self.driver.existing_dhcp_networks.assert_called_once_with(
|
||||
dhcp.conf,
|
||||
@@ -828,6 +873,7 @@ class TestDhcpAgent(base.BaseTestCase):
|
||||
self.driver.existing_dhcp_networks.return_value = networks
|
||||
|
||||
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
dhcp.init_host()
|
||||
|
||||
self.driver.existing_dhcp_networks.assert_called_once_with(
|
||||
dhcp.conf,
|
||||
@@ -861,6 +907,7 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
||||
cache_cls = self.cache_p.start()
|
||||
self.cache = mock.Mock()
|
||||
self.cache.is_port_message_stale.return_value = False
|
||||
self.cache.get_network_ids.return_value = {1, 2, 3}
|
||||
cache_cls.return_value = self.cache
|
||||
self.mock_makedirs_p = mock.patch("os.makedirs")
|
||||
self.mock_makedirs = self.mock_makedirs_p.start()
|
||||
@@ -868,6 +915,7 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
||||
'DhcpAgent._populate_networks_cache')
|
||||
self.mock_init = self.mock_init_p.start()
|
||||
self.dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
|
||||
self.dhcp.init_host()
|
||||
self.call_driver_p = mock.patch.object(self.dhcp, 'call_driver')
|
||||
self.call_driver = self.call_driver_p.start()
|
||||
self.schedule_resync_p = mock.patch.object(self.dhcp,
|
||||
|
||||
Reference in New Issue
Block a user