diff options
author | Ronald Bradford <ronald.bradford@gmail.com> | 2016-01-29 20:49:12 +0000 |
---|---|---|
committer | Ronald Bradford <ronald.bradford@gmail.com> | 2016-02-04 20:54:06 +0000 |
commit | f59bd45aa386f74f8767c9c5cf41d77c4912bb9b (patch) | |
tree | a2226ae4b97ea5a69dd6eb759c6568a2c97a8be5 | |
parent | 4baa7e024bda085a1774f83514e9c721de4ec58a (diff) | |
download | oslo-config-f59bd45aa386f74f8767c9c5cf41d77c4912bb9b.tar.gz |
refactor generator closures to private methods
Move inline closures to enable unit testing of methods.
Refactored additional code to enable future improvements of generated
comments.
Change-Id: I03e96b0ed10d5fcd2b61ee9cfcde4c0a34f78a54
-rw-r--r-- | oslo_config/generator.py | 61 | ||||
-rw-r--r-- | oslo_config/tests/test_generator.py | 81 |
2 files changed, 113 insertions, 29 deletions
diff --git a/oslo_config/generator.py b/oslo_config/generator.py index 3e801d0..b00ac43 100644 --- a/oslo_config/generator.py +++ b/oslo_config/generator.py @@ -287,6 +287,36 @@ def on_load_failure_callback(*args, **kwargs): raise +def _output_opts(f, group, namespaces): + f.format_group(group) + for (namespace, opts) in sorted(namespaces, + key=operator.itemgetter(0)): + f.write('\n#\n# From %s\n#\n' % namespace) + for opt in opts: + f.write('\n') + f.format(opt) + + +def _get_group_name(item): + group = item[0] + # The keys of the groups dictionary could be an OptGroup. Otherwise the + # help text of an OptGroup wouldn't be part of the generated sample + # file. It could also be just a plain group name without any further + # attributes. That's the reason why we have to differentiate here. + return group.name if isinstance(group, cfg.OptGroup) else group + + +def _get_groups(conf_ns): + groups = {'DEFAULT': []} + for namespace, listing in conf_ns: + for group, opts in listing: + if not opts: + continue + namespaces = groups.setdefault(group or 'DEFAULT', []) + namespaces.append((namespace, opts)) + return groups + + def generate(conf): """Generate a sample config file. @@ -303,39 +333,12 @@ def generate(conf): formatter = _OptFormatter(output_file=output_file, wrap_width=conf.wrap_width) - groups = {'DEFAULT': []} - for namespace, listing in _list_opts(conf.namespace): - for group, opts in listing: - if not opts: - continue - namespaces = groups.setdefault(group or 'DEFAULT', []) - namespaces.append((namespace, opts)) - - def _output_opts(f, group, namespaces): - f.format_group(group) - for (namespace, opts) in sorted(namespaces, - key=operator.itemgetter(0)): - f.write('\n#\n# From %s\n#\n' % namespace) - for opt in opts: - f.write('\n') - f.format(opt) - - def _get_group_name(item): - group = item[0] - # The keys of the groups dictionary could be an OptGroup. Otherwise the - # help text of an OptGroup wouldn't be part of the generated sample - # file. It could also be just a plain group name without any further - # attributes. That's the reason why we have to distinct this here. - if isinstance(group, cfg.OptGroup): - group_name = group.name - else: - group_name = group - return group_name + groups = _get_groups(_list_opts(conf.namespace)) # Output the "DEFAULT" section as the very first section _output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT')) - # output all other config sections with opts in alphabetical order + # output all other config sections with groups in alphabetical order for group, namespaces in sorted(groups.items(), key=_get_group_name): formatter.write('\n\n') _output_opts(formatter, group, namespaces) diff --git a/oslo_config/tests/test_generator.py b/oslo_config/tests/test_generator.py index 152c59a..ee94327 100644 --- a/oslo_config/tests/test_generator.py +++ b/oslo_config/tests/test_generator.py @@ -18,6 +18,7 @@ import fixtures import mock from oslotest import base from six import moves +import tempfile import testscenarios from oslo_config import cfg @@ -849,6 +850,86 @@ class IgnoreDoublesTestCase(base.BaseTestCase): self.assertEqual(len(config_opts), slurped_opts) +class GeneratorAdditionalTestCase(base.BaseTestCase): + + opts = [cfg.StrOpt('foo', help='foo option', default='fred'), + cfg.StrOpt('bar', help='bar option'), + cfg.StrOpt('foo_bar', help='foobar'), + cfg.StrOpt('str_opt', help='a string'), + cfg.BoolOpt('bool_opt', help='a boolean'), + cfg.IntOpt('int_opt', help='an integer')] + + def test_get_group_name(self): + name = "group1" + item = [name] + self.assertEqual(name, generator._get_group_name(item)) + + def test_get_group_name_as_optgroup(self): + name = "group2" + item = [cfg.OptGroup(name)] + self.assertEqual(name, generator._get_group_name(item)) + + def test_get_groups_empty_ns(self): + groups = generator._get_groups([]) + self.assertEqual({'DEFAULT': []}, groups) + + def test_get_groups_single_ns(self): + config = [("namespace1", [ + ("beta", self.opts), + ("alpha", self.opts)])] + groups = generator._get_groups(config) + self.assertEqual(['DEFAULT', 'alpha', 'beta'], sorted(groups)) + + def test_get_groups_multiple_ns(self): + config = [("namespace1", [ + ("beta", self.opts), + ("alpha", self.opts)]), + ("namespace2", [ + ("gamma", self.opts), + ("alpha", self.opts)])] + groups = generator._get_groups(config) + self.assertEqual(['DEFAULT', 'alpha', 'beta', 'gamma'], sorted(groups)) + + def test_output_opts_empty_default(self): + + config = [("namespace1", [ + ("alpha", [])])] + groups = generator._get_groups(config) + + fd, tmp_file = tempfile.mkstemp() + f = open(tmp_file, 'w+') + formatter = generator._OptFormatter(output_file=f) + expected = '''[DEFAULT] +''' + generator._output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT')) + f.close() + content = open(tmp_file).read() + self.assertEqual(expected, content) + + def test_output_opts_group(self): + + config = [("namespace1", [ + ("alpha", [self.opts[0]])])] + groups = generator._get_groups(config) + + fd, tmp_file = tempfile.mkstemp() + f = open(tmp_file, 'w+') + formatter = generator._OptFormatter(output_file=f) + expected = '''[alpha] + +# +# From namespace1 +# + +# foo option (string value) +#foo = fred +''' + generator._output_opts(formatter, 'alpha', groups.pop('alpha')) + f.close() + content = open(tmp_file).read() + self.assertEqual(expected, content) + + class GeneratorRaiseErrorTestCase(base.BaseTestCase): def test_generator_raises_error(self): |