def _input_output(cls: "StateMirror") -> "StateMirror": """Add the "InputPath" and "OutputPath" parameters to the class.""" cls.InputPath = RHODES_ATTRIB(default=JsonPath("$"), validator=optional(instance_of(JsonPath)), converter=convert_to_json_path) cls.__doc__ = docstring_with_param( cls, "InputPath", JsonPath, description= "The portion of the state input data to be used as input for the state", default=JsonPath("$"), ) cls.OutputPath = RHODES_ATTRIB(default=JsonPath("$"), validator=optional(instance_of(JsonPath)), converter=convert_to_json_path) cls.__doc__ = docstring_with_param( cls, "OutputPath", JsonPath, description= "The portion of the state input data to be passed to the next state", default=JsonPath("$"), ) return cls
def test_promote(path_reader, source_result, requested_promotion, expected_input): machine = StateMachine() starter = machine.start_with( Pass("Foo", ResultPath=JsonPath(source_result))) test = starter.promote(path_reader(requested_promotion)) assert test.title == "Foo-PromoteResult" assert test.InputPath == JsonPath(expected_input) assert test.ResultPath == JsonPath(source_result) assert test.member_of is machine
def _result_path(cls: "StateMirror") -> "StateMirror": """Add the "ResultPath" parameter to the class.""" cls.ResultPath = RHODES_ATTRIB(default=JsonPath("$"), validator=optional(instance_of(JsonPath)), converter=convert_to_json_path) cls.__doc__ = docstring_with_param( cls, "ResultPath", JsonPath, description= "Where in the state input data to place the results of this state", default=JsonPath("$"), ) return cls
def test_convert_to_json_path(path_value): expected = JsonPath(RAW_PATH) test = convert_to_json_path(path_value) # must be expected == test here because of VariablePath assert expected.path == test.path
def promote( self, path: Union[str, Enum, jsonpath_rw.JSONPath, JsonPath]) -> "Pass": """Add a :class:`Pass` state after this state that promotes a path in the input to this state's ``ResultPath``. Path *must* start with a path relative this state's ``ResultPath`` as indicated by a ``@.`` prefix. :param path: Path to promote """ # TODO: move this to the resultpath decorator? if not hasattr(self, "ResultPath"): raise AttributeError( f"{self.__class__.__name__} does not support 'promote'") path = convert_to_json_path(path) path_str = str(path) if not path_str.startswith("@."): raise ValueError("Promotion path must be relative (@.baz.wat)") input_path = JsonPath(f"{self.ResultPath}{path_str[1:]}") return self.then( Pass(f"{self.title}-PromoteResult", InputPath=input_path, ResultPath=self.ResultPath))
def test_amazon_sns_request_response(): expected_task = Task( "TestTask", Resource="arn:aws:states:::sns:publish", Parameters=Parameters( TopicArn="arn:aws:sns:us-east-1:123456789012:accretion-notify", Message=JsonPath("$.foo.bar")), ) expected = expected_task.to_dict() test_task = AmazonSns( "TestTask", TopicArn="arn:aws:sns:us-east-1:123456789012:accretion-notify", Message=JsonPath("$.foo.bar")) test = test_task.to_dict() assert test == expected
def test_amazon_sns_callback(): expected_task = Task( "TestTask", Resource="arn:aws:states:::sns:publish.waitForTaskToken", Parameters=Parameters( TopicArn="arn:aws:sns:us-east-1:123456789012:accretion-notify", Message=JsonPath("$.foo.bar")), ) expected = expected_task.to_dict() test_task = AmazonSns( "TestTask", Pattern=IntegrationPattern.WAIT_FOR_CALLBACK, TopicArn="arn:aws:sns:us-east-1:123456789012:accretion-notify", Message=JsonPath("$.foo.bar"), ) test = test_task.to_dict() assert test == expected
def test_accretion_listener_new_1(): test = StateMachine(Comment="Replication Listener") event_filter = test.start_with( Task("Filter", Resource=EVENT_FILTER_RESOURCE, ResultPath="$")) skip_check = event_filter.then(Choice("ShouldProcess")) skip_check.else_(Succeed("IgnoreEvent", Comment="Ignore this event")) locate_artifact = skip_check.if_( VariablePath("$.ProcessEvent") == True).then( Task("LocateArtifact", Resource=ARTIFACT_LOCATOR_RESOURCE, ResultPath="$.Artifact")) artifact_check = locate_artifact.then(Choice("ArtifactCheck")) publisher = artifact_check.if_( VariablePath("$.Artifact.Found") == True).then( Task("PublishNewVersion", Resource=LAYER_VERSION_PUBLISHER_RESOURCE, ResultPath="$.Layer")) publisher.then( Task( "Notify", Resource="arn:aws:states:::sns:publish", Parameters=Parameters(TopicArn=NOTIFY_TOPIC, Message=JsonPath("$.Layer")), )).end() artifact_check.if_( all_( VariablePath("$.Artifact.Found") == False, VariablePath("$.Artifact.ReadAttempts") > 15)).then( Fail("ReplicationTimeout", Error="Timed out waiting for artifact to replicate")) waiter = artifact_check.else_(Wait("WaitForReplication", Seconds=60)) waiter.then(locate_artifact) compare_state_machine("accretion_listener", test)
with pytest.raises(ValueError) as excinfo: Pass("Foo", Next="Bar", End=True) excinfo.match("Only one of 'Next' and 'End' is allowed") def test_invalid_end(): with pytest.raises(ValueError) as excinfo: Pass("Foo", End=False) excinfo.match("If 'End' is set, value must be True") @pytest.mark.parametrize( "cls, name, value", ((Pass, "InputPath", JsonPath("$")), (Pass, "OutputPath", JsonPath("$")), (Pass, "ResultPath", JsonPath("$"))), ) def test_default_value(cls, name, value): instance = cls("Foo") test = getattr(instance, name) assert test == value @pytest.mark.parametrize( "source_result, requested_promotion, expected_input", (("$.foo.bar", "@.baz", "$.foo.bar.baz"), ("$", "@.bar.baz", "$.bar.baz")), ) @pytest.mark.parametrize("path_reader",
from rhodes.choice_rules import VariablePath from rhodes.structures import JsonPath pytestmark = [pytest.mark.local, pytest.mark.functional] RAW_PATH = "$.path.to.value" class MyEnum(Enum): MY_PATH = RAW_PATH @pytest.mark.parametrize( "path_value", ( pytest.param(RAW_PATH, id="string"), pytest.param(MyEnum.MY_PATH, id="enum"), pytest.param(jsonpath_rw.parse(RAW_PATH), id="jsonpath_rw.JSONPath"), pytest.param(JsonPath(RAW_PATH), id="JsonPath"), pytest.param(VariablePath(RAW_PATH), id="VariablePath"), ), ) def test_convert_to_json_path(path_value): expected = JsonPath(RAW_PATH) test = convert_to_json_path(path_value) # must be expected == test here because of VariablePath assert expected.path == test.path
from rhodes.structures import JsonPath, Parameters __all__ = ( "try_to_create_and_delete_state_machine", "build_and_try_single_step_state_machine", "SERVICE_INTEGRATION_SIMPLE_CASES", "SERVICE_INTEGRATION_COMPLEX_CASES", "SERVICE_INTEGRATION_BOTH_CASES", ) class JunkEnum(Enum): FOO = "BAR" SERVICE_INTEGRATION_SIMPLE_CASES = (None, "some data", JunkEnum.FOO, JsonPath("$.foo.bar")) SERVICE_INTEGRATION_COMPLEX_CASES = ( None, JsonPath("$.foo.bar"), JunkEnum.FOO, Parameters(foo="bar"), dict(foo="bar"), ) SERVICE_INTEGRATION_BOTH_CASES = SERVICE_INTEGRATION_SIMPLE_CASES + SERVICE_INTEGRATION_COMPLEX_CASES[3:] def _state_machine_name() -> str: return f"rhodes-integ-{uuid4()}" @lru_cache(maxsize=1)
), ], Default="DefaultState", ) _load_and_test_vector(kind="choice", name=name, value=test) @pytest.mark.parametrize( "name,kwargs", ( ("wait_ten_seconds", dict(Seconds=10, Next="NextState")), ("wait_for_seconds_path", dict(SecondsPath="$.seconds", Next="NextState")), ("wait_for_seconds_path", dict(SecondsPath=JsonPath("$.seconds"), Next="NextState")), ("wait_until_timestamp", dict(Timestamp="2016-03-14T01:59:00Z", Next="NextState")), ("wait_until_timestamp_path", dict(TimestampPath="$.expirydate", Next="NextState")), ("wait_until_timestamp_path", dict(TimestampPath=JsonPath("$.expirydate"), Next="NextState")), ), ) def test_wait(name: str, kwargs: Dict): test = Wait(name, **kwargs) _load_and_test_vector(kind="wait", name=name, value=test) def test_succeed():