From 426408359951eadcbbcfe483622e0e95db8ea8da Mon Sep 17 00:00:00 2001 From: Omer Anson Date: Wed, 1 Jun 2016 10:18:49 +0300 Subject: [PATCH] Generate OVSDB schema helper in a separate method Move the generation of the schema helper in OVSDB connection to a different method In the OVSDB connection class, move the code retrieving the schema helper to a separate method. This will allow subclasses to override this method, and retrieve the schema helper in a different manner, or provide it to the Connection subclass in advance. This use-case came up in Dragonflow, where we wanted to retrieve specific columns within specific tables, and not the whole tables. Change-Id: I634841a2402e5d9bcbf1983a17eee2bb1a6299fb Related-Bug: 1612403 --- neutron/agent/ovsdb/native/connection.py | 49 ++++++++++++------- .../agent/ovsdb/native/test_connection.py | 16 ++++++ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/neutron/agent/ovsdb/native/connection.py b/neutron/agent/ovsdb/native/connection.py index 013e2e70045..ebc7529b933 100644 --- a/neutron/agent/ovsdb/native/connection.py +++ b/neutron/agent/ovsdb/native/connection.py @@ -61,6 +61,7 @@ class Connection(object): self.lock = threading.Lock() self.schema_name = schema_name self.idl_class = idl_class or idl.Idl + self._schema_filter = None def start(self, table_name_list=None): """ @@ -70,30 +71,14 @@ class Connection(object): schema_helper will register all tables for given schema_name as default. """ + self._schema_filter = table_name_list with self.lock: if self.idl is not None: return - try: - helper = idlutils.get_schema_helper(self.connection, - self.schema_name) - except Exception: - # We may have failed do to set-manager not being called - helpers.enable_connection_uri(self.connection) + helper = self.get_schema_helper() + self.update_schema_helper(helper) - # There is a small window for a race, so retry up to a second - @retrying.retry(wait_exponential_multiplier=10, - stop_max_delay=1000) - def do_get_schema_helper(): - return idlutils.get_schema_helper(self.connection, - self.schema_name) - helper = do_get_schema_helper() - - if table_name_list is None: - helper.register_all() - else: - for table_name in table_name_list: - helper.register_table(table_name) self.idl = self.idl_class(self.connection, helper) idlutils.wait_for_change(self.idl, self.timeout) self.poller = poller.Poller() @@ -101,6 +86,32 @@ class Connection(object): self.thread.setDaemon(True) self.thread.start() + def get_schema_helper(self): + """Retrieve the schema helper object from OVSDB""" + try: + helper = idlutils.get_schema_helper(self.connection, + self.schema_name) + except Exception: + # We may have failed do to set-manager not being called + helpers.enable_connection_uri(self.connection) + + # There is a small window for a race, so retry up to a second + @retrying.retry(wait_exponential_multiplier=10, + stop_max_delay=1000) + def do_get_schema_helper(): + return idlutils.get_schema_helper(self.connection, + self.schema_name) + helper = do_get_schema_helper() + + return helper + + def update_schema_helper(self, helper): + if self._schema_filter: + for table_name in self._schema_filter: + helper.register_table(table_name) + else: + helper.register_all() + def run(self): while True: self.idl.wait(self.poller) diff --git a/neutron/tests/unit/agent/ovsdb/native/test_connection.py b/neutron/tests/unit/agent/ovsdb/native/test_connection.py index 7c9f4ee96c1..f60ea070bab 100644 --- a/neutron/tests/unit/agent/ovsdb/native/test_connection.py +++ b/neutron/tests/unit/agent/ovsdb/native/test_connection.py @@ -50,6 +50,22 @@ class TestOVSNativeConnection(base.BaseTestCase): def test_start_with_table_name_list(self): self._test_start(table_name_list=['fake-table1', 'fake-table2']) + @mock.patch.object(connection, 'TransactionQueue') + @mock.patch.object(idl, 'Idl') + @mock.patch.object(idlutils, 'wait_for_change') + def test_start_call_graph(self, wait_for_change, idl, transaction_queue): + self.connection = connection.Connection( + mock.sentinel, mock.sentinel, mock.sentinel) + self.connection.get_schema_helper = mock.Mock() + helper = self.connection.get_schema_helper.return_value + self.connection.update_schema_helper = mock.Mock() + with mock.patch.object(poller, 'Poller') as poller_mock,\ + mock.patch('threading.Thread'): + poller_mock.return_value.block.side_effect = eventlet.sleep + self.connection.start() + self.connection.get_schema_helper.assert_called_once_with() + self.connection.update_schema_helper.assert_called_once_with(helper) + def test_transaction_queue_init(self): # a test to cover py34 failure during initialization (LP Bug #1580270) # make sure no ValueError: can't have unbuffered text I/O is raised