Esempio n. 1
0
 def test_config_jsonschema(self):
     """ test a working config schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = {'config': 'config.json'}
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     msg = adapter.loadNestedEvent(in_msg, {})
     assert msg["config"]["inlinestr"] == 'prefixbarsuffix'
Esempio n. 2
0
 def test_input_jsonschema(self):
     """ test a working input schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = {'input': 'input.json'}
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     in_msg["payload"] = {"hello": "world"}
     msg = adapter.loadNestedEvent(in_msg, {})
     assert msg["input"]["hello"] == "world"
Esempio n. 3
0
 def test_output_jsonschema(self):
     """ test a working output schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = { 'output': 'output.json' }
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     msg = adapter.loadNestedEvent(in_msg, {})
     messageConfig = msg.get('messageConfig')
     handler_response = { "goodbye": "world" }
     result = adapter.createNextEvent(handler_response, in_msg, messageConfig)
     assert result["payload"]["goodbye"] == "world"
Esempio n. 4
0
 def test_failing_input_jsonschema(self):
     """ test a failing input schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = {'input': 'input.json'}
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     in_msg["payload"] = {"hello": 1}
     try:
         adapter.loadNestedEvent(in_msg, {})
     except ValidationError as e:
         assert e.message == "input schema: 1 is not of type u'string'"
         pass
Esempio n. 5
0
 def test_failing_config_jsonschema(self):
     """ test a failing input schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = { 'config': 'config.json' }
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     in_msg["workflow_config"]["Example"]["boolean_option"] = '{{$.meta.boolean_option}}'
     in_msg["meta"]["boolean_option"] = "notgoingtowork"
     try:
         adapter.loadNestedEvent(in_msg, {})
     except ValidationError as e:
         assert e.message == "config schema: 'notgoingtowork' is not of type u'boolean'"
         pass
Esempio n. 6
0
 def test_failing_output_jsonschema(self):
     """ test a working output schema """
     inp = open(os.path.join(self.test_folder, 'templates.input.json'))
     schemas = { 'output': 'output.json' }
     adapter = message_adapter.message_adapter(schemas)
     in_msg = json.loads(inp.read())
     msg = adapter.loadNestedEvent(in_msg, {})
     messageConfig = msg.get('messageConfig')
     handler_response = { "goodbye": 1 }
     try:
         adapter.createNextEvent(handler_response, in_msg, messageConfig,)
     except ValidationError as e:
         assert e.message == "output schema: 1 is not of type u'string'"
         pass
# use input with both python 2 & 3
try:
    import __builtin__
    input = getattr(__builtin__, 'raw_input')
except (ImportError, AttributeError):
    pass

if __name__ == '__main__':
    functionName = sys.argv[1]
    allInput = json.loads(input())
    if 'schemas' in allInput:
        schemas = allInput['schemas']
    else:
        schemas = None
    transformer = message_adapter.message_adapter(schemas)
    exitCode = 1
    event = allInput['event']

    try:
        if (functionName == 'loadRemoteEvent'):
            result = transformer.loadRemoteEvent(event)
        elif (functionName == 'loadNestedEvent'):
            context = allInput['context']
            result = transformer.loadNestedEvent(event, context)
        elif (functionName == 'createNextEvent'):
            handlerResponse = allInput['handler_response']
            if 'message_config' in allInput:
                messageConfig = allInput['message_config']
            else:
                messageConfig = None
Esempio n. 8
0
class Test(unittest.TestCase):
    """ Test class """

    s3_object = {'input': ':blue_whale:'}
    bucket_name = 'testing-internal'
    key_name = 'blue_whale-event.json'
    event_with_replace = {'replace': {'Bucket': bucket_name, 'Key': key_name}}
    event_without_replace = {'input': ':baby_whale:'}
    test_uuid = 'aad93279-95d4-4ada-8c43-aa5823f8bbbc'
    next_event_object_key_name = "events/{0}".format(test_uuid)
    s3 = aws.s3()
    cumulus_message_adapter = message_adapter.message_adapter()
    test_folder = os.path.join(os.getcwd(), 'examples/messages')
    schemas_folder = os.path.join(os.getcwd(), 'examples/schemas')
    os.environ["LAMBDA_TASK_ROOT"] = os.path.join(os.getcwd(), 'examples')

    def setUp(self):
        self.nested_response = {'input': {'dataLocation': 's3://source.jpg'}}

        self.s3.Bucket(self.bucket_name).create()
        self.s3.Object(self.bucket_name,
                       self.key_name).put(Body=json.dumps(self.s3_object))

    def tearDown(self):
        delete_objects_object = {
            'Objects': [{
                'Key': self.key_name
            }, {
                'Key': self.next_event_object_key_name
            }]
        }
        self.s3.Bucket(
            self.bucket_name).delete_objects(Delete=delete_objects_object)
        self.s3.Bucket(self.bucket_name).delete()

    # loadRemoteEvent tests
    def test_returns_remote_s3_object(self):
        """ Test remote s3 event is returned when 'replace' key is present """
        result = self.cumulus_message_adapter.loadRemoteEvent(
            self.event_with_replace)
        assert result == self.s3_object

    def test_returns_event(self):
        """ Test event argument is returned when 'replace' key is not present """
        result = self.cumulus_message_adapter.loadRemoteEvent(
            self.event_without_replace)
        assert result == self.event_without_replace

    # loadNestedEvent tests
    def test_returns_loadNestedEvent_local(self):
        """
        Test returns 'config', 'input' and 'messageConfig' in expected format
        - 'input' in return value is from 'payload' in first argument object
        - 'config' in return value is the task ($.cumulus_meta.task) configuration
           with 'cumulus_message' excluded
        - 'messageConfig' in return value is the cumulus_message.input of the task configuration
        """

        nested_event_local = {
            "workflow_config": {
                "Example": {
                    "bar": "baz",
                    "cumulus_message": {
                        "input":
                        "{{$.payload.input}}",
                        "outputs": [{
                            "source": "{{$.input.anykey}}",
                            "destination": "{{$.payload.out}}"
                        }]
                    }
                }
            },
            "cumulus_meta": {
                "task": "Example",
                "message_source": "local",
                "id": "id-1234"
            },
            "meta": {
                "foo": "bar"
            },
            "payload": {
                "input": {
                    "anykey": "anyvalue"
                }
            }
        }

        nested_event_local_return = {
            'input': {
                'anykey': 'anyvalue'
            },
            'config': {
                'bar': 'baz'
            },
            'messageConfig': {
                'input':
                '{{$.payload.input}}',
                'outputs': [{
                    'source': '{{$.input.anykey}}',
                    'destination': '{{$.payload.out}}'
                }]
            }
        }

        result = self.cumulus_message_adapter.loadNestedEvent(
            nested_event_local, {})
        assert result == nested_event_local_return

    # assignOutputs tests
    def test_result_payload_without_config(self):
        """ Test nestedResponse is returned when no config argument is passed """
        result = self.cumulus_message_adapter._message_adapter__assignOutputs(  # pylint: disable=no-member
            self.nested_response, {}, None)
        assert result['payload'] == self.nested_response

    def test_result_payload_without_config_outputs(self):
        """ Test nestedResponse is returned when config has no outputs key/value """
        message_config_without_outputs = {}
        result = self.cumulus_message_adapter._message_adapter__assignOutputs(  # pylint: disable=no-member
            self.nested_response, {}, message_config_without_outputs)
        assert result['payload'] == self.nested_response

    def test_result_payload_with_simple_config_outputs(self):
        """ Test payload value is updated when messageConfig contains outputs templates """
        # messageConfig objects
        message_config_with_simple_outputs = {
            'outputs': [{
                'source': '{{$.input.dataLocation}}',
                'destination': '{{$.payload}}'
            }]
        }

        result = self.cumulus_message_adapter._message_adapter__assignOutputs(  # pylint: disable=no-member
            self.nested_response, {}, message_config_with_simple_outputs)
        assert result['payload'] == 's3://source.jpg'

    def test_result_payload_with_nested_config_outputs(self):
        """
        Test nested payload value is updated when messageConfig contains
        outputs templates with child nodes
        """
        message_config_with_nested_outputs = {
            'outputs': [{
                'source': '{{$.input.dataLocation}}',
                'destination': '{{$.payload.dataLocation}}'
            }]
        }

        result = self.cumulus_message_adapter._message_adapter__assignOutputs(  # pylint: disable=no-member
            self.nested_response, {}, message_config_with_nested_outputs)
        assert result['payload'] == {'dataLocation': 's3://source.jpg'}

    # createNextEvent tests
    def test_with_replace(self):
        """
        Test 'replace' key is deleted from value returned from createNextEvent
        """
        result = self.cumulus_message_adapter.createNextEvent(
            self.nested_response, self.event_with_replace, None)
        assert 'replace' not in result

    def test_small_result_returns_event(self):
        """ Test return result is the event result when it's not too big """
        result = self.cumulus_message_adapter.createNextEvent(
            self.nested_response, self.event_without_replace, None)
        expected_result = {
            'input': ':baby_whale:',
            'exception': 'None',
            'payload': {
                'input': {
                    'dataLocation': 's3://source.jpg'
                }
            }
        }
        assert result == expected_result

    @patch.object(cumulus_message_adapter, 'MAX_NON_S3_PAYLOAD_SIZE', 1)
    @patch('uuid.uuid4')
    def test_big_result_stored_remotely(self, uuid_mock):
        """
        Test remote event is stored in S3 and return value points
        to remote location with 'replace' key/value
        """

        event_with_ingest = {
            'cumulus_meta': {
                'workflow': 'testing',
                "system_bucket": self.bucket_name
            }
        }

        uuid_mock.return_value = self.test_uuid
        create_next_event_result = self.cumulus_message_adapter.createNextEvent(
            self.nested_response, event_with_ingest, None)
        expected_create_next_event_result = {
            'cumulus_meta': {
                'workflow': 'testing',
                'system_bucket': self.bucket_name
            },
            'replace': {
                'Bucket': self.bucket_name,
                'Key': self.next_event_object_key_name
            }
        }
        remote_event = self.s3.Object(self.bucket_name,
                                      self.next_event_object_key_name).get()
        remote_event_object = json.loads(
            remote_event['Body'].read().decode('utf-8'))
        expected_remote_event_object = {
            'cumulus_meta': {
                'workflow': 'testing',
                'system_bucket': self.bucket_name
            },
            'exception': 'None',
            'payload': {
                'input': {
                    'dataLocation': 's3://source.jpg'
                }
            }
        }
        assert remote_event_object == expected_remote_event_object
        assert create_next_event_result == expected_create_next_event_result

    def test_basic(self):
        """ test basic.input.json """
        inp = open(os.path.join(self.test_folder, 'basic.input.json'))
        out = open(os.path.join(self.test_folder, 'basic.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    def test_jsonpath(self):
        """ test jsonpath.input.json """
        inp = open(os.path.join(self.test_folder, 'jsonpath.input.json'))
        out = open(os.path.join(self.test_folder, 'jsonpath.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    def test_meta(self):
        """ test meta.input.json """
        inp = open(os.path.join(self.test_folder, 'meta.input.json'))
        out = open(os.path.join(self.test_folder, 'meta.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    def test_remote(self):
        """ test remote.input.json """
        inp = open(os.path.join(self.test_folder, 'remote.input.json'))
        out = open(os.path.join(self.test_folder, 'remote.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        bucket_name = in_msg['replace']['Bucket']
        key_name = in_msg['replace']['Key']
        data_filename = os.path.join(self.test_folder, key_name)
        with open(data_filename, 'r') as f:
            datasource = json.load(f)
        self.s3.Bucket(bucket_name).create()
        self.s3.Object(bucket_name, key_name).put(Body=json.dumps(datasource))

        remoteEvent = self.cumulus_message_adapter.loadRemoteEvent(in_msg)
        msg = self.cumulus_message_adapter.loadNestedEvent(remoteEvent, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, remoteEvent, messageConfig)

        delete_objects_object = {'Objects': [{'Key': key_name}]}
        self.s3.Bucket(bucket_name).delete_objects(
            Delete=delete_objects_object)
        self.s3.Bucket(bucket_name).delete()

        assert result == out_msg

    @patch.object(cumulus_message_adapter,
                  '_message_adapter__getCurrentSfnTask',
                  return_value="Example")
    def test_sfn(self, getCurrentSfnTask_function):
        """ test sfn.input.json """
        inp = open(os.path.join(self.test_folder, 'sfn.input.json'))
        out = open(os.path.join(self.test_folder, 'sfn.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    @patch.object(cumulus_message_adapter,
                  '_message_adapter__getCurrentSfnTask',
                  return_value="Example")
    def test_inline_template(self, getCurrentSfnTask_function):
        """ test inline_template.input.json """
        inp = open(os.path.join(self.test_folder,
                                'inline_template.input.json'))
        out = open(
            os.path.join(self.test_folder, 'inline_template.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    def test_templates(self):
        """ test templates.input.json """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        out = open(os.path.join(self.test_folder, 'templates.output.json'))
        in_msg = json.loads(inp.read())
        out_msg = json.loads(out.read())

        msg = self.cumulus_message_adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        if 'messageConfig' in msg: del msg['messageConfig']
        result = self.cumulus_message_adapter.createNextEvent(
            msg, in_msg, messageConfig)
        assert result == out_msg

    def test_input_jsonschema(self):
        """ test a working input schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'input': 'input.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        in_msg["payload"] = {"hello": "world"}
        msg = adapter.loadNestedEvent(in_msg, {})
        assert msg["input"]["hello"] == "world"

    def test_failing_input_jsonschema(self):
        """ test a failing input schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'input': 'input.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        in_msg["payload"] = {"hello": 1}
        try:
            adapter.loadNestedEvent(in_msg, {})
        except ValidationError as e:
            assert e.message == "input schema: 1 is not of type u'string'"
            pass

    def test_config_jsonschema(self):
        """ test a working config schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'config': 'config.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        msg = adapter.loadNestedEvent(in_msg, {})
        assert msg["config"]["inlinestr"] == 'prefixbarsuffix'

    def test_failing_config_jsonschema(self):
        """ test a failing input schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'config': 'config.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        in_msg["workflow_config"]["Example"][
            "boolean_option"] = '{{$.meta.boolean_option}}'
        in_msg["meta"]["boolean_option"] = "notgoingtowork"
        try:
            adapter.loadNestedEvent(in_msg, {})
        except ValidationError as e:
            assert e.message == "config schema: 'notgoingtowork' is not of type u'boolean'"
            pass

    def test_output_jsonschema(self):
        """ test a working output schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'output': 'output.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        msg = adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        handler_response = {"goodbye": "world"}
        result = adapter.createNextEvent(handler_response, in_msg,
                                         messageConfig)
        assert result["payload"]["goodbye"] == "world"

    def test_failing_output_jsonschema(self):
        """ test a working output schema """
        inp = open(os.path.join(self.test_folder, 'templates.input.json'))
        schemas = {'output': 'output.json'}
        adapter = message_adapter.message_adapter(schemas)
        in_msg = json.loads(inp.read())
        msg = adapter.loadNestedEvent(in_msg, {})
        messageConfig = msg.get('messageConfig')
        handler_response = {"goodbye": 1}
        try:
            adapter.createNextEvent(
                handler_response,
                in_msg,
                messageConfig,
            )
        except ValidationError as e:
            assert e.message == "output schema: 1 is not of type u'string'"
            pass