def _generate_config(params=None, setting_file_name=None, initial=True) -> GenerateConfigResponse: """Generate a configuration given a settings file""" if params is None: params = [] if setting_file_name: settings_file_path = os.path.join(TEST_FIXTURE_DIR, setting_file_name) with open(settings_file_path) as file: try: settings_contents = yaml.load(file, Loader=Loader) except yaml.parser.ParserError: # let the config subsystem catch the invalid yaml file settings_contents = {} else: settings_file_path = "" settings_contents = {} # deepcopy here to ensure we do not modify the original application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params, settings_file_path=settings_file_path or None, initial=initial, ) messages, exit_messages = configurator.configure() return GenerateConfigResponse( messages=messages, exit_messages=exit_messages, application_configuration=application_configuration, settings_contents=settings_contents, )
def test_import_error(): """Ensure an error for invalid action_package""" test_config = ApplicationConfiguration( application_name="test_config1", internals=Internals(action_packages=["__ansible_navigator.__actions"]), post_processor=NavigatorPostProcessor(), subcommands=[ SubCommand(name="subcommand1", description="subcommand1"), ], entries=[ Entry( name="app", short_description="test_app", value=EntryValue(current="subcommand1"), ), Entry( name="mode", short_description="mode", value=EntryValue(), ), ], ) configurator = Configurator(params=[], application_configuration=test_config) configurator._post_process() message = "Unable to load action package: '__ansible_navigator.__actions':" message += " No module named '__ansible_navigator'" assert message in (entry.message for entry in configurator._messages) error = "Unable to find an action for 'subcommand1', tried: '__ansible_navigator.__actions'" assert error in configurator._errors
def test_cmdline_source_not_set(): """Ensure a configuration without a ``subparser`` entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", application_version="1.0", internals=Internals(), post_processor=NavigatorPostProcessor(), subcommands=[ SubCommand( name="subcommand1", description="subcommand1", version_added="v0.0", ), ], entries=[ SettingsEntry( name="cmdline", short_description="cmdline", value=SettingsEntryValue(), version_added="v0.0", ), ], ) configurator = Configurator(params=[], application_configuration=test_config) configurator._post_process() assert "Completed post processing for cmdline" in configurator._messages[ 0][1] assert not configurator._exit_messages
def test_subcommand_not_found(): """Ensure an error for invalid subcommand/action""" test_config = ApplicationConfiguration( application_name="test_config1", internals=Internals(action_packages=["ansible_navigator.actions"]), post_processor=NavigatorPostProcessor(), subcommands=[ SubCommand(name="__test_action", description="test_action"), ], entries=[ Entry( name="app", short_description="test_app", value=EntryValue(current="__test_action"), ), Entry( name="mode", short_description="mode", value=EntryValue(), ), ], ) configurator = Configurator(params=[], application_configuration=test_config) configurator._post_process() error = "Unable to find an action for '__test_action', tried: 'ansible_navigator.actions'" assert error in configurator._errors
def test_many_subcommand(): """Ensure a configuration without a ``subparser`` entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", application_version="1.0", internals=Internals(), post_processor=None, subcommands=[ SubCommand( name="subcommand1", description="subcommand1", version_added="v0.0", ), ], entries=[ SettingsEntry( name="sb1", short_description="Subcommands", subcommand_value=True, value=SettingsEntryValue(default="welcome"), version_added="v0.0", ), SettingsEntry( name="sb2", short_description="Subcommands", subcommand_value=True, value=SettingsEntryValue(default="welcome"), version_added="v0.0", ), ], ) with pytest.raises(ValueError, match="Multiple entries with subparser value defined"): Configurator(params=[], application_configuration=test_config).configure()
def test_many_subcommand(): """Ensure a Config without a subparse entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", post_processor=None, subcommands=[ SubCommand(name="subcommand1", description="subcommand1"), ], entries=[ Entry( name="sb1", short_description="Subcommands", subcommand_value=True, value=EntryValue(default="welcome"), ), Entry( name="sb2", short_description="Subcommands", subcommand_value=True, value=EntryValue(default="welcome"), ), ], ) with pytest.raises(ValueError, match="Multiple entries with subparser value defined"): Configurator(params=[], application_configuration=test_config).configure()
def test_env_var(monkeypatch: pytest.MonkeyPatch, data: Scenario): """Test the time zone post processor using the environment variable. :param monkeypatch: The monkey patch fixture :param data: The test data """ application_configuration = deepcopy(NavigatorConfiguration) application_configuration.internals.initializing = True configurator = Configurator(application_configuration=application_configuration, params=[]) monkeypatch.setenv("TZ", str(data.current)) _messages, exit_messages = configurator.configure() if data.exit_message_substr: assert data.exit_message_substr in exit_messages[2].message else: assert application_configuration.entry("time_zone").value.current == data.expected
def test_cmdline_source_not_set(): """Ensure a Config without a subparse entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", post_processor=NavigatorPostProcessor(), subcommands=[ SubCommand(name="subcommand1", description="subcommand1"), ], entries=[ Entry( name="cmdline", short_description="cmdline", value=EntryValue(), ), ], ) configurator = Configurator(params=[], application_configuration=test_config) configurator._post_process() assert "Completed post processing for cmdline" in configurator._messages[ 0][1] assert configurator._exit_messages == []
def test_no_subcommand(): """Ensure a Config without a subparse entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", post_processor=None, subcommands=[ SubCommand(name="subcommand1", description="subcommand1"), ], entries=[], ) with pytest.raises(ValueError, match="No entry with subparser value defined"): Configurator(params=[], application_configuration=test_config).configure()
def test_subcommand_not_found(): """Ensure an error for invalid subcommand/action""" test_config = ApplicationConfiguration( application_name="test_config1", application_version="1.0", internals=Internals(action_packages=["ansible_navigator.actions"]), post_processor=NavigatorPostProcessor(), subcommands=[ SubCommand( name="__test_action", description="test_action", version_added="v0.0", ), ], entries=[ SettingsEntry( name="app", short_description="test_app", value=SettingsEntryValue(current="__test_action"), version_added="v0.0", ), SettingsEntry( name="mode", short_description="mode", value=SettingsEntryValue(), version_added="v0.0", ), ], ) test_config.internals.initializing = True configurator = Configurator(params=[], application_configuration=test_config) configurator._post_process() exit_msg = "Unable to find an action for '__test_action', tried: 'ansible_navigator.actions'" assert exit_msg in [ exit_msg.message for exit_msg in configurator._exit_messages ]
def test_apply_cli_subset_none(): """Ensure subset none works for apply CLI""" test_config = ApplicationConfiguration( application_name="test_application", post_processor=None, subcommands=[ SubCommand(name="list", description="list"), SubCommand(name="run", description="run"), ], entries=[ Entry( name="subcommand", short_description="Subcommands", subcommand_value=True, value=EntryValue(default="run"), ), Entry( name="z", apply_to_subsequent_cli=C.NONE, cli_parameters=CliParameters(short="-z"), short_description="the z parameter", value=EntryValue(), ), ], ) configurator = Configurator(params=["list", "-z", "zebra"], application_configuration=test_config, initial=True) _messages, exit_messages = configurator.configure() assert not exit_messages assert isinstance(test_config.initial, ApplicationConfiguration) expected = [ ("subcommand", "list"), ("z", "zebra"), ] for expect in expected: assert test_config.entry(expect[0]).value.current == expect[1] assert test_config.entry(expect[0]).value.source is C.USER_CLI configurator = Configurator(params=["run"], application_configuration=test_config, apply_previous_cli_entries=C.ALL) _messages, exit_messages = configurator.configure() assert not exit_messages expected = [ ("subcommand", "run", C.USER_CLI), ("z", C.NOT_SET, C.NOT_SET), ] for expect in expected: assert test_config.entry(expect[0]).value.current == expect[1] assert test_config.entry(expect[0]).value.source is expect[2]
def test_apply_previous_cli_cmdline_not_applied(): """Ensure the command line parameters are not carried forward""" params = "run /tmp/site.yml --ee False --forks 15" application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params.split(), initial=True, ) _messages, exit_messages = configurator.configure() assert not exit_messages assert isinstance(application_configuration.initial, ApplicationConfiguration) expected = [ ("app", "run"), ("cmdline", ["--forks", "15"]), ("execution_environment", False), ("playbook", "/tmp/site.yml"), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is C.USER_CLI params = "doc shell" configurator = Configurator( application_configuration=application_configuration, params=params.split(), apply_previous_cli_entries=C.ALL, ) _messages, exit_messages = configurator.configure() assert not exit_messages expected = [ ("app", "doc", C.USER_CLI), ("cmdline", C.NOT_SET, C.NOT_SET), ("execution_environment", False, C.PREVIOUS_CLI), ("playbook", "/tmp/site.yml", C.PREVIOUS_CLI), ("plugin_name", "shell", C.USER_CLI), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2]
def test_apply_previous_cli_none(_mf1): """Ensure nothing is carried forward""" params = "run /tmp/site.yml --ee False --forks 15" application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params.split(), initial=True, ) _messages, errors = configurator.configure() assert errors == [] assert isinstance(application_configuration.initial, ApplicationConfiguration) expected = [ ("app", "run"), ("cmdline", ["--forks", "15"]), ("playbook", "/tmp/site.yml"), ("execution_environment", False), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is C.USER_CLI params = "doc shell" configurator = Configurator( application_configuration=application_configuration, params=params.split(), apply_previous_cli_entries=C.NONE, ) _messages, errors = configurator.configure() assert errors == [] expected = [ ("app", "doc", C.USER_CLI), ("cmdline", C.NOT_SET, C.NOT_SET), ("playbook", C.NOT_SET, C.NOT_SET), ("execution_environment", True, C.DEFAULT_CFG), ("plugin_name", "shell", C.USER_CLI), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2]
def test_apply_previous_cli_specified(): """Ensure only some of the previous CLI parameters are applied when requested""" params = "doc shell --ee False --eei test_image:latest --forks 15" application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params.split(), initial=True, ) _messages, exit_messages = configurator.configure() assert not exit_messages assert isinstance(application_configuration.initial, ApplicationConfiguration) expected = [ ("app", "doc"), ("cmdline", ["--forks", "15"]), ("execution_environment", False), ("execution_environment_image", "test_image:latest"), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is C.USER_CLI params = "doc shell" configurator = Configurator( application_configuration=application_configuration, params=params.split(), apply_previous_cli_entries=[ "execution_environment", "execution_environment_image" ], ) _messages, exit_messages = configurator.configure() assert not exit_messages expected = [ ("app", "doc", C.USER_CLI), ("cmdline", C.NOT_SET, C.NOT_SET), ("execution_environment", False, C.PREVIOUS_CLI), ("execution_environment_image", "test_image:latest", C.PREVIOUS_CLI), ("plugin_name", "shell", C.USER_CLI), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2]
def test_no_subcommand(): """Ensure a configuration without no ``subparser`` entry fails""" test_config = ApplicationConfiguration( application_name="test_config1", application_version="1.0", internals=Internals(), post_processor=None, subcommands=[ SubCommand( name="subcommand1", description="subcommand1", version_added="v0.0", ), ], entries=[], ) with pytest.raises(ValueError, match="No entry with subparser value defined"): Configurator(params=[], application_configuration=test_config).configure()
def test_apply_previous_cli_all(): """Ensure all previous cli parameter are applied when requested""" params = "doc shell --ee False --eei test_image --forks 15" expected = [ ("app", "doc"), ("cmdline", ["--forks", "15"]), ("execution_environment", False), ("execution_environment_image", "test_image"), ("plugin_name", "shell"), ] application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params.split(), initial=True, ) _messages, errors = configurator.configure() assert errors == [] assert isinstance(application_configuration.initial, ApplicationConfiguration) for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is C.USER_CLI params = "doc" configurator = Configurator( application_configuration=application_configuration, params=params.split(), apply_previous_cli_entries=C.ALL, ) _messages, errors = configurator.configure() assert errors == [] expected = [ ("app", "doc", C.USER_CLI), ("cmdline", ["--forks", "15"], C.PREVIOUS_CLI), ("execution_environment", False, C.PREVIOUS_CLI), ("execution_environment_image", "test_image", C.PREVIOUS_CLI), ("plugin_name", "shell", C.PREVIOUS_CLI), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2]
def test_apply_previous_cli_mixed(): """Ensure a mixed configuration passes""" params = "doc shell --ee False --eei test_image:latest --forks 15" application_configuration = deepcopy(NavigatorConfiguration) configurator = Configurator( application_configuration=application_configuration, params=params.split(), initial=True, ) with mock.patch.dict( os.environ, {"ANSIBLE_NAVIGATOR_PASS_ENVIRONMENT_VARIABLES": "ENV1,ENV2"}): _messages, exit_messages = configurator.configure() assert not exit_messages assert isinstance(application_configuration.initial, ApplicationConfiguration) expected = [ ("app", "doc", C.USER_CLI), ("cmdline", ["--forks", "15"], C.USER_CLI), ("execution_environment", False, C.USER_CLI), ("execution_environment_image", "test_image:latest", C.USER_CLI), ("pass_environment_variable", ["ENV1", "ENV2"], C.ENVIRONMENT_VARIABLE), ("plugin_name", "shell", C.USER_CLI), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2] params = "doc shell --eei different_image:latest" configurator = Configurator( application_configuration=application_configuration, params=params.split(), apply_previous_cli_entries=C.ALL, ) with mock.patch.dict( os.environ, {"ANSIBLE_NAVIGATOR_SET_ENVIRONMENT_VARIABLES": "ENV1=VAL1"}): _messages, exit_messages = configurator.configure() assert not exit_messages expected = [ ("app", "doc", C.USER_CLI), ("cmdline", ["--forks", "15"], C.PREVIOUS_CLI), ("execution_environment", False, C.PREVIOUS_CLI), ("execution_environment_image", "different_image:latest", C.USER_CLI), ("pass_environment_variable", C.NOT_SET, C.NOT_SET), ("plugin_name", "shell", C.USER_CLI), ("set_environment_variable", { "ENV1": "VAL1" }, C.ENVIRONMENT_VARIABLE), ] for expect in expected: assert application_configuration.entry( expect[0]).value.current == expect[1] assert application_configuration.entry( expect[0]).value.source is expect[2]