summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonald Bradford <ronald.bradford@gmail.com>2016-01-29 20:49:12 +0000
committerRonald Bradford <ronald.bradford@gmail.com>2016-02-04 20:54:06 +0000
commitf59bd45aa386f74f8767c9c5cf41d77c4912bb9b (patch)
treea2226ae4b97ea5a69dd6eb759c6568a2c97a8be5
parent4baa7e024bda085a1774f83514e9c721de4ec58a (diff)
downloadoslo-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.py61
-rw-r--r--oslo_config/tests/test_generator.py81
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):