def test_restart_dhcp_server_sends_command(self): recorder = FakeMethod() self.patch(tasks, 'call_and_check', recorder) restart_dhcp_server() self.assertEqual( (1, (['sudo', '-n', 'service', 'maas-dhcp-server', 'restart'],)), (recorder.call_count, recorder.extract_args()[0]))
def test_remove_calls_omshell_correctly(self): server_address = factory.getRandomString() shared_key = factory.getRandomString() ip_address = factory.getRandomIPAddress() shell = Omshell(server_address, shared_key) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, "thing1\nthing2\nobj: <null>")) shell._run = recorder shell.remove(ip_address) expected_script = dedent("""\ server {server} key omapi_key {key} connect new host set name = "{ip}" open remove """) expected_script = expected_script.format(server=server_address, key=shared_key, ip=ip_address) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual([(expected_script, )], recorder.extract_args())
def test_try_connection_calls_omshell_correctly(self): server_address = factory.make_string() shell = Omshell(server_address, "", ipv6=self.ipv6) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, b"obj: <null>")) shell._run = recorder shell.try_connection() expected_script = dedent("""\ server {server} port {port} connect """) expected_script = expected_script.format(server=server_address, port=self.port) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual( [1, (expected_script.encode("utf-8"), )], [recorder.call_count, recorder.extract_args()[0]], )
def test_start_up_calls_setup_maas_avahi_service(self): recorder = FakeMethod() self.patch(start_up, 'setup_maas_avahi_service', recorder) start_up.start_up() self.assertEqual( (1, [()]), (recorder.call_count, recorder.extract_args()))
def test_start_up_calls_write_full_dns_config(self): recorder = FakeMethod() self.patch(start_up, 'write_full_dns_config', recorder) start_up.start_up() self.assertEqual( (1, [()]), (recorder.call_count, recorder.extract_args()))
def test_remove_calls_omshell_correctly(self): server_address = factory.getRandomString() shared_key = factory.getRandomString() ip_address = factory.getRandomIPAddress() shell = Omshell(server_address, shared_key) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, "thing1\nthing2\nobj: <null>")) shell._run = recorder shell.remove(ip_address) expected_args = (dedent("""\ server {server} key omapi_key {key} connect new host set name = "{ip}" open remove """).format( server=server_address, key=shared_key, ip=ip_address),) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual([expected_args], recorder.extract_args())
def test_create_calls_omshell_correctly(self): server_address = factory.getRandomString() shared_key = factory.getRandomString() ip_address = factory.getRandomIPAddress() mac_address = factory.getRandomMACAddress() shell = Omshell(server_address, shared_key) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, "hardware-type")) shell._run = recorder shell.create(ip_address, mac_address) expected_args = (dedent("""\ server {server} key omapi_key {key} connect new host set ip-address = {ip} set hardware-address = {mac} set hardware-type = 1 set name = "{ip}" create """).format( server=server_address, key=shared_key, ip=ip_address, mac=mac_address),) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual( [1, expected_args], [recorder.call_count, recorder.extract_args()[0]])
def test_create_calls_omshell_correctly(self): server_address = factory.getRandomString() shared_key = factory.getRandomString() ip_address = factory.getRandomIPAddress() mac_address = factory.getRandomMACAddress() shell = Omshell(server_address, shared_key) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, "hardware-type")) shell._run = recorder shell.create(ip_address, mac_address) expected_script = dedent("""\ server {server} key omapi_key {key} connect new host set ip-address = {ip} set hardware-address = {mac} set hardware-type = 1 set name = "{ip}" create """) expected_script = expected_script.format(server=server_address, key=shared_key, ip=ip_address, mac=mac_address) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual([1, (expected_script, )], [recorder.call_count, recorder.extract_args()[0]])
def test_modify_calls_omshell_correctly(self): server_address = factory.make_string() shared_key = factory.make_string() ip_address = factory.make_ip_address(ipv6=self.ipv6) mac_address = factory.make_mac_address() shell = Omshell(server_address, shared_key, ipv6=self.ipv6) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, b"hardware-type")) shell._run = recorder shell.modify(ip_address, mac_address) expected_script = dedent("""\ server {server} key omapi_key {key} connect new host set name = "{name}" open set ip-address = {ip} set hardware-address = {mac} set hardware-type = 1 update """) expected_script = expected_script.format( server=server_address, key=shared_key, ip=ip_address, mac=mac_address, name=mac_address.replace(':', '-')) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual( [1, (expected_script.encode("utf-8"),)], [recorder.call_count, recorder.extract_args()[0]])
def test_restart_dhcp_server_sends_command(self): recorder = FakeMethod() self.patch(tasks, 'call_and_check', recorder) restart_dhcp_server() self.assertEqual( (1, (['sudo', '-n', 'service', 'maas-dhcp-server', 'restart'], )), (recorder.call_count, recorder.extract_args()[0]))
def test_remove_calls_omshell_correctly(self): server_address = factory.make_string() shared_key = factory.make_string() mac_address = factory.make_mac_address() shell = Omshell(server_address, shared_key, ipv6=self.ipv6) # Instead of calling a real omshell, we'll just record the # parameters passed to Popen. recorder = FakeMethod(result=(0, b"thing1\nthing2\nobj: <null>")) shell._run = recorder shell.remove(mac_address) expected_script = dedent("""\ server {server} port {port} key omapi_key {key} connect new host set name = "{mac}" open remove """).format( server=server_address, port=self.port, key=shared_key, mac=mac_address.replace(":", "-"), ) expected_results = (expected_script.encode("utf-8"), ) # Check that the 'stdin' arg contains the correct set of # commands. self.assertEqual([expected_results], recorder.extract_args())
def test_get_maas_facing_server_address_resolves_hostname(self): ip = factory.getRandomIPAddress() resolver = FakeMethod(result=ip) self.patch(server_address, 'gethostbyname', resolver) hostname = self.make_hostname() self.set_DEFAULT_MAAS_URL(hostname=hostname) self.assertEqual( (ip, [(hostname, )]), (get_maas_facing_server_address(), resolver.extract_args()))
def test_get_dns_server_address_resolves_hostname(self): ip = factory.getRandomIPAddress() resolver = FakeMethod(result=ip) self.patch(server_address, 'gethostbyname', resolver) hostname = factory.make_hostname() self.patch_DEFAULT_MAAS_URL_with_random_values(hostname=hostname) self.assertEqual( (ip, [(hostname, )]), (dns.get_dns_server_address(), resolver.extract_args()))
def test_update_leases_processes_leases_if_changed(self): self.set_lease_state() self.patch(leases_module, 'send_leases', FakeMethod()) leases = factory.make_random_leases() self.fake_leases_file(leases) self.patch(Omshell, 'create', FakeMethod()) update_leases() self.assertEqual([(leases, )], leases_module.send_leases.extract_args())
def test_get_dns_server_address_uses_nodegroup_maas_url(self): ip = factory.getRandomIPAddress() resolver = FakeMethod(result=ip) self.patch(server_address, 'gethostbyname', resolver) hostname = factory.make_hostname() maas_url = 'http://%s' % hostname nodegroup = factory.make_node_group(maas_url=maas_url) self.assertEqual( (ip, [(hostname, )]), (dns.get_dns_server_address(nodegroup), resolver.extract_args()))
def test_call_calls_all_given_methods(self): methods = FakeMethod(), FakeMethod() method = MultiFakeMethod(methods) call1_args = "input 1" call2_args = "input 2" method(call1_args) method(call2_args) self.assertEqual( [[('input 1',)], [('input 2',)]], [methods[0].extract_args(), methods[1].extract_args()])
def test_process_node_tags_integration(self): self.set_secrets() get_nodes = FakeMethod(result=make_response( httplib.OK, b'["system-id1", "system-id2"]', 'application/json', )) post_hw_details = FakeMethod(result=make_response( httplib.OK, bson.BSON.encode({ 'system-id1': { 'lshw': b'<node />' }, 'system-id2': { 'lshw': b'<not-node />' }, }), 'application/bson', )) get_fake = MultiFakeMethod([get_nodes]) post_update_fake = FakeMethod(result=make_response( httplib.OK, b'{"added": 1, "removed": 1}', 'application/json', )) post_fake = MultiFakeMethod([post_hw_details, post_update_fake]) self.patch(MAASClient, 'get', get_fake) self.patch(MAASClient, 'post', post_fake) tag_name = factory.make_name('tag') nodegroup_uuid = get_recorded_nodegroup_uuid() tag_definition = '//lshw:node' tag_nsmap = {"lshw": "lshw"} tags.process_node_tags(tag_name, tag_definition, tag_nsmap=tag_nsmap) nodegroup_url = '/api/1.0/nodegroups/%s/' % (nodegroup_uuid, ) tag_url = '/api/1.0/tags/%s/' % (tag_name, ) self.assertEqual([((nodegroup_url, ), { 'op': 'list_nodes' })], get_nodes.calls) self.assertEqual([ ((nodegroup_url, ), { 'op': 'details', 'system_ids': ['system-id1', 'system-id2'], }), ], post_hw_details.calls) self.assertEqual([ ((tag_url, ), { 'as_json': True, 'op': 'update_nodes', 'nodegroup': nodegroup_uuid, 'definition': tag_definition, 'add': ['system-id1'], 'remove': ['system-id2'], }), ], post_update_fake.calls)
def test_write_full_dns_passes_reload_retry_parameter(self): self.patch(settings, 'DNS_CONNECT', True) recorder = FakeMethod() self.create_managed_nodegroup() @task def recorder_task(*args, **kwargs): return recorder(*args, **kwargs) self.patch(tasks, 'rndc_command', recorder_task) dns.write_full_dns_config(reload_retry=True) self.assertEqual(([(['reload'], True)]), recorder.extract_args())
def test_process_leases_records_state_before_sending(self): self.set_lease_state() self.patch(Omshell, 'create', FakeMethod()) self.fake_leases_file({}) self.patch(leases_module, 'send_leases', FakeMethod(failure=StopExecuting())) new_leases = factory.make_random_leases() try: process_leases(datetime.utcnow(), new_leases) except StopExecuting: pass self.fake_leases_file(new_leases) self.assertIsNone(check_lease_changes())
def test_rndc_command_can_be_retried(self): # The rndc_command task can be retried. # Simulate a temporary failure. number_of_failures = RNDC_COMMAND_MAX_RETRY raised_exception = CalledProcessError(factory.make_name('exception'), random.randint(100, 200)) simulate_failures = MultiFakeMethod( [FakeMethod(failure=raised_exception)] * number_of_failures + [FakeMethod()]) self.patch(tasks, 'execute_rndc_command', simulate_failures) command = factory.getRandomString() result = rndc_command.delay(command, retry=True) self.assertTrue(result.successful())
def test_rndc_command_is_retried_a_limited_number_of_times(self): # If we simulate RNDC_COMMAND_MAX_RETRY + 1 failures, the # task fails. number_of_failures = RNDC_COMMAND_MAX_RETRY + 1 raised_exception = utils.ExternalProcessError( random.randint(100, 200), factory.make_name('exception')) simulate_failures = MultiFakeMethod( [FakeMethod(failure=raised_exception)] * number_of_failures + [FakeMethod()]) self.patch(tasks, 'execute_rndc_command', simulate_failures) command = factory.getRandomString() self.assertRaises(utils.ExternalProcessError, rndc_command.delay, command, retry=True)
def test_send_leases_does_nothing_without_credentials(self): self.patch(MAASClient, 'post', FakeMethod()) self.set_items_needed_for_lease_update() self.clear_api_credentials() leases = factory.make_random_leases() send_leases(leases) self.assertEqual([], MAASClient.post.calls)
def test_process_leases_records_update(self): self.set_lease_state() self.patch(leases_module, 'send_leases', FakeMethod()) new_leases = factory.make_random_leases() self.fake_leases_file(new_leases) process_leases(datetime.utcnow(), new_leases) self.assertIsNone(check_lease_changes())
def test_update_leases_does_nothing_without_lease_changes(self): fake_send_leases = FakeMethod() self.patch(leases_module, 'send_leases', fake_send_leases) leases = factory.make_random_leases() leases_file = self.fake_leases_file(leases) self.set_lease_state(get_write_time(leases_file), leases.copy()) self.assertEqual([], leases_module.send_leases.calls)
def test_check_lease_changes_does_not_parse_unchanged_leases_file(self): parser = FakeMethod() leases_file = self.fake_leases_file() self.patch(leases_module, 'parse_leases_file', parser) self.set_lease_state(get_write_time(leases_file), {}) update_leases() self.assertSequenceEqual([], parser.calls)
def test_add_dhcp_host_maps_adds_maps_if_managing_dhcp(self): self.patch(Omshell, 'create', FakeMethod()) nodegroup = factory.make_node_group() leases = factory.make_random_leases() nodegroup.add_dhcp_host_maps(leases) self.assertEqual([(leases.keys()[0], leases.values()[0])], Omshell.create.extract_args())
def test_add_dhcp_host_maps_does_nothing_if_not_managing_dhcp(self): self.patch(Omshell, 'create', FakeMethod()) nodegroup = factory.make_node_group( management=NODEGROUPINTERFACE_MANAGEMENT.UNMANAGED) leases = factory.make_random_leases() nodegroup.add_dhcp_host_maps(leases) self.assertEqual([], Omshell.create.extract_args())
def test_get_dns_server_address_raises_if_hostname_doesnt_resolve(self): url = maastesting_factory.make_simple_http_url() self.useFixture(RegionConfigurationFixture(maas_url=url)) self.patch( zonegenerator, 'get_maas_facing_server_addresses', FakeMethod(failure=socket.error)) self.assertRaises(UnresolvableHost, get_dns_server_address)
def test_fakemethod_raises_given_failure(self): class ExpectedException(Exception): pass self.assertRaises( ExpectedException, FakeMethod(failure=ExpectedException()))
def test_update_node_tags_can_be_retried(self): self.set_secrets() # The update_node_tags task can be retried. # Simulate a temporary failure. number_of_failures = UPDATE_NODE_TAGS_MAX_RETRY raised_exception = MissingCredentials(factory.make_name('exception'), random.randint(100, 200)) simulate_failures = MultiFakeMethod( [FakeMethod(failure=raised_exception)] * number_of_failures + [FakeMethod()]) self.patch(tags, 'process_node_tags', simulate_failures) tag = factory.getRandomString() result = update_node_tags.delay(tag, '//node', tag_nsmap=None, retry=True) self.assertTrue(result.successful())
def test_change_node_other_field_does_not_update_zone(self): self.patch(settings, "DNS_CONNECT", True) nodegroup, node, lease = self.create_nodegroup_with_lease() recorder = FakeMethod() self.patch(DNSZoneConfigBase, 'write_config', recorder) node.error = factory.getRandomString() node.save() self.assertEqual(0, recorder.call_count)
def test_upload_leases_processes_leases_unconditionally(self): leases = factory.make_random_leases() leases_file = self.fake_leases_file(leases) self.set_lease_state(get_write_time(leases_file), leases.copy()) self.patch(leases_module, 'send_leases', FakeMethod()) upload_leases() self.assertEqual([(leases, )], leases_module.send_leases.extract_args())
def test_execute_rndc_command_executes_command(self): recorder = FakeMethod() fake_dir = patch_dns_config_path(self) self.patch(config, 'call_and_check', recorder) command = factory.make_string() execute_rndc_command([command]) rndc_conf_path = os.path.join(fake_dir, MAAS_RNDC_CONF_NAME) expected_command = ['rndc', '-c', rndc_conf_path, command] self.assertEqual((expected_command, ), recorder.calls[0][0])
def test_remove_dhcp_host_map_failure(self): # Check that task failures are caught. Nothing much happens in # the Task code right now though. ip = factory.getRandomIPAddress() server_address = factory.getRandomString() key = factory.getRandomString() self.patch(Omshell, '_run', FakeMethod(result=(0, "this_will_fail"))) self.assertRaises(CalledProcessError, remove_dhcp_host_map.delay, ip, server_address, key)
def test_update_node_tags_is_retried_a_limited_number_of_times(self): self.set_secrets() # If we simulate UPDATE_NODE_TAGS_MAX_RETRY + 1 failures, the # task fails. number_of_failures = UPDATE_NODE_TAGS_MAX_RETRY + 1 raised_exception = MissingCredentials(factory.make_name('exception'), random.randint(100, 200)) simulate_failures = MultiFakeMethod( [FakeMethod(failure=raised_exception)] * number_of_failures + [FakeMethod()]) self.patch(tags, 'process_node_tags', simulate_failures) tag = factory.getRandomString() self.assertRaises(MissingCredentials, update_node_tags.delay, tag, '//node', tag_nsmap=None, retry=True)
def test_extract_kwargs_returns_just_call_kwargs(self): stub = FakeMethod() stub(1, 2, 3, x=12) self.assertItemsEqual([{'x': 12}], stub.extract_kwargs())