28
29
from twisted.application.service import MultiService
29
30
from twisted.python.usage import UsageError
34
class TestConfig(TestCase):
35
"""Tests for `provisioningserver.plugin.Config`."""
37
def test_defaults(self):
46
'logfile': '/some/where.log',
53
mandatory_arguments = {
54
"logfile": "/some/where.log",
56
observed = Config.to_python(mandatory_arguments)
57
self.assertEqual(expected, observed)
60
# Configuration can be parsed from a snippet of YAML.
61
observed = Config.parse(
62
b'logfile: "/some/where.log"')
63
self.assertEqual("/some/where.log", observed["logfile"])
66
# Configuration can be loaded and parsed from a file.
67
filename = os.path.join(
68
self.useFixture(TempDir()).path, "config.yaml")
69
with open(filename, "wb") as stream:
70
stream.write(b'logfile: "/some/where.log"')
71
observed = Config.load(filename)
72
self.assertEqual("/some/where.log", observed["logfile"])
74
def test_load_example(self):
75
# The example configuration can be loaded and validated.
76
filename = os.path.join(
77
os.path.dirname(__file__), os.pardir,
78
os.pardir, os.pardir, "etc", "pserv.yaml")
81
def test_oops_directory_without_reporter(self):
82
# It is an error to omit the OOPS reporter if directory is specified.
84
'logfile: "/some/where.log"\n'
86
' directory: /tmp/oops\n'
88
expected = MatchesException(
89
formencode.Invalid, "oops: You must give a value for reporter")
91
partial(Config.parse, config),
32
95
class TestOptions(TestCase):
33
96
"""Tests for `provisioningserver.plugin.Options`."""
36
"RabbitMQ is not yet a required component "
37
"of a running MaaS installation. Re-enable "
38
"when RabbitMQ is once again needed; remove "
39
"the other similarly named test.")
40
def test_defaults_SKIPPED(self):
43
"brokerhost": "127.0.0.1",
44
"brokerpassword": None,
48
"logfile": "pserv.log",
50
"oops-reporter": "MAAS-PS",
53
self.assertEqual(expected, options.defaults)
55
98
def test_defaults(self):
56
99
options = Options()
58
"logfile": "pserv.log",
60
"oops-reporter": "MAAS-PS",
100
expected = {"config-file": "pserv.yaml"}
63
101
self.assertEqual(expected, options.defaults)
65
103
def check_exception(self, options, message, *arguments):
68
106
partial(options.parseOptions, arguments),
69
107
Raises(MatchesException(UsageError, message)))
72
"RabbitMQ is not yet a required component "
73
"of a running MaaS installation.")
74
def test_option_brokeruser_required(self):
78
"--brokeruser must be specified")
81
"RabbitMQ is not yet a required component "
82
"of a running MaaS installation.")
83
def test_option_brokerpassword_required(self):
87
"--brokerpassword must be specified",
88
"--brokeruser", "Bob")
90
109
def test_parse_minimal_options(self):
91
110
options = Options()
92
111
# The minimal set of options that must be provided.
94
113
options.parseOptions(arguments) # No error.
97
"RabbitMQ is not yet a required component "
98
"of a running MaaS installation. Re-enable "
99
"when RabbitMQ is once again needed; remove "
100
"the other similarly named test.")
101
def test_parse_int_options_SKIPPED(self):
102
# Some options are converted to ints.
105
"--brokerpassword", "Hoskins",
106
"--brokerport", "4321",
107
"--brokeruser", "Bob",
110
options.parseOptions(arguments)
111
self.assertEqual(4321, options["brokerport"])
112
self.assertEqual(3456, options["port"])
114
def test_parse_int_options(self):
115
# Some options are converted to ints.
120
options.parseOptions(arguments)
121
self.assertEqual(3456, options["port"])
124
"RabbitMQ is not yet a required component "
125
"of a running MaaS installation. Re-enable "
126
"when RabbitMQ is once again needed; remove "
127
"the other similarly named test.")
128
def test_parse_broken_int_options_SKIPPED(self):
129
# An error is raised if the integer options do not contain integers.
132
"--brokerpassword", "Hoskins",
133
"--brokerport", "Jr.",
134
"--brokeruser", "Bob",
137
UsageError, options.parseOptions, arguments)
139
def test_parse_broken_int_options(self):
140
# An error is raised if the integer options do not contain integers.
143
"--port", "Metallica",
146
UsageError, options.parseOptions, arguments)
149
"RabbitMQ is not yet a required component "
150
"of a running MaaS installation. Re-enable "
151
"when RabbitMQ is once again needed; remove "
152
"the other similarly named test.")
153
def test_oops_dir_without_reporter_SKIPPED(self):
154
# It is an error to omit the OOPS reporter if directory is specified.
157
"--brokerpassword", "Hoskins",
158
"--brokeruser", "Bob",
159
"--oops-dir", "/some/where",
160
"--oops-reporter", "",
162
expected = MatchesException(
163
UsageError, "A reporter must be supplied")
165
partial(options.parseOptions, arguments),
168
def test_oops_dir_without_reporter(self):
169
# It is an error to omit the OOPS reporter if directory is specified.
172
"--oops-dir", "/some/where",
173
"--oops-reporter", "",
175
expected = MatchesException(
176
UsageError, "A reporter must be supplied")
178
partial(options.parseOptions, arguments),
182
116
class TestProvisioningServiceMaker(TestCase):
183
117
"""Tests for `provisioningserver.plugin.ProvisioningServiceMaker`."""
185
def get_log_file(self):
187
self.useFixture(TempDir()).path, "pserv.log")
120
super(TestProvisioningServiceMaker, self).setUp()
121
self.tempdir = self.useFixture(TempDir()).path
123
def write_config(self, config):
124
if "logfile" not in config:
125
logfile = os.path.join(self.tempdir, "pserv.log")
126
config = dict(config, logfile=logfile)
127
config_filename = os.path.join(self.tempdir, "config.yaml")
128
with open(config_filename, "wb") as stream:
129
yaml.dump(config, stream)
130
return config_filename
189
132
def test_init(self):
190
133
service_maker = ProvisioningServiceMaker("Harry", "Hill")
206
149
self.assertEqual(
207
150
len(service.namedServices), len(service.services),
208
151
"Not all services are named.")
209
site_service = service.getServiceNamed("site")
210
self.assertEqual(options["port"], site_service.args[0])
213
"RabbitMQ is not yet a required component "
214
"of a running MaaS installation.")
215
153
def test_makeService_with_broker(self):
217
155
The log, oops, site, and amqp services are created when the broker
218
156
user and password options are given.
220
158
options = Options()
221
options["brokerpassword"] = "Hoskins"
222
options["brokeruser"] = "Bob"
223
options["logfile"] = self.get_log_file()
159
options["config-file"] = self.write_config(
160
{"broker": {"username": "Bob", "password": "Hoskins"}})
224
161
service_maker = ProvisioningServiceMaker("Harry", "Hill")
225
service = service_maker.makeService(options, _set_proc_title=False)
162
service = service_maker.makeService(options)
226
163
self.assertIsInstance(service, MultiService)
227
164
self.assertSequenceEqual(
228
165
["amqp", "log", "oops", "site"],