Exemplo n.º 1
0
def start_ethereum(smoketest_genesis):
    RST_RPC_PORT = next(get_free_port('127.0.0.1', 27854))
    os.environ['RST_RPC_PORT'] = str(RST_RPC_PORT)
    cmd = os.environ.get('RST_ETH_COMMAND', DEFAULT_ETH_COMMAND)
    args = shlex.split(Template(cmd).substitute(os.environ))

    keystore = os.path.join(os.environ['RST_DATADIR'], 'keystore')
    if not os.path.exists(keystore):
        os.makedirs(keystore)
    with open(os.path.join(keystore, 'account.json'), 'wb') as handler:
        json.dump(TEST_ACCOUNT, handler)

    init_out, init_err = init_with_genesis(smoketest_genesis)

    ethereum_node = subprocess.Popen(
        args,
        universal_newlines=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    time.sleep(.1)
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    ethereum_config = dict(
        rpc=os.environ['RST_RPC_PORT'],
        keystore=keystore,
        address=TEST_ACCOUNT['address'],
        init_log_out=init_out,
        init_log_err=init_err,
    )
    return ethereum_node, ethereum_config
Exemplo n.º 2
0
def port_generator(request, worker_id):
    """ count generator used to get a unique port number. """
    if worker_id == "master":
        # xdist is not in use to run parallel tests
        port_offset = 0
    else:
        port_offset = int(worker_id.replace("gw", "")) * 1000
    return get_free_port(request.config.getoption("base_port") + port_offset)
Exemplo n.º 3
0
def matrix_server_starter(
    *,
    count: int = 1,
    config_generator: ContextManager = None,
    log_context: str = None,
    initial_port: int = 8500,
) -> ContextManager:
    with ExitStack() as exit_stack:
        if config_generator is None:
            config_generator = exit_stack.enter_context(
                generate_synapse_config())
        server_urls = []
        for _, port in zip(range(count),
                           get_free_port(initial_port=initial_port)):
            server_name, config_file = config_generator(port)
            server_url = ParsedURL(f'https://{server_name}')
            server_urls.append(server_url)

            synapse_io = subprocess.DEVNULL
            # Used in CI to capture the logs for failure analysis
            if _SYNAPSE_LOGS_PATH:
                log_file_path = Path(_SYNAPSE_LOGS_PATH).joinpath(
                    f'{server_name}.log')
                log_file_path.parent.mkdir(parents=True, exist_ok=True)
                log_file = exit_stack.enter_context(log_file_path.open('at'))

                # Preface log with header
                header = datetime.utcnow().isoformat()
                if log_context:
                    header = f'{header}: {log_context}'
                header = f' {header} '
                log_file.write(f'{header:=^100}\n')
                log_file.flush()

                synapse_io = subprocess.DEVNULL, log_file, subprocess.STDOUT

            exit_stack.enter_context(
                HTTPExecutor(
                    [
                        sys.executable,
                        '-m',
                        'synapse.app.homeserver',
                        f'--server-name={server_name}',
                        f'--config-path={config_file!s}',
                    ],
                    url=urljoin(server_url, '/_matrix/client/versions'),
                    method='GET',
                    timeout=30,
                    cwd=config_file.parent,
                    verify_tls=False,
                    io=synapse_io,
                ), )
        yield server_urls
Exemplo n.º 4
0
def matrix_server_starter(
        *,
        count: int = 1,
        config_generator: ContextManager = None,
        log_context: str = None,
) -> ContextManager:
    with ExitStack() as exit_stack:
        if config_generator is None:
            config_generator = exit_stack.enter_context(generate_synapse_config())
        server_urls = []
        for _, port in zip(range(count), get_free_port(initial_port=8500)):
            server_name, config_file = config_generator(port)
            server_url = ParsedURL(f'https://{server_name}')
            server_urls.append(server_url)

            synapse_io = subprocess.DEVNULL
            # Used in CI to capture the logs for failure analysis
            if _SYNAPSE_LOGS_PATH:
                log_file_path = Path(_SYNAPSE_LOGS_PATH).joinpath(f'{server_name}.log')
                log_file_path.parent.mkdir(parents=True, exist_ok=True)
                log_file = exit_stack.enter_context(log_file_path.open('at'))

                # Preface log with header
                header = datetime.utcnow().isoformat()
                if log_context:
                    header = f'{header}: {log_context}'
                header = f' {header} '
                log_file.write(f'{header:=^100}\n')
                log_file.flush()

                synapse_io = subprocess.DEVNULL, log_file, subprocess.STDOUT

            exit_stack.enter_context(
                HTTPExecutor(
                    [
                        sys.executable,
                        '-m',
                        'synapse.app.homeserver',
                        f'--server-name={server_name}',
                        f'--config-path={config_file.name}',
                    ],
                    url=urljoin(server_url, '/_matrix/client/versions'),
                    method='GET',
                    timeout=30,
                    cwd=config_file.parent,
                    io=synapse_io,
                ),
            )
        yield server_urls
Exemplo n.º 5
0
def start_ethereum(smoketest_genesis):
    ensure_executable(os.environ.setdefault('RST_GETH_BINARY', 'geth'))
    RST_RPC_PORT = next(get_free_port('127.0.0.1', 27854))
    os.environ['RST_RPC_PORT'] = str(RST_RPC_PORT)
    cmd = os.environ.get('RST_ETH_COMMAND', DEFAULT_ETH_COMMAND)
    args = shlex.split(
        Template(cmd).substitute(os.environ),
    )

    keystore = os.path.join(os.environ['RST_DATADIR'], 'keystore')
    if not os.path.exists(keystore):
        os.makedirs(keystore)
    with open(os.path.join(keystore, 'account.json'), 'w') as handler:
        json.dump(TEST_ACCOUNT, handler)
    with open(os.path.join(keystore, 'password'), 'w') as handler:
        handler.write(TEST_ACCOUNT_PASSWORD)

    init_out, init_err = init_with_genesis(smoketest_genesis)

    args.extend(['--password', os.path.join(keystore, 'password')])
    ethereum_node = subprocess.Popen(
        args,
        universal_newlines=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        encoding='UTF-8',
    )
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    time.sleep(.1)
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    ethereum_config = dict(
        rpc=os.environ['RST_RPC_PORT'],
        keystore=keystore,
        address=to_checksum_address(TEST_ACCOUNT['address']),
        init_log_out=init_out,
        init_log_err=init_err,
    )
    return ethereum_node, ethereum_config
Exemplo n.º 6
0
def start_ethereum(smoketest_genesis):
    ensure_executable(os.environ.setdefault('RST_GETH_BINARY', 'geth'))
    RST_RPC_PORT = next(get_free_port('127.0.0.1', 27854))
    os.environ['RST_RPC_PORT'] = str(RST_RPC_PORT)
    cmd = os.environ.get('RST_ETH_COMMAND', DEFAULT_ETH_COMMAND)
    args = shlex.split(
        Template(cmd).substitute(os.environ),
    )

    keystore = os.path.join(os.environ['RST_DATADIR'], 'keystore')
    if not os.path.exists(keystore):
        os.makedirs(keystore)
    with open(os.path.join(keystore, 'account.json'), 'w') as handler:
        json.dump(TEST_ACCOUNT, handler)
    with open(os.path.join(keystore, 'password'), 'w') as handler:
        handler.write(TEST_ACCOUNT_PASSWORD)

    init_out, init_err = init_with_genesis(smoketest_genesis)

    args.extend(['--password', os.path.join(keystore, 'password')])
    ethereum_node = subprocess.Popen(
        args,
        universal_newlines=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        encoding='UTF-8',
    )
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    time.sleep(.1)
    ethereum_node.stdin.write(TEST_ACCOUNT_PASSWORD + os.linesep)
    ethereum_config = dict(
        rpc=os.environ['RST_RPC_PORT'],
        keystore=keystore,
        address=to_checksum_address(TEST_ACCOUNT['address']),
        init_log_out=init_out,
        init_log_err=init_err,
    )
    return ethereum_node, ethereum_config
Exemplo n.º 7
0
def setup_testchain(eth_client: EthClient,
                    print_step: Callable) -> ContextManager[Dict[str, Any]]:
    # TODO: This has a lot of overlap with `raiden.tests.utils.eth_node.run_private_blockchain` -
    #       refactor into a unified utility
    print_step('Starting Ethereum node')

    ensure_executable(eth_client.value)

    free_port = get_free_port()
    rpc_port = next(free_port)
    p2p_port = next(free_port)
    base_datadir = os.environ['RST_DATADIR']

    description = EthNodeDescription(
        private_key=TEST_PRIVKEY,
        rpc_port=rpc_port,
        p2p_port=p2p_port,
        miner=True,
        extra_config={},
        blockchain_type=eth_client.value,
    )

    eth_rpc_endpoint = f'http://127.0.0.1:{rpc_port}'
    web3 = Web3(HTTPProvider(endpoint_uri=eth_rpc_endpoint))
    web3.middleware_stack.inject(geth_poa_middleware, layer=0)

    config = eth_node_config(
        description.private_key,
        description.p2p_port,
        description.rpc_port,
    )

    config.update({
        'unlock': 0,
        'mine': True,
        'password': os.path.join(base_datadir, 'pw'),
    })

    nodes_configuration = [config]
    logdir = os.path.join(base_datadir, 'logs')

    # the marker is hardcoded in the genesis file
    random_marker = remove_0x_prefix(encode_hex(b'raiden'))
    seal_account = privatekey_to_address(description.private_key)
    accounts_to_fund = [TEST_ACCOUNT_ADDRESS, TEST_PARTNER_ADDRESS]

    genesis_description = GenesisDescription(
        prefunded_accounts=accounts_to_fund,
        random_marker=random_marker,
        chain_id=NETWORKNAME_TO_ID['smoketest'],
    )

    if eth_client is EthClient.GETH:
        keystore = os.path.join(eth_node_to_datadir(config, base_datadir),
                                'keystore')
        genesis_path = os.path.join(base_datadir, 'custom_genesis.json')
        geth_generate_poa_genesis(
            genesis_path=genesis_path,
            genesis_description=genesis_description,
            seal_account=seal_account,
        )
    elif eth_client is EthClient.PARITY:
        genesis_path = f'{base_datadir}/chainspec.json'
        parity_generate_chain_spec(
            genesis_path=genesis_path,
            genesis_description=genesis_description,
            seal_account=seal_account,
        )
        keystore = parity_create_account(nodes_configuration[0], base_datadir,
                                         genesis_path)
    else:
        raise RuntimeError(f'Invalid eth client type: {eth_client.value}')

    node_runner = eth_run_nodes(
        eth_node_descs=[description],
        nodes_configuration=nodes_configuration,
        base_datadir=base_datadir,
        genesis_file=genesis_path,
        chain_id=NETWORKNAME_TO_ID['smoketest'],
        random_marker=random_marker,
        verbosity='info',
        logdir=logdir,
    )
    with node_runner as node_executors:
        yield dict(
            eth_client=eth_client,
            base_datadir=base_datadir,
            eth_rpc_endpoint=eth_rpc_endpoint,
            keystore=keystore,
            node_executors=node_executors,
            web3=web3,
        )
Exemplo n.º 8
0
def port_generator():
    """ count generator used to get a unique port number. """
    return get_free_port('127.0.0.1')
Exemplo n.º 9
0
def port_generator(request):
    """ count generator used to get a unique port number. """
    return get_free_port(request.config.getoption("base_port"))
Exemplo n.º 10
0
def main() -> None:
    import argparse
    import configparser
    import re

    NODE_SECTION_RE = re.compile("^node[0-9]+")

    parser = argparse.ArgumentParser()
    parser.add_argument("--nodes-data-dir", default=os.getcwd())
    parser.add_argument("--wait-after-first-sync",
                        default=False,
                        action="store_true")
    parser.add_argument("--profiler-data-directory", default=None)
    parser.add_argument("--interface", default="127.0.0.1")
    parser.add_argument("--iterations", default=5, type=int)
    parser.add_argument("config")
    args = parser.parse_args()

    if args.profiler_data_directory is not None and os.geteuid() != 0:
        raise RuntimeError(
            "To enable profiling the script has to be executed with root.")

    config = configparser.ConfigParser()
    config.read(args.config)

    datadir = args.nodes_data_dir

    interface = Host(args.interface)
    port_generator = get_free_port(5000)
    retry_timeout = 1

    nodes_config: List[NodeConfig] = list()

    token_address = config.defaults()["token-address"]
    if not is_checksum_address(token_address):
        raise ValueError(
            f"Invalid token address {token_address}, check it is checksummed.")

    defaults = {
        "--log-config": "raiden:DEBUG",
        "--environment-type": "development",
        "--datadir": datadir,
    }

    for section in config:
        if NODE_SECTION_RE.match(section):
            node_config = config[section]
            address = node_config["address"]

            node = defaults.copy()
            node.update({
                "--keystore-path": node_config["keystore-path"],
                "--password-file": node_config["password-file"],
                "--eth-rpc-endpoint": node_config["eth-rpc-endpoint"],
                "--network-id": node_config["network-id"],
                "--address": address,
            })

            pathfinding_url = node_config.get("pathfinding-service-address")
            if pathfinding_url is not None:
                node["--pathfinding-service-address"] = pathfinding_url

            raiden_args = [
                "raiden",
                "--accept-disclaimer",
                "--log-json",
                "--disable-debug-logfile",
                "--flat-fee",
                token_address,
                "0",
                "--proportional-fee",
                token_address,
                "0",
                "--proportional-imbalance-fee",
                token_address,
                "0",
            ]
            raiden_args.extend(chain.from_iterable(node.items()))

            # The REST interface uses checksummed address. Normalize it here.
            address = to_checksum_address(address)

            nodedir = os.path.join(
                datadir, f"node_{pex(to_canonical_address(address))}")
            nodes_config.append(
                NodeConfig(raiden_args, interface, address, nodedir))

    # TODO: Determine the `capacity_lower_bound` by querying the nodes.
    capacity_lower_bound = 1130220

    profiler_data_directory = args.profiler_data_directory

    iterations = args.iterations
    if iterations is None:
        iteration_counter = count()
    else:
        iteration_counter = iter(range(iterations))

    # def stop_on_signal(sig=None, _frame=None):
    #     stop.set()
    # gevent.signal(signal.SIGQUIT, stop_on_signal)
    # gevent.signal(signal.SIGTERM, stop_on_signal)
    # gevent.signal(signal.SIGINT, stop_on_signal)

    # TODO: If any of the processes crashes the script should collect and
    # bundle the logs.
    #
    # Cleanup with the Janitor is not strictily necessary for the stress test,
    # since once can assume a bug happened and the state of the node is
    # inconsistent, however it is nice to have.
    with Janitor() as nursery:
        nodes_running = start_and_wait_for_all_servers(nursery, port_generator,
                                                       nodes_config,
                                                       retry_timeout)

        if nodes_running is None:
            return

        if args.wait_after_first_sync:
            nursery.spawn_under_watch(wait_for_user_input).get()

        test_config = StressTestConfiguration(
            port_generator,
            retry_timeout,
            Amount(capacity_lower_bound),
            token_address,
            iteration_counter,
            profiler_data_directory,
        )

        nursery.spawn_under_watch(run_stress_test, nursery, nodes_running,
                                  test_config)
        nursery.wait(timeout=None)
Exemplo n.º 11
0
def smoketest(ctx, debug, eth_client):
    """ Test, that the raiden installation is sane. """
    from raiden.tests.utils.smoketest import setup_testchain_and_raiden, run_smoketest
    from raiden.tests.utils.transport import make_requests_insecure, matrix_server_starter

    report_file = mktemp(suffix='.log')
    configure_logging(
        logger_level_config={'': 'DEBUG'},
        log_file=report_file,
        disable_debug_logfile=ctx.parent.params['disable_debug_logfile'],
    )
    click.secho(f'Report file: {report_file}', fg='yellow')

    def append_report(subject: str, data: Optional[AnyStr] = None):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log')

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    stdout = sys.stdout

    def print_step(description: str, error: bool = False) -> None:
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ),
            file=stdout,
        )

    print_step('Getting smoketest configuration')
    contracts_version = environment_type_to_contracts_version(
        ctx.parent.params['environment_type'], )

    with setup_testchain_and_raiden(
            transport=ctx.parent.params['transport'],
            eth_client=eth_client,
            matrix_server=ctx.parent.params['matrix_server'],
            contracts_version=contracts_version,
            print_step=print_step,
    ) as result:
        args = result['args']
        contract_addresses = result['contract_addresses']
        token = result['token']
        ethereum_nodes = result['ethereum_nodes']
        # Also respect environment type
        args['environment_type'] = ctx.parent.params['environment_type']
        for option_ in run.params:
            if option_.name in args.keys():
                args[option_.name] = option_.process_value(
                    ctx, args[option_.name])
            else:
                args[option_.name] = option_.default

        port = next(get_free_port(5001))

        args['api_address'] = 'localhost:' + str(port)

        if args['transport'] == 'udp':
            with SocketFactory('127.0.0.1', port,
                               strategy='none') as mapped_socket:
                args['mapped_socket'] = mapped_socket
                success = run_smoketest(
                    print_step=print_step,
                    append_report=append_report,
                    args=args,
                    contract_addresses=contract_addresses,
                    token=token,
                    debug=debug,
                    ethereum_nodes=ethereum_nodes,
                )
        elif args['transport'] == 'matrix':
            args['mapped_socket'] = None
            print_step('Starting Matrix transport')
            try:
                with matrix_server_starter() as server_urls:
                    # Disable TLS verification so we can connect to the self signed certificate
                    make_requests_insecure()
                    urllib3.disable_warnings(InsecureRequestWarning)
                    args['extra_config'] = {
                        'transport': {
                            'matrix': {
                                'available_servers': server_urls,
                            },
                        },
                    }
                    success = run_smoketest(
                        print_step=print_step,
                        append_report=append_report,
                        args=args,
                        contract_addresses=contract_addresses,
                        token=token,
                        debug=debug,
                        ethereum_nodes=ethereum_nodes,
                    )
            except (PermissionError, ProcessExitedWithError,
                    FileNotFoundError):
                append_report('Matrix server start exception',
                              traceback.format_exc())
                print_step(
                    f'Error during smoketest setup, report was written to {report_file}',
                    error=True,
                )
                success = False
        else:
            # Shouldn't happen
            raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 12
0
def setup_testchain_and_raiden(transport, matrix_server, print_step):
    print_step('Starting Ethereum node')

    ensure_executable('geth')

    free_port = get_free_port('127.0.0.1', 27854)
    rpc_port = next(free_port)
    p2p_port = next(free_port)
    base_datadir = os.environ['RST_DATADIR']

    description = GethNodeDescription(
        private_key=TEST_PRIVKEY,
        rpc_port=rpc_port,
        p2p_port=p2p_port,
        miner=True,
    )

    eth_rpc_endpoint = f'http://127.0.0.1:{rpc_port}'
    web3 = Web3(HTTPProvider(endpoint_uri=eth_rpc_endpoint))
    web3.middleware_stack.inject(geth_poa_middleware, layer=0)

    config = geth_node_config(
        description.private_key,
        description.p2p_port,
        description.rpc_port,
    )

    config.update({
        'unlock': 0,
        'mine': True,
        'password': os.path.join(base_datadir, 'pw'),
    })

    nodes_configuration = [config]
    geth_node_config_set_bootnodes(nodes_configuration)
    keystore = os.path.join(geth_node_to_datadir(config, base_datadir),
                            'keystore')

    logdir = os.path.join(base_datadir, 'logs')

    processes_list = geth_run_nodes(
        geth_nodes=[description],
        nodes_configuration=nodes_configuration,
        base_datadir=base_datadir,
        genesis_file=os.path.join(get_project_root(),
                                  'smoketest_genesis.json'),
        chain_id=NETWORKNAME_TO_ID['smoketest'],
        verbosity=0,
        logdir=logdir,
    )

    try:
        # the marker is hardcoded in the genesis file
        random_marker = remove_0x_prefix(encode_hex(b'raiden'))
        geth_wait_and_check(web3, [], random_marker)

        for process in processes_list:
            process.poll()

            if process.returncode is not None:
                raise ValueError(
                    f'geth process failed with exit code {process.returncode}')

    except (ValueError, RuntimeError) as e:
        # If geth_wait_and_check or the above loop throw an exception make sure
        # we don't end up with a rogue geth process running in the background
        for process in processes_list:
            process.terminate()
        raise e

    print_step('Deploying Raiden contracts')

    client = JSONRPCClient(web3, get_private_key(keystore))
    # for smoketest use the precompiled contracts
    contract_manager = ContractManager(contracts_precompiled_path())

    contract_addresses = deploy_smoketest_contracts(
        client=client,
        chain_id=NETWORKNAME_TO_ID['smoketest'],
        contract_manager=contract_manager,
    )
    token = deploy_token(
        deploy_client=client,
        contract_manager=contract_manager,
        initial_amount=1000,
        decimals=0,
        token_name='TKN',
        token_symbol='TKN',
    )
    registry = TokenNetworkRegistry(
        jsonrpc_client=client,
        registry_address=contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
        contract_manager=contract_manager,
    )
    registry.add_token(to_canonical_address(token.contract.address))

    print_step('Setting up Raiden')

    if matrix_server == 'auto':
        matrix_server = 'http://localhost:8008'

    endpoint_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
    tokennetwork_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
    secret_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_SECRET_REGISTRY], )
    return {
        'args': {
            'address': to_checksum_address(TEST_ACCOUNT_ADDRESS),
            'datadir': keystore,
            'endpoint_registry_contract_address':
            endpoint_registry_contract_address,
            'eth_rpc_endpoint': eth_rpc_endpoint,
            'gas_price': 'fast',
            'keystore_path': keystore,
            'matrix_server': matrix_server,
            'network_id': str(NETWORKNAME_TO_ID['smoketest']),
            'password_file': click.File()(os.path.join(base_datadir, 'pw')),
            'tokennetwork_registry_contract_address':
            tokennetwork_registry_contract_address,
            'secret_registry_contract_address':
            secret_registry_contract_address,
            'sync_check': False,
            'transport': transport,
        },
        'contract_addresses': contract_addresses,
        'ethereum': processes_list,
        'token': token,
    }
Exemplo n.º 13
0
def smoketest(ctx, debug, eth_client):
    """ Test, that the raiden installation is sane. """
    from raiden.tests.utils.smoketest import setup_testchain_and_raiden, run_smoketest
    from raiden.tests.utils.transport import make_requests_insecure, matrix_server_starter

    report_file = mktemp(suffix=".log")
    configure_logging(
        logger_level_config={"": "DEBUG"},
        log_file=report_file,
        disable_debug_logfile=ctx.parent.params["disable_debug_logfile"],
    )
    free_port_generator = get_free_port()
    click.secho(f"Report file: {report_file}", fg="yellow")

    def append_report(subject: str, data: Optional[AnyStr] = None):
        with open(report_file, "a", encoding="UTF-8") as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                write_data: str
                if isinstance(data, bytes):
                    write_data = data.decode()
                else:
                    write_data = data
                handler.writelines([write_data + os.linesep])

    append_report("Raiden version", json.dumps(get_system_spec()))
    append_report("Raiden log")

    step_count = 7
    if ctx.parent.params["transport"] == "matrix":
        step_count = 8
    step = 0

    stdout = sys.stdout

    def print_step(description: str, error: bool = False) -> None:
        nonlocal step
        step += 1
        click.echo(
            "{} {}".format(
                click.style(f"[{step}/{step_count}]", fg="blue"),
                click.style(description, fg="green" if not error else "red"),
            ),
            file=stdout,
        )

    print_step("Getting smoketest configuration")
    contracts_version = environment_type_to_contracts_version(
        ctx.parent.params["environment_type"])

    with setup_testchain_and_raiden(
            transport=ctx.parent.params["transport"],
            eth_client=eth_client,
            matrix_server=ctx.parent.params["matrix_server"],
            contracts_version=contracts_version,
            print_step=print_step,
            free_port_generator=free_port_generator,
    ) as result:
        args = result["args"]
        contract_addresses = result["contract_addresses"]
        token = result["token"]
        ethereum_nodes = result["ethereum_nodes"]
        # Also respect environment type
        args["environment_type"] = ctx.parent.params["environment_type"]
        for option_ in run.params:
            if option_.name in args.keys():
                args[option_.name] = option_.process_value(
                    ctx, args[option_.name])
            else:
                args[option_.name] = option_.default

        port = next(free_port_generator)

        args["api_address"] = "localhost:" + str(port)

        if args["transport"] == "udp":
            with SocketFactory("127.0.0.1", port,
                               strategy="none") as mapped_socket:
                args["mapped_socket"] = mapped_socket
                success = run_smoketest(
                    print_step=print_step,
                    append_report=append_report,
                    args=args,
                    contract_addresses=contract_addresses,
                    token=token,
                    debug=debug,
                    ethereum_nodes=ethereum_nodes,
                )
        elif args["transport"] == "matrix":
            args["mapped_socket"] = None
            print_step("Starting Matrix transport")
            try:
                with matrix_server_starter(
                        free_port_generator=free_port_generator
                ) as server_urls:
                    # Disable TLS verification so we can connect to the self signed certificate
                    make_requests_insecure()
                    urllib3.disable_warnings(InsecureRequestWarning)
                    args["extra_config"] = {
                        "transport": {
                            "matrix": {
                                "available_servers": server_urls
                            }
                        }
                    }
                    success = run_smoketest(
                        print_step=print_step,
                        append_report=append_report,
                        args=args,
                        contract_addresses=contract_addresses,
                        token=token,
                        debug=debug,
                        ethereum_nodes=ethereum_nodes,
                    )
            except (PermissionError, ProcessExitedWithError,
                    FileNotFoundError):
                append_report("Matrix server start exception",
                              traceback.format_exc())
                print_step(
                    f"Error during smoketest setup, report was written to {report_file}",
                    error=True,
                )
                success = False
        else:
            # Shouldn't happen
            raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 14
0
def smoketest(ctx, debug, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        run_smoketests,
        setup_testchain_and_raiden,
    )

    report_file = mktemp(suffix='.log')
    configure_logging(
        logger_level_config={'': 'DEBUG'},
        log_file=report_file,
        disable_debug_logfile=ctx.parent.params['disable_debug_logfile'],
    )
    click.secho(
        f'Report file: {report_file}',
        fg='yellow',
    )

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ),
        )

    print_step('Getting smoketest configuration')

    result = setup_testchain_and_raiden(
        ctx.parent.params['transport'],
        ctx.parent.params['matrix_server'],
        print_step,
        'pre_limits',  # smoke test should work with pre-limits contract version
    )
    args = result['args']
    contract_addresses = result['contract_addresses']
    token = result['token']
    ethereum = result['ethereum']

    for option_ in run.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    port = next(get_free_port('127.0.0.1', 5001))

    args['api_address'] = 'localhost:' + str(port)

    def _run_smoketest():
        print_step('Starting Raiden')

        config = deepcopy(App.DEFAULT_CONFIG)
        if args.get('extra_config', dict()):
            merge_dict(config, args['extra_config'])
            del args['extra_config']
        args['config'] = config

        raiden_stdout = StringIO()
        with contextlib.redirect_stdout(raiden_stdout):
            try:
                # invoke the raiden app
                app = run_app(**args)

                raiden_api = RaidenAPI(app.raiden)
                rest_api = RestAPI(raiden_api)
                api_server = APIServer(rest_api)
                (api_host, api_port) = split_endpoint(args['api_address'])
                api_server.start(api_host, api_port)

                raiden_api.channel_open(
                    registry_address=contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
                    token_address=to_canonical_address(token.contract.address),
                    partner_address=to_canonical_address(TEST_PARTNER_ADDRESS),
                )
                raiden_api.set_total_channel_deposit(
                    contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
                    to_canonical_address(token.contract.address),
                    to_canonical_address(TEST_PARTNER_ADDRESS),
                    TEST_DEPOSIT_AMOUNT,
                )
                token_addresses = [to_checksum_address(token.contract.address)]

                success = False
                print_step('Running smoketest')
                error = run_smoketests(
                    app.raiden,
                    args['transport'],
                    token_addresses,
                    contract_addresses[CONTRACT_ENDPOINT_REGISTRY],
                    debug=debug,
                )
                if error is not None:
                    append_report('Smoketest assertion error', error)
                else:
                    success = True
            finally:
                app.stop()
                app.raiden.get()
                node = ethereum[0]
                node.send_signal(2)
                err, out = node.communicate()

                append_report('Ethereum stdout', out)
                append_report('Ethereum stderr', err)
        append_report('Raiden Node stdout', raiden_stdout.getvalue())
        if success:
            print_step(f'Smoketest successful')
        else:
            print_step(f'Smoketest had errors', error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port, strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with matrix_server_starter() as server_urls:
                # Disable TLS verification so we can connect to the self signed certificate
                make_requests_insecure()
                urllib3.disable_warnings(InsecureRequestWarning)
                args['extra_config'] = {
                    'transport': {
                        'matrix': {
                            'available_servers': server_urls,
                        },
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError, FileNotFoundError):
            append_report('Matrix server start exception', traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 15
0
def port_generator(request):
    """ count generator used to get a unique port number. """
    return get_free_port('127.0.0.1', request.config.option.initial_port)
Exemplo n.º 16
0
def setup_testchain(print_step):
    print_step('Starting Ethereum node')

    ensure_executable('geth')

    free_port = get_free_port('127.0.0.1')
    rpc_port = next(free_port)
    p2p_port = next(free_port)
    base_datadir = os.environ['RST_DATADIR']

    description = EthNodeDescription(
        private_key=TEST_PRIVKEY,
        rpc_port=rpc_port,
        p2p_port=p2p_port,
        miner=True,
    )

    eth_rpc_endpoint = f'http://127.0.0.1:{rpc_port}'
    web3 = Web3(HTTPProvider(endpoint_uri=eth_rpc_endpoint))
    web3.middleware_stack.inject(geth_poa_middleware, layer=0)

    config = eth_node_config(
        description.private_key,
        description.p2p_port,
        description.rpc_port,
    )

    config.update({
        'unlock': 0,
        'mine': True,
        'password': os.path.join(base_datadir, 'pw'),
    })

    nodes_configuration = [config]
    eth_node_config_set_bootnodes(nodes_configuration)
    keystore = os.path.join(eth_node_to_datadir(config, base_datadir),
                            'keystore')

    logdir = os.path.join(base_datadir, 'logs')

    processes_list = eth_run_nodes(
        eth_nodes=[description],
        nodes_configuration=nodes_configuration,
        base_datadir=base_datadir,
        genesis_file=os.path.join(get_project_root(),
                                  'smoketest_genesis.json'),
        chain_id=NETWORKNAME_TO_ID['smoketest'],
        verbosity=0,
        logdir=logdir,
    )

    try:
        # the marker is hardcoded in the genesis file
        random_marker = remove_0x_prefix(encode_hex(b'raiden'))
        eth_wait_and_check(
            web3=web3,
            accounts_addresses=[],
            random_marker=random_marker,
            processes_list=processes_list,
        )
    except (ValueError, RuntimeError) as e:
        # If geth_wait_and_check or the above loop throw an exception make sure
        # we don't end up with a rogue geth process running in the background
        for process in processes_list:
            process.terminate()
        raise e

    return dict(
        base_datadir=base_datadir,
        eth_rpc_endpoint=eth_rpc_endpoint,
        keystore=keystore,
        processes_list=processes_list,
        web3=web3,
    )
Exemplo n.º 17
0
def main() -> None:
    import argparse
    import configparser
    import re

    NODE_SECTION_RE = re.compile("^node[0-9]+")

    parser = argparse.ArgumentParser()
    parser.add_argument("--nodes-data-dir", default=os.getcwd())
    parser.add_argument("--interface", default="127.0.0.1")
    parser.add_argument("config")
    args = parser.parse_args()

    config = configparser.ConfigParser()
    config.read(args.config)

    datadir = args.nodes_data_dir

    interface = args.interface
    port_generator = get_free_port(5000)
    retry_timeout = 1

    nodes_config: List[NodeConfig] = list()
    nodes_running: List[RunningNode] = list()

    defaults = {
        "--log-config": "raiden:DEBUG",
        "--environment-type": "development",
        "--datadir": datadir,
    }

    for section in config:
        if NODE_SECTION_RE.match(section):
            node_config = config[section]
            address = node_config["address"]
            port = next(port_generator)
            api_url = f"{interface}:{port}"

            node = defaults.copy()
            node.update(
                {
                    "--keystore-path": node_config["keystore-path"],
                    "--password-file": node_config["password-file"],
                    "--eth-rpc-endpoint": node_config["eth-rpc-endpoint"],
                    "--network-id": node_config["network-id"],
                    "--address": address,
                    "--api-address": api_url,
                }
            )

            pathfinding_url = node_config.get("pathfinding-service-address")
            if pathfinding_url is not None:
                node["--pathfinding-service-address"] = pathfinding_url

            raiden_args = [
                "raiden",
                "--accept-disclaimer",
                "--log-json",
                "--disable-debug-logfile",
                "--flat-fee",
                "0xf9BA8aDF7F7024D7de8eB37b4c981CFFe3C88Ea7",
                "0",
                "--proportional-fee",
                "0xf9BA8aDF7F7024D7de8eB37b4c981CFFe3C88Ea7",
                "0",
                "--proportional-imbalance-fee",
                "0xf9BA8aDF7F7024D7de8eB37b4c981CFFe3C88Ea7",
                "0",
                "--flamegraph",
                "/tmp/flamegraph",
            ]
            raiden_args.extend(chain.from_iterable(node.items()))

            if not is_checksum_address(address):
                raise ValueError(f"address {address} is not checksummed.")

            nodedir = os.path.join(datadir, f"node_{pex(to_canonical_address(address))}")
            nodes_config.append(
                NodeConfig(raiden_args, address, BaseURL(f"http://{api_url}"), nodedir)
            )

    # TODO: Determine the `capacity_lower_bound` by querying the nodes.
    capacity_lower_bound = 1130220

    iterations = 5
    token_address = config.defaults()["token-address"]

    if not is_checksum_address(token_address):
        raise ValueError(f"Invalid token address {token_address}, check it is checksummed.")

    if iterations is None:
        iteration_counter = count()
    else:
        iteration_counter = iter(range(iterations))

    stop = Event()

    force_quit(stop, gevent.getcurrent(), timeout=5)

    # def stop_on_signal(sig=None, _frame=None):
    #     stop.set()
    # gevent.signal(signal.SIGQUIT, stop_on_signal)
    # gevent.signal(signal.SIGTERM, stop_on_signal)
    # gevent.signal(signal.SIGINT, stop_on_signal)

    # TODO: If any of the processes crashes the script should collect and
    # bundle the logs.
    #
    # Cleanup with the Janitor is not strictily necessary for the stress test,
    # since once can assume a bug happened and the state of the node is
    # inconsistent, however it is nice to have.
    with Janitor(stop) as nursery:
        nodes_running = start_and_wait_for_all_servers(nursery, nodes_config, retry_timeout)

        # If any of the processes failed to startup
        if stop.is_set():
            return

        # Uncomment this if you want to interact manually with the started nodes
        # print("All nodes are ready! Press Enter to continue and perform the stress tests.")
        # input()

        nursery.spawn_under_watch(
            run_stress_test,
            nursery,
            retry_timeout,
            nodes_running,
            capacity_lower_bound,
            token_address,
            iteration_counter,
        ).get()
Exemplo n.º 18
0
Arquivo: cli.py Projeto: sekmet/raiden
def smoketest(ctx: Context, debug: bool, eth_client: EthClient,
              report_path: Optional[str]) -> None:  # pragma: no cover
    """ Test, that the raiden installation is sane. """
    from raiden.tests.utils.smoketest import run_smoketest, setup_smoketest, step_printer

    raiden_stdout = StringIO()

    assert ctx.parent, MYPY_ANNOTATION
    environment_type = ctx.parent.params["environment_type"]
    disable_debug_logfile = ctx.parent.params["disable_debug_logfile"]

    if report_path is None:
        report_file = mktemp(suffix=".log")
    else:
        report_file = report_path

    click.secho(f"Report file: {report_file}", fg="yellow")

    configure_logging(
        logger_level_config={"": "DEBUG"},
        log_file=report_file,
        disable_debug_logfile=disable_debug_logfile,
    )

    def append_report(subject: str, data: Optional[AnyStr] = None) -> None:
        with open(report_file, "a", encoding="UTF-8") as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                write_data: str
                if isinstance(data, bytes):
                    write_data = data.decode()
                else:
                    write_data = data
                handler.writelines([write_data + os.linesep])

    append_report("Raiden version", json.dumps(get_system_spec()))
    append_report("Raiden log")

    free_port_generator = get_free_port()
    try:
        with step_printer(step_count=7, stdout=sys.stdout) as print_step:
            with setup_smoketest(
                    eth_client=eth_client,
                    print_step=print_step,
                    free_port_generator=free_port_generator,
                    debug=debug,
                    stdout=raiden_stdout,
                    append_report=append_report,
            ) as setup:
                args = setup.args
                port = next(free_port_generator)

                args["api_address"] = f"localhost:{port}"
                args["environment_type"] = environment_type

                # Matrix server
                args["one_to_n_contract_address"] = "0x" + "1" * 40
                args["routing_mode"] = RoutingMode.PRIVATE
                args["flat_fee"] = ()
                args["proportional_fee"] = ()
                args["proportional_imbalance_fee"] = ()

                for option_ in run.params:
                    if option_.name in args.keys():
                        args[option_.name] = option_.process_value(
                            ctx, args[option_.name])
                    else:
                        args[option_.name] = option_.default

                run_smoketest(print_step=print_step, setup=setup)

            append_report("Raiden Node stdout", raiden_stdout.getvalue())

    except:  # noqa pylint: disable=bare-except
        if debug:
            import pdb

            pdb.post_mortem()  # pylint: disable=no-member

        error = traceback.format_exc()
        append_report("Smoketest execution error", error)
        print_step("Smoketest execution error", error=True)
        success = False
    else:
        print_step("Smoketest successful")
        success = True

    if not success:
        sys.exit(1)
Exemplo n.º 19
0
def smoketest(eth_client: EthClient):
    from raiden.network.utils import get_free_port
    from raiden.tests.utils.smoketest import setup_smoketest, step_printer

    free_port_generator = get_free_port()
    datadir = mkdtemp()

    captured_stdout = StringIO()

    with report() as (report_file, append_report):
        append_report("Setting up Smoketest")
        with step_printer(step_count=6, stdout=sys.stdout) as print_step:
            setup: RaidenTestSetup
            with setup_smoketest(
                eth_client=eth_client,
                print_step=print_step,
                free_port_generator=free_port_generator,
                debug=False,
                stdout=captured_stdout,
                append_report=append_report,
            ) as setup:
                deployment_data = smoketest_deployed_contracts(setup.contract_addresses)
                config_file = create_smoketest_config_file(setup, datadir)

                keystore_file = os.path.join(setup.args["keystore_path"], "keyfile")
                password_file = setup.args["password_file"]
                print_step("Running scenario player")
                append_report("Scenario Player Log", captured_stdout.getvalue())
                env = EnvironmentConfig(
                    pfs_fee=FeeAmount(100),
                    environment_type="development",
                    environment_file_name="smoketest",
                    matrix_servers=[setup.args["matrix_server"]],
                    transfer_token=TokenAddress(bytes([1] * 20)),
                    pfs_with_fee=URI("http://www.example.com"),
                    eth_rpc_endpoints=[URI(setup.args["eth_rpc_endpoint"])],
                    ms_reward_with_margin=TokenAmount(1),
                    settlement_timeout_min=BlockTimeout(100),
                    raiden_client="raiden",
                    wait_short=5,
                    wait_long=10,
                )
                try:
                    run_(
                        data_path=Path(datadir),
                        auth="",
                        password=None,
                        keystore_file=keystore_file,
                        scenario_file=config_file,
                        enable_ui=False,
                        password_file=password_file,
                        log_file_name=report_file,
                        environment=env,
                        smoketest_deployment_data=deployment_data,
                        delete_snapshots=False,
                        raiden_client="raiden",
                    )
                except SystemExit as ex:
                    append_report("Captured", captured_stdout.getvalue())
                    if ex.code != 0:
                        print_step("Error when running scenario player", error=True)
                        sys.exit(ex.code)
                    else:
                        print_step("Smoketest successful!")
Exemplo n.º 20
0
def smoketest(ctx, debug, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        run_smoketests,
        setup_testchain_and_raiden,
    )

    report_file = mktemp(suffix='.log')
    configure_logging(
        logger_level_config={'': 'DEBUG'},
        log_file=report_file,
        disable_debug_logfile=ctx.parent.params['disable_debug_logfile'],
    )
    click.secho(
        f'Report file: {report_file}',
        fg='yellow',
    )

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ), )

    print_step('Getting smoketest configuration')

    result = setup_testchain_and_raiden(
        ctx.parent.params['transport'],
        ctx.parent.params['matrix_server'],
        print_step,
        'pre_limits',  # smoke test should work with pre-limits contract version
    )
    args = result['args']
    contract_addresses = result['contract_addresses']
    token = result['token']
    ethereum = result['ethereum']

    for option_ in run.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    port = next(get_free_port('127.0.0.1', 5001))

    args['api_address'] = 'localhost:' + str(port)

    def _run_smoketest():
        print_step('Starting Raiden')

        config = deepcopy(App.DEFAULT_CONFIG)
        if args.get('extra_config', dict()):
            merge_dict(config, args['extra_config'])
            del args['extra_config']
        args['config'] = config

        raiden_stdout = StringIO()
        with contextlib.redirect_stdout(raiden_stdout):
            try:
                # invoke the raiden app
                app = run_app(**args)

                raiden_api = RaidenAPI(app.raiden)
                rest_api = RestAPI(raiden_api)
                api_server = APIServer(rest_api)
                (api_host, api_port) = split_endpoint(args['api_address'])
                api_server.start(api_host, api_port)

                raiden_api.channel_open(
                    registry_address=contract_addresses[
                        CONTRACT_TOKEN_NETWORK_REGISTRY],
                    token_address=to_canonical_address(token.contract.address),
                    partner_address=to_canonical_address(TEST_PARTNER_ADDRESS),
                )
                raiden_api.set_total_channel_deposit(
                    contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
                    to_canonical_address(token.contract.address),
                    to_canonical_address(TEST_PARTNER_ADDRESS),
                    TEST_DEPOSIT_AMOUNT,
                )
                token_addresses = [to_checksum_address(token.contract.address)]

                success = False
                print_step('Running smoketest')
                error = run_smoketests(
                    app.raiden,
                    args['transport'],
                    token_addresses,
                    contract_addresses[CONTRACT_ENDPOINT_REGISTRY],
                    debug=debug,
                )
                if error is not None:
                    append_report('Smoketest assertion error', error)
                else:
                    success = True
            finally:
                app.stop()
                app.raiden.get()
                node = ethereum[0]
                node.send_signal(2)
                err, out = node.communicate()

                append_report('Ethereum stdout', out)
                append_report('Ethereum stderr', err)
        append_report('Raiden Node stdout', raiden_stdout.getvalue())
        if success:
            print_step(f'Smoketest successful')
        else:
            print_step(f'Smoketest had errors', error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port,
                           strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with matrix_server_starter() as server_urls:
                # Disable TLS verification so we can connect to the self signed certificate
                make_requests_insecure()
                urllib3.disable_warnings(InsecureRequestWarning)
                args['extra_config'] = {
                    'transport': {
                        'matrix': {
                            'available_servers': server_urls,
                        },
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError, FileNotFoundError):
            append_report('Matrix server start exception',
                          traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 21
0
def smoketest(ctx, debug, **kwargs):
    """ Test, that the raiden installation is sane.
    """
    from raiden.api.python import RaidenAPI
    from raiden.blockchain.abi import get_static_or_compile
    from raiden.utils import get_contract_path

    # Check the solidity compiler early in the smoketest.
    #
    # Binary distributions don't need the solidity compiler but source
    # distributions do. Since this is checked by `get_static_or_compile`
    # function, use it as a proxy for validating the setup.
    get_static_or_compile(
        get_contract_path('HumanStandardToken.sol'),
        'HumanStandardToken',
    )

    report_file = tempfile.mktemp(suffix='.log')
    open(report_file, 'w+')

    def append_report(subject, data):
        with open(report_file, 'a') as handler:
            handler.write('{:=^80}'.format(' %s ' % subject.upper()) + os.linesep)
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('raiden version', json.dumps(get_system_spec()))
    append_report('raiden log', None)

    print('[1/5] getting smoketest configuration')
    smoketest_config = load_or_create_smoketest_config()

    print('[2/5] starting ethereum')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])

    print('[3/5] starting raiden')

    # setup logging to log only into our report file
    slogging.configure(':DEBUG', log_file=report_file)
    root = slogging.getLogger()
    for handler in root.handlers:
        if isinstance(handler, slogging.logging.StreamHandler):
            root.handlers.remove(handler)
            break
    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=smoketest_config['contracts']['discovery_address'],
        registry_contract_address=smoketest_config['contracts']['registry_address'],
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(ethereum_config['rpc']),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
    )
    for option in app.params:
        if option.name in args.keys():
            args[option.name] = option.process_value(ctx, args[option.name])
        else:
            args[option.name] = option.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    args['mapped_socket'] = None
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(next(get_free_port('127.0.0.1', 5001)))
    args['sync_check'] = False

    # invoke the raiden app
    app_ = ctx.invoke(app, **args)

    raiden_api = RaidenAPI(app_.raiden)
    rest_api = RestAPI(raiden_api)
    api_server = APIServer(rest_api)
    (api_host, api_port) = split_endpoint(args['api_address'])
    api_server.start(api_host, api_port)

    success = False
    try:
        print('[4/5] running smoketests...')
        error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
        if error is not None:
            append_report('smoketest assertion error', error)
        else:
            success = True
    finally:
        app_.stop()
        ethereum.send_signal(2)

        err, out = ethereum.communicate()
        append_report('geth init stdout', ethereum_config['init_log_out'].decode('utf-8'))
        append_report('geth init stderr', ethereum_config['init_log_err'].decode('utf-8'))
        append_report('ethereum stdout', out)
        append_report('ethereum stderr', err)
        append_report('smoketest configuration', json.dumps(smoketest_config))
    if success:
        print('[5/5] smoketest successful, report was written to {}'.format(report_file))
    else:
        print('[5/5] smoketest had errors, report was written to {}'.format(report_file))
        sys.exit(1)
Exemplo n.º 22
0
def port_generator(request):
    """ count generator used to get a unique port number. """
    return get_free_port('127.0.0.1', request.config.option.initial_port)
Exemplo n.º 23
0
def smoketest(ctx, debug, local_matrix, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    import binascii
    from web3 import Web3, HTTPProvider
    from web3.middleware import geth_poa_middleware
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.geth import geth_wait_and_check
    from raiden.tests.integration.contracts.fixtures.contracts import deploy_token
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        deploy_smoketest_contracts,
        get_private_key,
        load_smoketest_config,
        start_ethereum,
        run_smoketests,
    )

    report_file = tempfile.mktemp(suffix='.log')
    configure_logging({'': 'DEBUG'}, log_file=report_file)

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ), )

    print_step('Getting smoketest configuration')
    smoketest_config = load_smoketest_config()
    if not smoketest_config:
        append_report(
            'Smoketest configuration',
            'Could not load the smoketest genesis configuration file.',
        )

    print_step('Starting Ethereum node')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])
    port = ethereum_config['rpc']
    web3_client = Web3(HTTPProvider(f'http://0.0.0.0:{port}'))
    web3_client.middleware_stack.inject(geth_poa_middleware, layer=0)
    random_marker = binascii.hexlify(b'raiden').decode()
    privatekeys = []
    geth_wait_and_check(web3_client, privatekeys, random_marker)

    print_step('Deploying Raiden contracts')
    host = '0.0.0.0'
    client = JSONRPCClient(
        host,
        ethereum_config['rpc'],
        get_private_key(),
        web3=web3_client,
    )
    contract_addresses = deploy_smoketest_contracts(client, 627)

    token_contract = deploy_token(client)
    token = token_contract(1000, 0, 'TKN', 'TKN')

    registry = TokenNetworkRegistry(
        client, contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY])

    registry.add_token(to_canonical_address(token.contract.address))

    print_step('Setting up Raiden')
    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_ENDPOINT_REGISTRY], ),
        registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], ),
        secret_registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_SECRET_REGISTRY], ),
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(port),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
        network_id='627',
        transport=ctx.parent.params['transport'],
        matrix_server='http://localhost:8008'
        if ctx.parent.params['matrix_server'] == 'auto' else
        ctx.parent.params['matrix_server'],
    )
    smoketest_config['transport'] = args['transport']
    for option_ in app.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    port = next(get_free_port('127.0.0.1', 5001))
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(port)
    args['sync_check'] = False

    def _run_smoketest():
        print_step('Starting Raiden')

        # invoke the raiden app
        app_ = ctx.invoke(app, **args)

        raiden_api = RaidenAPI(app_.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        raiden_api.channel_open(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            None,
            None,
        )
        raiden_api.set_total_channel_deposit(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            TEST_DEPOSIT_AMOUNT,
        )

        smoketest_config['contracts'][
            'registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
        smoketest_config['contracts'][
            'secret_registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_SECRET_REGISTRY], )
        smoketest_config['contracts'][
            'discovery_address'] = to_checksum_address(
                contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
        smoketest_config['contracts']['token_address'] = to_checksum_address(
            token.contract.address, )

        success = False
        try:
            print_step('Running smoketest')
            error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('Smoketest assertion error', error)
            else:
                success = True
        finally:
            app_.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('Ethereum init stdout',
                          ethereum_config['init_log_out'].decode('utf-8'))
            append_report('Ethereum init stderr',
                          ethereum_config['init_log_err'].decode('utf-8'))
            append_report('Ethereum stdout', out)
            append_report('Ethereum stderr', err)
            append_report('Smoketest configuration',
                          json.dumps(smoketest_config))
        if success:
            print_step(
                f'Smoketest successful, report was written to {report_file}')
        else:
            print_step(
                f'Smoketest had errors, report was written to {report_file}',
                error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port,
                           strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() != 'none':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with HTTPExecutor(
                    local_matrix,
                    status=r'^[24]\d\d$',
                    url=urljoin(args['matrix_server'],
                                '/_matrix/client/versions'),
                    shell=True,
            ):
                args['extra_config'] = {
                    'matrix': {
                        'discovery_room': {
                            'server': 'matrix.local.raiden'
                        },
                        'server_name': 'matrix.local.raiden',
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError):
            append_report('Matrix server start exception',
                          traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    elif args['transport'] == 'matrix' and local_matrix.lower() == "none":
        args['mapped_socket'] = None
        success = _run_smoketest()
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 24
0
def smoketest(ctx, debug, local_matrix, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        load_smoketest_config,
        run_smoketests,
        setup_testchain_and_raiden,
    )

    report_file = tempfile.mktemp(suffix='.log')
    configure_logging({'': 'DEBUG'}, log_file=report_file)

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ), )

    print_step('Getting smoketest configuration')
    smoketest_config = load_smoketest_config()
    if not smoketest_config:
        append_report(
            'Smoketest configuration',
            'Could not load the smoketest genesis configuration file.',
        )

    result = setup_testchain_and_raiden(
        smoketest_config,
        ctx.parent.params['transport'],
        ctx.parent.params['matrix_server'],
        print_step,
    )
    args = result['args']
    contract_addresses = result['contract_addresses']
    token = result['token']
    ethereum = result['ethereum']
    ethereum_config = result['ethereum_config']

    smoketest_config['transport'] = args['transport']
    for option_ in run.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    port = next(get_free_port('127.0.0.1', 5001))

    args['api_address'] = 'localhost:' + str(port)

    def _run_smoketest():
        print_step('Starting Raiden')

        # invoke the raiden app
        app = run_app(**args)

        raiden_api = RaidenAPI(app.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        raiden_api.channel_open(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            None,
            None,
        )
        raiden_api.set_total_channel_deposit(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            TEST_DEPOSIT_AMOUNT,
        )

        smoketest_config['contracts'][
            'registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
        smoketest_config['contracts'][
            'secret_registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_SECRET_REGISTRY], )
        smoketest_config['contracts'][
            'discovery_address'] = to_checksum_address(
                contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
        smoketest_config['contracts']['token_address'] = to_checksum_address(
            token.contract.address, )

        success = False
        try:
            print_step('Running smoketest')
            error = run_smoketests(app.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('Smoketest assertion error', error)
            else:
                success = True
        finally:
            app.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('Ethereum init stdout',
                          ethereum_config['init_log_out'].decode('utf-8'))
            append_report('Ethereum init stderr',
                          ethereum_config['init_log_err'].decode('utf-8'))
            append_report('Ethereum stdout', out)
            append_report('Ethereum stderr', err)
            append_report('Smoketest configuration',
                          json.dumps(smoketest_config))
        if success:
            print_step(
                f'Smoketest successful, report was written to {report_file}')
        else:
            print_step(
                f'Smoketest had errors, report was written to {report_file}',
                error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port,
                           strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() != 'none':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with HTTPExecutor(
                    local_matrix,
                    url=urljoin(args['matrix_server'],
                                '/_matrix/client/versions'),
                    method='GET',
                    timeout=30,
                    shell=True,
            ):
                args['extra_config'] = {
                    'transport': {
                        'matrix': {
                            'discovery_room': {
                                'server': 'matrix.local.raiden'
                            },
                            'server_name': 'matrix.local.raiden',
                        },
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError):
            append_report('Matrix server start exception',
                          traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    elif args['transport'] == 'matrix' and local_matrix.lower() == "none":
        args['mapped_socket'] = None
        success = _run_smoketest()
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 25
0
def smoketest(ctx, debug, local_matrix, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    import binascii
    from web3 import Web3, HTTPProvider
    from web3.middleware import geth_poa_middleware
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.geth import geth_wait_and_check
    from raiden.tests.integration.contracts.fixtures.contracts import deploy_token
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        deploy_smoketest_contracts,
        get_private_key,
        load_smoketest_config,
        start_ethereum,
        run_smoketests,
    )

    report_file = tempfile.mktemp(suffix='.log')
    configure_logging({'': 'DEBUG'}, log_file=report_file)

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ),
        )

    print_step('Getting smoketest configuration')
    smoketest_config = load_smoketest_config()
    if not smoketest_config:
        append_report(
            'Smoketest configuration',
            'Could not load the smoketest genesis configuration file.',
        )

    print_step('Starting Ethereum node')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])
    port = ethereum_config['rpc']
    web3_client = Web3(HTTPProvider(f'http://0.0.0.0:{port}'))
    web3_client.middleware_stack.inject(geth_poa_middleware, layer=0)
    random_marker = binascii.hexlify(b'raiden').decode()
    privatekeys = []
    geth_wait_and_check(web3_client, privatekeys, random_marker)

    print_step('Deploying Raiden contracts')
    host = '0.0.0.0'
    client = JSONRPCClient(
        host,
        ethereum_config['rpc'],
        get_private_key(),
        web3=web3_client,
    )
    contract_addresses = deploy_smoketest_contracts(client, 627)

    token_contract = deploy_token(client)
    token = token_contract(1000, 0, 'TKN', 'TKN')

    registry = TokenNetworkRegistry(client, contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY])

    registry.add_token(to_canonical_address(token.contract.address))

    print_step('Setting up Raiden')
    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_ENDPOINT_REGISTRY],
        ),
        registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
        ),
        secret_registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_SECRET_REGISTRY],
        ),
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(port),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
        network_id='627',
        transport=ctx.parent.params['transport'],
        matrix_server='http://localhost:8008'
                      if ctx.parent.params['matrix_server'] == 'auto'
                      else ctx.parent.params['matrix_server'],
    )
    smoketest_config['transport'] = args['transport']
    for option_ in app.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    port = next(get_free_port('127.0.0.1', 5001))
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(port)
    args['sync_check'] = False

    def _run_smoketest():
        print_step('Starting Raiden')

        # invoke the raiden app
        app_ = ctx.invoke(app, **args)

        raiden_api = RaidenAPI(app_.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        raiden_api.channel_open(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            None,
            None,
        )
        raiden_api.set_total_channel_deposit(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            TEST_DEPOSIT_AMOUNT,
        )

        smoketest_config['contracts']['registry_address'] = to_checksum_address(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
        )
        smoketest_config['contracts']['secret_registry_address'] = to_checksum_address(
            contract_addresses[CONTRACT_SECRET_REGISTRY],
        )
        smoketest_config['contracts']['discovery_address'] = to_checksum_address(
            contract_addresses[CONTRACT_ENDPOINT_REGISTRY],
        )
        smoketest_config['contracts']['token_address'] = to_checksum_address(
            token.contract.address,
        )

        success = False
        try:
            print_step('Running smoketest')
            error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('Smoketest assertion error', error)
            else:
                success = True
        finally:
            app_.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('Ethereum init stdout', ethereum_config['init_log_out'].decode('utf-8'))
            append_report('Ethereum init stderr', ethereum_config['init_log_err'].decode('utf-8'))
            append_report('Ethereum stdout', out)
            append_report('Ethereum stderr', err)
            append_report('Smoketest configuration', json.dumps(smoketest_config))
        if success:
            print_step(f'Smoketest successful, report was written to {report_file}')
        else:
            print_step(f'Smoketest had errors, report was written to {report_file}', error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port, strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() != 'none':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with HTTPExecutor(
                local_matrix,
                status=r'^[24]\d\d$',
                url=urljoin(args['matrix_server'], '/_matrix/client/versions'),
                shell=True,
            ):
                args['extra_config'] = {
                    'matrix': {
                        'discovery_room': {'server': 'matrix.local.raiden'},
                        'server_name': 'matrix.local.raiden',
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError):
            append_report('Matrix server start exception', traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    elif args['transport'] == 'matrix' and local_matrix.lower() == "none":
        args['mapped_socket'] = None
        success = _run_smoketest()
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 26
0
def smoketest(
    ctx: Context, debug: bool, eth_client: EthClient, report_path: Optional[str]
) -> None:
    """ Test, that the raiden installation is sane. """
    from raiden.tests.utils.smoketest import (
        setup_raiden,
        run_smoketest,
        setup_matrix_for_smoketest,
        setup_testchain_for_smoketest,
    )
    from raiden.tests.utils.transport import make_requests_insecure, ParsedURL

    step_count = 8
    step = 0
    stdout = sys.stdout
    raiden_stdout = StringIO()

    assert ctx.parent, MYPY_ANNOTATION
    environment_type = ctx.parent.params["environment_type"]
    transport = ctx.parent.params["transport"]
    disable_debug_logfile = ctx.parent.params["disable_debug_logfile"]
    matrix_server = ctx.parent.params["matrix_server"]

    if transport != "matrix":
        raise RuntimeError(f"Invalid transport type '{transport}'")

    if report_path is None:
        report_file = mktemp(suffix=".log")
    else:
        report_file = report_path

    make_requests_insecure()
    urllib3.disable_warnings(InsecureRequestWarning)

    click.secho(f"Report file: {report_file}", fg="yellow")

    configure_logging(
        logger_level_config={"": "DEBUG"},
        log_file=report_file,
        disable_debug_logfile=disable_debug_logfile,
    )

    def append_report(subject: str, data: Optional[AnyStr] = None) -> None:
        with open(report_file, "a", encoding="UTF-8") as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                write_data: str
                if isinstance(data, bytes):
                    write_data = data.decode()
                else:
                    write_data = data
                handler.writelines([write_data + os.linesep])

    append_report("Raiden version", json.dumps(get_system_spec()))
    append_report("Raiden log")

    def print_step(description: str, error: bool = False) -> None:
        nonlocal step
        step += 1
        click.echo(
            "{} {}".format(
                click.style(f"[{step}/{step_count}]", fg="blue"),
                click.style(description, fg="green" if not error else "red"),
            ),
            file=stdout,
        )

    contracts_version = RAIDEN_CONTRACT_VERSION

    try:
        free_port_generator = get_free_port()
        ethereum_nodes = None

        datadir = mkdtemp()
        testchain_manager: ContextManager[Dict[str, Any]] = setup_testchain_for_smoketest(
            eth_client=eth_client,
            print_step=print_step,
            free_port_generator=free_port_generator,
            base_datadir=datadir,
            base_logdir=datadir,
        )
        matrix_manager: ContextManager[
            List[Tuple[ParsedURL, HTTPExecutor]]
        ] = setup_matrix_for_smoketest(
            print_step=print_step,
            free_port_generator=free_port_generator,
            broadcast_rooms_aliases=[
                make_room_alias(NETWORKNAME_TO_ID["smoketest"], DISCOVERY_DEFAULT_ROOM),
                make_room_alias(NETWORKNAME_TO_ID["smoketest"], PATH_FINDING_BROADCASTING_ROOM),
            ],
        )

        # Do not redirect the stdout on a debug session, otherwise the REPL
        # will also be redirected
        if debug:
            stdout_manager = contextlib.nullcontext()
        else:
            stdout_manager = contextlib.redirect_stdout(raiden_stdout)

        with stdout_manager, testchain_manager as testchain, matrix_manager as server_urls:
            result = setup_raiden(
                transport=transport,
                matrix_server=matrix_server,
                print_step=print_step,
                contracts_version=contracts_version,
                eth_client=testchain["eth_client"],
                eth_rpc_endpoint=testchain["eth_rpc_endpoint"],
                web3=testchain["web3"],
                base_datadir=testchain["base_datadir"],
                keystore=testchain["keystore"],
            )

            args = result["args"]
            contract_addresses = result["contract_addresses"]
            ethereum_nodes = testchain["node_executors"]
            token = result["token"]

            port = next(free_port_generator)

            args["api_address"] = f"localhost:{port}"
            args["environment_type"] = environment_type

            # Matrix server
            # TODO: do we need more than one here?
            first_server = server_urls[0]
            args["matrix_server"] = first_server[0]
            args["one_to_n_contract_address"] = "0x" + "1" * 40
            args["routing_mode"] = RoutingMode.LOCAL
            args["flat_fee"] = ()
            args["proportional_fee"] = ()
            args["proportional_imbalance_fee"] = ()

            for option_ in run.params:
                if option_.name in args.keys():
                    args[option_.name] = option_.process_value(ctx, args[option_.name])
                else:
                    args[option_.name] = option_.default

            try:
                run_smoketest(
                    print_step=print_step,
                    args=args,
                    contract_addresses=contract_addresses,
                    token=token,
                )
            finally:
                if ethereum_nodes:
                    for node_executor in ethereum_nodes:
                        node = node_executor.process
                        node.send_signal(signal.SIGINT)

                        try:
                            node.wait(10)
                        except TimeoutExpired:
                            print_step("Ethereum node shutdown unclean, check log!", error=True)
                            node.kill()

                        if isinstance(node_executor.stdio, tuple):
                            logfile = node_executor.stdio[1]
                            logfile.flush()
                            logfile.seek(0)
                            append_report("Ethereum Node log output", logfile.read())

        append_report("Raiden Node stdout", raiden_stdout.getvalue())

    except:  # noqa pylint: disable=bare-except
        if debug:
            import pdb

            pdb.post_mortem()  # pylint: disable=no-member

        error = traceback.format_exc()
        append_report("Smoketest execution error", error)
        print_step("Smoketest execution error", error=True)
        success = False
    else:
        print_step(f"Smoketest successful")
        success = True

    if not success:
        sys.exit(1)
Exemplo n.º 27
0
def smoketest(ctx, debug, local_matrix, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    import binascii

    from raiden.api.python import RaidenAPI
    from raiden.blockchain.abi import get_static_or_compile
    from raiden.tests.utils.blockchain import geth_wait_and_check
    from raiden.tests.integration.fixtures.backend_geth import web3
    from raiden.tests.utils.smoketest import (
        load_smoketest_config,
        start_ethereum,
        run_smoketests,
        patch_smoke_fns,
    )
    from raiden.utils import get_contract_path
    from raiden.raiden_service import RaidenService

    # TODO: Temporary until we also deploy contracts in smoketests
    # This function call patches the initial query filtering to create some fake
    # events. That is done to make up for the missing events that would have
    # been generated and populated the state if the contracts were deployed
    # and not precompiled in the smoketest genesis file
    RaidenService.install_and_query_payment_network_filters = patch_smoke_fns(
        RaidenService.install_and_query_payment_network_filters, )

    # Check the solidity compiler early in the smoketest.
    #
    # Binary distributions don't need the solidity compiler but source
    # distributions do. Since this is checked by `get_static_or_compile`
    # function, use it as a proxy for validating the setup.
    get_static_or_compile(
        get_contract_path('HumanStandardToken.sol'),
        'HumanStandardToken',
    )

    report_file = tempfile.mktemp(suffix='.log')
    configure_logging({'': 'DEBUG'}, log_file=report_file)

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('raiden version', json.dumps(get_system_spec()))
    append_report('raiden log', None)

    print('[1/5] getting smoketest configuration')
    smoketest_config = load_smoketest_config()
    if not smoketest_config:
        append_report(
            'smoketest configuration',
            'Could not load the smoketest genesis configuration file.',
        )

    print('[2/5] starting ethereum')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])
    port = ethereum_config['rpc']
    web3_client = web3([port])

    random_marker = binascii.hexlify(b'raiden').decode()
    privatekeys = []
    geth_wait_and_check(web3_client, privatekeys, random_marker)

    print('[3/5] starting raiden')

    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=smoketest_config['contracts']
        ['discovery_address'],
        registry_contract_address=smoketest_config['contracts']
        ['registry_address'],
        secret_registry_contract_address=smoketest_config['contracts']
        ['secret_registry_address'],
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(port),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
        network_id='627',
        transport=ctx.parent.params['transport'],
        matrix_server='http://localhost:8008'
        if ctx.parent.params['matrix_server'] == 'auto' else
        ctx.parent.params['matrix_server'],
    )
    smoketest_config['transport'] = args['transport']
    for option_ in app.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    port = next(get_free_port('127.0.0.1', 5001))
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(port)
    args['sync_check'] = False

    def _run_smoketest():
        # invoke the raiden app
        app_ = ctx.invoke(app, **args)

        raiden_api = RaidenAPI(app_.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        success = False
        try:
            print('[4/5] running smoketests...')
            error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('smoketest assertion error', error)
            else:
                success = True
        finally:
            app_.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('geth init stdout',
                          ethereum_config['init_log_out'].decode('utf-8'))
            append_report('geth init stderr',
                          ethereum_config['init_log_err'].decode('utf-8'))
            append_report('ethereum stdout', out)
            append_report('ethereum stderr', err)
            append_report('smoketest configuration',
                          json.dumps(smoketest_config))
        if success:
            print(
                '[5/5] smoketest successful, report was written to {}'.format(
                    report_file))
        else:
            print(
                '[5/5] smoketest had errors, report was written to {}'.format(
                    report_file))
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port,
                           strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() != 'none':
        print('WARNING: The Matrix transport is experimental')
        args['mapped_socket'] = None
        with HTTPExecutor(
                local_matrix,
                status=r'^[24]\d\d$',
                url=urljoin(args['matrix_server'], '/_matrix'),
        ):
            args['extra_config'] = {
                'matrix': {
                    'discovery_room': {
                        'server': 'matrix.local.raiden'
                    },
                    'server_name': 'matrix.local.raiden',
                },
            }
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() == "none":
        print('WARNING: The Matrix transport is experimental')
        args['mapped_socket'] = None
        success = _run_smoketest()
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemplo n.º 28
0
def smoketest(ctx, debug, **kwargs):
    """ Test, that the raiden installation is sane.
    """
    from raiden.api.python import RaidenAPI
    from raiden.blockchain.abi import get_static_or_compile
    from raiden.utils import get_contract_path

    # Check the solidity compiler early in the smoketest.
    #
    # Binary distributions don't need the solidity compiler but source
    # distributions do. Since this is checked by `get_static_or_compile`
    # function, use it as a proxy for validating the setup.
    get_static_or_compile(
        get_contract_path('HumanStandardToken.sol'),
        'HumanStandardToken',
    )

    report_file = tempfile.mktemp(suffix='.log')
    open(report_file, 'w+')

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write('{:=^80}'.format(' %s ' % subject.upper()) +
                          os.linesep)
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('raiden version', json.dumps(get_system_spec()))
    append_report('raiden log', None)

    print('[1/5] getting smoketest configuration')
    smoketest_config = load_or_create_smoketest_config()

    print('[2/5] starting ethereum')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])

    print('[3/5] starting raiden')

    # setup logging to log only into our report file
    slogging.configure(':DEBUG', log_file=report_file)
    root = slogging.getLogger()
    for handler in root.handlers:
        if isinstance(handler, slogging.logging.StreamHandler):
            root.handlers.remove(handler)
            break
    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=smoketest_config['contracts']
        ['discovery_address'],
        registry_contract_address=smoketest_config['contracts']
        ['registry_address'],
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(ethereum_config['rpc']),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
    )
    for option in app.params:
        if option.name in args.keys():
            args[option.name] = option.process_value(ctx, args[option.name])
        else:
            args[option.name] = option.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    args['mapped_socket'] = None
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(
        next(get_free_port('127.0.0.1', 5001)))
    args['sync_check'] = False

    # invoke the raiden app
    app_ = ctx.invoke(app, **args)

    raiden_api = RaidenAPI(app_.raiden)
    rest_api = RestAPI(raiden_api)
    api_server = APIServer(rest_api)
    (api_host, api_port) = split_endpoint(args['api_address'])
    api_server.start(api_host, api_port)

    success = False
    try:
        print('[4/5] running smoketests...')
        error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
        if error is not None:
            append_report('smoketest assertion error', error)
        else:
            success = True
    finally:
        app_.stop()
        ethereum.send_signal(2)

        err, out = ethereum.communicate()
        append_report('geth init stdout',
                      ethereum_config['init_log_out'].decode('utf-8'))
        append_report('geth init stderr',
                      ethereum_config['init_log_err'].decode('utf-8'))
        append_report('ethereum stdout', out)
        append_report('ethereum stderr', err)
        append_report('smoketest configuration', json.dumps(smoketest_config))
    if success:
        print('[5/5] smoketest successful, report was written to {}'.format(
            report_file))
    else:
        print('[5/5] smoketest had errors, report was written to {}'.format(
            report_file))
        sys.exit(1)
Exemplo n.º 29
0
def port_generator():
    """ count generator used to get a unique port number. """
    return get_free_port('127.0.0.1')