Add initialization in StringMatchingFilterObj class

In order to support LIKE statement filter in OVO objects,
StringMatchingFilterObj class is introduced. However, this class
does not provide initial attributes of "starts", "contains" and
"ends".

In real usage, if these attributes are not initialized, we will
hit failures in method apply_filters() in db/_model_query.py.

This patch adds the initialization back.

Secondly, a typo of "obj_utils.StringMatchingContains" is revised
in this patch too.

Change-Id: If828068d8d08ff09dff6c63d53320bc397d32448
Closes-Bug: #1724446
This commit is contained in:
Lujin 2017-10-18 15:09:37 +09:00
parent 0bbfad2de7
commit 28e8265651
3 changed files with 41 additions and 5 deletions

View File

@ -73,7 +73,7 @@ using example of DNSNameServer:
# for fetching objects with substrings in a string field:
from neutron.objects import utils as obj_utils
dnses = DNSNameServer.get_objects(context, address=obj_utils.StringMatchingContains('10.0.0'))
dnses = DNSNameServer.get_objects(context, address=obj_utils.StringContains('10.0.0'))
# will return list of all dns name servers from DB that has '10.0.0' in their addresses
# to update fields:

View File

@ -26,18 +26,17 @@ def convert_filters(**kwargs):
class StringMatchingFilterObj(object):
@property
def is_contains(self):
return bool(getattr(self, "contains"))
return bool(getattr(self, "contains", False))
@property
def is_starts(self):
return bool(getattr(self, "starts"))
return bool(getattr(self, "starts", False))
@property
def is_ends(self):
return bool(getattr(self, "ends"))
return bool(getattr(self, "ends", False))
class StringContains(StringMatchingFilterObj):

View File

@ -20,6 +20,7 @@ from neutron.db import _model_query as model_query
from neutron.db import models_v2
from neutron.objects import base
from neutron.objects.db import api
from neutron.objects import utils as obj_utils
from neutron.tests import base as test_base
from neutron.tests.unit import testlib_api
@ -98,6 +99,42 @@ class CRUDScenarioTestCase(testlib_api.SqlTestCase):
self.ctxt, self.model, name='foo', status=None)
self.assertEqual(obj, new_objs[0])
def test_get_objects_with_string_matching_filters_contains(self):
obj1 = api.create_object(self.ctxt, self.model, {'name': 'obj_con_1'})
obj2 = api.create_object(self.ctxt, self.model, {'name': 'obj_con_2'})
obj3 = api.create_object(self.ctxt, self.model, {'name': 'obj_3'})
objs = api.get_objects(
self.ctxt, self.model, name=obj_utils.StringContains('con'))
self.assertEqual(2, len(objs))
self.assertIn(obj1, objs)
self.assertIn(obj2, objs)
self.assertNotIn(obj3, objs)
def test_get_objects_with_string_matching_filters_starts(self):
obj1 = api.create_object(self.ctxt, self.model, {'name': 'pre_obj1'})
obj2 = api.create_object(self.ctxt, self.model, {'name': 'pre_obj2'})
obj3 = api.create_object(self.ctxt, self.model, {'name': 'obj_3'})
objs = api.get_objects(
self.ctxt, self.model, name=obj_utils.StringStarts('pre'))
self.assertEqual(2, len(objs))
self.assertIn(obj1, objs)
self.assertIn(obj2, objs)
self.assertNotIn(obj3, objs)
def test_get_objects_with_string_matching_filters_ends(self):
obj1 = api.create_object(self.ctxt, self.model, {'name': 'obj1_end'})
obj2 = api.create_object(self.ctxt, self.model, {'name': 'obj2_end'})
obj3 = api.create_object(self.ctxt, self.model, {'name': 'obj_3'})
objs = api.get_objects(
self.ctxt, self.model, name=obj_utils.StringEnds('end'))
self.assertEqual(2, len(objs))
self.assertIn(obj1, objs)
self.assertIn(obj2, objs)
self.assertNotIn(obj3, objs)
def test_get_object_create_update_delete(self):
obj = api.create_object(self.ctxt, self.model, {'name': 'foo'})