1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# We know we are not using root and handlers.
# pylint: disable-msg=W0612
"""Test canonical.config."""
__metaclass__ = type
from doctest import (
DocTestSuite,
ELLIPSIS,
NORMALIZE_WHITESPACE,
)
import os
import unittest
from lazr.config import ConfigSchema
from lazr.config.interfaces import ConfigErrors
import pkg_resources
import ZConfig
import canonical.config
# Configs that shouldn't be tested.
EXCLUDED_CONFIGS = ['lpnet-template']
# Calculate some landmark paths.
schema_file = pkg_resources.resource_filename('zope.app.server', 'schema.xml')
schema = ZConfig.loadSchema(schema_file)
here = os.path.dirname(canonical.config.__file__)
lazr_schema_file = os.path.join(here, 'schema-lazr.conf')
def make_test(config_file, description):
def test_function():
root, handlers = ZConfig.loadConfig(schema, config_file)
# Hack the config file name into test_function's __name__ so that the test
# -vv output is more informative. Unfortunately, FunctionTestCase's
# description argument doesn't do what we want.
test_function.__name__ = description
return unittest.FunctionTestCase(test_function)
def make_config_test(config_file, description):
"""Return a class to test a single lazr.config file.
The config file name is shown in the output of test.py -vv. eg.
(canonical.config.tests.test_config.../configs/schema.lazr.conf)
"""
class LAZRConfigTestCase(unittest.TestCase):
"""Test a lazr.config."""
def testConfig(self):
"""Validate the config against the schema.
All errors in the config are displayed when it is invalid.
"""
schema = ConfigSchema(lazr_schema_file)
config = schema.load(config_file)
try:
config.validate()
except ConfigErrors, error:
message = '\n'.join([str(e) for e in error.errors])
self.fail(message)
# Hack the config file name into the class name.
LAZRConfigTestCase.__name__ = '../' + description
return LAZRConfigTestCase
class TestCanonicalConfig(unittest.TestCase):
def test_dir(self):
# dir(config) returns methods, variables and section names.
config = canonical.config.config
names = set(dir(config))
self.assertTrue(names.issuperset(dir(config.__class__)))
self.assertTrue(names.issuperset(config.__dict__))
section_names = set(section.name for section in config._config)
self.assertTrue(names.issuperset(section_names))
def test_iter(self):
# iter(config) returns an iterator of sections.
config = canonical.config.config
sections = set(config._config)
self.assertEqual(sections, set(config))
def test_suite():
"""Return a suite of canonical.conf and all conf files."""
# We know we are not using dirnames.
# pylint: disable-msg=W0612
suite = unittest.TestSuite()
suite.addTest(DocTestSuite(
'canonical.config',
optionflags=NORMALIZE_WHITESPACE | ELLIPSIS,
))
load_testcase = unittest.defaultTestLoader.loadTestsFromTestCase
# Add a test for every launchpad[.lazr].conf file in our tree.
for config_dir in canonical.config.CONFIG_ROOT_DIRS:
for dirpath, dirnames, filenames in os.walk(config_dir):
if os.path.basename(dirpath) in EXCLUDED_CONFIGS:
del dirnames[:] # Don't look in subdirectories.
continue
for filename in filenames:
if filename == 'launchpad.conf':
config_file = os.path.join(dirpath, filename)
description = os.path.relpath(config_file, config_dir)
suite.addTest(make_test(config_file, description))
elif filename.endswith('-lazr.conf'):
# Test the lazr.config conf files.
config_file = os.path.join(dirpath, filename)
description = os.path.relpath(config_file, config_dir)
testcase = make_config_test(config_file, description)
suite.addTest(load_testcase(testcase))
else:
# This file is not a config that can be validated.
pass
# Other tests.
suite.addTest(load_testcase(TestCanonicalConfig))
return suite
|