ovsdbapp/ovsdbapp/tests/unit/backend/ovs_idl/test_idlutils.py

172 lines
6.7 KiB
Python

# Copyright 2016, Mirantis Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from ovsdbapp import api
from ovsdbapp.backend.ovs_idl import idlutils
from ovsdbapp.tests import base
class MockColumn(object):
def __init__(self, name, type, is_optional=False, test_value=None):
self.name = name
self.type = mock.MagicMock(
**{"key.type.name": type,
"is_optional": mock.Mock(return_value=is_optional),
})
# for test purposes only to operate with some values in condition_match
# testcase
self.test_value = test_value
class MockTable(object):
def __init__(self, name, *columns):
# columns is a list of tuples (col_name, col_type)
self.name = name
self.columns = {c.name: c for c in columns}
class MockRow(object):
def __init__(self, table):
self._table = table
def __getattr__(self, attr):
if attr in self._table.columns:
return self._table.columns[attr].test_value
return super(MockRow, self).__getattr__(attr)
class MockCommand(api.Command):
def __init__(self, result):
self.result = result
def execute(self, **kwargs):
pass
class TestIdlUtils(base.TestCase):
def test_condition_match(self):
"""Make sure that the function respects the following:
* if column type is_optional and value is a single element, value is
transformed to a length-1-list
* any other value is returned as it is, no type conversions
"""
table = MockTable("SomeTable",
MockColumn("tag", "integer", is_optional=True,
test_value=[42]),
MockColumn("num", "integer", is_optional=True,
test_value=[]),
MockColumn("ids", "integer", is_optional=False,
test_value=42),
MockColumn("comments", "string",
test_value=["a", "b", "c"]),
MockColumn("status", "string",
test_value="sorry for inconvenience"))
row = MockRow(table=table)
self.assertTrue(idlutils.condition_match(row, ("tag", "=", 42)))
# optional types can be compared only as single elements
self.assertRaises(ValueError,
idlutils.condition_match, row, ("tag", "!=", [42]))
# empty list comparison is ok for optional types though
self.assertTrue(idlutils.condition_match(row, ("tag", "!=", [])))
self.assertTrue(idlutils.condition_match(row, ("num", "=", [])))
# value = [] may be compared to a single elem if optional column type
self.assertTrue(idlutils.condition_match(row, ("num", "!=", 42)))
# no type conversion for non optional types
self.assertTrue(idlutils.condition_match(row, ("ids", "=", 42)))
self.assertTrue(idlutils.condition_match(
row, ("status", "=", "sorry for inconvenience")))
self.assertFalse(idlutils.condition_match(
row, ("status", "=", "sorry")))
# bad types
self.assertRaises(ValueError,
idlutils.condition_match, row, ("ids", "=", "42"))
self.assertRaises(ValueError,
idlutils.condition_match, row, ("ids", "!=", "42"))
self.assertRaises(ValueError,
idlutils.condition_match, row,
("ids", "!=", {"a": "b"}))
# non optional list types are kept as they are
self.assertTrue(idlutils.condition_match(
row, ("comments", "=", ["c", "b", "a"])))
# also true because list comparison is relaxed
self.assertTrue(idlutils.condition_match(
row, ("comments", "=", ["c", "b"])))
self.assertTrue(idlutils.condition_match(
row, ("comments", "!=", ["d"])))
def test_db_replace_record_dict(self):
obj = {'a': 1, 'b': 2}
self.assertIs(obj, idlutils.db_replace_record(obj))
def test_db_replace_record_dict_cmd(self):
obj = {'a': 1, 'b': MockCommand(2)}
res = {'a': 1, 'b': 2}
self.assertEqual(res, idlutils.db_replace_record(obj))
def test_db_replace_record_list(self):
obj = [1, 2, 3]
self.assertIs(obj, idlutils.db_replace_record(obj))
def test_db_replace_record_list_cmd(self):
obj = [1, MockCommand(2), 3]
res = [1, 2, 3]
self.assertEqual(res, idlutils.db_replace_record(obj))
def test_db_replace_record_tuple(self):
obj = (1, 2, 3)
self.assertIs(obj, idlutils.db_replace_record(obj))
def test_db_replace_record_tuple_cmd(self):
obj = (1, MockCommand(2), 3)
res = (1, 2, 3)
self.assertEqual(res, idlutils.db_replace_record(obj))
def test_db_replace_record(self):
obj = "test"
self.assertIs(obj, idlutils.db_replace_record(obj))
def test_db_replace_record_cmd(self):
obj = MockCommand("test")
self.assertEqual("test", idlutils.db_replace_record(obj))
@mock.patch('sys.platform', 'linux2')
def test_row_by_record_linux(self):
FAKE_RECORD = 'fake_record'
mock_idl_ = mock.MagicMock()
mock_table = mock.MagicMock(
rows={mock.sentinel.row: mock.sentinel.row_value})
mock_idl_.tables = {mock.sentinel.table_name: mock_table}
res = idlutils.row_by_record(mock_idl_,
mock.sentinel.table_name,
FAKE_RECORD)
self.assertEqual(mock.sentinel.row_value, res)
@mock.patch('sys.platform', 'win32')
def test_row_by_record_win(self):
FAKE_RECORD_GUID = '7b0f349d-5524-4d36-afff-5222b9fdee8c'
mock_idl_ = mock.MagicMock()
mock_table = mock.MagicMock(
rows={mock.sentinel.row: mock.sentinel.row_value})
mock_idl_.tables = {mock.sentinel.table_name: mock_table}
res = idlutils.row_by_record(mock_idl_,
mock.sentinel.table_name,
FAKE_RECORD_GUID)
self.assertEqual(mock.sentinel.row_value, res)