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_formulate_get_adds_parameters_to_url(self): params = { factory.getRandomString(): factory.getRandomString() for counter in range(3)} url, headers = make_client()._formulate_get(make_path(), params) expectation = {key: [value] for key, value in params.items()} self.assertEqual(expectation, parse_qs(urlparse(url).query))
def test_ContainsAll_raises_if_one_element_is_missing(self): items = [factory.getRandomString() for i in range(3)] self.assertRaises( MismatchError, self.assertThat, items, ContainsAll([items[0], factory.getRandomString()]))
def test_formulate_change_passes_parameters_in_body(self): params = {factory.getRandomString(): factory.getRandomString()} url, headers, body = make_client()._formulate_change( make_path(), params) post, _ = parse_headers_and_body_with_django(headers, body) self.assertEqual( {name: [value] for name, value in params.items()}, post)
def test_copies_boot_image_files_from_tarball(self): prefix = factory.make_name() kernel_content = factory.getRandomString() initrd_content = factory.getRandomString() img_content = factory.getRandomString() tarball = factory.make_tarball(self.make_dir(), { '%s-vmlinuz.gz' % prefix: kernel_content, '%s-initrd.gz' % prefix: initrd_content, '%s.img' % prefix: img_content, }) target_dir = self.make_dir() self.patch(ephemerals_script, 'call_uec2roottar') extract_image_tarball(tarball, target_dir) self.assertItemsEqual( ['linux', 'initrd.gz', 'disk.img'], listdir(target_dir)) self.assertThat( os.path.join(target_dir, 'linux'), FileContains(kernel_content)) self.assertThat( os.path.join(target_dir, 'initrd.gz'), FileContains(initrd_content)) self.assertThat( os.path.join(target_dir, 'disk.img'), FileContains(img_content))
def test_write_dns_zone_config_writes_file(self): command = factory.getRandomString() domain = factory.getRandomString() network = IPNetwork('192.168.0.3/24') ip = factory.getRandomIPInNetwork(network) forward_zone = DNSForwardZoneConfig( domain, serial=random.randint(1, 100), mapping={factory.getRandomString(): ip}, networks=[network]) reverse_zone = DNSReverseZoneConfig( domain, serial=random.randint(1, 100), mapping={factory.getRandomString(): ip}, network=network) result = write_dns_zone_config.delay( zones=[forward_zone, reverse_zone], callback=rndc_command.subtask(args=[command])) forward_file_name = 'zone.%s' % domain reverse_file_name = 'zone.0.168.192.in-addr.arpa' self.assertThat( ( result.successful(), os.path.join(self.dns_conf_dir, forward_file_name), os.path.join(self.dns_conf_dir, reverse_file_name), self.rndc_recorder.calls, ), MatchesListwise( ( Equals(True), FileExists(), FileExists(), Equals([((command, ), {})]), )), result)
def test_extract_suggested_named_conf_extracts_section(self): named_part = factory.getRandomString() # Actual rndc-confgen output, mildly mangled for testing purposes. # Note the awkward line break. The code works by matching that exact # line, so there's no leeway with the spacing. rndc_config = dedent("""\ # Start of rndc.conf %(rndc_part)s # End of rndc.conf # %(start_marker)s %(named_part)s # End of named.conf """) % { 'start_marker': ( 'Use with the following in named.conf, ' 'adjusting the allow list as needed:'), 'rndc_part': factory.getRandomString(), 'named_part': named_part, } # What you get is just the suggested named.conf that's embedded in # the rndc-confgen output, not including its header and footer. self.assertEqual( named_part + '\n', extract_suggested_named_conf(rndc_config))
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_initialisation(self): server_address = factory.getRandomString() shared_key = factory.getRandomString() shell = Omshell(server_address, shared_key) self.assertThat( shell, MatchesStructure.byEquality( server_address=server_address, shared_key=shared_key))
def make_client(root=None, result=None): """Create a MAASClient.""" if root is None: root = make_url() auth = MAASOAuth( factory.getRandomString(), factory.getRandomString(), factory.getRandomString()) return MAASClient(auth, FakeDispatcher(result=result), root)
def test_are_identical_dirs_returns_false_if_file_was_removed(self): shared_file = factory.getRandomString() contents = factory.getRandomString() old = os.path.dirname( self.make_file(name=shared_file, contents=contents)) new = os.path.dirname( self.make_file(name=shared_file, contents=contents)) factory.make_file(old) self.assertFalse(are_identical_dirs(old, new))
def test_default_mode(self): content = factory.getRandomString() filename = factory.getRandomString() mocked_atomic_write = self.get_and_run_mocked_script( content, filename, ('--filename', filename)) mocked_atomic_write.assert_called_once_with( content, filename, mode=0600, overwrite=True)
def test_passes_overwrite_flag(self): content = factory.getRandomString() filename = factory.getRandomString() mocked_atomic_write = self.get_and_run_mocked_script( content, filename, ('--filename', filename, '--no-overwrite')) mocked_atomic_write.assert_called_once_with( content, filename, mode=0600, overwrite=False)
def test_find_settings(self): # find_settings() returns a dict of settings from a Django-like # settings file. It excludes settings beginning with underscores. module = new.module(b"example") module.SETTING = factory.getRandomString() module._NOT_A_SETTING = factory.getRandomString() expected = {"SETTING": module.SETTING} observed = find_settings(module) self.assertEqual(expected, observed)
def test_incremental_write_increments_modification_time(self): content = factory.getRandomString() filename = self.make_file(contents=factory.getRandomString()) # Pretend that this file is older than it is. So that # incrementing its mtime won't put it in the future. old_mtime = os.stat(filename).st_mtime - 10 os.utime(filename, (old_mtime, old_mtime)) incremental_write(content, filename) self.assertAlmostEqual( os.stat(filename).st_mtime, old_mtime + 1, delta=0.01)
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_post_passes_parameters(self): param = factory.getRandomString() method = factory.getRandomString() client = make_client() client.post(make_path(), method, parameter=param) request = client.dispatcher.last_call post, _ = parse_headers_and_body_with_django( request["headers"], request["data"]) self.assertTrue(request["request_url"].endswith('?op=%s' % (method,))) self.assertEqual({"parameter": [param]}, post)
def test_does_not_modify_original(self): original_text = factory.getRandomString().encode('ascii') original_file = self.make_file(contents=original_text) self.run_command(original_file, factory.getRandomString()) with open(original_file, 'rb') as reread_file: contents_after = reread_file.read() self.assertEqual(original_text, contents_after)
def test_get_passes_parameters(self): path = make_path() param = factory.getRandomString() method = factory.getRandomString() client = make_client() client.get(path, method, parameter=param) request = client.dispatcher.last_call self.assertIsNone(request['data']) query = parse_qs(urlparse(request['request_url']).query) self.assertItemsEqual([param], query['parameter'])
def test_execute_rndc_command_executes_command(self): recorder = FakeMethod() fake_dir = factory.getRandomString() self.patch(config, 'call_and_check', recorder) self.patch(conf, 'DNS_CONFIG_DIR', fake_dir) command = factory.getRandomString() 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_passes_mode_flag(self): content = factory.getRandomString() filename = factory.getRandomString() # Mode that's unlikely to occur in the wild. mode = 0377 mocked_atomic_write = self.get_and_run_mocked_script( content, filename, ('--filename', filename, '--mode', oct(mode))) mocked_atomic_write.assert_called_once_with( content, filename, mode=mode, overwrite=True)
def test_encode_multipart_data_produces_bytes(self): data = { factory.getRandomString(): ( factory.getRandomString().encode('ascii')), } files = { factory.getRandomString(): ( BytesIO(factory.getRandomString().encode('ascii'))), } body, headers = encode_multipart_data(data, files) self.assertIsInstance(body, bytes)
def test_import_local_settings_1(self): # The local settings module has not yet been imported, so fake one. config = dedent(""" SETTING = %r _NOT_A_SETTING = %r """ % (factory.getRandomString(), factory.getRandomString())) module = self.make_file( name=b"%s.py" % self.local_settings_module, contents=config) module_dir, module_file = os.path.split(module) self.addCleanup(sys.modules.pop, self.local_settings_module, None) self.useFixture(PythonPathEntry(module_dir)) self._test_import_local_settings()
def test_remove_dhcp_host_map(self): # We don't want to actually run omshell in the task, so we stub # out the wrapper class's _run method and record what it would # do. ip = factory.getRandomIPAddress() server_address = factory.getRandomString() key = factory.getRandomString() recorder = FakeMethod(result=(0, "obj: <null>")) self.patch(Omshell, '_run', recorder) remove_dhcp_host_map.delay(ip, server_address, key) self.assertRecordedStdin(recorder, ip, server_address, key)
def test_reverse_data_slash_22(self): # DNSReverseZoneConfig calculates the reverse data correctly for # a /22 network. domain = factory.getRandomString() hostname = factory.getRandomString() ip = '192.168.0.10' network = IPNetwork('192.168.0.1/22') dns_zone_config = DNSReverseZoneConfig( domain, mapping={hostname: ip}, network=network) self.assertEqual( '168.192.in-addr.arpa', dns_zone_config.zone_name)
def test_request_from_http(self): # We can't just call self.make_file because HTTPServerFixture will only # serve content from the current WD. And we don't want to create random # content in the original WD. self.useFixture(TempWDFixture()) name = factory.getRandomString() content = factory.getRandomString().encode('ascii') factory.make_file(location='.', name=name, contents=content) with HTTPServerFixture() as httpd: url = urljoin(httpd.url, name) response = MAASDispatcher().dispatch_query(url, {}) self.assertEqual(200, response.code) self.assertEqual(content, response.read())
def test_add_new_dhcp_host_map(self): # We don't want to actually run omshell in the task, so we stub # out the wrapper class's _run method and record what it would # do. mac = factory.getRandomMACAddress() ip = factory.getRandomIPAddress() server_address = factory.getRandomString() key = factory.getRandomString() recorder = FakeMethod(result=(0, "hardware-type")) self.patch(Omshell, '_run', recorder) add_new_dhcp_host_map.delay({ip: mac}, server_address, key) self.assertRecordedStdin(recorder, ip, mac, server_address, key)
def test_extract_suggested_named_conf_notices_missing_boundary(self): # extract_suggested_named_conf raises an exception if it does not # find the expected boundary between the rndc and named parts of the # generated configuration. rndc_config = dedent("""\ # Start of rndc.conf %s %s # End of named.conf """) % (factory.getRandomString(), factory.getRandomString()) self.assertRaises( ValueError, extract_suggested_named_conf, rndc_config)
def test_post_as_json(self): param = factory.getRandomString() method = factory.getRandomString() list_param = [factory.getRandomString() for i in range(10)] client = make_client() client.post(make_path(), method, as_json=True, param=param, list_param=list_param) request = client.dispatcher.last_call self.assertEqual('application/json', request['headers'].get('Content-Type')) content = parse_headers_and_body_with_mimer( request['headers'], request['data']) self.assertTrue(request["request_url"].endswith('?op=%s' % (method,))) self.assertEqual({'param': param, 'list_param': list_param}, content)
def test_import_boot_images_sets_proxy(self): recorder = self.patch(tasks, 'call_and_check') proxy = factory.getRandomString() import_boot_images(http_proxy=proxy) expected_env = dict(os.environ, http_proxy=proxy, https_proxy=proxy) recorder.assert_called_once_with( ['sudo', '-n', '-E', 'maas-import-pxe-files'], env=expected_env)
def test_forward_zone_get_static_mapping_returns_iterator(self): name = factory.getRandomString() network = IPNetwork('192.12.0.1/30') dns_ip = factory.getRandomIPInNetwork(network) dns_zone_config = DNSForwardZoneConfig( name, networks=[network], dns_ip=dns_ip) self.assertThat( dns_zone_config.get_static_mapping(), MatchesAll( IsInstance(Iterable), Not(IsInstance(Sequence))))
def test_writes_dns_zone_config(self): target_dir = self.make_dir() self.patch(DNSForwardZoneConfig, 'target_dir', target_dir) domain = factory.getRandomString() hostname = factory.getRandomString() network = factory.getRandomNetwork() ip = factory.getRandomIPInNetwork(network) dns_zone_config = DNSForwardZoneConfig( domain, serial=random.randint(1, 100), mapping={hostname: ip}, networks=[network]) dns_zone_config.write_config() self.assertThat( os.path.join(target_dir, 'zone.%s' % domain), FileContains( matcher=ContainsAll( [ '%s IN CNAME %s' % (hostname, generated_hostname(ip)), '%s IN A %s' % (generated_hostname(ip), ip), ])))
def test_runs_as_script(self): original_text = factory.getRandomString() original_file = self.make_file(original_text) script = os.path.join(root, "bin", "maas-provision") command = Popen( [script, "customize-config", original_file], stdin=PIPE, stdout=PIPE, env=dict(PYTHONPATH=":".join(sys.path), LC_ALL='en_US.UTF-8')) command.communicate(original_text) self.assertEqual(0, command.returncode)
def test_atomic_write_does_not_leak_temp_file_on_failure(self): # If the overwrite fails, atomic_write does not leak its # temporary file. self.patch(os, 'rename', Mock(side_effect=OSError())) filename = self.make_file() with ExpectedException(OSError): atomic_write(factory.getRandomString(), filename) self.assertEqual( [os.path.basename(filename)], os.listdir(os.path.dirname(filename)))
def test_create_raises_when_omshell_fails(self): # If the call to omshell doesn't result in output containing the # magic string 'hardware-type' it means the set of commands # failed. server_address = factory.getRandomString() shared_key = factory.getRandomString() ip_address = factory.getRandomIPAddress() mac_address = factory.getRandomMACAddress() shell = Omshell(server_address, shared_key) # Fake a call that results in a failure with random output. random_output = factory.getRandomString() recorder = FakeMethod(result=(0, random_output)) shell._run = recorder exc = self.assertRaises(ExternalProcessError, shell.create, ip_address, mac_address) self.assertEqual(random_output, exc.output)
def test_script_executable(self): content = factory.getRandomString() script = ["%s/bin/maas-provision" % root, 'atomic-write'] target_file = self.make_file() script.extend(('--filename', target_file, '--mode', '615')) cmd = Popen( script, stdin=PIPE, env=dict(PYTHONPATH=":".join(sys.path))) cmd.communicate(content) self.assertThat(target_file, FileContains(content)) self.assertEqual(0615, stat.S_IMODE(os.stat(target_file).st_mode))
def test_creates_real_fresh_directory(self): stored_text = factory.getRandomString() filename = factory.make_name('test-file') with tempdir() as directory: self.assertThat(directory, DirExists()) write_text_file(os.path.join(directory, filename), stored_text) retrieved_text = read_text_file(os.path.join(directory, filename)) files = os.listdir(directory) self.assertEqual(stored_text, retrieved_text) self.assertEqual([filename], files)
def test_post_dispatches_to_resource(self): path = make_path() client = make_client() method = factory.getRandomString() client.post(path, method) request = client.dispatcher.last_call self.assertEqual( client._make_url(path) + "?op=%s" % (method, ), request['request_url']) self.assertIn('Authorization', request['headers']) self.assertEqual('POST', request['method'])
def test_ignores_other_options(self): profile = factory.make_name('profile') self.assertEqual( profile, get_profile_option([ '--unrelated', 'option', '--profile', profile, factory.getRandomString(), ]))
def test_overwrites_existing_obsolete_file(self): text = factory.getRandomString() legacy_config = self.make_legacy_config(text) obsolete_config = legacy_config + '.obsolete' factory.make_file(os.path.dirname(obsolete_config), os.path.basename(obsolete_config)) retire_legacy_config() self.assertThat(legacy_config, Not(FileExists())) self.assertThat(obsolete_config, FileContains(text))
def test_patch(self): config = RabbitServerResources(hostname=factory.getRandomString(), port=factory.getRandomPort()) self.useFixture(config) self.useFixture(RabbitServerSettings(config)) self.assertEqual("%s:%d" % (config.hostname, config.port), settings.RABBITMQ_HOST) self.assertEqual("guest", settings.RABBITMQ_PASSWORD) self.assertEqual("guest", settings.RABBITMQ_USERID) self.assertEqual("/", settings.RABBITMQ_VIRTUAL_HOST) self.assertTrue(settings.RABBITMQ_PUBLISH)
def test_write_full_dns_config_sets_up_config(self): # write_full_dns_config writes the config file, writes # the zone files, and reloads the dns service. domain = factory.getRandomString() network = IPNetwork('192.168.0.3/24') ip = factory.getRandomIPInNetwork(network) zones = [ DNSForwardZoneConfig(domain, serial=random.randint(1, 100), mapping={factory.getRandomString(): ip}, networks=[network]), DNSReverseZoneConfig(domain, serial=random.randint(1, 100), mapping={factory.getRandomString(): ip}, network=network), ] command = factory.getRandomString() result = write_full_dns_config.delay( zones=zones, callback=rndc_command.subtask(args=[command]), upstream_dns=factory.getRandomIPAddress()) forward_file_name = 'zone.%s' % domain reverse_file_name = 'zone.0.168.192.in-addr.arpa' self.assertThat(( result.successful(), self.rndc_recorder.calls, os.path.join(self.dns_conf_dir, forward_file_name), os.path.join(self.dns_conf_dir, reverse_file_name), os.path.join(self.dns_conf_dir, MAAS_NAMED_CONF_NAME), os.path.join(self.dns_conf_dir, MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME), ), MatchesListwise(( Equals(True), Equals([((command, ), {})]), FileExists(), FileExists(), FileExists(), FileExists(), )))
def test_get_reader_regular_file(self): # TFTPBackend.get_reader() returns a regular FilesystemReader for # paths not matching re_config_file. data = factory.getRandomString().encode("ascii") temp_file = self.make_file(name="example", contents=data) temp_dir = path.dirname(temp_file) backend = TFTPBackend(temp_dir, "http://nowhere.example.com/") reader = yield backend.get_reader("example") self.addCleanup(reader.finish) self.assertEqual(len(data), reader.size) self.assertEqual(data, reader.read(len(data))) self.assertEqual(b"", reader.read(1))
def test_process_not_OK_response(self): response = make_response(httplib.NOT_FOUND, b"", "application/json") response.url = factory.getRandomString() error = self.assertRaises(urllib2.HTTPError, tags.process_response, response) self.assertThat( error, MatchesStructure.byEquality(url=response.url, code=response.code, msg="Not Found, expected 200 OK", headers=response.headers, fp=response.fp))
def test_move_file_by_glob_moves_file(self): content = factory.getRandomString() source_dir, source_name = split_path(self.make_file(contents=content)) target_dir, target_name = self.make_target() move_file_by_glob(source_dir, source_name[:3] + '*', target_dir, target_name) self.assertThat(os.path.join(source_dir, source_name), Not(FileExists())) self.assertThat(os.path.join(target_dir, target_name), FileContains(content))
def test_calls_atomic_write(self): self.patch_popen() path = os.path.join(self.make_dir(), factory.make_name('file')) contents = factory.getRandomString() sudo_write_file(path, contents) provisioningserver.utils.Popen.assert_called_once_with([ 'sudo', '-n', 'maas-provision', 'atomic-write', '--filename', path, '--mode', '0644', ], stdin=PIPE)
def test_arg_setup(self): parser = self.get_parser() filename = factory.getRandomString() args = parser.parse_args(( '--no-overwrite', '--filename', filename, '--mode', "111")) self.assertThat( args, MatchesStructure.byEquality( no_overwrite=True, filename=filename, mode="111"))
def test_import_settings(self): # import_settings() copies settings from another module into the # caller's global scope. source = new.module(b"source") source.SETTING = factory.getRandomString() target = new.module(b"target") target._source = source target._import_settings = import_settings eval("_import_settings(_source)", vars(target)) expected = {"SETTING": source.SETTING} observed = find_settings(target) self.assertEqual(expected, observed)
def test_reverse_data_slash_24(self): # DNSReverseZoneConfig calculates the reverse data correctly for # a /24 network. domain = factory.make_name('zone') hostname = factory.getRandomString() ip = '192.168.0.5' network = IPNetwork('192.168.0.1/24') dns_zone_config = DNSReverseZoneConfig( domain, mapping={hostname: ip}, network=network) self.assertEqual( '0.168.192.in-addr.arpa', dns_zone_config.zone_name)
def test_does_not_require_config(self): defaults = Config.get_defaults() no_file = os.path.join(self.make_dir(), factory.make_name() + '.yaml') self.useFixture( EnvironmentVariableFixture('MAAS_PROVISIONING_SETTINGS', no_file)) parser = make_arg_parser(factory.getRandomString()) args = parser.parse_args('') self.assertEqual(defaults['boot']['ephemeral']['images_directory'], args.output) self.assertItemsEqual([], args.filters)
def test_make_destination_returns_existing_directory(self): tftproot = self.make_dir() arch, subarch, release, purpose = make_arch_subarch_release_purpose() expected_dest = locate_tftp_path(compose_image_path( arch, subarch, release, purpose), tftproot=tftproot) os.makedirs(expected_dest) contents = factory.getRandomString() testfile = factory.make_name('testfile') factory.make_file(expected_dest, contents=contents, name=testfile) dest = make_destination(tftproot, arch, subarch, release, purpose) self.assertThat(os.path.join(dest, testfile), FileContains(contents))
def test_get_static_mapping(self): name = factory.getRandomString() network = IPNetwork('192.12.0.1/30') dns_zone_config = DNSReverseZoneConfig(name, network=network) self.assertItemsEqual( [ ('0', '%s.' % generated_hostname('192.12.0.0', name)), ('1', '%s.' % generated_hostname('192.12.0.1', name)), ('2', '%s.' % generated_hostname('192.12.0.2', name)), ('3', '%s.' % generated_hostname('192.12.0.3', name)), ], dns_zone_config.get_static_mapping(), )
def test_render_template_raises_PowerActionFail(self): # If not enough arguments are supplied to fill in template # variables then a PowerActionFail is raised. pa = PowerAction(POWER_TYPE.WAKE_ON_LAN) template_name = factory.getRandomString() template = ShellTemplate("template: {{mac}}", name=template_name) self.assertThat( lambda: pa.render_template(template), Raises( MatchesException( PowerActionFail, ".*name 'mac' is not defined at line \d+ column \d+ " "in file %s" % re.escape(template_name))))
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_write_config_skips_writing_if_overwrite_false(self): # If DNSConfig is created with overwrite=False, it won't # overwrite an existing config file. target_dir = self.make_dir() self.patch(DNSConfig, 'target_dir', target_dir) random_content = factory.getRandomString() factory.make_file( location=target_dir, name=MAAS_NAMED_CONF_NAME, contents=random_content) dnsconfig = DNSConfig() dnsconfig.write_config(overwrite=False) self.assertThat( os.path.join(target_dir, MAAS_NAMED_CONF_NAME), FileContains(random_content))
def test_write_config_writes_config(self): target_dir = self.make_dir() self.patch(DNSConfig, 'target_dir', target_dir) domain = factory.getRandomString() network = IPNetwork('192.168.0.3/24') ip = factory.getRandomIPInNetwork(network) forward_zone = DNSForwardZoneConfig( domain, mapping={factory.getRandomString(): ip}, networks=[network]) reverse_zone = DNSReverseZoneConfig( domain, mapping={factory.getRandomString(): ip}, network=network) dnsconfig = DNSConfig((forward_zone, reverse_zone)) dnsconfig.write_config() self.assertThat( os.path.join(target_dir, MAAS_NAMED_CONF_NAME), FileContains( matcher=ContainsAll( [ 'zone.%s' % domain, 'zone.0.168.192.in-addr.arpa', MAAS_NAMED_RNDC_CONF_NAME, ])))
def test_writes_dns_zone_config_with_NS_record(self): target_dir = self.make_dir() self.patch(DNSReverseZoneConfig, 'target_dir', target_dir) network = factory.getRandomNetwork() dns_ip = factory.getRandomIPAddress() dns_zone_config = DNSReverseZoneConfig( factory.getRandomString(), serial=random.randint(1, 100), dns_ip=dns_ip, network=network) dns_zone_config.write_config() self.assertThat( os.path.join( target_dir, 'zone.%s' % dns_zone_config.zone_name), FileContains( matcher=Contains('IN NS %s.' % dns_zone_config.domain)))
def test_writes_reverse_dns_zone_config(self): target_dir = self.make_dir() self.patch(DNSReverseZoneConfig, 'target_dir', target_dir) domain = factory.getRandomString() network = IPNetwork('192.168.0.1/22') dns_zone_config = DNSReverseZoneConfig( domain, serial=random.randint(1, 100), network=network) dns_zone_config.write_config() reverse_file_name = 'zone.168.192.in-addr.arpa' expected = Contains( '10.0 IN PTR %s' % generated_hostname('192.168.0.10')) self.assertThat( os.path.join(target_dir, reverse_file_name), FileContains(matcher=expected))
def test_updates_install_image(self): arch = self.get_arch() release = 'precise' tftp_path = compose_tftp_path(self.tftproot, arch, release, 'install', 'linux') os.makedirs(os.path.dirname(tftp_path)) with open(tftp_path, 'w') as existing_file: existing_file.write(factory.getRandomString()) archive = self.make_downloads(arch=arch, release=release) self.call_script(archive, self.tftproot, arch=arch, release=release) _, download_path = compose_download_dir(archive, arch, release) expected_contents = read_file( download_path, compose_download_kernel_name(arch, release)) self.assertThat(tftp_path, FileContains(expected_contents))
def test_supports_content_encoding_gzip(self): # The client will set the Accept-Encoding: gzip header, and it will # also decompress the response if it comes back with Content-Encoding: # gzip. self.useFixture(TempWDFixture()) name = factory.getRandomString() content = factory.getRandomString(300).encode('ascii') factory.make_file(location='.', name=name, contents=content) called = [] orig_urllib = urllib2.urlopen def logging_urlopen(*args, **kwargs): called.append((args, kwargs)) return orig_urllib(*args, **kwargs) self.patch(urllib2, 'urlopen', logging_urlopen) with HTTPServerFixture() as httpd: url = urljoin(httpd.url, name) res = MAASDispatcher().dispatch_query(url, {}) self.assertEqual(200, res.code) self.assertEqual(content, res.read()) request = called[0][0][0] self.assertEqual([((request, ), {})], called) self.assertEqual('gzip', request.headers.get('Accept-encoding'))