Exemple #1
0
def configure_debug_logfile_path(debug_log_file_path: Optional[str]) -> str:
    """Determine the pathname for the debug logfile based on the given argument and user's OS"""

    if debug_log_file_path is not None:
        given_dir = os.path.dirname(debug_log_file_path)
        # If it's not just a filename relative to the current directory make sure
        # that the directory exists
        if given_dir != "" and not os.path.isdir(given_dir):
            raise ConfigurationError(
                f"The provided directory {given_dir} for the debuglog filename "
                f"either does not exist or is not a directory")

        return debug_log_file_path

    # From here and on determine default based on user's system
    time = datetime.datetime.utcnow().isoformat()
    debug_log_file_name = f"raiden-debug_{time}.log"

    home = os.path.expanduser("~")
    if home == "~":  # Could not expand user path, just use /tmp
        datadir = "/tmp"
    if sys.platform == "darwin":
        datadir = os.path.join(home, "Library", "Logs", "Raiden")
    elif sys.platform == "win32" or sys.platform == "cygwin":
        datadir = os.path.join(home, "AppData", "Roaming", "Raiden")
    elif os.name == "posix":
        datadir = os.path.join(home, ".raiden")
    else:
        raise RuntimeError("Unsupported Operating System")

    if not os.path.exists(datadir):
        os.makedirs(datadir)

    return os.path.join(datadir, debug_log_file_name)
Exemple #2
0
def test_run_error_reporting(cli_runner, monkeypatch):
    caught_exceptions = {
        APIServerPortInUseError(): ReturnCode.PORT_ALREADY_IN_USE,
        ConfigurationError(): ReturnCode.RAIDEN_CONFIGURATION_ERROR,
        ConnectTimeout(): ReturnCode.GENERIC_COMMUNICATION_ERROR,
        ConnectionError(): ReturnCode.GENERIC_COMMUNICATION_ERROR,
        EthereumNonceTooLow(): ReturnCode.ETH_ACCOUNT_ERROR,
        EthNodeInterfaceError(): ReturnCode.ETH_INTERFACE_ERROR,
        KeystoreAuthenticationError(): ReturnCode.ETH_ACCOUNT_ERROR,
        KeystoreFileNotFound(): ReturnCode.ETH_ACCOUNT_ERROR,
        RaidenUnrecoverableError(): ReturnCode.FATAL,
        ReplacementTransactionUnderpriced(): ReturnCode.ETH_ACCOUNT_ERROR,
        RequestsConnectionError(): ReturnCode.GENERIC_COMMUNICATION_ERROR,
        Exception(): ReturnCode.FATAL,
    }

    for exception, code in caught_exceptions.items():
        monkeypatch.setattr(cli, "run_services", mock_raises(exception))
        result = cli_runner(cli.run, "--accept-disclaimer")
        assert result.exception.code == code
Exemple #3
0
def apply_config_file(
    command_function: Union[click.Command, click.Group],
    cli_params: Dict[str, Any],
    ctx,
    config_file_option_name="config_file",
):
    """ Applies all options set in the config file to `cli_params` """
    options_using_default = ctx.meta.get(CONTEXT_KEY_DEFAULT_OPTIONS, set())
    paramname_to_param = {param.name: param for param in command_function.params}
    path_params = {
        param.name
        for param in command_function.params
        if isinstance(param.type, (click.Path, click.File))
    }

    config_file_path = Path(cli_params[config_file_option_name])
    config_file_values: MutableMapping[str, Any] = dict()
    try:
        with config_file_path.open() as config_file:
            config_file_values = load(config_file)
    except OSError as ex:
        # Silently ignore if 'file not found' and the config file path is the default and
        # the option wasn't explicitly supplied on the command line
        config_file_param = paramname_to_param[config_file_option_name]
        config_file_default_path = Path(
            config_file_param.type.expand_default(  # type: ignore
                config_file_param.get_default(ctx), cli_params
            )
        )
        default_config_missing = (
            ex.errno == errno.ENOENT
            and config_file_path.resolve() == config_file_default_path.resolve()
            and config_file_option_name in options_using_default
        )
        if default_config_missing:
            cli_params["config_file"] = None
        else:
            raise ConfigurationError(f"Error opening config file: {ex}")

    except TomlDecodeError as ex:
        raise ConfigurationError(f"Error loading config file: {ex}")

    for config_name, config_value in config_file_values.items():
        config_name_int = config_name.replace("-", "_")

        if config_name_int not in paramname_to_param:
            click.secho(
                f"Unknown setting '{config_name}' found in config file - ignoring.", fg="yellow"
            )
            continue

        if config_name_int in path_params:
            # Allow users to use `~` in paths in the config file
            config_value = os.path.expanduser(config_value)

        if config_name_int == LOG_CONFIG_OPTION_NAME:
            # Uppercase log level names
            config_value = {k: v.upper() for k, v in config_value.items()}
        else:
            # Pipe config file values through cli converter to ensure correct types
            # We exclude `log-config` because it already is a dict when loading from toml
            try:
                config_value = paramname_to_param[config_name_int].type.convert(
                    config_value, paramname_to_param[config_name_int], ctx
                )
            except click.BadParameter as ex:
                raise ConfigurationError(f"Invalid config file setting '{config_name}': {ex}")

        # Only use the config file value if the option wasn't explicitly given on the command line
        option_has_default = paramname_to_param[config_name_int].default is not None
        if not option_has_default or config_name_int in options_using_default:
            cli_params[config_name_int] = config_value