Exemple #1
0
def _parse(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Runs a load test.')
    parser.add_argument('fqn', help='Fully Qualified Name of the test',
                        nargs='?')

    parser.add_argument('--config', help='Configuration file to read',
                        type=str, default=None)

    parser.add_argument('-u', '--users', help='Number of virtual users',
                        type=str, default='1')

    parser.add_argument('--test-dir', help='Directory to run the test from',
                        type=str, default=None)

    parser.add_argument('--python-dep', help='Python (PyPI) dependencies '
                                             'to install',
                        action='append', default=[])

    parser.add_argument('--include-file',
                        help='File(s) to include (needed for the test) '
                             '- glob-style',
                        action='append', default=[])

    # loads works with hits or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--hits', help='Number of hits per user',
                       type=str, default=None)
    group.add_argument('-d', '--duration', help='Duration of the test (s)',
                       type=int, default=None)

    parser.add_argument('--version', action='store_true', default=False,
                        help='Displays Loads version and exits.')

    parser.add_argument('--test-runner', default=None,
                        help='The path to binary to use as the test runner '
                             'when in distributed mode. The default is '
                             'this (python) runner')

    parser.add_argument('--server-url', default=None,
                        help='The URL of the server you want to test. It '
                             'will override any value your provided in '
                             'the tests for the WebTest client.')

    parser.add_argument('--observer', action='append',
                        help='Callable that will receive the final results. '
                             'Only in distributed mode (runs on the broker)')

    parser.add_argument('--no-patching',
                        help='Deactivate Gevent monkey patching.',
                        action='store_true', default=False)

    parser.add_argument('--project-name', help='Project name.',
                        default='N/A')

    #
    # distributed options
    #
    parser.add_argument('-a', '--agents', help='Number of agents to use.',
                        type=int)

    parser.add_argument('--zmq-receiver', default=None,
                        help=('ZMQ socket where the runners send the events to'
                              ' (opened on the agent side).'))

    parser.add_argument('--zmq-publisher', default=DEFAULT_PUBLISHER,
                        help='ZMQ socket where the test results messages '
                             'are published.')

    parser.add_argument('--ping-broker', action='store_true', default=False,
                        help='Pings the broker to get info, display it and '
                             'exits.')

    parser.add_argument('--check-cluster', action='store_true', default=False,
                        help='Runs a test on all agents then exits.')

    parser.add_argument('--purge-broker', action='store_true', default=False,
                        help='Stops all runs on the broker and exits.')

    parser.add_argument('-b', '--broker', help='Broker endpoint',
                        default=DEFAULT_FRONTEND)

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument('--quiet', action='store_true', default=False,
                        help='Do not print any log messages.')
    parser.add_argument('--output', action='append', default=['stdout'],
                        help='The output which will get the results',
                        choices=outputs)

    parser.add_argument('--attach', help='Reattach to a distributed run',
                        action='store_true', default=False)

    parser.add_argument('--detach', help='Detach immediatly the current '
                                         'distributed run',
                        action='store_true', default=False)

    # Adds the per-output and per-runner options.
    add_options(RUNNERS, parser, fmt='--{name}-{option}')
    add_options(output_list(), parser, fmt='--output-{name}-{option}')

    args = parser.parse_args(sysargs)
    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=['loads'])
        if 'fqn' in config['loads']:
            config_args += [config['loads']['fqn']]
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and 'stdout' in args.output:
        args.output.remove('stdout')

    return args, parser
Exemple #2
0
 def test_register_multiple_times(self):
     register_output(FakeOutput)
     register_output(FakeOutput)
     self.assertTrue(FakeOutput in output_list())
     self.assertEquals(len(output_list()), 1)
Exemple #3
0
def _parse(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Runs a load test.')
    parser.add_argument('fqn',
                        help='Fully Qualified Name of the test',
                        nargs='?')

    parser.add_argument('--config',
                        help='Configuration file to read',
                        type=str,
                        default=None)

    parser.add_argument('-u',
                        '--users',
                        help='Number of virtual users',
                        type=str,
                        default='1')

    parser.add_argument('--test-dir',
                        help='Directory to run the test from',
                        type=str,
                        default=None)

    parser.add_argument('--python-dep',
                        help='Python (PyPI) dependencies '
                        'to install',
                        action='append',
                        default=[])

    parser.add_argument('--include-file',
                        help='File(s) to include (needed for the test) '
                        '- glob-style',
                        action='append',
                        default=[])

    parser.add_argument('--ssh',
                        help='SSH tunnel - e.g. user@server:port',
                        type=str,
                        default=None)

    # loads works with hits or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--hits',
                       help='Number of hits per user',
                       type=str,
                       default=None)
    group.add_argument('-d',
                       '--duration',
                       help='Duration of the test (s)',
                       type=int,
                       default=None)

    parser.add_argument('--version',
                        action='store_true',
                        default=False,
                        help='Displays Loads version and exits.')

    parser.add_argument('--test-runner',
                        default=None,
                        help='The path to binary to use as the test runner '
                        'when in distributed mode. The default is '
                        'this (python) runner')

    parser.add_argument('--server-url',
                        default=None,
                        help='The URL of the server you want to test. It '
                        'will override any value your provided in '
                        'the tests for the WebTest client.')

    parser.add_argument('--observer',
                        action='append',
                        choices=[observer.name for observer in observers],
                        help='Callable that will receive the final results. '
                        'Only in distributed mode (runs on the broker)')

    #
    # Loading observers options
    #
    for observer in observers:
        prefix = '--observer-%s-' % observer.name
        for option in observer.options:
            name = prefix + option['name']
            parser.add_argument(name,
                                help=option.get('help'),
                                default=option.get('default'),
                                type=option.get('type'),
                                action=option.get('action'))

    parser.add_argument('--no-patching',
                        help='Deactivate Gevent monkey patching.',
                        action='store_true',
                        default=False)

    parser.add_argument('--project-name', help='Project name.', default='N/A')

    #
    # distributed options
    #
    parser.add_argument('-a',
                        '--agents',
                        help='Number of agents to use.',
                        type=int)

    parser.add_argument('--zmq-receiver',
                        default=None,
                        help=('ZMQ socket where the runners send the events to'
                              ' (opened on the agent side).'))

    parser.add_argument('--zmq-publisher',
                        default=DEFAULT_PUBLISHER,
                        help='ZMQ socket where the test results messages '
                        'are published.')

    parser.add_argument('--ping-broker',
                        action='store_true',
                        default=False,
                        help='Pings the broker to get info, display it and '
                        'exits.')

    parser.add_argument('--check-cluster',
                        action='store_true',
                        default=False,
                        help='Runs a test on all agents then exits.')

    parser.add_argument('--purge-broker',
                        action='store_true',
                        default=False,
                        help='Stops all runs on the broker and exits.')

    parser.add_argument('-b',
                        '--broker',
                        help='Broker endpoint',
                        default=DEFAULT_FRONTEND)

    parser.add_argument('--user-id',
                        help='Name of the user who runs the test',
                        type=str,
                        default='undefined')

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument('--batched',
                        action='store_true',
                        default=False,
                        help='Batch results in distributed mode')

    parser.add_argument('--quiet',
                        action='store_true',
                        default=False,
                        help='Do not print any log messages.')
    parser.add_argument('--output',
                        action='append',
                        default=['stdout'],
                        help='The output which will get the results',
                        choices=outputs)

    parser.add_argument('--attach',
                        help='Reattach to a distributed run',
                        action='store_true',
                        default=False)

    parser.add_argument('--detach',
                        help='Detach immediatly the current '
                        'distributed run',
                        action='store_true',
                        default=False)

    # Adds the per-output and per-runner options.
    add_options(RUNNERS, parser, fmt='--{name}-{option}')
    add_options(output_list(), parser, fmt='--output-{name}-{option}')

    args = parser.parse_args(sysargs)
    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=['loads'])
        if 'fqn' in config['loads']:
            config_args += [config['loads']['fqn']]
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and 'stdout' in args.output:
        args.output.remove('stdout')

    return args, parser
Exemple #4
0
 def test_register_item_works(self):
     register_output(FakeOutput)
     self.assertTrue(FakeOutput in output_list())
Exemple #5
0
def _parse(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description="Runs a load test.")
    parser.add_argument("fqn", help="Fully Qualified Name of the test", nargs="?")

    parser.add_argument("--config", help="Configuration file to read", type=str, default=None)

    parser.add_argument("-u", "--users", help="Number of virtual users", type=str, default="1")

    parser.add_argument("--test-dir", help="Directory to run the test from", type=str, default=None)

    parser.add_argument("--python-dep", help="Python (PyPI) dependencies " "to install", action="append", default=[])

    parser.add_argument(
        "--include-file", help="File(s) to include (needed for the test) " "- glob-style", action="append", default=[]
    )

    parser.add_argument("--ssh", help="SSH tunnel - e.g. user@server:port", type=str, default=None)

    # loads works with hits or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--hits", help="Number of hits per user", type=str, default=None)
    group.add_argument("-d", "--duration", help="Duration of the test (s)", type=int, default=None)

    parser.add_argument("--version", action="store_true", default=False, help="Displays Loads version and exits.")

    parser.add_argument(
        "--test-runner",
        default=None,
        help="The path to binary to use as the test runner "
        "when in distributed mode. The default is "
        "this (python) runner",
    )

    parser.add_argument(
        "--server-url",
        default=None,
        help="The URL of the server you want to test. It "
        "will override any value your provided in "
        "the tests for the WebTest client.",
    )

    parser.add_argument(
        "--observer",
        action="append",
        choices=[observer.name for observer in observers],
        help="Callable that will receive the final results. " "Only in distributed mode (runs on the broker)",
    )

    #
    # Loading observers options
    #
    for observer in observers:
        prefix = "--observer-%s-" % observer.name
        for option in observer.options:
            name = prefix + option["name"]
            parser.add_argument(
                name,
                help=option.get("help"),
                default=option.get("default"),
                type=option.get("type"),
                action=option.get("action"),
            )

    parser.add_argument("--no-patching", help="Deactivate Gevent monkey patching.", action="store_true", default=False)

    parser.add_argument("--project-name", help="Project name.", default="N/A")

    #
    # distributed options
    #
    parser.add_argument("-a", "--agents", help="Number of agents to use.", type=int)

    parser.add_argument(
        "--zmq-receiver",
        default=None,
        help=("ZMQ socket where the runners send the events to" " (opened on the agent side)."),
    )

    parser.add_argument(
        "--zmq-publisher",
        default=DEFAULT_PUBLISHER,
        help="ZMQ socket where the test results messages " "are published.",
    )

    parser.add_argument(
        "--ping-broker",
        action="store_true",
        default=False,
        help="Pings the broker to get info, display it and " "exits.",
    )

    parser.add_argument(
        "--check-cluster", action="store_true", default=False, help="Runs a test on all agents then exits."
    )

    parser.add_argument(
        "--purge-broker", action="store_true", default=False, help="Stops all runs on the broker and exits."
    )

    parser.add_argument("-b", "--broker", help="Broker endpoint", default=DEFAULT_FRONTEND)

    parser.add_argument("--user-id", help="Name of the user who runs the test", type=str, default="undefined")

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument("--batched", action="store_true", default=False, help="Batch results in distributed mode")

    parser.add_argument("--quiet", action="store_true", default=False, help="Do not print any log messages.")
    parser.add_argument(
        "--output", action="append", default=["stdout"], help="The output which will get the results", choices=outputs
    )

    parser.add_argument("--attach", help="Reattach to a distributed run", action="store_true", default=False)

    parser.add_argument(
        "--detach", help="Detach immediatly the current " "distributed run", action="store_true", default=False
    )

    # Adds the per-output and per-runner options.
    add_options(RUNNERS, parser, fmt="--{name}-{option}")
    add_options(output_list(), parser, fmt="--output-{name}-{option}")

    args = parser.parse_args(sysargs)
    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=["loads"])
        if "fqn" in config["loads"]:
            config_args += [config["loads"]["fqn"]]
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and "stdout" in args.output:
        args.output.remove("stdout")

    return args, parser
Exemple #6
0
def main(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Runs a load test.')
    parser.add_argument('fqn', help='Fully Qualified Name of the test',
                        nargs='?')

    parser.add_argument('--config', help='Configuration file to read',
                        type=str, default=None)

    parser.add_argument('-u', '--users', help='Number of virtual users',
                        type=str, default='1')

    parser.add_argument('--test-dir', help='Directory to run the test from',
                        type=str, default=None)

    parser.add_argument('--python-dep', help='Python (PyPI) dependencies '
                                             'to install',
                        action='append', default=[])

    parser.add_argument('--include-file',
                        help='File(s) to include (needed for the test) '
                             '- glob-style',
                        action='append', default=[])

    # loads works with hits or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--hits', help='Number of hits per user',
                       type=str, default=None)
    group.add_argument('-d', '--duration', help='Duration of the test (s)',
                       type=int, default=None)

    parser.add_argument('--version', action='store_true', default=False,
                        help='Displays Loads version and exits.')

    parser.add_argument('--test-runner', default=None,
                        help='The path to binary to use as the test runner '
                             'when in distributed mode. The default is '
                             'this (python) runner')

    parser.add_argument('--server-url', default=None,
                        help='The URL of the server you want to test. It '
                             'will override any value your provided in '
                             'the tests for the WebTest client.')

    parser.add_argument('--observer', action='append',
                        help='Callable that will receive the final results. '
                             'Only in distributed mode (runs on the broker)')

    parser.add_argument('--no-patching',
                        help='Deactivate Gevent monkey patching.',
                        action='store_true', default=False)

    #
    # distributed options
    #
    parser.add_argument('-a', '--agents', help='Number of agents to use.',
                        type=int)

    parser.add_argument('--zmq-receiver', default=None,
                        help=('ZMQ socket where the runners send the events to'
                              ' (opened on the agent side).'))

    parser.add_argument('--zmq-publisher', default=DEFAULT_PUBLISHER,
                        help='ZMQ socket where the test results messages '
                             'are published.')

    parser.add_argument('--ping-broker', action='store_true', default=False,
                        help='Pings the broker to get info, display it and '
                             'exits.')

    parser.add_argument('--check-cluster', action='store_true', default=False,
                        help='Runs a test on all agents then exits.')

    parser.add_argument('--purge-broker', action='store_true', default=False,
                        help='Stops all runs on the broker and exits.')

    parser.add_argument('-b', '--broker', help='Broker endpoint',
                        default=DEFAULT_FRONTEND)

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument('--quiet', action='store_true', default=False,
                        help='Do not print any log messages.')
    parser.add_argument('--output', action='append', default=['stdout'],
                        help='The output which will get the results',
                        choices=outputs)

    parser.add_argument('--attach', help='Reattach to a distributed run',
                        action='store_true', default=False)

    parser.add_argument('--detach', help='Detach immediatly the current '
                                         'distributed run',
                        action='store_true', default=False)

    # Adds the per-output and per-runner options.
    add_options(RUNNERS, parser, fmt='--{name}-{option}')
    add_options(output_list(), parser, fmt='--output-{name}-{option}')

    args = parser.parse_args(sysargs)

    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=['loads'])
        if 'fqn' in config['loads']:
            config_args += [config['loads']['fqn']]
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and 'stdout' in args.output:
        args.output.remove('stdout')

    # loggers setting
    wslogger = logging.getLogger('ws4py')
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    wslogger.addHandler(ch)
    set_logger()

    if args.version:
        print(__version__)
        sys.exit(0)

    if args.ping_broker:
        client = Client(args.broker)
        res = client.ping()
        print('Broker running on pid %d' % res['pid'])
        print('%d agents registered' % len(res['agents']))
        print('endpoints:')
        for name, location in res['endpoints'].items():
            print('  - %s: %s' % (name, location))

        runs = client.list_runs()
        if len(runs) == 0:
            print('Nothing is running right now.')
        else:
            print('We have %d run(s) right now:' % len(runs))
            for run_id, agents in runs.items():
                print('  - %s with %d agent(s)' % (run_id, len(agents)))
        sys.exit(0)

    if args.purge_broker:
        client = Client(args.broker)
        runs = client.list_runs()
        if len(runs) == 0:
            print('Nothing to purge.')
        else:
            print('We have %d run(s) right now:' % len(runs))

            for run_id, workers in runs.items():
                print('Purging %s...' % run_id)
                client.stop_run(run_id)

            print('Purged.')

        sys.exit(0)

    if args.check_cluster:
        args.fqn = 'loads.examples.test_blog.TestWebSite.test_health'
        client = Client(args.broker)
        res = client.ping()
        args.agents = len(res['agents'])
        args.hits = '1'
        print('Running a healt check on all %d agents' % args.agents)

    if args.fqn is None and not args.attach:
        parser.print_usage()
        sys.exit(0)

    args = dict(args._get_kwargs())
    res = run(args)
    return res
Exemple #7
0
def main(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Runs a load test.')
    parser.add_argument('fqn',
                        help='Fully Qualified Name of the test',
                        nargs='?')

    parser.add_argument('--config',
                        help='Configuration file to read',
                        type=str,
                        default=None)

    parser.add_argument('-u',
                        '--users',
                        help='Number of virtual users',
                        type=str,
                        default='1')

    parser.add_argument('--test-dir',
                        help='Directory to run the test from',
                        type=str,
                        default=None)

    parser.add_argument('--python-dep',
                        help='Python (PyPI) dependencies '
                        'to install',
                        action='append',
                        default=[])

    parser.add_argument('--include-file',
                        help='File(s) to include (needed for the test) '
                        '- glob-style',
                        action='append',
                        default=[])

    # loads works with hits or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--hits',
                       help='Number of hits per user',
                       type=str,
                       default=None)
    group.add_argument('-d',
                       '--duration',
                       help='Duration of the test (s)',
                       type=int,
                       default=None)

    parser.add_argument('--version',
                        action='store_true',
                        default=False,
                        help='Displays Loads version and exits.')

    parser.add_argument('--test-runner',
                        default=None,
                        help='The path to binary to use as the test runner '
                        'when in distributed mode. The default is '
                        'this (python) runner')

    parser.add_argument('--server-url',
                        default=None,
                        help='The URL of the server you want to test. It '
                        'will override any value your provided in '
                        'the tests for the WebTest client.')

    parser.add_argument('--observer',
                        action='append',
                        help='Callable that will receive the final results. '
                        'Only in distributed mode (runs on the broker)')

    parser.add_argument('--no-patching',
                        help='Deactivate Gevent monkey patching.',
                        action='store_true',
                        default=False)

    #
    # distributed options
    #
    parser.add_argument('-a',
                        '--agents',
                        help='Number of agents to use.',
                        type=int)

    parser.add_argument('--zmq-receiver',
                        default=None,
                        help=('ZMQ socket where the runners send the events to'
                              ' (opened on the agent side).'))

    parser.add_argument('--zmq-publisher',
                        default=DEFAULT_PUBLISHER,
                        help='ZMQ socket where the test results messages '
                        'are published.')

    parser.add_argument('--ping-broker',
                        action='store_true',
                        default=False,
                        help='Pings the broker to get info, display it and '
                        'exits.')

    parser.add_argument('--check-cluster',
                        action='store_true',
                        default=False,
                        help='Runs a test on all agents then exits.')

    parser.add_argument('--purge-broker',
                        action='store_true',
                        default=False,
                        help='Stops all runs on the broker and exits.')

    parser.add_argument('-b',
                        '--broker',
                        help='Broker endpoint',
                        default=DEFAULT_FRONTEND)

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument('--quiet',
                        action='store_true',
                        default=False,
                        help='Do not print any log messages.')
    parser.add_argument('--output',
                        action='append',
                        default=['stdout'],
                        help='The output which will get the results',
                        choices=outputs)

    parser.add_argument('--attach',
                        help='Reattach to a distributed run',
                        action='store_true',
                        default=False)

    parser.add_argument('--detach',
                        help='Detach immediatly the current '
                        'distributed run',
                        action='store_true',
                        default=False)

    # Adds the per-output and per-runner options.
    add_options(RUNNERS, parser, fmt='--{name}-{option}')
    add_options(output_list(), parser, fmt='--output-{name}-{option}')

    args = parser.parse_args(sysargs)

    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=['loads'])
        if 'fqn' in config['loads']:
            config_args += [config['loads']['fqn']]
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and 'stdout' in args.output:
        args.output.remove('stdout')

    # loggers setting
    wslogger = logging.getLogger('ws4py')
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    wslogger.addHandler(ch)
    set_logger()

    if args.version:
        print(__version__)
        sys.exit(0)

    if args.ping_broker:
        client = Client(args.broker)
        res = client.ping()
        print('Broker running on pid %d' % res['pid'])
        print('%d agents registered' % len(res['agents']))
        print('endpoints:')
        for name, location in res['endpoints'].items():
            print('  - %s: %s' % (name, location))

        runs = client.list_runs()
        if len(runs) == 0:
            print('Nothing is running right now.')
        else:
            print('We have %d run(s) right now:' % len(runs))
            for run_id, agents in runs.items():
                print('  - %s with %d agent(s)' % (run_id, len(agents)))
        sys.exit(0)

    if args.purge_broker:
        client = Client(args.broker)
        runs = client.list_runs()
        if len(runs) == 0:
            print('Nothing to purge.')
        else:
            print('We have %d run(s) right now:' % len(runs))

            for run_id, workers in runs.items():
                print('Purging %s...' % run_id)
                client.stop_run(run_id)

            print('Purged.')

        sys.exit(0)

    if args.check_cluster:
        args.fqn = 'loads.examples.test_blog.TestWebSite.test_health'
        client = Client(args.broker)
        res = client.ping()
        args.agents = len(res['agents'])
        args.hits = '1'
        print('Running a healt check on all %d agents' % args.agents)

    if args.fqn is None and not args.attach:
        parser.print_usage()
        sys.exit(0)

    args = dict(args._get_kwargs())
    res = run(args)
    return res
Exemple #8
0
def main(sysargs=None):
    if sysargs is None:
        sysargs = sys.argv[1:]

    parser = argparse.ArgumentParser(description='Runs a load test.')
    parser.add_argument('fqn', help='Fully qualified name of the test',
                        nargs='?')

    parser.add_argument('--config', help='Configuration file to read',
                        type=str, default=None)

    parser.add_argument('-u', '--users', help='Number of virtual users',
                        type=str, default='1')

    # loads works with cycles or duration
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-c', '--cycles', help='Number of cycles per users',
                       type=str, default=None)
    group.add_argument('-d', '--duration', help='Duration of the test (s)',
                       type=int, default=None)

    parser.add_argument('--version', action='store_true', default=False,
                        help='Displays Loads version and exits.')

    parser.add_argument('-a', '--agents', help='Number of agents to use',
                        type=int)

    parser.add_argument('-b', '--broker', help='Broker endpoint',
                        default=DEFAULT_FRONTEND)

    parser.add_argument('--test-runner', default=None,
                        help='The path to binary to use as the test runner '
                             'when in distributed mode. The default is '
                             'this runner')

    parser.add_argument('--server-url', default=None,
                        help='The URL of the server you want to test. It '
                             'will override any value your provided in '
                             'the tests for the WebTest client.')

    parser.add_argument('--zmq-receiver', default=DEFAULT_RECEIVER,
                        help='Socket where the agents send the results to.')

    parser.add_argument('--zmq-publisher', default=DEFAULT_PUBLISHER,
                        help='Socket where the results are published.')

    outputs = [st.name for st in output_list()]
    outputs.sort()

    parser.add_argument('--quiet', action='store_true', default=False)
    parser.add_argument('--output', action='append', default=['stdout'],
                        help='The output used to display the results',
                        choices=outputs)

    parser.add_argument('--aws-image-id', help='Amazon Server Id', type=str,
                        default='ami-be77e08e')
    parser.add_argument('--aws-access-key', help='Amazon Access Key',
                        type=str, default=os.environ.get('ACCESS_KEY'))
    parser.add_argument('--aws-secret-key', help='Amazon Secret Key',
                        type=str, default=os.environ.get('SECRET_KEY'))
    parser.add_argument('--aws-ssh-user', help='Amazon User',
                        type=str, default='ubuntu')
    parser.add_argument('--aws-ssh-key', help='Amazon SSH Key file',
                        type=str, default='ubuntu')
    parser.add_argument('--aws', help='Running on AWS?', action='store_true',
                        default=False)
    parser.add_argument('--aws-python-deps', help='Python deps to install',
                        action='append', default=[])
    parser.add_argument('--aws-system-deps', help='System deps to install',
                        action='append', default=[])
    parser.add_argument('--aws-test-dir', help='Test dir to embark',
                        default=None)

    # per-output options
    for output in output_list():
        for option, value in output.options.items():
            help, type_, default, cli = value
            if not cli:
                continue

            kw = {'help': help, 'type': type_}
            if default is not None:
                kw['default'] = default

            parser.add_argument('--output-%s-%s' % (output.name, option),
                                **kw)

    args = parser.parse_args(sysargs)

    if args.config is not None:
        # second pass !
        config = Config(args.config)
        config_args = config.scan_args(parser, strip_prefixes=['loads'])
        args = parser.parse_args(args=sysargs + config_args)

    if args.quiet and 'stdout' in args.output:
        args.output.remove('stdout')

    # loggers setting
    wslogger = logging.getLogger('ws4py')
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    wslogger.addHandler(ch)
    set_logger()

    if args.version:
        print(__version__)
        sys.exit(0)

    if args.fqn is None:
        parser.print_usage()
        sys.exit(0)

    # deploy on amazon
    if args.aws:
        try_import('paramiko', 'boto')

        from loads.deploy import aws_deploy
        master, master_id = aws_deploy(args.aws_access_key,
                                       args.aws_secret_key,
                                       args.aws_ssh_user,
                                       args.aws_ssh_key,
                                       args.aws_image_id,
                                       args.aws_python_deps,
                                       args.aws_system_deps,
                                       args.aws_test_dir)
        # XXX
        args.broker = 'tcp://%s:5553' % master['host']
        args.zmq_publisher = 'tcp://%s:5554' % master['host']
    else:
        master_id = None

    try:
        args = dict(args._get_kwargs())
        res = run(args)
        return res
    finally:
        if master_id is not None:
            print 'Shutting down Amazon boxes'
            from loads.deploy import aws_shutdown
            aws_shutdown(args['aws_access_key'],
                         args['aws_secret_key'],
                         master_id)