Add unit tests for validator

We need to bump our minimum version for mock to 3.0.0 in order for
mocking of 'open' to work correctly with the ConfigParser. From the
mock changelog: "Issue #32933: unittest.mock.mock_open() now supports
iteration over the file contents."

Change-Id: I9522083b7b0f785fe0e9cbdf8a9042112820bed4
This commit is contained in:
Ben Nemec 2019-06-03 17:59:08 +00:00
parent 9513d26b47
commit dc9b711a3f
4 changed files with 123 additions and 5 deletions

View File

@ -20,7 +20,7 @@ keystoneauth1==3.4.0
linecache2==1.0.0
MarkupSafe==1.0
mccabe==0.2.1
mock==2.0.0
mock==3.0.0
mox3==0.20.0
netaddr==0.7.18
openstackdocstheme==1.18.1

View File

@ -0,0 +1,114 @@
# Copyright 2019 Red Hat, 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 oslotest import base
import six
from oslo_config import cfg
from oslo_config import fixture
from oslo_config import validator
OPT_DATA = {'options': {'foo': {'opts': [{'name': 'opt'}]},
'bar': {'opts': [{'name': 'opt'}]},
},
'deprecated_options': {'bar': [{'name': 'opt'}]}}
VALID_CONF = """
[foo]
opt = value
"""
DEPRECATED_CONF = """
[bar]
opt = value
"""
INVALID_CONF = """
[foo]
opts = value
"""
MISSING_GROUP_CONF = """
[oo]
opt = value
"""
class TestValidator(base.BaseTestCase):
def setUp(self):
super(TestValidator, self).setUp()
self.conf = cfg.ConfigOpts()
self.conf_fixture = self.useFixture(fixture.Config(self.conf))
validator._register_cli_opts(self.conf)
if six.PY2:
self.open_name = '__builtin__.open'
else:
self.open_name = 'builtins.open'
@mock.patch('oslo_config.validator.load_opt_data')
def test_passing(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf')
m = mock.mock_open(read_data=VALID_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(0, validator._validate(self.conf))
@mock.patch('oslo_config.validator.load_opt_data')
def test_deprecated(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf')
m = mock.mock_open(read_data=DEPRECATED_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(0, validator._validate(self.conf))
@mock.patch('oslo_config.validator.load_opt_data')
def test_deprecated_fatal_warnings(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf',
fatal_warnings=True)
m = mock.mock_open(read_data=DEPRECATED_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(1, validator._validate(self.conf))
@mock.patch('oslo_config.validator.load_opt_data')
def test_missing(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf')
m = mock.mock_open(read_data=INVALID_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(1, validator._validate(self.conf))
@mock.patch('oslo_config.validator.load_opt_data')
def test_missing_group(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf')
m = mock.mock_open(read_data=MISSING_GROUP_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(1, validator._validate(self.conf))
@mock.patch('oslo_config.validator.load_opt_data')
def test_exclude_groups(self, mock_lod):
mock_lod.return_value = OPT_DATA
self.conf_fixture.config(opt_data='mocked.yaml',
input_file='mocked.conf',
exclude_group=['oo'])
m = mock.mock_open(read_data=MISSING_GROUP_CONF)
with mock.patch(self.open_name, m):
self.assertEqual(0, validator._validate(self.conf))
def test_invalid_options(self):
self.assertRaises(RuntimeError, validator._validate, self.conf)

View File

@ -85,17 +85,21 @@ def _validate_opt(group, option, opt_data):
return option in name_data
def load_opt_data(conf):
with open(conf.opt_data) as f:
return yaml.safe_load(f)
def _validate(conf):
conf.register_opts(_validator_opts)
if conf.namespace:
groups = generator._get_groups(generator._list_opts(conf.namespace))
opt_data = generator._generate_machine_readable_data(groups, conf)
elif conf.opt_data:
with open(conf.opt_data) as f:
opt_data = yaml.safe_load(f)
opt_data = load_opt_data(conf)
else:
# TODO(bnemec): Implement this logic with group?
raise RuntimeError('Neither namespace or opt-data provided.')
raise RuntimeError('Neither namespace nor opt-data provided.')
sections = {}
parser = cfg.ConfigParser(conf.input_file, sections)
parser.parse()

View File

@ -24,7 +24,7 @@ sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD
sphinx!=1.6.6,!=1.6.7,>=1.6.2;python_version>='3.4' # BSD
# mocking framework
mock>=2.0.0 # BSD
mock>=3.0.0 # BSD
requests_mock>=1.5.0 # Apache-2.0
# Bandit security code scanner