def test_init_module_method_noninteractive(): add_dummy_language_plugin() artifact_type = "MODULE" args = get_args("dummy", "Test::Test::Test::MODULE", artifact_type) mock_project, patch_project = get_mock_project() patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) with TemporaryDirectory() as temporary_directory: mock_project.root = Path(temporary_directory) with patch_project, patch_get_parser as mock_parser: main(args_in=[ "init", "--type-name", args.type_name, "--artifact-type", args.artifact_type, args.language, "--dummy", ]) mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_module.assert_called_once_with(args.type_name) mock_project.generate.assert_not_called()
def _invoke_and_expect_hook(status, hook_payload_path, command, *args): ( mock_project, patch_project, patch_session, patch_creds, patch_account, patch_type_name, ) = _setup_hook_test() # fmt: off with patch_project, \ patch_account, \ patch_type_name, \ patch_session as mock_session, \ patch_creds as mock_creds: mock_client = mock_session.return_value.client.return_value mock_client.invoke.side_effect = lambda **_kwargs: { "Payload": StringIO(json.dumps({"status": status})) } main(args_in=["invoke", "hook", command, str(hook_payload_path), *args]) # fmt: on mock_creds.assert_called() return mock_project, mock_client.invoke
def test_init_module_method_interactive(): type_name = object() language = object() mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.module.init_module.input_typename", return_value=type_name) patch_l = patch("rpdk.core.resource.init_resource.input_language", return_value=language) patch_at = patch("rpdk.core.init.init_artifact_type", return_value="MODULE") with TemporaryDirectory() as temporary_directory: mock_project.root = Path(temporary_directory) with patch_project, patch_tn as mock_tn, patch_l as mock_l, patch_at as mock_t: main(args_in=["init"]) mock_tn.assert_called_once_with() mock_l.assert_not_called() mock_t.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_module.assert_called_once_with(type_name) mock_project.generate.assert_not_called()
def test_test_command_happy_path(base, capsys, args_in, pytest_args, plugin_args): # pylint: disable=too-many-locals create_input_file(base, '{"a": 1}', '{"a": 2}', '{"b": 1}') mock_project = Mock(spec=Project) mock_project.schema = SCHEMA mock_project.root = base mock_project.executable_entrypoint = None mock_project.artifact_type = ARTIFACT_TYPE_RESOURCE patch_project = patch("rpdk.core.test.Project", autospec=True, return_value=mock_project) patch_plugin = patch("rpdk.core.test.ContractPlugin", autospec=True) patch_client = patch("rpdk.core.test.ResourceClient", autospec=True) patch_pytest = patch("rpdk.core.test.pytest.main", autospec=True, return_value=0) patch_ini = patch("rpdk.core.test.temporary_ini_file", side_effect=mock_temporary_ini_file) # fmt: off with patch_project, \ patch_plugin as mock_plugin, \ patch_client as mock_client, \ patch_pytest as mock_pytest, \ patch_ini as mock_ini: main(args_in=["test"] + args_in) # fmt: on mock_project.load.assert_called_once_with() function_name, endpoint, region, enforce_timeout = plugin_args mock_client.assert_called_once_with( function_name, endpoint, region, mock_project.schema, EMPTY_OVERRIDE, { "CREATE": { "a": 1 }, "UPDATE": { "a": 2 }, "INVALID": { "b": 1 } }, None, enforce_timeout, None, None, ) mock_plugin.assert_called_once_with(mock_client.return_value) mock_ini.assert_called_once_with() mock_pytest.assert_called_once_with(["-c", RANDOM_INI, "-m", ""] + pytest_args, plugins=[mock_plugin.return_value]) _out, err = capsys.readouterr() assert not err
def test_generate_command_generate_with_args(capsys): mock_project = Mock(spec=Project) mock_project.type_name = "foo" with patch("rpdk.core.generate.Project", autospec=True, return_value=mock_project): main(args_in=[ "generate", "--endpoint-url", "http://localhost/3001", "--region", "us-east-1", "--target-schemas", "/files/target-schema.json", "/files/other-target-schema", ]) mock_project.load.assert_called_once_with() mock_project.generate.assert_called_once_with( "http://localhost/3001", "us-east-1", ["/files/target-schema.json", "/files/other-target-schema"], ) mock_project.generate_docs.assert_called_once_with() out, err = capsys.readouterr() assert not err assert "foo" in out
def test_init_resource_method_interactive(): type_name = object() language = object() mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.resource.init_resource.input_typename", return_value=type_name) patch_l = patch("rpdk.core.resource.init_resource.input_language", return_value=language) patch_at = patch("rpdk.core.init.init_artifact_type", return_value="RESOURCE") with patch_project, patch_at as mock_t, patch_tn as mock_tn, patch_l as mock_l: main(args_in=["init"]) mock_tn.assert_called_once_with() mock_l.assert_called_once_with() mock_t.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init.assert_called_once_with( type_name, language, { "version": False, "subparser_name": None, "verbose": 0, "force": False, "type_name": None, "artifact_type": None, }, ) mock_project.generate.assert_called_once_with()
def _invoke_and_expect(status, payload_path, command, *args): mock_project = Mock(spec=Project) mock_project.schema = {} mock_project.root = None patch_project = patch("rpdk.core.invoke.Project", autospec=True, return_value=mock_project) patch_session = patch( "rpdk.core.contract.resource_client.create_sdk_session", autospec=True) patch_creds = patch( "rpdk.core.contract.resource_client.get_temporary_credentials", autospec=True, return_value={}, ) patch_account = patch( "rpdk.core.contract.resource_client.get_account", autospec=True, return_value=ACCOUNT, ) with patch_project, patch_session as mock_session, patch_creds as mock_creds: with patch_account as mock_account: mock_client = mock_session.return_value.client.return_value mock_client.invoke.side_effect = lambda **_kwargs: { "Payload": StringIO(json.dumps({"status": status})) } mock_account.return_value = ACCOUNT main(args_in=["invoke", command, str(payload_path), *args]) # mock_account.assert_called_once_with(mock_client) mock_creds.assert_called_once() return mock_project, mock_client.invoke
def test_init_method_noninteractive_invalid_type_name(): add_dummy_language_plugin() type_name = object() args = get_args("dummy", "invalid_type_name") mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.init.input_typename", return_value=type_name) patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) with patch_project, patch_tn as mock_tn, patch_get_parser as mock_parser: main(args_in=["init", "-t", args.type_name, args.language, "--dummy"]) mock_tn.assert_called_once_with() mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init.assert_called_once_with( type_name, args.language, { "version": False, "subparser_name": args.language, "verbose": 0, "force": False, "type_name": args.type_name, "language": args.language, "dummy": True, }, ) mock_project.generate.assert_called_once_with()
def test_keyboard_interrupt(capsys, payload_path, command): mock_project = Mock(spec=Project) mock_project.schema = {} mock_project.root = None patch_project = patch("rpdk.core.invoke.Project", autospec=True, return_value=mock_project) patch_session = patch( "rpdk.core.contract.resource_client.create_sdk_session", autospec=True) patch_creds = patch( "rpdk.core.contract.resource_client.get_temporary_credentials", autospec=True, return_value={}, ) patch_dumps = patch.object(json, "dumps", side_effect=KeyboardInterrupt) with patch_project, patch_creds, patch_dumps, patch_session as mock_session: mock_client = mock_session.return_value.client.return_value main(args_in=["invoke", command, str(payload_path)]) mock_project.load.assert_called_once_with() mock_client.invoke.assert_not_called() _out, err = capsys.readouterr() assert not err
def test_keyboard_interrupt_hook(capsys, hook_payload_path, command): ( mock_project, patch_project, patch_session, patch_creds, patch_account, patch_type_name, ) = _setup_hook_test() patch_dumps = patch.object(json, "dumps", side_effect=KeyboardInterrupt) # fmt: off with patch_project, \ patch_creds, \ patch_dumps, \ patch_account, \ patch_type_name, \ patch_session as mock_session: mock_client = mock_session.return_value.client.return_value main(args_in=["invoke", "hook", command, str(hook_payload_path)]) # fmt: on mock_project.load.assert_called_once_with() mock_client.invoke.assert_not_called() _out, err = capsys.readouterr() assert not err
def test_value_error_on_json_load(capsys, invalid_payload, command): mock_project = Mock(spec=Project) mock_project.schema = {} mock_project.root = None mock_project.executable_entrypoint = None patch_project = patch("rpdk.core.invoke.Project", autospec=True, return_value=mock_project) patch_session = patch( "rpdk.core.contract.resource_client.create_sdk_session", autospec=True) patch_creds = patch( "rpdk.core.contract.resource_client.get_temporary_credentials", autospec=True, return_value={}, ) patch_account = patch( "rpdk.core.contract.resource_client.get_account", autospec=True, return_value="", ) with patch_project, patch_session, patch_creds, patch_account: with pytest.raises(SystemExit): main(args_in=["invoke", command, str(invalid_payload)]) out, _err = capsys.readouterr() assert "Invalid JSON" in out
def test_init_hook_method_interactive(): type_name = object() language = object() mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.hook.init_hook.input_typename", return_value=type_name) patch_l = patch("rpdk.core.hook.init_hook.input_language", return_value=language) patch_at = patch("rpdk.core.init.init_artifact_type", return_value="HOOK") with patch_project, patch_at as mock_t, patch_tn as mock_tn, patch_l as mock_l: main(args_in=["init"]) mock_tn.assert_called_once_with() mock_l.assert_called_once_with() mock_t.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_hook.assert_called_once_with( type_name, language, { "version": False, "subparser_name": None, "verbose": 0, "force": False, "type_name": None, "artifact_type": None, "endpoint_url": None, "region": None, "target_schemas": [], }, ) mock_project.generate.assert_called_once_with(None, None, [])
def test_init_module_method_noninteractive(): add_dummy_language_plugin() artifact_type = "MODULE" args = get_args("dummy", "Test::Test::Test::MODULE", artifact_type) mock_project, patch_project = get_mock_project() patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) # flake8: noqa: B950 # pylint: disable=line-too-long with patch_project, patch_get_parser as mock_parser: main(args_in=[ "init", "--type-name", args.type_name, "--artifact-type", args.artifact_type, args.language, "--dummy", ]) mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_module.assert_called_once_with(args.type_name) mock_project.generate.assert_not_called()
def test_command_with_invalid_subcommand(capsys, command): with patch("rpdk.core.invoke.invoke", autospec=True) as mock_func: with pytest.raises(SystemExit) as excinfo: main(args_in=["invoke", command]) assert excinfo.value.code != EXIT_UNHANDLED_EXCEPTION _, err = capsys.readouterr() assert "invalid choice:" in err mock_func.assert_not_called()
def test_subcommand_with_required_params(capsys, command): with patch("rpdk.core.invoke.invoke", autospec=True) as mock_func: with pytest.raises(SystemExit) as excinfo: main(args_in=["invoke", command]) assert excinfo.value.code != EXIT_UNHANDLED_EXCEPTION _, err = capsys.readouterr() assert "the following arguments are required" in err mock_func.assert_not_called()
def test_init_hook_method_noninteractive_target_schemas(): add_dummy_language_plugin() artifact_type = "HOOK" args = get_args("dummy", "Test::Test::Test", artifact_type) mock_project, patch_project = get_mock_project() patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) with patch_project, patch_get_parser as mock_parser: main(args_in=[ "init", "--type-name", args.type_name, "--artifact-type", args.artifact_type, "--target-schemas", "/files/target-schema.json,/files/other-target-schema.json", args.language, "--dummy", ]) mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_hook.assert_called_once_with( args.type_name, args.language, { "version": False, "subparser_name": args.language, "verbose": 0, "force": False, "type_name": args.type_name, "language": args.language, "dummy": True, "artifact_type": artifact_type, "endpoint_url": None, "region": None, "target_schemas": [ "/files/target-schema.json", "/files/other-target-schema.json", ], }, ) mock_project.generate.assert_called_once_with( None, None, ["/files/target-schema.json", "/files/other-target-schema.json"])
def test_test_command_happy_path_hook(base, capsys, args_in, pytest_args, plugin_args): # pylint: disable=too-many-locals mock_project = Mock(spec=Project) mock_project.schema = HOOK_SCHEMA mock_project.root = base mock_project.artifact_type = ARTIFACT_TYPE_HOOK mock_project.executable_entrypoint = None mock_project._load_target_info.return_value = HOOK_TARGET_INFO marker_options = _get_expected_marker_options(mock_project.artifact_type) patch_project = patch("rpdk.core.test.Project", autospec=True, return_value=mock_project) patch_plugin = patch("rpdk.core.test.ContractPlugin", autospec=True) patch_hook_client = patch("rpdk.core.test.HookClient", autospec=True) patch_pytest = patch("rpdk.core.test.pytest.main", autospec=True, return_value=0) patch_ini = patch("rpdk.core.test.temporary_ini_file", side_effect=mock_temporary_ini_file) # fmt: off with patch_project, \ patch_plugin as mock_plugin, \ patch_hook_client as mock_hook_client, \ patch_pytest as mock_pytest, \ patch_ini as mock_ini: main(args_in=["test"] + args_in) # fmt: on mock_project.load.assert_called_once_with() function_name, endpoint, region, enforce_timeout = plugin_args mock_hook_client.assert_called_once_with( function_name, endpoint, region, mock_project.schema, EMPTY_HOOK_OVERRIDE, None, None, enforce_timeout, mock_project.type_name, None, None, None, None, HOOK_TARGET_INFO, ) mock_plugin.assert_called_once_with( {"hook_client": mock_hook_client.return_value}) mock_ini.assert_called_once_with() mock_pytest.assert_called_once_with( ["-c", RANDOM_INI, "-m", marker_options] + pytest_args, plugins=[mock_plugin.return_value], ) _out, err = capsys.readouterr() assert not err
def test_test_command_module_project_succeeds(): mock_project = Mock(spec=Project) mock_project.artifact_type = ARTIFACT_TYPE_MODULE patch_project = patch("rpdk.core.test.Project", autospec=True, return_value=mock_project) with patch_project: main(args_in=["test"])
def test_validate_command_valid_schema(capsys): mock_project = Mock(spec=Project) with patch("rpdk.core.validate.Project", autospec=True, return_value=mock_project): main(args_in=["validate"]) mock_project.load.assert_called_once_with() out, err = capsys.readouterr() assert not err assert "failed" not in out
def test_generate_command_generate(capsys): mock_project = Mock(spec=Project) mock_project.type_name = "foo" with patch("rpdk.core.generate.Project", autospec=True, return_value=mock_project): main(args_in=["generate"]) mock_project.load.assert_called_once_with() mock_project.generate.assert_called_once_with() out, err = capsys.readouterr() assert not err assert "foo" in out
def test_value_error_on_json_load_resource(capsys, invalid_payload, command): ( _mock_project, patch_project, patch_session, patch_creds, patch_account, ) = _setup_resource_test() with patch_project, patch_session, patch_creds, patch_account: with pytest.raises(SystemExit): main(args_in=["invoke", "resource", command, str(invalid_payload)]) out, _err = capsys.readouterr() assert "Invalid JSON" in out
def test_main_unhandled_exception_before_logging(capsys): with patch( "rpdk.core.cli.unittest_patch_setup_subparser", autospec=True, side_effect=Exception, ) as mock_hook: with pytest.raises(SystemExit) as excinfo: main(args_in=[]) assert excinfo.value.code == EXIT_UNHANDLED_EXCEPTION mock_hook.assert_called_once() out, err = capsys.readouterr() assert not out assert "Unhandled exception" in err assert "Traceback" in err assert "rpdk.log" not in err
def test_init_hook_method_noninteractive_invalid_type_name(): add_dummy_language_plugin() type_name = object() artifact_type = "HOOK" args = get_args("dummy", "invalid_type_name", "HOOK") mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.hook.init_hook.input_typename", return_value=type_name) patch_t = patch("rpdk.core.init.init_artifact_type", return_value=artifact_type) patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) with patch_project, patch_t, patch_tn as mock_tn, patch_get_parser as mock_parser: main(args_in=[ "init", "-t", args.type_name, "-a", args.artifact_type, args.language, "--dummy", ]) mock_tn.assert_called_once_with() mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init_hook.assert_called_once_with( type_name, args.language, { "version": False, "subparser_name": args.language, "verbose": 0, "force": False, "type_name": args.type_name, "artifact_type": artifact_type, "dummy": True, "language": args.language, "endpoint_url": None, "region": None, "target_schemas": [], }, ) mock_project.generate.assert_called_once_with(None, None, [])
def test_init_resource_method_noninteractive_invalid_type_name(): add_dummy_language_plugin() type_name = object() artifact_type = "RESOURCE" args = get_args("dummy", "invalid_type_name", "RESOURCE") mock_project, patch_project = get_mock_project() patch_tn = patch("rpdk.core.resource.init_resource.input_typename", return_value=type_name) patch_t = patch("rpdk.core.init.init_artifact_type", return_value=artifact_type) patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) # flake8: noqa: B950 # pylint: disable=line-too-long with patch_project, patch_t, patch_tn as mock_tn, patch_get_parser as mock_parser: main(args_in=[ "init", "-t", args.type_name, "-a", args.artifact_type, args.language, "--dummy", ]) mock_tn.assert_called_once_with() mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init.assert_called_once_with( type_name, args.language, { "version": False, "subparser_name": args.language, "verbose": 0, "force": False, "type_name": args.type_name, "artifact_type": artifact_type, "dummy": True, "language": args.language, }, ) mock_project.generate.assert_called_once_with()
def test_test_command_return_code_on_error(): mock_project = Mock(spec=Project) mock_project.root = None mock_project.schema = SCHEMA mock_project.executable_entrypoint = None patch_project = patch( "rpdk.core.test.Project", autospec=True, return_value=mock_project ) patch_plugin = patch("rpdk.core.test.ContractPlugin", autospec=True) patch_client = patch("rpdk.core.test.ResourceClient", autospec=True) patch_pytest = patch("rpdk.core.test.pytest.main", autospec=True, return_value=1) with patch_project, patch_plugin, patch_client, patch_pytest: with pytest.raises(SystemExit) as excinfo: main(args_in=["test"]) assert excinfo.value.code != EXIT_UNHANDLED_EXCEPTION
def test_main_sysexit_exception_after_logging(capsys): def raise_exception(_args): raise SysExitRecommendedError(ERROR_MSG) def setup_subparser(subparsers, parents): parser = subparsers.add_parser("fail", parents=parents) parser.set_defaults(command=raise_exception) with patch( "rpdk.core.cli.unittest_patch_setup_subparser", autospec=True, side_effect=setup_subparser, ) as mock_hook: with pytest.raises(SystemExit) as excinfo: main(args_in=["fail"]) assert excinfo.value.code == 1 mock_hook.assert_called_once() out, err = capsys.readouterr() assert ERROR_MSG in out assert not err
def test_init_resource_method_noninteractive(): add_dummy_language_plugin() artifact_type = "RESOURCE" args = get_args("dummy", "Test::Test::Test", artifact_type) mock_project, patch_project = get_mock_project() patch_get_parser = patch("rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser}) with patch_project, patch_get_parser as mock_parser: main(args_in=[ "init", "--type-name", args.type_name, "--artifact-type", args.artifact_type, args.language, "--dummy", ]) mock_parser.assert_called_once() mock_project.load_settings.assert_called_once_with() mock_project.init.assert_called_once_with( args.type_name, args.language, { "version": False, "subparser_name": args.language, "verbose": 0, "force": False, "type_name": args.type_name, "language": args.language, "dummy": True, "artifact_type": artifact_type, }, ) mock_project.generate.assert_called_once_with()
def test_main_unhandled_exception_after_logging(capsys): def raise_exception(_args): raise Exception def setup_subparser(subparsers, parents): parser = subparsers.add_parser("fail", parents=parents) parser.set_defaults(command=raise_exception) with patch( "rpdk.core.cli.unittest_patch_setup_subparser", autospec=True, side_effect=setup_subparser, ) as mock_hook: with pytest.raises(SystemExit) as excinfo: main(args_in=["fail"]) assert excinfo.value.code == EXIT_UNHANDLED_EXCEPTION mock_hook.assert_called_once() out, err = capsys.readouterr() assert not out assert "Unhandled exception" in err assert "Traceback" not in err assert "rpdk.log" in err assert "github.com" in err
def test_main_downstream_wrapped_exception_after_logging(capsys): def raise_exception(_args): raise DownstreamError("ignored") from Exception(ERROR_MSG) def setup_subparser(subparsers, parents): parser = subparsers.add_parser("fail", parents=parents) parser.set_defaults(command=raise_exception) with patch( "rpdk.core.cli.unittest_patch_setup_subparser", autospec=True, side_effect=setup_subparser, ) as mock_hook: with pytest.raises(SystemExit) as excinfo: main(args_in=["fail"]) assert excinfo.value.code == 2 mock_hook.assert_called_once() out, err = capsys.readouterr() assert not out assert ERROR_MSG in err assert "Traceback" not in err assert "rpdk.log" in err assert "github.com" in err
def test_test_command_happy_path(capsys, args_in, pytest_args, plugin_args): # pylint: disable=too-many-locals mock_project = Mock(spec=Project) mock_project.schema = SCHEMA mock_project.root = None patch_project = patch("rpdk.core.test.Project", autospec=True, return_value=mock_project) patch_plugin = patch("rpdk.core.test.ContractPlugin", autospec=True) patch_client = patch("rpdk.core.test.ResourceClient", autospec=True) patch_pytest = patch("rpdk.core.test.pytest.main", autospec=True, return_value=0) patch_ini = patch("rpdk.core.test.temporary_ini_file", side_effect=mock_temporary_ini_file) # fmt: off with patch_project, \ patch_plugin as mock_plugin, \ patch_client as mock_client, \ patch_pytest as mock_pytest, \ patch_ini as mock_ini: main(args_in=["test"] + args_in) # fmt: on mock_project.load.assert_called_once_with() function_name, endpoint, region = plugin_args mock_client.assert_called_once_with(function_name, endpoint, region, mock_project.schema, EMPTY_OVERRIDE, None) mock_plugin.assert_called_once_with(mock_client.return_value) mock_ini.assert_called_once_with() mock_pytest.assert_called_once_with(["-c", RANDOM_INI, "-m", ""] + pytest_args, plugins=[mock_plugin.return_value]) _out, err = capsys.readouterr() assert not err