class TestConfigureAuthentication(MAASTestCase): def setUp(self): super().setUp() self.maas_bin_path = "snap-path/bin/maas-region" self.mock_subprocess = self.patch(init, "subprocess") self.mock_environ = patch.dict(init.os.environ, {"SNAP": "snap-path"}, clear=True) self.mock_environ.start() self.parser = ArgumentParser() init.add_rbac_options(self.parser) init.add_candid_options(self.parser) def tearDown(self): self.mock_subprocess.stop() self.mock_environ.stop() super().tearDown() def test_no_options(self): options = self.parser.parse_args([]) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual(([self.maas_bin_path, "configauth"], ), args) self.assertEqual({}, kwargs) def test_rbac_url(self): config_auth_args = ["--rbac-url", "http://rrbac.example.com/"] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_rbac_service_name(self): config_auth_args = ["--rbac-service-name", "mymaas"] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_candid_agent_file(self): _, agent_file_path = tempfile.mkstemp() self.addCleanup(os.remove, agent_file_path) config_auth_args = ["--candid-agent-file", agent_file_path] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs)
class TestCreateAdminOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_create_admin_options(self.parser) def test_create_admin_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) def test_create_admin_options_username(self): options = self.parser.parse_args( ['--admin-username', 'my-username']) self.assertEqual('my-username', options.admin_username) def test_create_admin_options_password(self): options = self.parser.parse_args(['--admin-password', 'my-password']) self.assertEqual('my-password', options.admin_password) def test_create_admin_options_email(self): options = self.parser.parse_args(['--admin-email', '*****@*****.**']) self.assertEqual('*****@*****.**', options.admin_email) def test_create_admin_options_ssh_import(self): options = self.parser.parse_args(['--admin-ssh-import', 'lp:me']) self.assertEqual('lp:me', options.admin_ssh_import)
def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_create_admin_options(self.parser) self.mock_call = self.patch(init.subprocess, 'call') self.mock_print_msg = self.patch(init, 'print_msg') self.maas_region_path = init.get_maas_region_bin_path()
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, "call") self.check_output_mock = self.patch(init.subprocess, "check_output") self.check_output_mock.return_value = json.dumps( {"external_auth_url": ""}) # avoid printouts self.mock_stdout = self.patch(init.sys, "stdout", StringIO()) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_defaults(self): options = self.parser.parse_args([]) self.assertFalse(options.skip_admin) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) self.assertIsNone(options.candid_agent_file) self.assertIsNone(options.rbac_url) def test_init_maas_calls_subcommands(self): options = self.parser.parse_args([]) self.cmd(options) configauth_call, createadmin_call = self.call_mock.mock_calls _, args1, kwargs1 = configauth_call _, args2, kwargs2 = createadmin_call self.assertEqual(([self.maas_region_path, "configauth"], ), args1) self.assertEqual({}, kwargs1) self.assertEqual(([self.maas_region_path, "createadmin"], ), args2) self.assertEqual({}, kwargs2)
def test_get_optional_args_returns_optional_args(self): option = "--%s" % factory.make_name("opt") parser = ArgumentParser(add_help=False) parser.add_argument(option) args = api.ActionHelp.get_optional_args(parser) self.assertEqual([[option]], [action.option_strings for action in args])
def test_requires_root(self): parser = ArgumentParser() cmd = snappy.cmd_status(parser) self.patch(os, "getuid").return_value = 1000 error = self.assertRaises(SystemExit, cmd, parser.parse_args([])) self.assertEqual(str(error), "The 'status' command must be run by root.")
class TestAddIdmOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_idm_options(self.parser) def test_add_idm_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.idm_url) self.assertIsNone(options.idm_user) self.assertIsNone(options.idm_key) self.assertIsNone(options.idm_agent_file) def test_add_idm_options_idm_url(self): options = self.parser.parse_args( ['--idm-url', 'http://idm.example.com/']) self.assertEqual('http://idm.example.com/', options.idm_url) def test_add_idm_options_idm_user(self): options = self.parser.parse_args(['--idm-user', 'my-user']) self.assertEqual('my-user', options.idm_user) def test_add_idm_options_idm_key(self): options = self.parser.parse_args(['--idm-key', 'my-key']) self.assertEqual('my-key', options.idm_key) def test_add_idm_options_idm_agent_file(self): fd, agent_file_name = tempfile.mkstemp() self.addCleanup(os.remove, agent_file_name) os.write(fd, b'my-agent-file-content') os.close(fd) options = self.parser.parse_args(['--idm-agent-file', agent_file_name]) self.assertEqual('my-agent-file-content', options.idm_agent_file.read())
class TestAddCandidOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_candid_options(self.parser) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_add_candid_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.candid_agent_file) def test_add_candid_options_candid_domain(self): options = self.parser.parse_args( ['--candid-domain', 'mydomain']) self.assertEqual('mydomain', options.candid_domain) def test_add_candid_options_candid_agent_file(self): options = self.parser.parse_args(['--candid-agent-file', 'agent.file']) self.assertEqual(options.candid_agent_file, 'agent.file') def test_add_candid_options_candid_admin_group(self): options = self.parser.parse_args( ['--candid-admin-group', 'admins']) self.assertEqual('admins', options.candid_admin_group)
def test_compose_positional_args_does_not_end_with_newline(self): arg = factory.make_name('arg', sep='_') parser = ArgumentParser() parser.add_argument(arg) self.assertThat( '\n'.join(api.ActionHelp.compose_positional_args(parser)), Not(EndsWith('\n')))
def test_compose_positional_args_does_not_end_with_newline(self): arg = factory.make_name("arg", sep="_") parser = ArgumentParser() parser.add_argument(arg) self.assertThat( "\n".join(api.ActionHelp.compose_positional_args(parser)), Not(EndsWith("\n")), )
def test_cmd_configure_supervisord(self): self.patch(snappy, "get_current_mode").return_value = "region+rack" mock_render_supervisord = self.patch(snappy, "render_supervisord") mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") parser = ArgumentParser() cmd = snappy.cmd_reconfigure_supervisord(parser) cmd(parser.parse_args([])) mock_render_supervisord.assert_called_once_with("region+rack") mock_sighup_supervisord.assert_called_once()
def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_config(self.parser) self.patch(os, "getuid").return_value = 0 snap_common = self.make_dir() snap_data = self.make_dir() self.useFixture(EnvironmentVariableFixture("SNAP_COMMON", snap_common)) self.useFixture(EnvironmentVariableFixture("SNAP_DATA", snap_data))
def setUp(self): super().setUp() self.maas_bin_path = 'snap-path/bin/maas-region' self.mock_subprocess = self.patch(init, 'subprocess') self.mock_environ = patch.dict(init.os.environ, {'SNAP': 'snap-path'}, clear=True) self.mock_environ.start() self.parser = ArgumentParser() init.add_idm_options(self.parser)
def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, 'call') self.check_output_mock = self.patch(init.subprocess, 'check_output') self.check_output_mock.return_value = json.dumps( {'external_auth_url': ''})
def setUp(self): super().setUp() self.maas_bin_path = "snap-path/bin/maas-region" self.mock_subprocess = self.patch(init, "subprocess") self.mock_environ = patch.dict(init.os.environ, {"SNAP": "snap-path"}, clear=True) self.mock_environ.start() self.parser = ArgumentParser() init.add_rbac_options(self.parser) init.add_candid_options(self.parser)
def test_compose_positional_args_describes_positional_args(self): arg = factory.make_name('arg', sep='_') parser = ArgumentParser() parser.add_argument(arg) self.assertEqual( dedent("""\ Positional arguments: \t%s """.rstrip()) % arg, '\n'.join(api.ActionHelp.compose_positional_args(parser)))
def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_init(self.parser) self.patch(os, 'getuid').return_value = 0 self.patch( os, 'environ', { 'SNAP': '/snap/maas', 'SNAP_COMMON': '/snap/maas/common', 'SNAP_DATA': '/snap/maas/data' }) self.mock_read_input = self.patch(snappy, 'read_input')
def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, "call") self.check_output_mock = self.patch(init.subprocess, "check_output") self.check_output_mock.return_value = json.dumps( {"external_auth_url": ""}) # avoid printouts self.mock_stdout = self.patch(init.sys, "stdout", StringIO()) self.mock_stderr = self.patch(init.sys, "stderr", StringIO())
class TestCmdConfig(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_config(self.parser) self.patch(os, "getuid").return_value = 0 snap_common = self.make_dir() snap_data = self.make_dir() self.useFixture(EnvironmentVariableFixture("SNAP_COMMON", snap_common)) self.useFixture(EnvironmentVariableFixture("SNAP_DATA", snap_data)) def test_show(self): # Regression test for LP:1892868 stdout = io.StringIO() self.patch(sys, "stdout", stdout) options = self.parser.parse_args([]) self.assertIsNone(self.cmd(options)) self.assertEqual(stdout.getvalue(), "Mode: none\n") def test_enable_debugging(self): mock_maas_configuration = self.patch(snappy, "MAASConfiguration") mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") options = self.parser.parse_args(["--enable-debug"]) stdout = io.StringIO() self.patch(sys, "stdout", stdout) self.cmd(options) mock_maas_configuration().update.assert_called_once_with( {"debug": True} ) # After config is changed, services are restarted self.assertEqual(stdout.getvalue(), "Stopping services\n") mock_sighup_supervisord.assert_called_once_with() def test_reenable_debugging(self): mock_maas_configuration = self.patch(snappy, "MAASConfiguration") config_manager = mock_maas_configuration() mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") options = self.parser.parse_args(["--enable-debug"]) stdout = io.StringIO() self.patch(sys, "stdout", stdout) # Simulate the value already being enabled current_config = config_manager.get() current_config.get.side_effect = {"debug": True}.__getitem__ self.cmd(options) config_manager.update.assert_not_called() self.assertEqual(stdout.getvalue(), "") mock_sighup_supervisord.assert_not_called()
class TestAddRBACOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_rbac_options(self.parser) def test_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.rbac_url) def test_rbac_url(self): options = self.parser.parse_args( ['--rbac-url', 'http://rbac.example.com/']) self.assertEqual('http://rbac.example.com/', options.rbac_url)
def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_init(self.parser) self.patch(os, "getuid").return_value = 0 self.patch( os, "environ", { "SNAP": "/snap/maas", "SNAP_COMMON": "/snap/maas/common", "SNAP_DATA": "/snap/maas/data", }, ) self.mock_read_input = self.patch(snappy, "read_input")
def test_compose_epilog_preserves_indentation(self): indent = ' ' * 8 epilog = indent + factory.make_name('epi') self.assertEqual( "\n\n%s" % epilog, '\n'.join( api.ActionHelp.compose_epilog(ArgumentParser(epilog=epilog))))
def test_registers_subparsers(self): profile_name = list(self.make_profile().keys())[0] parser = ArgumentParser() self.assertIsNone(parser._subparsers) api.register_api_commands(parser) self.assertIsNotNone(parser._subparsers) self.assertIsNotNone(parser.subparsers.choices[profile_name])
def test_compose_optional_args_returns_empty_if_none_defined(self): self.assertEqual( [], api.ActionHelp.compose_optional_args( ArgumentParser(add_help=False) ), )
def test_compose_epilog_returns_epilog(self): epilog = factory.make_name("epi") self.assertEqual( "\n\n%s" % epilog, "\n".join( api.ActionHelp.compose_epilog(ArgumentParser(epilog=epilog))), )
def test_compose_epilog_explains_documented_keyword_args(self): epilog = ":param foo: The amount of foo." self.assertEqual( "\n\n%s\n%s" % (api.ActionHelp.keyword_args_help, epilog), "\n".join( api.ActionHelp.compose_epilog(ArgumentParser(epilog=epilog))), )
def test_subparsers_have_appropriate_execute_defaults(self): parser = ArgumentParser() cli.register_cli_commands(parser) self.assertIsInstance( parser.subparsers.choices["login"].get_default("execute"), cli.cmd_login, )
def test_load_init_command_no_snap(self): environ = {} self.patch(os, "environ", environ) parser = ArgumentParser() cli.register_cli_commands(parser) subparser = parser.subparsers.choices.get("init") self.assertIsInstance(subparser.get_default("execute"), cli.cmd_init)
def test_compose_optional_args_describes_optional_args(self): long_option = '--%s' % factory.make_name('opt', sep='_') short_option = '-o' option_help = factory.make_name('help') parser = ArgumentParser(add_help=False) parser.add_argument(long_option, short_option, help=option_help) expected_text = dedent("""\ Common command-line options: %s \t%s """) % (', '.join([long_option, short_option]), option_help) self.assertEqual( expected_text.rstrip(), '\n'.join(api.ActionHelp.compose_optional_args(parser)))
def test_doesnt_call_load_regiond_commands_if_no_maasserver(self): self.patch(cli, "get_django_management").return_value = sentinel.management self.patch(cli, "is_maasserver_available").return_value = None mock_load_regiond_commands = self.patch(cli, "load_regiond_commands") parser = ArgumentParser() cli.register_cli_commands(parser) self.assertThat(mock_load_regiond_commands, MockNotCalled())
def test_handlers_registered_using_correct_names(self): profile = self.make_profile() parser = ArgumentParser() api.register_api_commands(parser) for resource in profile.values()[0]["description"]["resources"]: for action in resource["auth"]["actions"]: # Profile names are matched as-is. profile_name = profile.keys()[0] # Handler names are processed with handler_command_name before # being added to the argument parser tree. handler_name = handler_command_name(resource["name"]) # Action names are processed with safe_name before being added # to the argument parser tree. action_name = safe_name(action["name"]) # Parsing these names as command-line arguments yields an # options object. Its execute attribute is an instance of # Action (or a subclass thereof). options = parser.parse_args( (profile_name, handler_name, action_name)) self.assertIsInstance(options.execute, api.Action)