
Allows for an option to be tagged with advanced true/ false, notifying the end user about uncommon usage. Such an option is not normally used, and will be moved to the bottom of the respective namespace. Only options set to true (default: false) will be tagged as such in generated sample files. Change-Id: I2689aba283e473bb293bf0cf0c1c4bcb5979d115 Implements: blueprint advanced-option
484 lines
14 KiB
Python
484 lines
14 KiB
Python
# 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 textwrap
|
|
|
|
import mock
|
|
from oslotest import base
|
|
|
|
from oslo_config import cfg
|
|
from oslo_config import sphinxext
|
|
|
|
|
|
class FormatGroupTest(base.BaseTestCase):
|
|
|
|
def test_none_in_default(self):
|
|
# option with None group placed in DEFAULT
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
help='this appears in the default group'),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
this appears in the default group
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_default_value(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
default='this is the default',
|
|
help='this appears in the default group'),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``this is the default``
|
|
|
|
this appears in the default group
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_min(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
min=1),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
:Minimum Value: 1
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_min_0(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
min=0),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
:Minimum Value: 0
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_max(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
max=1),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
:Maximum Value: 1
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_max_0(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
max=0),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
:Maximum Value: 0
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_with_choices(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
choices=['a', 'b', 'c', None, '']),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
:Valid Values: a, b, c, <None>, ''
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_group_obj_without_help(self):
|
|
# option with None group placed in DEFAULT
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name='group',
|
|
group_obj=cfg.OptGroup('group'),
|
|
opt_list=[cfg.StrOpt('opt_name')],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: group
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_group_obj_with_help(self):
|
|
# option with None group placed in DEFAULT
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name='group',
|
|
group_obj=cfg.OptGroup('group', help='group help'),
|
|
opt_list=[cfg.StrOpt('opt_name')],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: group
|
|
|
|
group help
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_deprecated_opts_without_deprecated_group(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
deprecated_name='deprecated_name',
|
|
)
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
.. list-table:: Deprecated Variations
|
|
:header-rows: 1
|
|
|
|
- * Group
|
|
* Name
|
|
- * DEFAULT
|
|
* deprecated_name
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_deprecated_opts_with_deprecated_group(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
deprecated_name='deprecated_name',
|
|
deprecated_group='deprecated_group',
|
|
)
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
.. list-table:: Deprecated Variations
|
|
:header-rows: 1
|
|
|
|
- * Group
|
|
* Name
|
|
- * deprecated_group
|
|
* deprecated_name
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_deprecated_for_removal(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
deprecated_for_removal=True,
|
|
deprecated_reason='because I said so',
|
|
deprecated_since='13.0',
|
|
)
|
|
],
|
|
)))
|
|
self.assertIn('.. warning::', results)
|
|
self.assertIn('because I said so', results)
|
|
self.assertIn('since 13.0', results)
|
|
|
|
def test_mutable(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
mutable=True),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
:Mutable: This option can be changed without restarting.
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_not_mutable(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.IntOpt('opt_name',
|
|
mutable=False),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: integer
|
|
:Default: ``<None>``
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_advanced(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
advanced=True),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
:Advanced Option: intended for advanced users and not used
|
|
:by the majority of users, and might have a significant
|
|
:effect on stability and/or performance.
|
|
|
|
''').lstrip(), results)
|
|
|
|
def test_not_advanced(self):
|
|
results = '\n'.join(list(sphinxext._format_group(
|
|
app=mock.Mock(),
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=[
|
|
cfg.StrOpt('opt_name',
|
|
advanced=False),
|
|
],
|
|
)))
|
|
self.assertEqual(textwrap.dedent('''
|
|
.. oslo.config:group:: DEFAULT
|
|
|
|
.. oslo.config:option:: opt_name
|
|
|
|
:Type: string
|
|
:Default: ``<None>``
|
|
|
|
''').lstrip(), results)
|
|
|
|
|
|
class FormatOptionHelpTest(base.BaseTestCase):
|
|
|
|
@mock.patch('oslo_config.generator._list_opts')
|
|
@mock.patch('oslo_config.sphinxext._format_group')
|
|
def test_split_namespaces(self, _format_group, _list_opts):
|
|
_list_opts.return_value = [
|
|
('namespace1', [(None, ['opt1'])]),
|
|
('namespace2', [(None, ['opt2'])]),
|
|
]
|
|
list(sphinxext._format_option_help(
|
|
app=None,
|
|
namespaces=['namespace1', 'namespace2'],
|
|
split_namespaces=True))
|
|
_format_group.assert_any_call(
|
|
app=None,
|
|
namespace='namespace1',
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=['opt1'],
|
|
)
|
|
_format_group.assert_any_call(
|
|
app=None,
|
|
namespace='namespace2',
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=['opt2'],
|
|
)
|
|
|
|
@mock.patch('oslo_config.generator._list_opts')
|
|
@mock.patch('oslo_config.sphinxext._format_group')
|
|
def test_dont_split_namespaces(self, _format_group, _list_opts):
|
|
_list_opts.return_value = [
|
|
('namespace1', [(None, ['opt1'])]),
|
|
('namespace2', [(None, ['opt2'])]),
|
|
]
|
|
list(sphinxext._format_option_help(
|
|
app=None,
|
|
namespaces=['namespace1', 'namespace2'],
|
|
split_namespaces=False))
|
|
_format_group.assert_called_once_with(
|
|
app=None,
|
|
namespace=None,
|
|
group_name=None,
|
|
group_obj=None,
|
|
opt_list=['opt1', 'opt2'],
|
|
)
|
|
|
|
@mock.patch('oslo_config.generator._list_opts')
|
|
@mock.patch('oslo_config.sphinxext._format_group')
|
|
def test_dont_split_namespaces_with_group(self, _format_group, _list_opts):
|
|
grp_obj = cfg.OptGroup('grp1')
|
|
_list_opts.return_value = [
|
|
('namespace1', [(grp_obj, ['opt1'])]),
|
|
('namespace2', [('grp1', ['opt2'])]),
|
|
]
|
|
list(sphinxext._format_option_help(
|
|
app=None,
|
|
namespaces=['namespace1', 'namespace2'],
|
|
split_namespaces=False))
|
|
_format_group.assert_any_call(
|
|
app=None,
|
|
namespace=None,
|
|
group_name='grp1',
|
|
group_obj=grp_obj,
|
|
opt_list=['opt1', 'opt2'],
|
|
)
|
|
|
|
@mock.patch('oslo_config.generator._list_opts')
|
|
@mock.patch('oslo_config.sphinxext._format_group')
|
|
def test_split_namespaces_with_group(self, _format_group, _list_opts):
|
|
grp_obj = cfg.OptGroup('grp1')
|
|
_list_opts.return_value = [
|
|
('namespace1', [(grp_obj, ['opt1'])]),
|
|
('namespace2', [('grp1', ['opt2'])]),
|
|
]
|
|
list(sphinxext._format_option_help(
|
|
app=None,
|
|
namespaces=['namespace1', 'namespace2'],
|
|
split_namespaces=True))
|
|
print(_format_group.call_args_list)
|
|
_format_group.assert_any_call(
|
|
app=None,
|
|
namespace='namespace1',
|
|
group_name='grp1',
|
|
group_obj=grp_obj,
|
|
opt_list=['opt1'],
|
|
)
|
|
_format_group.assert_any_call(
|
|
app=None,
|
|
namespace='namespace2',
|
|
group_name='grp1',
|
|
group_obj=None,
|
|
opt_list=['opt2'],
|
|
)
|