Example #1
0
def test_raise_for_type_mismatch(story, typ, val):
    command_conf = {
        'type': typ
    }

    line = {'ln': '10'}

    valid = False
    if typ == 'string' and isinstance(val, str):
        valid = True
    elif typ == 'int' and isinstance(val, int):
        valid = True
    elif typ == 'float' and isinstance(val, float):
        valid = True
    elif typ == 'list' and isinstance(val, list):
        valid = True
    elif typ == 'map' and isinstance(val, dict):
        valid = True
    elif typ == 'boolean' and isinstance(val, bool):
        valid = True
    elif typ == 'any':
        valid = True

    if valid:
        Services.raise_for_type_mismatch(story, line, 'arg_name',
                                         val, command_conf)
    else:
        with pytest.raises(ArgumentTypeMismatchError):
            Services.raise_for_type_mismatch(story, line, 'arg_name',
                                             val, command_conf)
Example #2
0
async def test_services_execute_args(story, async_mock):
    handler = async_mock(return_value='output')

    Services.register_internal('my_service', 'my_command',
                               {'arg1': {'type': 'string'}},
                               'any', handler)

    assert Services.is_internal('my_service', 'my_command') is True
    line = {
        Line.service: 'my_service',
        Line.command: 'my_command',
        Line.method: 'execute',
        'args': [
            {
                '$OBJECT': 'argument',
                'name': 'arg1',
                'argument': {
                    '$OBJECT': 'string',
                    'string': 'Hello world!'
                }
            }
        ]
    }

    assert await Services.execute(story, line) == 'output'
    handler.mock.assert_called_with(story=story, line=line,
                                    resolved_args={'arg1': 'Hello world!'})
Example #3
0
def test_parse_output_invalid_cast(story):
    command_conf = {
        'output': {
            'type': 'int'
        }
    }

    with pytest.raises(StoryscriptError):
        Services.parse_output(command_conf, 'not_an_int', story, {}, '')
Example #4
0
def test_parse_output_invalid_type(story):
    command_conf = {
        'output': {
            'type': 'foo'
        }
    }

    with pytest.raises(StoryscriptError):
        Services.parse_output(command_conf, 'blah', story, {}, '')
Example #5
0
def test_raise_for_type_mismatch_enum(story, val):
    command_conf = {'type': 'enum', 'enum': ['a', 'b', 'c']}

    if val in command_conf['enum']:
        Services.raise_for_type_mismatch(story, {}, 'arg_name', val,
                                         command_conf)
    else:
        with pytest.raises(ArgumentTypeMismatchError):
            Services.raise_for_type_mismatch(story, {}, 'arg_name', val,
                                             command_conf)
Example #6
0
async def test_services_execute_execute_internal(story, async_mock):
    handler = async_mock(return_value='output')

    Services.register_internal('my_service', 'my_command', {}, 'any', handler)

    assert Services.is_internal('my_service', 'my_command') is True
    line = {
        Line.service: 'my_service',
        Line.command: 'my_command',
        Line.method: 'execute'
    }

    assert await Services.execute(story, line) == 'output'
Example #7
0
def test_multipart_producer():
    w = Writer()
    boundary = str(uuid.uuid4())
    body = {
        'simple_arg': FormField('simple_arg', 10),
        'simple_arg2': FormField('simple_arg2', 'hello'),
        'hello_file': FileFormField('f1', 'hello world'.encode(),
                                    'hello.txt', 'text/plain')
    }
    list(Services._multipart_producer(body, boundary, w.write))
    expected = (
        f'--{boundary}\r\n'
        'Content-Disposition: form-data; name="simple_arg"\r\n'
        '\r\n'
        '10'
        '\r\n'
        f'--{boundary}\r\n'
        'Content-Disposition: form-data; name="simple_arg2"\r\n'
        '\r\n'
        'hello'
        '\r\n'
        f'--{boundary}\r\n'
        'Content-Disposition: form-data; name="f1"; filename="hello.txt"\r\n'
        'Content-Type: text/plain\r\n'
        '\r\n'
        'hello world'
        '\r\n'
        f'--{boundary}--\r\n'
    )

    assert w.out == expected
Example #8
0
def test_parse_output(output_type, story):
    line = {}
    command_conf = {
        'output': {
            'type': output_type
        }
    }

    expected_output = None
    actual_input = None

    if output_type == 'string':
        actual_input = 'hello'
        expected_output = 'hello'
    elif output_type == 'int':
        actual_input = b'10'
        expected_output = 10
    elif output_type == 'float':
        actual_input = b'7.0'
        expected_output = 7.0
    elif output_type == 'boolean':
        actual_input = f'true'
        expected_output = True
    elif output_type is None:
        actual_input = None
        expected_output = None
    elif output_type == 'any':
        actual_input = b'empty'
        expected_output = b'empty'

    assert Services.parse_output(
        command_conf, actual_input, story, line, '') == expected_output
Example #9
0
def test_service_get_command_conf_events(story):
    chain = deque(
        [Service('service'),
         Command('cmd'),
         Event('foo'),
         Command('bar')])
    story.app.services = {
        'service': {
            'configuration': {
                'actions': {
                    'cmd': {
                        'events': {
                            'foo': {
                                'output': {
                                    'actions': {
                                        'bar': {
                                            'a': 'b'
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    assert Services.get_command_conf(story, chain) == {'a': 'b'}
Example #10
0
def test_smart_insert(patch, story, value):
    patch.object(Services, 'raise_for_type_mismatch')

    command_conf = {'type': 'string'}

    m = {}

    key = 'my_key'

    if isinstance(value, dict) or isinstance(value, list):
        expected = json.dumps(value)
    else:
        expected = value

    Services.smart_insert(story, {}, command_conf, key, value, m)
    Services.raise_for_type_mismatch.assert_called_with(
        story, {}, key, expected, command_conf)

    assert m[key] == expected
Example #11
0
def test_service_is_hosted_externally(app, external):
    service_name = 'my_service'
    app.services = {
        service_name: {
            ServiceConstants.config: {
                ServiceConstants.hosted_externally: external
            }
        }
    }

    assert Services.is_hosted_externally(app, service_name) is external
Example #12
0
async def test_services_execute_execute_external(patch, story, async_mock):
    patch.object(Services, 'execute_external', new=async_mock())
    assert Services.is_internal('foo_service', 'blah') is False
    line = {
        Line.service: 'foo_service',
        Line.command: 'foo_command',
        Line.method: 'execute'
    }

    assert await Services.execute(story, line) \
        == await Services.execute_external()
Example #13
0
def test_service_get_command_conf_simple(story):
    chain = deque([Service('service'), Command('cmd')])
    story.app.services = {
        'service': {
            'configuration': {
                'actions': {
                    'cmd': {'x': 'y'}
                }
            }
        }
    }
    assert Services.get_command_conf(story, chain) == {'x': 'y'}
Example #14
0
def test_set_logger(logger):
    Services.set_logger(logger)
    assert Services.logger == logger
Example #15
0
def test_convert_bytes_to_string():
    assert Services._convert_bytes_to_string(b'hello') == 'hello'
    assert Services._convert_bytes_to_string('hello') == 'hello'
Example #16
0
def test_resolve_chain(story):
    """
    The story tested here is:
    alpine echo as client
        when client foo as echo_helper
            alpine echo
                echo_helper sonar  # This isn't possible, but OK.
            echo_helper sonar

    """
    story.app.services = {
        'alpine': {}
    }

    story.tree = {
        '1': {
            Line.method: 'execute',
            Line.service: 'alpine',
            Line.command: 'echo',
            Line.enter: '2',
            Line.output: ['client']
        },
        '2': {
            Line.method: 'when',
            Line.service: 'client',
            Line.command: 'foo',
            Line.parent: '1',
            Line.output: ['echo_helper']
        },
        '3': {
            Line.method: 'execute',
            Line.service: 'alpine',
            Line.command: 'echo',
            Line.parent: '2',
            Line.enter: '4'
        },
        '4': {
            Line.method: 'execute',
            Line.service: 'echo_helper',
            Line.command: 'sonar',
            Line.parent: '3'
        },
        '5': {
            Line.method: 'execute',
            Line.service: 'echo_helper',
            Line.command: 'sonar',
            Line.parent: '2'
        }
    }

    assert Services.resolve_chain(story, story.tree['1']) \
        == deque([Service(name='alpine'), Command(name='echo')])

    assert Services.resolve_chain(story, story.tree['2']) \
        == deque([Service(name='alpine'),
                  Command(name='echo'), Event(name='foo')])

    assert Services.resolve_chain(story, story.tree['3']) \
        == deque([Service(name='alpine'), Command(name='echo')])

    assert Services.resolve_chain(story, story.tree['4']) \
        == deque([Service(name='alpine'), Command(name='echo'),
                  Event(name='foo'), Command(name='sonar')])

    assert Services.resolve_chain(story, story.tree['5']) \
        == deque([Service(name='alpine'), Command(name='echo'),
                  Event(name='foo'), Command(name='sonar')])
Example #17
0
def test_services_log_registry(logger):
    Services.init(logger)
    Services.register_internal('my_service', 'my_command', {}, 'any', None)
    Services.log_internal()
    logger.info.assert_called_with(
        'Discovered internal service my_service - [\'my_command\']')