Fix CI failed: test_get_volume_filter_options_using_config

Recently, CI failed(py27, py35 and other unit tests) due to
test_get_volume_filter_options_using_config case.

In patch[1], we remove deprecated query_volume_filters config option,
but the test case is fixed by a wrong way. The
``CONF.resource_query_filters_file`` is a **json path**, but NOT a
**json str**, if we want to overwrite it, we should overwrite the
_FILTERS_COLLECTION.[2]

Unfortunately, if we have already called the _initialize_filters in
other case (before this case), this error will not be exposed. So, we
didn't find this error occurring in first-CI.

This patch try to fix this issue.

Co-Authored-By: wanghao <sxmatch1986@gmail.com>

Closes-bug: #1809647

[1] https://review.openstack.org/#/c/620632/
[2] https://review.openstack.org/#/c/620632/2/cinder/api/common.py@356

Change-Id: I190cc67a001ffce2a533480e6e39e26cd3f981df
This commit is contained in:
Yikun Jiang 2018-12-24 17:41:04 +08:00 committed by wanghao
parent ea844fbee8
commit 785435a18f
3 changed files with 55 additions and 5 deletions

View File

@ -41,6 +41,7 @@ from oslo_utils import timeutils
import six import six
import testtools import testtools
from cinder.api import common as api_common
from cinder.common import config from cinder.common import config
from cinder import context from cinder import context
from cinder import coordination from cinder import coordination
@ -141,6 +142,18 @@ class TestCase(testtools.TestCase):
notifier.notifications = self.notifier.notifications notifier.notifications = self.notifier.notifications
return notifier return notifier
def _reset_filter_file(self):
self.override_config('resource_query_filters_file',
os.path.join(
os.path.abspath(
os.path.join(
os.path.dirname(__file__),
'..',
)
),
self.RESOURCE_FILTER_PATH))
api_common._FILTERS_COLLECTION = None
def setUp(self): def setUp(self):
"""Run before each test method to initialize test environment.""" """Run before each test method to initialize test environment."""
super(TestCase, self).setUp() super(TestCase, self).setUp()

View File

@ -16,8 +16,10 @@
import datetime import datetime
import iso8601 import iso8601
import json
import ddt import ddt
import fixtures
import mock import mock
from oslo_config import cfg from oslo_config import cfg
import six import six
@ -61,6 +63,8 @@ class VolumeApiTest(test.TestCase):
self.controller = volumes.VolumeController(self.ext_mgr) self.controller = volumes.VolumeController(self.ext_mgr)
self.maxDiff = None self.maxDiff = None
self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True)
# This will be cleaned up by the NestedTempfile fixture in base class
self.tmp_path = self.useFixture(fixtures.TempDir()).path
@mock.patch( @mock.patch(
'cinder.api.openstack.wsgi.Controller.validate_name_and_description') 'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
@ -1677,7 +1681,16 @@ class VolumeApiTest(test.TestCase):
def test_get_volume_filter_options_using_config(self): def test_get_volume_filter_options_using_config(self):
filter_list = ["name", "status", "metadata", "bootable", filter_list = ["name", "status", "metadata", "bootable",
"migration_status", "availability_zone", "group_id"] "migration_status", "availability_zone", "group_id"]
self.override_config('resource_query_filters_file', # Clear the filters collection to make sure the filters collection
{'volume': filter_list}) # cache can be reloaded using tmp filter file.
common._FILTERS_COLLECTION = None
tmp_filter_file = self.tmp_path + '/resource_filters_tests.json'
self.override_config('resource_query_filters_file', tmp_filter_file)
with open(tmp_filter_file, 'w') as f:
f.write(json.dumps({"volume": filter_list}))
self.assertEqual(filter_list, self.assertEqual(filter_list,
self.controller._get_volume_filter_options()) self.controller._get_volume_filter_options())
# Reset the CONF.resource_query_filters_file and clear the filters
# collection to avoid leaking other cases, and it will be re-loaded
# from CONF.resource_query_filters_file in next call.
self._reset_filter_file()

View File

@ -14,13 +14,16 @@
import datetime import datetime
import ddt import ddt
import iso8601 import iso8601
import json
import fixtures
import mock import mock
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from oslo_utils import strutils from oslo_utils import strutils
from six.moves import http_client from six.moves import http_client
import webob import webob
from cinder.api import common
from cinder.api import extensions from cinder.api import extensions
from cinder.api import microversions as mv from cinder.api import microversions as mv
from cinder.api.v2.views.volumes import ViewBuilder from cinder.api.v2.views.volumes import ViewBuilder
@ -58,8 +61,13 @@ class VolumeApiTest(test.TestCase):
self.flags(host='fake') self.flags(host='fake')
self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True)
# This will be cleaned up by the NestedTempfile fixture in base class
self.tmp_path = self.useFixture(fixtures.TempDir()).path
def test_check_volume_filters_called(self): def test_check_volume_filters_called(self):
# Clear the filters collection to make sure the filters collection
# cache can be reloaded using tmp filter file.
common._FILTERS_COLLECTION = None
with mock.patch.object(vol_get.API, with mock.patch.object(vol_get.API,
'check_volume_filters') as volume_get: 'check_volume_filters') as volume_get:
req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True') req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True')
@ -68,15 +76,24 @@ class VolumeApiTest(test.TestCase):
req.headers = mv.get_mv_header(mv.BASE_VERSION) req.headers = mv.get_mv_header(mv.BASE_VERSION)
req.environ['cinder.context'].is_admin = True req.environ['cinder.context'].is_admin = True
tmp_filter_file = self.tmp_path + '/resource_filters_tests.json'
self.override_config('resource_query_filters_file', self.override_config('resource_query_filters_file',
{'volume': ['bootable']}) tmp_filter_file)
with open(tmp_filter_file, 'w') as f:
f.write(json.dumps({"volume": ['bootable']}))
self.controller.index(req) self.controller.index(req)
filters = req.params.copy() filters = req.params.copy()
volume_get.assert_called_with(filters, False) volume_get.assert_called_with(filters, False)
# Reset the CONF.resource_query_filters_file and clear the filters
# collection to avoid leaking other cases, and it will be re-loaded
# from CONF.resource_query_filters_file in next call.
self._reset_filter_file()
def test_check_volume_filters_strict_called(self): def test_check_volume_filters_strict_called(self):
# Clear the filters collection to make sure the filters collection
# cache can be reloaded using tmp filter file.
common._FILTERS_COLLECTION = None
with mock.patch.object(vol_get.API, with mock.patch.object(vol_get.API,
'check_volume_filters') as volume_get: 'check_volume_filters') as volume_get:
req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True') req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True')
@ -87,12 +104,19 @@ class VolumeApiTest(test.TestCase):
req.api_version_request = mv.get_api_version( req.api_version_request = mv.get_api_version(
mv.VOLUME_LIST_BOOTABLE) mv.VOLUME_LIST_BOOTABLE)
tmp_filter_file = self.tmp_path + '/resource_filters_tests.json'
self.override_config('resource_query_filters_file', self.override_config('resource_query_filters_file',
{'volume': ['bootable']}) tmp_filter_file)
with open(tmp_filter_file, 'w') as f:
f.write(json.dumps({"volume": ['bootable']}))
self.controller.index(req) self.controller.index(req)
filters = req.params.copy() filters = req.params.copy()
volume_get.assert_called_with(filters, True) volume_get.assert_called_with(filters, True)
# Reset the CONF.resource_query_filters_file and clear the filters
# collection to avoid leaking other cases, and it will be re-loaded
# from CONF.resource_query_filters_file in next call.
self._reset_filter_file()
def _create_volume_with_glance_metadata(self): def _create_volume_with_glance_metadata(self):
vol1 = db.volume_create(self.ctxt, {'display_name': 'test1', vol1 = db.volume_create(self.ctxt, {'display_name': 'test1',