288
301
self.assertEqual(fake_render_result.encode("utf-8"), output)
289
302
backend.render_pxe_config.assert_called_once_with(
290
303
kernel_params=fake_kernel_params, **fake_params)
306
class TestTFTPService(MAASTestCase):
308
def test_tftp_service(self):
309
# A TFTP service is configured and added to the top-level service.
311
factory.getRandomIPAddress(),
312
factory.getRandomIPAddress(),
315
tftp_module, "get_all_interface_addresses",
317
example_root = self.make_dir()
318
example_generator = "http://example.com/generator"
319
example_port = factory.getRandomPort()
320
tftp_service = TFTPService(
321
root=example_root, generator=example_generator,
323
tftp_service.updateServers()
324
# The "tftp" service is a multi-service containing UDP servers for
325
# each interface defined by get_all_interface_addresses().
326
self.assertIsInstance(tftp_service, MultiService)
327
# There's also a TimerService that updates the servers every 45s.
329
tftp_service.refresher, MatchesStructure.byEquality(
330
step=45, parent=tftp_service, name="refresher",
331
call=(tftp_service.updateServers, (), {}),
333
expected_backend = MatchesAll(
334
IsInstance(TFTPBackend),
336
lambda backend: backend.base.path,
337
Equals(example_root)),
339
lambda backend: backend.generator_url.geturl(),
340
Equals(example_generator)))
341
expected_protocol = MatchesAll(
344
lambda protocol: protocol.backend,
346
expected_server = MatchesAll(
347
IsInstance(internet.UDPServer),
349
lambda service: len(service.args),
352
lambda service: service.args[0], # port
353
Equals(example_port)),
355
lambda service: service.args[1], # protocol
358
tftp_service.getServers(),
359
AllMatch(expected_server))
360
# Only the interface used for each service differs.
361
self.assertItemsEqual(
362
[svc.kwargs for svc in tftp_service.getServers()],
363
[{"interface": interface} for interface in interfaces])
365
def test_tftp_service_rebinds_on_HUP(self):
366
# Initial set of interfaces to bind to.
367
interfaces = {"1.1.1.1", "2.2.2.2"}
369
tftp_module, "get_all_interface_addresses",
372
tftp_service = TFTPService(
373
root=self.make_dir(), generator="http://mighty/wind",
374
port=factory.getRandomPort())
375
tftp_service.updateServers()
377
# The child services of tftp_services are named after the
378
# interface they bind to.
379
self.assertEqual(interfaces, {
380
server.name for server in tftp_service.getServers()
383
# Update the set of interfaces to bind to.
384
interfaces.add("3.3.3.3")
385
interfaces.remove("1.1.1.1")
387
# Ask the TFTP service to update its set of servers.
388
tftp_service.updateServers()
390
# We're in the reactor thread but we want to move the reactor
391
# forwards, hence we need to get all explicit about it.
392
reactor.runUntilCurrent()
394
# The interfaces now bound match the updated interfaces set.
395
self.assertEqual(interfaces, {
396
server.name for server in tftp_service.getServers()