From 55cb8e4026f025a351896909ba6fa05e3f882003 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Thu, 2 Jul 2015 00:16:51 -0700 Subject: [PATCH] OVS native DBListcommand if_exists support Add support for the if_exists flag to the OVS native db list command. Closes-Bug: #1470742 Closes-Bug: #1470894 Change-Id: Ife48d99c145cfab7f0f5523f4cdfd33492085355 --- neutron/agent/ovsdb/native/commands.py | 38 ++++++++++++++----- .../tests/functional/agent/test_ovs_lib.py | 14 +++++++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/neutron/agent/ovsdb/native/commands.py b/neutron/agent/ovsdb/native/commands.py index b8bb1b117..973c4cac1 100644 --- a/neutron/agent/ovsdb/native/commands.py +++ b/neutron/agent/ovsdb/native/commands.py @@ -351,24 +351,42 @@ class PortToBridgeCommand(BaseCommand): class DbListCommand(BaseCommand): def __init__(self, api, table, records, columns, if_exists): super(DbListCommand, self).__init__(api) + self.requested_info = {'records': records, 'columns': columns, + 'table': table} self.table = self.api._tables[table] self.columns = columns or self.table.columns.keys() + ['_uuid'] self.if_exists = if_exists if records: - self.records = [ - idlutils.row_by_record(self.api.idl, table, record).uuid - for record in records] + self.records = [] + for record in records: + try: + self.records.append(idlutils.row_by_record( + self.api.idl, table, record).uuid) + except idlutils.RowNotFound: + if self.if_exists: + continue + raise else: self.records = self.table.rows.keys() def run_idl(self, txn): - self.result = [ - { - c: idlutils.get_column_value(self.table.rows[uuid], c) - for c in self.columns - } - for uuid in self.records - ] + try: + self.result = [ + { + c: idlutils.get_column_value(self.table.rows[uuid], c) + for c in self.columns + if not self.if_exists or uuid in self.table.rows + } + for uuid in self.records + ] + except KeyError: + # NOTE(kevinbenton): this is converted to a RuntimeError for compat + # with the vsctl version. It might make more sense to change this + # to a RowNotFoundError in the future. + raise RuntimeError(_LE( + "Row removed from DB during listing. Request info: " + "Table=%(table)s. Columns=%(columns)s. " + "Records=%(records)s.") % self.requested_info) class DbFindCommand(BaseCommand): diff --git a/neutron/tests/functional/agent/test_ovs_lib.py b/neutron/tests/functional/agent/test_ovs_lib.py index f43048189..dc2e994cb 100644 --- a/neutron/tests/functional/agent/test_ovs_lib.py +++ b/neutron/tests/functional/agent/test_ovs_lib.py @@ -14,6 +14,7 @@ # under the License. import collections +import mock import uuid from neutron.agent.common import ovs_lib @@ -197,6 +198,19 @@ class OVSBridgeTestCase(OVSBridgeTestBase): expected = set([x.vif_id for x in vif_ports]) self.assertEqual(expected, ports) + def test_get_vif_port_set_with_missing_port(self): + self.create_ovs_port() + vif_ports = [self.create_ovs_vif_port()] + + # return an extra port to make sure the db list ignores it + orig = self.br.get_port_name_list + new_port_name_list = lambda: orig() + ['anotherport'] + mock.patch.object(self.br, 'get_port_name_list', + new=new_port_name_list).start() + ports = self.br.get_vif_port_set() + expected = set([vif_ports[0].vif_id]) + self.assertEqual(expected, ports) + def test_get_port_tag_dict(self): # Simple case tested in port test_set_get_clear_db_val pass -- 2.45.2