def test_edit_user_POST_profile_updates_attributes(self): self.client.login(user=factory.make_admin()) user = factory.make_User() params = make_user_attribute_params(user) params.update({ 'last_name': factory.make_name('Newname'), 'email': '*****@*****.**' % factory.make_string(), 'is_superuser': True, 'username': factory.make_name('newname'), }) response = self.client.post( reverse('accounts-edit', args=[user.username]), get_prefixed_form_data('profile', params)) self.assertEqual(http.client.FOUND, response.status_code) self.assertAttributes(reload_object(user), subset_dict(params, user_attributes))
def test_prevents_unsupported_osystem(self): reserved_name = "%s/%s" % ( factory.make_name("osystem"), factory.make_name("series"), ) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": reserved_name, "title": factory.make_name("title"), "architecture": make_usable_architecture(self), "filetype": upload_type, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertFalse(form.is_valid())
def test_POST_creates_user_external_auth_not_local(self): Config.objects.set_config("external_auth_url", "http://auth.example.com") self.become_admin() username = factory.make_name("user") email = factory.make_email_address() password = factory.make_string() self.client.post( reverse("users_handler"), { "username": username, "email": email, "password": password, "is_superuser": "******", }, ) created_user = User.objects.get(username=username) self.assertFalse(created_user.userprofile.is_local)
def test_store_result_stores_script_version(self): script = factory.make_Script() old_version = script.script script.script = script.script.update(factory.make_string()) script.save() script_result = factory.make_ScriptResult( status=SCRIPT_STATUS.RUNNING, script=script) exit_status = random.randint(0, 255) script_result.store_result( exit_status, script_version_id=old_version.id) self.assertEquals(exit_status, script_result.exit_status) self.assertEquals(b'', script_result.output) self.assertEquals(b'', script_result.stdout) self.assertEquals(b'', script_result.stderr) self.assertEquals(b'', script_result.result) self.assertEquals(old_version, script_result.script_version)
def test_POST_new_invalid_tag_name(self): self.become_admin() # We do not check the full possible set of invalid names here, a more # thorough check is done in test_tag, we just check that we get a # reasonable error here. invalid = 'invalid:name' definition = '//node' comment = factory.make_string() response = self.client.post(reverse('tags_handler'), { 'name': invalid, 'comment': comment, 'definition': definition, }) self.assertEqual( http.client.BAD_REQUEST, response.status_code, 'We did not get BAD_REQUEST for an invalid tag name: %r' % (invalid, )) self.assertFalse(Tag.objects.filter(name=invalid).exists())
def test_GET_query_with_nonexistent_id_returns_empty_list(self): # Trying to list events for a nonexistent node id returns a list # containing no nodes -- even if other (non-matching) nodes exist. node = factory.make_Node() make_events(node=node) existing_id = node.system_id nonexistent_id = existing_id + factory.make_string() response = self.client.get(reverse("events_handler"), { "op": "query", "id": [nonexistent_id] }) self.assertThat( json_load_bytes(response.content), ContainsDict({ "count": Equals(0), "events": HasLength(0) }), )
def test_get_all_prefixed_values_returns_sub_dict(self): inputs = [ { "prefix_test": "a", "key": "b", "prefix_2": "c" }, {}, { "b": factory.make_string() }, ] prefix = "prefix_" expected = [{"test": "a", "2": "c"}, {}, {}] self.assertEqual( expected, [get_all_prefixed_values(data, prefix) for data in inputs], )
def test_authenticate_create_user(self): username = factory.make_string() identity = SimpleIdentity(user=username) user = self.backend.authenticate(self.get_request(), identity=identity) self.assertIsNotNone(user.id) self.assertEqual(user.username, username) self.assertFalse(user.is_superuser) self.assertFalse(user.userprofile.is_local) self.mock_validate.assert_called_with( user, ExternalAuthInfo( type="candid", url="https://auth.example.com", domain="", admin_group="admins", ), force_check=True, )
def test_createadmin_not_prompt_for_ssh_import_if_other_params_given(self): stderr = StringIO() stdout = StringIO() username = factory.make_name("user") password = factory.make_string() email = factory.make_email_address() call_command( "createadmin", username=username, password=password, email=email, stdout=stdout, stderr=stderr, ) self.assertThat(stderr, IsEmpty) self.assertThat(stdout, IsEmpty)
def test_perform_action_catches_start_action_errors(self): error_text = factory.make_string(prefix="NodeActionError") exc = NodeActionError(error_text) self.patch(PowerOn, "execute").side_effect = exc with transaction.atomic(): user = factory.make_User() factory.make_SSHKey(user) node = factory.make_Node(status=NODE_STATUS.READY, owner=user) form = BulkNodeActionForm(user=user, data=dict(action=PowerOn.name, system_id=[node.system_id])) self.assertTrue(form.is_valid(), form._errors) with transaction.atomic(): done, not_actionable, not_permitted = form.save() self.assertEqual([0, 1, 0], [done, not_actionable, not_permitted])
def test_POST_admin_creates_machine_in_commissioning_state(self): # When an admin user enlists a machine, it goes into the # Commissioning state. response = self.client.post( reverse("machines_handler"), { "hostname": factory.make_string(), "architecture": make_usable_architecture(self), "power_type": "manual", "mac_addresses": ["aa:bb:cc:dd:ee:ff"], }, ) self.assertEqual(http.client.OK, response.status_code) system_id = json_load_bytes(response.content)["system_id"] self.assertEqual( NODE_STATUS.COMMISSIONING, Machine.objects.get(system_id=system_id).status, )
def test_revert_admin_only(self): dhcp_snippet = factory.make_DHCPSnippet() for _ in range(10): dhcp_snippet.value = dhcp_snippet.value.update( factory.make_string()) dhcp_snippet.save() value_id = dhcp_snippet.value.id revert_to = random.randint(-10, -1) response = self.client.post( self.get_dhcp_snippet_uri(dhcp_snippet), { "op": "revert", "to": revert_to }, ) self.assertEqual(http.client.FORBIDDEN, response.status_code, response.content) self.assertEqual(value_id, reload_object(dhcp_snippet).value.id)
def test_read_by_id(self): dhcp_snippet = factory.make_DHCPSnippet() # Generate some history dhcp_snippet.value = dhcp_snippet.value.update(factory.make_string()) dhcp_snippet.save() response = self.client.get(self.get_dhcp_snippet_uri(dhcp_snippet)) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_dhcp_snippet = json.loads(response.content.decode()) self.assertThat( parsed_dhcp_snippet, Equals({ "id": dhcp_snippet.id, "name": dhcp_snippet.name, "value": dhcp_snippet.value.data, "description": dhcp_snippet.description, "history": [ { "id": dhcp_snippet.value.id, "value": dhcp_snippet.value.data, "created": ANY, }, { "id": dhcp_snippet.value.previous_version.id, "value": dhcp_snippet.value.previous_version.data, "created": ANY, }, ], "enabled": dhcp_snippet.enabled, "node": None, "subnet": None, "global_snippet": True, "resource_uri": self.get_dhcp_snippet_uri(dhcp_snippet), }), )
def test_read_by_name(self): dhcp_snippet = factory.make_DHCPSnippet() # Generate some history dhcp_snippet.value = dhcp_snippet.value.update(factory.make_string()) dhcp_snippet.save() uri = '/MAAS/api/2.0/dhcp-snippets/%s/' % dhcp_snippet.name response = self.client.get(uri) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_dhcp_snippet = json.loads(response.content.decode()) self.assertThat( parsed_dhcp_snippet, Equals({ 'id': dhcp_snippet.id, 'name': dhcp_snippet.name, 'value': dhcp_snippet.value.data, 'description': dhcp_snippet.description, 'history': [ { 'id': dhcp_snippet.value.id, 'value': dhcp_snippet.value.data, 'created': ANY, }, { 'id': dhcp_snippet.value.previous_version.id, 'value': dhcp_snippet.value.previous_version.data, 'created': ANY, }, ], 'enabled': dhcp_snippet.enabled, 'node': None, 'subnet': None, 'global_snippet': True, 'resource_uri': self.get_dhcp_snippet_uri(dhcp_snippet), }))
def test_edit_user_POST_profile_updates_attributes(self): self.client.login(user=factory.make_admin()) user = factory.make_User() params = make_user_attribute_params(user) params.update({ "last_name": factory.make_name("Newname"), "email": "*****@*****.**" % factory.make_string(), "is_superuser": True, "username": factory.make_name("newname"), }) response = self.client.post( reverse("accounts-edit", args=[user.username]), get_prefixed_form_data("profile", params), ) self.assertEqual(http.client.FOUND, response.status_code) self.assertAttributes(reload_object(user), subset_dict(params, user_attributes))
def test_run_smartctl_with_success(self): output = factory.make_string().encode('utf-8') storage = factory.make_name('storage') cmd = ['sudo', '-n', 'smartctl', '--xall', storage] self.patch(smartctl, "check_SMART_support") self.patch(smartctl, "run_smartctl_selftest") mock_print = self.patch(smartctl, "print") mock_popen = self.patch(smartctl, "Popen") mock_popen.return_value = Popen(['echo', '-n', output], stdout=PIPE) self.assertEquals(0, smartctl.run_smartctl(storage)) self.assertThat( mock_print, MockCallsMatch( call('INFO: Verifying and/or validating SMART tests...'), call('INFO: Running command: %s\n' % ' '.join(cmd)), call('SUCCESS: SMART tests have PASSED for: %s\n' % storage), call('---------------------------------------------------\n'), call(output.decode('utf-8'))))
def test_type_error_is_not_hidden(self): # This tests that bug #1228205 is fixed (i.e. that a # TypeError is properly reported and not swallowed by # piston). # Create a valid configuration item. name = 'maas_name' value = factory.make_string() Config.objects.set_config(name, value) # Patch ConfigManager.get_config so that it will raise a # TypeError exception. self.patch(ConfigManager, "get_config", Mock(side_effect=TypeError)) self.become_admin() response = self.client.get(reverse('maas_handler'), { 'op': 'get_config', 'name': name, }) self.assertEqual(http.client.INTERNAL_SERVER_ERROR, response.status_code, response.content)
def test_no_connections_available_has_usable_cluster_name_in_msg(self): # If a NoConnectionsAvailable exception carries a reference to # the cluster UUID, RPCErrorsMiddleware will look up the # cluster's name and make the error message it displays more # useful. request = factory.make_fake_request(factory.make_string(), "POST") rack_controller = factory.make_RackController() error = NoConnectionsAvailable(factory.make_name("msg"), uuid=rack_controller.system_id) self.process_request(request, error) expected_error_message = ( "Error: Unable to connect to rack controller '%s' (%s); no " "connections available." % (rack_controller.hostname, rack_controller.system_id)) self.assertEqual( [(constants.ERROR, expected_error_message, "")], request._messages.messages, )
def test_proxy_proxy_POST(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() self.client.login(user=factory.make_admin()) new_proxy = "http://%s.example.com:1234/" % factory.make_string() response = self.client.post( reverse('settings_network'), get_prefixed_form_data(prefix='proxy', data={ 'http_proxy': new_proxy, 'enable_http_proxy': True, 'use_peer_proxy': True, })) self.assertEqual(http.client.FOUND, response.status_code, response.content) self.assertEqual(new_proxy, Config.objects.get_config('http_proxy')) self.assertTrue(Config.objects.get_config('enable_http_proxy')) self.assertTrue(Config.objects.get_config('use_peer_proxy'))
def test_GET_query_with_some_matching_ids_returns_matching_nodes(self): # If some nodes match the requested ids and some don't, only the # events matching nodes specified are returned. existing_node = factory.make_Node() existing_id = existing_node.system_id existing_events = make_events(node=existing_node) nonexistent_id = existing_id + factory.make_string() make_events() # Some non-matching events. response = self.client.get( reverse('events_handler'), { 'op': 'query', 'id': [existing_id, nonexistent_id], 'level': 'DEBUG', }) parsed_result = json_load_bytes(response.content) self.assertItemsEqual( [event.id for event in existing_events], extract_event_ids(parsed_result)) self.assertEqual(len(existing_events), parsed_result['count'])
def test__update(self): script = factory.make_Script() name = factory.make_name('name') title = factory.make_name('title') description = factory.make_name('description') tags = [factory.make_name('tag') for _ in range(3)] script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES) timeout = random.randint(0, 1000) destructive = factory.pick_bool() script_content = factory.make_string() comment = factory.make_name('comment') orig_script_content = script.script.data form = ScriptForm(data={ 'name': name, 'title': title, 'description': description, 'tags': ','.join(tags), 'type': script_type, 'timeout': str(timeout), 'destructive': destructive, 'script': script_content, 'comment': comment, }, instance=script) self.assertTrue(form.is_valid(), form.errors) script = form.save() self.assertEquals(name, script.name) self.assertEquals(title, script.title) self.assertEquals(description, script.description) if script.destructive: tags.append('destructive') self.assertEquals(tags, script.tags) self.assertEquals(script_type, script.script_type) self.assertEquals(timedelta(0, timeout), script.timeout) self.assertEquals(destructive, script.destructive) self.assertEquals(script_content, script.script.data) self.assertEquals(comment, script.script.comment) self.assertEquals(orig_script_content, script.script.previous_version.data) self.assertEquals(None, script.script.previous_version.comment) self.assertFalse(script.default)
def test_run_nondestructive(self): drive = self.make_drive(with_path=True) run_bad_blocks = badblocks.RunBadBlocks(drive, False) output = factory.make_string() self.patch(badblocks, 'check_output').return_value = '4096' mock_popen = self.patch(badblocks, 'Popen') mock_popen.return_value = Popen(['echo', '-n', output], stdout=PIPE) run_bad_blocks.run() self.assertEquals(output.encode(), run_bad_blocks.output) self.assertEquals(0, run_bad_blocks.returncode) self.assertThat( mock_popen, MockCalledOnceWith( [ 'sudo', '-n', 'badblocks', '-b', '4096', '-v', '-n', drive['PATH'], ], stdout=PIPE, stderr=STDOUT))
def test_POST_non_admin_creates_machine_in_declared_state(self): # Upon non-admin enlistment, a machine goes into the New # state. Deliberate approval is required before we start # reinstalling the system, wiping its disks etc. response = self.client.post( reverse("machines_handler"), { "hostname": factory.make_string(), "architecture": make_usable_architecture(self), "mac_addresses": ["aa:bb:cc:dd:ee:ff"], }, ) self.assertEqual( http.client.OK, response.status_code, response.content ) system_id = json_load_bytes(response.content)["system_id"] self.assertEqual( NODE_STATUS.NEW, Machine.objects.get(system_id=system_id).status )
def test_list_returns_output_if_stdout_empty(self): node = factory.make_Node(with_empty_script_sets=True) for script_result in chain(node.current_commissioning_script_set, node.current_testing_script_set, node.current_installation_script_set): self.store_result(script_result, exit_status=0, output=factory.make_string()) url = reverse('node_results_handler') response = self.client.get(url, {'system_id': [node.system_id]}) self.assertThat(response, HasStatusCode(http.client.OK)) parsed_results = json_load_bytes(response.content) self.assertItemsEqual([ b64encode(script_result.output).decode() for script_result in chain(node.current_commissioning_script_set, node.current_testing_script_set, node.current_installation_script_set) ], [parsed_result['data'] for parsed_result in parsed_results])
def test_POST_new_invalid_tag_name(self): self.become_admin() # We do not check the full possible set of invalid names here, a more # thorough check is done in test_tag, we just check that we get a # reasonable error here. invalid = "invalid:name" definition = "//node" comment = factory.make_string() response = self.client.post( reverse("tags_handler"), {"name": invalid, "comment": comment, "definition": definition}, ) self.assertEqual( http.client.BAD_REQUEST, response.status_code, "We did not get BAD_REQUEST for an invalid tag name: %r" % (invalid,), ) self.assertFalse(Tag.objects.filter(name=invalid).exists())
def test_POST_new_sets_power_parameters_skip_check(self): # The api allows to skip the validation step and set arbitrary # power parameters. param = factory.make_string() response = self.client.post( reverse('machines_handler'), { 'architecture': make_usable_architecture(self), 'power_type': 'manual', 'power_parameters_param': param, 'power_parameters_skip_check': 'true', 'mac_addresses': ['AA:BB:CC:DD:EE:FF'], }) self.assertEqual(http.client.OK, response.status_code, response.content) machine = Machine.objects.get( system_id=json_load_bytes(response.content)['system_id']) self.assertEqual({'param': param}, reload_object(machine).power_parameters)
def test__caches_hash(self): # Fake the API description. api_description = factory.make_string() api_description_hasher = hash_canonical(api_description) # The description can only be fetched once before crashing. self.patch(doc_module, "describe_api").side_effect = [ api_description, factory.make_exception_type(), ] # The hash is generated and cached. self.assertThat( get_api_description_hash(), Equals(api_description_hasher.hexdigest()), ) self.assertThat( get_api_description_hash(), Equals(api_description_hasher.hexdigest()), ) # Calling `describe_api` a second time would have failed. self.assertRaises(Exception, doc_module.describe_api)
def test_stores_types(self): values = [ None, True, False, 3.33, "A simple string", [1, 2.43, "3"], { "not": 5, "another": "test" }, ] for value in values: name = factory.make_string() test_instance = JSONFieldModel(name=name, value=value) test_instance.save() test_instance = JSONFieldModel.objects.get(name=name) self.assertEqual(value, test_instance.value)
def test_update_self_as_unprivileged(self): user = factory.make_User() handler = UserHandler(user, {}, None) params = make_user_attribute_params(user) params.update({ "id": user.id, "last_name": factory.make_name("Newname"), "email": "new-{}@example.com".format(factory.make_string()), "is_superuser": True, "username": factory.make_name("newname"), }) handler.update(params) self.assertAttributes(reload_object(user), subset_dict(params, user_attributes))
def test_update_other_as_unprivileged(self): unpriv_user = factory.make_User() handler = UserHandler(unpriv_user, {}, None) user = factory.make_User() params = make_user_attribute_params(user) params.update({ "id": user.id, "last_name": factory.make_name("Newname"), "email": "new-{}@example.com".format(factory.make_string()), "is_superuser": True, "username": factory.make_name("newname"), }) with self.assertRaises(HandlerPermissionError): handler.update(params)