def test_appends_custom_section_initially(self): original = factory.make_name('Original-text') custom_text = factory.make_name('Custom-text') header, footer = maas_custom_config_markers self.assertEqual( [original, header, custom_text, footer], write_custom_config_section(original, custom_text).splitlines())
def test_create_succeeds_when_host_map_already_exists(self): # To omshell, creating the same host map twice is an error. But # Omshell.create swallows the error and makes it look like # success. params = { 'ip': factory.getRandomIPAddress(), 'mac': factory.getRandomMACAddress(), 'hostname': factory.make_name('hostname') } shell = Omshell(factory.make_name('server'), factory.make_name('key')) # This is the kind of error output we get if a host map has # already been created. error_output = dedent("""\ obj: host ip-address = %(ip)s hardware-address = %(mac)s name = "%(hostname)s" > can't open object: I/O error obj: host ip-address = %(ip)s hardware-address = %(mac)s name = "%(hostname)s" """) % params shell._run = Mock(return_value=(0, error_output)) shell.create(params['ip'], params['mac']) # The test is that we get here without error. pass
def make_api_credentials(): """Create a tuple of fake API credentials.""" return ( factory.make_name('consumer-key'), factory.make_name('resource-token'), factory.make_name('resource-secret'), )
def test_install_image_installs_alternate_purpose_as_symlink(self): tftp_root = self.make_dir() self.useFixture(ConfigFixture({'tftp': {'root': tftp_root}})) kernel_content = factory.getRandomString() kernel = self.make_file(name='linux', contents=kernel_content) downloaded_image = os.path.dirname(kernel) arch = factory.make_name('arch') subarch = factory.make_name('subarch') release = factory.make_name('release') purpose = factory.make_name('purpose') alternate_purpose = factory.make_name('alt') install_image( downloaded_image, arch, subarch, release, purpose, alternate_purpose=alternate_purpose) main_image = os.path.join(tftp_root, arch, subarch, release, purpose) self.assertThat( os.path.join(main_image, 'linux'), FileContains(kernel_content)) alternate_image = os.path.join( tftp_root, arch, subarch, release, alternate_purpose) self.assertTrue(os.path.islink(os.path.join(alternate_image))) self.assertThat( os.path.join(alternate_image, 'linux'), FileContains(kernel_content))
def test_compose_image_path_follows_maas_pxe_directory_layout(self): arch = factory.make_name('arch') subarch = factory.make_name('subarch') release = factory.make_name('release') purpose = factory.make_name('purpose') self.assertEqual( '%s/%s/%s/%s' % (arch, subarch, release, purpose), compose_image_path(arch, subarch, release, purpose))
def test_compose_image_path_does_not_include_tftp_root(self): arch = factory.make_name('arch') subarch = factory.make_name('subarch') release = factory.make_name('release') purpose = factory.make_name('purpose') self.assertThat( compose_image_path(arch, subarch, release, purpose), Not(StartsWith(self.tftproot)))
def test_get_target_name(self): release = factory.make_name('release', sep='_') version = factory.make_name('version', sep='_') arch = factory.make_name('arch', sep='_') version_name = factory.make_name('vername', sep='_') self.assertEqual( 'maas-%s-%s-%s-%s' % (release, version, arch, version_name), get_target_name(release, version, arch, version_name))
def test_init(self): temp_dir = self.make_dir() generator_url = "http://%s.example.com/%s" % ( factory.make_name("domain"), factory.make_name("path")) backend = TFTPBackend(temp_dir, generator_url) self.assertEqual((True, False), (backend.can_read, backend.can_write)) self.assertEqual(temp_dir, backend.base.path) self.assertEqual(generator_url, backend.generator_url.geturl())
def test_re_config_file_with_default_arch_and_subarch(self): arch = factory.make_name('arch', sep='') subarch = factory.make_name('subarch', sep='') match = TFTPBackend.re_config_file.match( 'pxelinux.cfg/default.%s-%s' % (arch, subarch)) self.assertIsNotNone(match) self.assertEqual({'mac': None, 'arch': arch, 'subarch': subarch}, match.groupdict())
def test_extend_path_builds_on_given_paths(self): base_dir = self.make_dir() lower_dir = factory.make_name('lower') subdir = factory.make_name('sub') os.makedirs(os.path.join(base_dir, lower_dir, subdir)) self.assertEqual( [[lower_dir, subdir]], extend_path(base_dir, [lower_dir]))
def test_cleans_up_temp_location(self): self.patch(ephemerals_script, 'install_image') temp_location = self.make_dir() storage_dir = self.prepare_storage_dir() install_image_from_simplestreams( storage_dir, release=factory.make_name('release'), arch=factory.make_name('arch'), temp_location=temp_location) self.assertItemsEqual([], listdir(temp_location))
def test_drill_down_drops_paths_that_do_not_go_deep_enough(self): base_dir = self.make_dir() shallow_dir = factory.make_name('shallow') os.makedirs(os.path.join(base_dir, shallow_dir)) deep_dir = factory.make_name('deep') subdir = factory.make_name('sub') os.makedirs(os.path.join(base_dir, deep_dir, subdir)) self.assertEqual( [[deep_dir, subdir]], drill_down(base_dir, [[shallow_dir], [deep_dir]]))
def test_discover_networks_returns_suitable_interfaces(self): eth = factory.make_name('eth') self.patch_netifaces({ eth: make_interface(), 'lo': make_interface(make_loopback()), factory.make_name('dummy'): make_interface({}), }) self.assertEqual( [eth], [ interface['interface'] for interface in network.discover_networks()])
def make_handler(): """Create a fake handler entry.""" return { 'name': factory.make_name('handler'), 'doc': "Short\n\nLong", 'params': [], 'actions': [{ 'name': factory.make_name('action'), 'doc': "Doc\n\nstring", }], }
def test_http_request_raises_error_if_cert_verify_fails(self): self.patch( httplib2.Http, "request", Mock(side_effect=httplib2.SSLHandshakeError())) error = self.assertRaises( CommandError, api.http_request, factory.make_name('fake_url'), factory.make_name('fake_method')) error_expected = ( "Certificate verification failed, use --insecure/-k to " "disable the certificate check.") self.assertEqual(error_expected, "%s" % error)
def test_drill_down_ignores_subdir_not_in_path(self): base_dir = self.make_dir() irrelevant_dir = factory.make_name('irrelevant') irrelevant_subdir = factory.make_name('subdir') relevant_dir = factory.make_name('relevant') relevant_subdir = factory.make_name('subdir') os.makedirs(os.path.join(base_dir, irrelevant_dir, irrelevant_subdir)) os.makedirs(os.path.join(base_dir, relevant_dir, relevant_subdir)) self.assertEqual( [[relevant_dir, relevant_subdir]], drill_down(base_dir, [[relevant_dir]]))
def test_cleans_up_temp_location(self): self.patch(subprocess, 'check_call') fake_image = factory.make_name('image') self.patch(ephemerals_script, 'move_file_by_glob').return_value = ( fake_image) tarball = factory.make_name('tarball') + '.tar.gz' target_dir = self.make_dir() temp_location = self.make_dir() extract_image_tarball(tarball, target_dir, temp_location) self.assertItemsEqual([], listdir(temp_location))
def test_drill_down_follows_directory_tree(self): base_dir = self.make_dir() lower_dir = factory.make_name('lower') os.makedirs(os.path.join(base_dir, lower_dir)) subdirs = [ factory.make_name('subdir-%d' % counter) for counter in range(3)] for subdir in subdirs: os.makedirs(os.path.join(base_dir, lower_dir, subdir)) self.assertItemsEqual( [[lower_dir, subdir] for subdir in subdirs], drill_down(base_dir, [[lower_dir]]))
def test_start_up_ignores_failure_on_refresh_secrets(self): start_cluster_controller.sleep.side_effect = None self.patch(MAASDispatcher, 'dispatch_query').side_effect = URLError( "Simulated HTTP failure.") self.assertRaises( Executing, start_cluster_controller.start_up, make_url(), self.make_connection_details(), factory.make_name('user'), factory.make_name('group')) self.assertEqual(1, os.execvpe.call_count)
def make_boot_image_params(): """Create an arbitrary dict of boot-image parameters. These are the parameters that together describe a kind of boot that we may need a kernel and initrd for: architecture, sub-architecture, Ubuntu release, and boot purpose. See the `tftppath` module for how these fit together. """ return dict( architecture=factory.make_name('architecture'), subarchitecture=factory.make_name('subarchitecture'), release=factory.make_name('release'), purpose=factory.make_name('purpose'))
def test_print_headers(self): # print_headers() prints the given headers, in order, with each # hyphen-delimited part of the header name capitalised, to the given # file, with the names right aligned, and with a 2 space left margin. headers = collections.OrderedDict() headers["two-two"] = factory.make_name("two") headers["one"] = factory.make_name("one") buf = io.StringIO() api.print_headers(headers, buf) self.assertEqual( (" One: %(one)s\n" " Two-Two: %(two-two)s\n") % headers, buf.getvalue())
def test_write_conf_writes_conf_file(self): conf = self.make_file() target = factory.make_name('target') image = factory.make_name('image') write_conf(conf, target, image) self.assertThat( read_text_file(conf), ContainsAll([ 'com.ubuntu:maas:%s' % target, 'backing-store "%s"' % image, '</target>', ]))
def test_render_with_extra_arguments_does_not_affect_output(self): # render_pxe_config() allows any keyword arguments as a safety valve. options = {"kernel_params": make_kernel_parameters(purpose="install")} # Capture the output before sprinking in some random options. output_before = render_pxe_config(**options) # Sprinkle some magic in. options.update( (factory.make_name("name"), factory.make_name("value")) for _ in range(10)) # Capture the output after sprinking in some random options. output_after = render_pxe_config(**options) # The generated template is the same. self.assertEqual(output_before, output_after)
def test_runs_uec2roottar(self): check_call = self.patch(subprocess, 'check_call') fake_image = factory.make_name('image') self.patch(ephemerals_script, 'move_file_by_glob').return_value = ( fake_image) tarball = factory.make_name('tarball') + '.tar.gz' target_dir = self.make_dir() extract_image_tarball(tarball, target_dir) check_call.assert_called_with([ 'uec2roottar', fake_image, os.path.join(target_dir, 'dist-root.tar.gz'), ])
def test_cleans_up_after_failure(self): self.patch(subprocess, 'check_call').side_effect = ( ExternalProcessError(-1, "some_command")) fake_image = factory.make_name('image') self.patch(ephemerals_script, 'move_file_by_glob').return_value = ( fake_image) tarball = factory.make_name('tarball') + '.tar.gz' target_dir = self.make_dir() temp_location = self.make_dir() self.assertRaises( ExternalProcessError, extract_image_tarball, tarball, target_dir, temp_location) self.assertItemsEqual([], listdir(temp_location))
def make_profile(name=None): """Create a fake profile dict.""" if name is None: name = factory.make_name('profile') return { 'name': name, 'url': 'http://%s.example.com/' % name, 'credentials': factory.make_name('credentials'), 'description': { 'resources': [ make_resource(), make_resource(), ], }, }
def test_start_celery_passes_environment(self): server_url = make_url() connection_details = self.make_connection_details() self.assertRaises( Executing, start_cluster_controller.start_celery, server_url, connection_details, factory.make_name('user'), factory.make_name('group')) env = dict( os.environ, CELERY_BROKER_URL=connection_details['BROKER_URL'], MAAS_URL=server_url, ) os.execvpe.assert_called_once_with(ANY, ANY, env=env)
def test_detect_sequence_clashes_ignores_unique_migrations(self): self.patch(db_migrations, 'list_migrations').return_value = tuple( make_migration_name(number) for number in range(5)) self.assertItemsEqual( [], db_migrations.detect_sequence_clashes(factory.make_name('app')))
def test_detect_sequence_clashes_finds_clashes(self): number = randint(0, 999) names = tuple(make_migration_name(number) for counter in range(2)) self.patch(db_migrations, 'list_migrations').return_value = names self.assertItemsEqual( [(number, name) for name in names], db_migrations.detect_sequence_clashes(factory.make_name('app')))
def set_maas_url(self): """Set the recorded MAAS URL for the duration of this test.""" maas_url = 'http://%s.example.com/%s/' % ( factory.make_name('host'), factory.getRandomString(), ) os.environ["MAAS_URL"] = maas_url
def test_get_state(self): state = factory.make_name("state") conn = self.configure_virshssh(state) expected = conn.get_state("") self.assertEqual(state, expected)
def make_context(): return { "power_address": factory.make_ipv4_address(), "power_user": factory.make_name("power_user"), "power_pass": factory.make_name("power_pass"), }
def test_set_caches_to_normalized_value(self): contents = " %s " % factory.make_name("contents") env.set_maas_id(contents) self.assertEqual(env._normalise_maas_id(contents), env.get_maas_id())
def test_set_caches(self): contents = factory.make_name("contents") env.set_maas_id(contents) os.unlink(self.maas_id_path) self.assertEqual(contents, env.get_maas_id())
def test_get_returns_contents_if_maas_id_file_contains_something(self): contents = factory.make_name("contents") with open(self.maas_id_path, "w") as fd: fd.write(contents) self.assertThat(env.get_maas_id(), Equals(contents))
def test_creates_file(self): path = os.path.join(self.make_dir(), factory.make_name("text")) text = factory.make_string() write_text_file(path, text) self.assertThat(path, FileContains(text, encoding="ascii"))
def test__passes_name_unchanged(self): name = factory.make_name("itf9:2") self.assertEqual(name, make_name_from_interface(name))
class FakeDHCPService(DHCPService): name = factory.make_name("name") service_name = factory.make_name("service") snap_service_name = factory.make_name("service")
def test_get_ip_address_returns_power_address(self): amt_power_driver = AMTPowerDriver() power_address = factory.make_name("power_address") result = amt_power_driver._get_ip_address(power_address, None) self.assertEqual(result, power_address)
def test_get_ammtool_boot_mode_pxe_booting(self): amt_power_driver = AMTPowerDriver() boot_mode = factory.make_name("boot_mode") result = amt_power_driver._get_amttool_boot_mode(boot_mode) self.assertEqual(result, boot_mode)
def make_tarball_name(prefix='tarball'): """Create an arbitrary name for a tarball.""" return factory.make_name(prefix) + '.tar.gz'
def make_image_name(suffix='.img'): """Create an image file name (but not the actual file).""" return factory.make_name('root') + suffix
def test_probe_and_enlist(self): # Patch VirshSSH list so that some machines are returned # with some fake architectures. user = factory.make_name("user") system_id = factory.make_name("system_id") machines = [factory.make_name("machine") for _ in range(5)] self.patch(virsh.VirshSSH, "list").return_value = machines fake_arch = factory.make_name("arch") mock_arch = self.patch(virsh.VirshSSH, "get_arch") mock_arch.return_value = fake_arch domain = factory.make_name("domain") # Patch get_state so that one of the machines is on, so we # can check that it will be forced off. fake_states = [ virsh.VirshVMState.ON, virsh.VirshVMState.OFF, virsh.VirshVMState.OFF, virsh.VirshVMState.ON, virsh.VirshVMState.ON, ] mock_state = self.patch(virsh.VirshSSH, "get_state") mock_state.side_effect = fake_states # Setup the power parameters that we should expect to be # the output of the probe_and_enlist fake_password = factory.make_string() poweraddr = factory.make_name("poweraddr") called_params = [] fake_macs = [] for machine in machines: macs = [factory.make_mac_address() for _ in range(4)] fake_macs.append(macs) called_params.append( { "power_address": poweraddr, "power_id": machine, "power_pass": fake_password, } ) # Patch the get_mac_addresses so we get a known list of # mac addresses for each machine. mock_macs = self.patch(virsh.VirshSSH, "get_mac_addresses") mock_macs.side_effect = fake_macs # Patch the poweroff and create as we really don't want these # actions to occur, but want to also check that they are called. mock_poweroff = self.patch(virsh.VirshSSH, "poweroff") mock_create_node = self.patch(virsh, "create_node") mock_create_node.side_effect = asynchronous( lambda *args, **kwargs: None if machines[4] in args else system_id ) mock_commission_node = self.patch(virsh, "commission_node") # Patch login and logout so that we don't really contact # a server at the fake poweraddr mock_login = self.patch(virsh.VirshSSH, "login") mock_login.return_value = True mock_logout = self.patch(virsh.VirshSSH, "logout") mock_get_machine_xml = self.patch(virsh.VirshSSH, "get_machine_xml") mock_get_machine_xml.side_effect = [ SAMPLE_DUMPXML, SAMPLE_DUMPXML_2, SAMPLE_DUMPXML_3, SAMPLE_DUMPXML_4, SAMPLE_DUMPXML, ] mock_run = self.patch(virsh.VirshSSH, "run") mock_run.side_effect = self._probe_and_enlist_mock_run # Perform the probe and enlist yield deferToThread( virsh.probe_virsh_and_enlist, user, poweraddr, fake_password, accept_all=True, domain=domain, ) # Check that login was called with the provided poweraddr and # password. self.expectThat( mock_login, MockCalledOnceWith(poweraddr, fake_password) ) # Check that the create command had the correct parameters for # each machine. self.expectThat( mock_create_node, MockCallsMatch( call( fake_macs[0], fake_arch, "virsh", called_params[0], domain, machines[0], ), call( fake_macs[1], fake_arch, "virsh", called_params[1], domain, machines[1], ), call( fake_macs[2], fake_arch, "virsh", called_params[2], domain, machines[2], ), call( fake_macs[3], fake_arch, "virsh", called_params[3], domain, machines[3], ), call( fake_macs[4], fake_arch, "virsh", called_params[4], domain, machines[4], ), ), ) # The first and last machine should have poweroff called on it, as it # was initial in the on state. self.expectThat( mock_poweroff, MockCallsMatch(call(machines[0]), call(machines[3])) ) self.assertThat(mock_logout, MockCalledOnceWith()) self.expectThat( mock_commission_node, MockCallsMatch( call(system_id, user), call(system_id, user), call(system_id, user), call(system_id, user), ), )
def test__returns_actual_image_file_unchanged(self): patch_is_filesystem_file(self, True) image = make_image(self) self.assertEqual( image, uec2roottar.get_image_file(image, factory.make_name('dir')))
def test_byte_name_is_rejected(self): name = factory.make_name("lock").encode("ascii") error = self.assertRaises(TypeError, NamedLock, name) self.assertThat(str(error), Equals("Lock name must be str, not bytes"))
def make_error_message(self): error = factory.make_name("msg") self.patch(power, "get_error_message").return_value = error return error
def test_path_is_read_only(self): lock = self.make_lock() with ExpectedException(AttributeError): lock.path = factory.make_name()
def make_context(): return { 'power_address': factory.make_ipv4_address(), 'power_user': factory.make_name('power_user'), 'power_pass': factory.make_name('power_pass'), }
def test_set_writes_argument_to_maas_id_file(self): contents = factory.make_name("contents") env.set_maas_id(contents) self.assertThat(self.maas_id_path, FileContains(contents))
def test_get_arch_returns_valid(self): arch = factory.make_name("arch") output = SAMPLE_DUMPXML % arch conn = self.configure_virshssh(output) expected = conn.get_arch("") self.assertEqual(arch, expected)
def test_set_None_clears_cache(self): contents = factory.make_name("contents") env.set_maas_id(contents) self.assertThat(env.get_maas_id(), Equals(contents)) env.set_maas_id(None) self.assertThat(env.get_maas_id(), Is(None))
def test_set(self): dummy_filename = factory.make_name("config") Config.DEFAULT_FILENAME = dummy_filename self.assertEqual(dummy_filename, Config.DEFAULT_FILENAME)
def make_variable(self): return factory.make_name("testvar"), factory.make_name("value")
def test_gets_filename_from_MAAS_PROVISIONING_SETTNGS(self): dummy_filename = factory.make_name("config") self.set_MAAS_CONFIG_DIR(None) self.set_MAAS_PROVISIONING_SETTINGS(dummy_filename) self.assertEqual(dummy_filename, Config.DEFAULT_FILENAME)
def test_creatorForNetloc_returns_tls_options(self): hostname = factory.make_name("hostname").encode("utf-8") port = random.randint(1000, 2000) contextFactory = WebClientContextFactory() opts = contextFactory.creatorForNetloc(hostname, port) self.assertIsInstance(opts, ClientTLSOptions)
def test_MAAS_PROVISIONING_SETTINGS_trumps_MAAS_CONFIG_DIR(self): provisioning_settings = factory.make_name("config") self.set_MAAS_CONFIG_DIR(os.path.dirname(self.make_config())) self.set_MAAS_PROVISIONING_SETTINGS(provisioning_settings) self.assertEqual(provisioning_settings, Config.DEFAULT_FILENAME)
def test_makes_events_as_properties(self): events = [factory.make_name("event") for _ in range(3)] group = EventGroup(*events) for event in events: self.expectThat(getattr(group, event), IsInstance(Event))
def test_string_name(self): name = factory.make_name("lock") expected = get_tentative_data_path("/run/lock/maas:" + name) observed = NamedLock(name).path self.assertEqual(expected, observed)
def test__calls_umount(self): self.patch(uec2roottar, 'check_call') mountpoint = factory.make_name('mount') uec2roottar.unmount(mountpoint) self.assertThat(uec2roottar.check_call, MockCalledOnceWith(['umount', mountpoint]))
def test_reset_clears_factories(self): eventloop.loop.factories = ((factory.make_name("service"), None), ) eventloop.loop.reset().wait(5) # The loop's factories are also reset. self.assertEqual(eventloop.loop.__class__.factories, eventloop.loop.factories)