コード例 #1
0
def test_add_service_as_module__adding_service_with_same_name_errors():
    """
    Adding a server, as module, with the same name as another service
    should error.
    """
    inline = InlineServices()
    inline.add_service_by_module('replyer',
                                 import_python_file_from_cwd(REPLYER_PATH))

    with pytest.raises(ValueError):
        inline.add_service_by_module('replyer',
                                     import_python_file_from_cwd(REPLYER_PATH))
コード例 #2
0
def test_set_main_service_as_module__adding_second_main_service_throws_error():
    """
    Adding a second main service, as module, should throw an error.
    """
    inline = InlineServices()
    inline.add_service_by_module(
        'multi_requester', import_python_file_from_cwd(MULTI_REQUESTER_PATH))

    with pytest.raises(ValueError):
        inline.set_main_service_by_module(
            'multi_requester',
            import_python_file_from_cwd(MULTI_REQUESTER_PATH))
コード例 #3
0
def test_set_main_service_as_module__setting_service_with_same_name_errors():
    """
    Adding a main service, as module, with the same name as another
    service should error.
    """
    inline = InlineServices()
    inline.add_service_by_module(
        'multi_requester', import_python_file_from_cwd(MULTI_REQUESTER_PATH))

    with pytest.raises(ValueError):
        inline.set_main_service_by_module(
            'multi_requester',
            import_python_file_from_cwd(MULTI_REQUESTER_PATH))
コード例 #4
0
def test_inline_services__services_can_be_run_with_imported_modules():
    """
    Make sure that services can be run together with inline services
    provided via modules.
    """
    inline = InlineServices()
    inline.set_main_service_by_module(
        'requester', import_python_file_from_cwd(REQUESTER_PATH))
    inline.add_service_by_module('replyer',
                                 import_python_file_from_cwd(REPLYER_PATH))
    inline.add_relation('requester', 'request', 'replyer', 'reply')
    inline.start()

    req_config = inline.get_service_config('requester')
    assert len(req_config['responses_recieved']) == 2
コード例 #5
0
def test_service__services_can_be_run_with_imported_modules():
    """
    Make sure the file loglevel and log folder function properly.
    """
    requester_log_path = f'{BASE_LOG_DIR}/requester_with_modules.log'
    replyer_log_path = f'{BASE_LOG_DIR}/replyer_with_modules.log'

    requester_module = import_python_file_from_cwd(REQUESTER_PATH)
    replyer_module = import_python_file_from_cwd(REPLYER_PATH)

    requester = Service(requester_module,
                        addresses=REQUESTER_ADDRS,
                        config=REQUESTER_CONFIG,
                        log_path=requester_log_path,
                        file_loglevel='DEBUG')
    replyer = Service(replyer_module,
                      addresses=REPLYER_ADDRS,
                      log_path=replyer_log_path,
                      file_loglevel='DEBUG')

    replyer.run_service()
    requester.run_service_as_main()

    start = time.time()
    is_success = False

    while not is_success:
        if time.time() - start > 1:
            break

        if not os.path.exists(requester_log_path):
            continue

        with open(requester_log_path, 'r') as requester_log:
            for line in requester_log.readlines():
                if 'GOT ALL RESPONSES' in line:
                    is_success = True

    replyer.stop_service()  # Make sure to stop service!

    if os.path.exists(requester_log_path):
        os.remove(requester_log_path)

    if os.path.exists(replyer_log_path):
        os.remove(replyer_log_path)

    if not is_success:
        raise RuntimeError('Test failed, figure it out!')
コード例 #6
0
def test_service_utils_setup_to_send__workflow_id_constant_on_to_send_calls():
    """
    Make sure the workflow id does not increment when "increment_id" is False.
    This will allow services that are in main_mode to not increment the same
    uuid consistently.
    """
    workflow_id = uuid.uuid4()

    def check_payload(payload):
        """
        This function is used to validate send payloads have the passed
        arguments
        """
        assert payload['workflow_id'] == workflow_id
        return RETURN_PAYLOAD

    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {},
                                          workflow_id=workflow_id,
                                          increment_id=False)

    connections['out']['out_connection_1'].send = check_payload

    for _ in range(4):
        to_send('out_connection_1', PROPER_ARGS)
コード例 #7
0
def test_service_utils__setup_to_send__workflow_id_put_into_to_send_payload():
    """
    Make sure if a workflow id is provided it is added to the payload.
    """
    workflow_id = uuid.uuid4()

    def check_payload(payload):
        """
        This function is used to validate send payloads have the passed
        arguments
        """
        assert payload['workflow_id'] == workflow_id
        return RETURN_PAYLOAD

    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {},
                                          workflow_id=workflow_id,
                                          increment_id=True)

    connections['out']['out_connection_1'].send = check_payload
    to_send('out_connection_1', PROPER_ARGS)
コード例 #8
0
def test_service_utils__setup_to_send__args_are_put_into_to_send_payload():
    """
    Make sure arguments are actually put into the payload
    """
    def check_payload(payload):
        """
        This function is used to validate send payloads have the passed
        arguments
        """
        if payload['args'] != PROPER_ARGS:
            raise RuntimeError('Payload does not have args added!!!')

        return RETURN_PAYLOAD

    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {})

    connections['out']['out_connection_1'].send = check_payload
    to_send('out_connection_1', PROPER_ARGS)
コード例 #9
0
def test_service_utils__setup_addresses__with_setup_addresses_func_case():
    """
    Make sure that the setup addresses func will indeed be called if provided.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addrs = service_utils.setup_addresses(addresses, imported_service, {})
    assert addrs['connections']['in']['in_connection_1']['in_conn_socket_3']
コード例 #10
0
def test_service_utils__setup_config__no_config_model_case():
    """
    Make sure to return an empty dict if there is no config model in the imported
    service. (It's optional)
    """
    wo_model_imported_service = utils.import_python_file_from_cwd(WO_SERVICE_PATH)
    config = service_utils.setup_config({}, wo_model_imported_service)
    assert config == {}
コード例 #11
0
def test_service_utils__setup_service_connections__no_connection_models_case():
    """
    Make sure if there's no connection models then an empty dict is returned.
    """
    imported_service = utils.import_python_file_from_cwd(WO_SERVICE_PATH)
    config = {}
    conns = service_utils.setup_service_connections(ADDRESSES_PATH,
                                                    imported_service, config)
    assert conns == {}
コード例 #12
0
def test_service_utils__setup_addresses__no_setup_addresses_func_case():
    """
    Make sure not provided setup addresses func in the imported service will not
    cause an error. (It's optional)
    """
    imported_service_wo_func = utils.import_python_file_from_cwd(WO_SERVICE_PATH)
    addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addrs = service_utils.setup_addresses(addresses, imported_service_wo_func, {})
    assert addrs['connections']['in']['in_connection_1']['in_conn_socket_1']
コード例 #13
0
def test_inline_services__main_by_module_can_have_provided_config():
    """
    Make sure that a main service, by module, can have a provided
    config.
    """
    inline = InlineServices()
    inline.set_main_service_by_module(
        'requester', import_python_file_from_cwd(REQUESTER_PATH),
        REQUESTER_CONFIG)
    inline.add_service_by_module(
        'replyer',
        import_python_file_from_cwd(REPLYER_PATH),
    )
    inline.add_relation('requester', 'request', 'replyer', 'reply')
    inline.start()

    req_config = inline.get_service_config('requester')
    assert len(req_config['responses_recieved']) == 4
コード例 #14
0
def test_inline_services__set_main_service_not_providing_a_string_path_throws_error(
):
    """
    Make sure that if setting a main service and accidentally passing a
    module a ValueError will be thrown.
    """
    inline = InlineServices()
    with pytest.raises(ValueError):
        inline.set_main_service('requester',
                                import_python_file_from_cwd(REQUESTER_PATH))
コード例 #15
0
def test_service_utils__setup_config__services_setup_config_functions_properly():
    """
    Make sure that the service can call setup config prior to the config
    file being used.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    del imported_service.config_model['required']['env_variable_1']
    config = utils.get_json_from_rel_path(CONFIG_PATH)
    config = service_utils.setup_config(config, imported_service)
    assert config['optional_1'] == 'optional_value_1'
    remove_imported_object_module(imported_service)
コード例 #16
0
def test_service_utils__setup_config__config_model_function_needed():
    """
    Make sure the imported service has a config model.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    del imported_service.config_model
    config = utils.get_json_from_rel_path(CONFIG_PATH)

    with pytest.raises(ValueError):
        config = service_utils.setup_config(config, imported_service)
    remove_imported_object_module(imported_service)
コード例 #17
0
def test_service_utils__setup_config__config_creation_is_validated():
    """
    Make sure that the setup config function actually validates what's
    provided by the config.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    del imported_service.config_model['optional']['config_2']
    config = utils.get_json_from_rel_path(CONFIG_PATH)

    with pytest.raises(ValueError):
        service_utils.setup_config(config, imported_service)
コード例 #18
0
def test_inline_services__add_service_not_providing_a_string_path_throws_error(
):
    """
    Make sure that if adding a service and accidentally passing a module
    a ValueError will be thrown.
    """
    inline = InlineServices()
    with pytest.raises(ValueError):
        inline.add_service(
            'replyer',
            import_python_file_from_cwd(REPLYER_PATH),
        )
コード例 #19
0
def test_service_utils__setup_service_connections__connection_models_case():
    """
    Make sure if there are connection models they are properly loaded.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    conns = service_utils.setup_service_connections(addresses,
                                                    imported_service, config)
    conn = conns['in']['in_connection_1']
    assert conn.__class__.__name__ == 'Replyer'
コード例 #20
0
def test_service_utils__setup_service_connections__connection_models_and_setup_conn_models_case(
):
    """
    Make sure setup_service_connections is properly called.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    conns = service_utils.setup_service_connections(addresses,
                                                    imported_service, config)
    conn = conns['out']['out_connection_1']
    assert conn.__class__.__name__ == 'Requester'
コード例 #21
0
def test_service_utils__run_init_function__will_properly_call_init_function():
    """
    Test to make sure that the init_function will be called.
    """
    success = False

    def set_success_to_true(*_):
        nonlocal success
        success = True

    imported_service = utils.import_python_file_from_cwd(WO_SERVICE_PATH)
    imported_service.init_function = set_success_to_true
    service_utils.run_init_function(imported_service, {}, {}, {})
    assert success
コード例 #22
0
    def set_main_service(self, service_name, rel_service_path, config=None):
        """
        Add the main service to be used. This service will be the initially called service within
        the inline service function.
        service_name::str The name of the service to be used for relations
        rel_service_path::str The relative path to the service from the cwd
        config::{} The service config passed to the service
        """
        if not isinstance(rel_service_path, str):
            raise ValueError('Please provided a string for the rel_service_path!')

        self.set_main_service_by_module(
            service_name,
            import_python_file_from_cwd(rel_service_path),
            config
        )
コード例 #23
0
    def add_service(self, service_name, rel_service_path, config=None):
        """
        Add a service to the inline service object. This service will be called if a relation is
        set to call it.
        service_name::str Name of the service to be used for relations
        rel_service_path::str The relative path to the service from the cwd
        config::{} The service config passed to the service
        """
        if not isinstance(rel_service_path, str):
            raise ValueError('Please provided a string for the rel_service_path!')

        self.add_service_by_module(
            service_name,
            import_python_file_from_cwd(rel_service_path),
            config
        )
コード例 #24
0
def test_service_utils__setup_to_send__to_send_validates_returned_args_case():
    """
    Make sure that the return arguments case will also be validated.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {})

    connections['out']['out_connection_1'].send = lambda payload: None

    with pytest.raises(ValueError):
        to_send('out_connection_1', PROPER_ARGS)
コード例 #25
0
def test_service_utils__setup_to_send__valid_connection_output_type_for_to_send(
):
    """
    Make sure that sending will function if the output type is a connection
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {})

    out_connection = connections['out']['out_connection_1']
    out_connection.args_validator = lambda args: None
    out_connection.send = lambda payload: RETURN_PAYLOAD
    to_send('out_connection_1', {})
コード例 #26
0
def test_service_utils__setup_to_send__to_send_returns_proper_args():
    """
    Make sure the to_send function properly sends arguments and
    gets the returned arguments back.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {})

    connections['out'][
        'out_connection_1'].send = lambda payload: RETURN_PAYLOAD
    return_arguments = to_send('out_connection_1', PROPER_ARGS)

    assert return_arguments == RETURN_PAYLOAD['return_args']
コード例 #27
0
def test_service_utils_setup_to_send__workflow_id_incremented_on_to_send_calls(
):
    """
    Make sure the workflow id appends the call number increases with each to_send
    call. This will allow a developer to more easily debug later down the line.
    """
    workflow_id = uuid.uuid4()
    call_count = 0

    def check_payload(payload):
        """
        This function is used to validate send payloads have the passed
        arguments
        """
        nonlocal call_count

        if call_count == 0:
            assert payload['workflow_id'] == workflow_id

        else:
            new_workflow_id = '{}_{}'.format(workflow_id, call_count)
            assert payload['workflow_id'] == new_workflow_id

        call_count += 1
        return RETURN_PAYLOAD

    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    config = {}
    cur_addresses = utils.get_json_from_rel_path(ADDRESSES_PATH)
    addresses = service_utils.setup_addresses(cur_addresses, imported_service,
                                              config)
    connections = service_utils.setup_service_connections(
        addresses, imported_service, config)
    to_send = service_utils.setup_to_send(connections, {},
                                          workflow_id=workflow_id,
                                          increment_id=True)

    connections['out']['out_connection_1'].send = check_payload

    for _ in range(4):
        to_send('out_connection_1', PROPER_ARGS)
コード例 #28
0
def entrance_point(
        service_definition,
        config,
        addresses,
        logger_args_dict,
        is_main=False,
        min_wait_time_s=0):
    """
    service_path::obj Either a string -> to then import the service file or an object itself.
    addresses = {
        'in': {
            'connection_name': {
                'socket_name': str
            },
        },
        'out': {},
    }
    config = {
        'config_1': 'thingy',
        'config_2': 12345
    }
    logger_args_dict = {
        console_loglevel: str,
        log_path: str,
        file_loglevel: str,
        backup_count: int,
    }
    """
    logging_utils.setup_package_logger(**logger_args_dict)

    if isinstance(service_definition, str):
        service_definition = utils.import_python_file_from_cwd(service_definition)

    config = setup_config(config if config is not None else {}, service_definition)
    addresses = setup_addresses(addresses, service_definition, config)
    connections = setup_service_connections(addresses, service_definition, config)


    setup_sig_handler_funcs(
        service_definition,
        config,
        setup_to_send(connections, logger_args_dict)
    )

    run_init_function(service_definition, connections, config, logger_args_dict)

    if is_main:
        run_main(
            service_definition.main,
            connections,
            config,
            logger_args_dict,
            min_wait_time_s
        )
    else:
        run_service(
            connections,
            config,
            logger_args_dict,
            min_wait_time_s
        )
コード例 #29
0
def test_service_utils__setup_addresses__no_addresses_path():
    """
    Make sure an address path does not cause any errors if not provided.
    """
    imported_service = utils.import_python_file_from_cwd(SERVICE_PATH)
    service_utils.setup_addresses({}, imported_service, {})
コード例 #30
0
def test_service_utils__run_init_function__will_not_fail_if_init_function_not_found():
    """
    Make sure that if the init_function is not available nothing will blow up.
    """
    imported_service = utils.import_python_file_from_cwd(WO_SERVICE_PATH)
    service_utils.run_init_function(imported_service, {}, {}, {})