Esempio n. 1
0
def main():
    parser, options, arguments = parse_options()

    # setup logging
    setup_logging(options.loglevel, options.logfile)
    logger = logging.getLogger(__name__)

    if options.show_version:
        print "Locust %s" % (version, )
        sys.exit(0)

    locustfile = find_locustfile(options.locustfile)
    if not locustfile:
        logger.error(
            "Could not find any locustfile! See --help for available options.")
        sys.exit(1)

    docstring, locusts = load_locustfile(locustfile)

    if options.list_commands:
        print "Available Locusts:"
        for name in locusts:
            print "    " + name
        sys.exit(0)

    if not locusts:
        logger.error("No Locust class found!")
        sys.exit(1)

    # make sure specified Locust exists
    if arguments:
        missing = set(arguments) - set(locusts.keys())
        if missing:
            logger.error("Unknown Locust(s): %s\n" % (", ".join(missing)))
            sys.exit(1)
        else:
            names = set(arguments) & set(locusts.keys())
            locust_classes = [locusts[n] for n in names]
    else:
        locust_classes = locusts.values()

    if options.show_task_ratio:
        console_logger.info("\n Task ratio per locust class")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes)
        console_logger.info("\n Total task ratio")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes, total=True)
        sys.exit(0)
    if options.show_task_ratio_json:
        from json import dumps
        task_data = {
            "per_class": get_task_ratio_dict(locust_classes),
            "total": get_task_ratio_dict(locust_classes, total=True)
        }
        console_logger.info(dumps(task_data))
        sys.exit(0)

    # if --master is set, make sure --no-web isn't set
    if options.master and options.no_web:
        logger.error(
            "Locust can not run distributed with the web interface disabled (do not use --no-web and --master together)"
        )
        sys.exit(0)

    if not options.no_web and not options.slave:
        # spawn web greenlet
        logger.info("Starting web monitor on port %s" % options.port)
        main_greenlet = gevent.spawn(web.start, locust_classes,
                                     options.hatch_rate, options.num_clients,
                                     options.num_requests, options.ramp,
                                     options.port)

    if not options.master and not options.slave:
        runners.locust_runner = LocalLocustRunner(locust_classes,
                                                  options.hatch_rate,
                                                  options.num_clients,
                                                  options.num_requests,
                                                  options.host)
        # spawn client spawning/hatching greenlet
        if options.no_web:
            runners.locust_runner.start_hatching(wait=True)
            main_greenlet = runners.locust_runner.greenlet
    elif options.master:
        runners.locust_runner = MasterLocustRunner(
            locust_classes,
            options.hatch_rate,
            options.num_clients,
            num_requests=options.num_requests,
            host=options.host,
            master_host=options.master_host)
    elif options.slave:
        runners.locust_runner = SlaveLocustRunner(
            locust_classes,
            options.hatch_rate,
            options.num_clients,
            num_requests=options.num_requests,
            host=options.host,
            master_host=options.master_host)
        main_greenlet = runners.locust_runner.greenlet

    if options.print_stats or (options.no_web and not options.slave):
        # spawn stats printing greenlet
        gevent.spawn(stats_printer)

    def shutdown(code=0):
        """
        Shut down locust by firing quitting event, printing stats and exiting
        """
        logger.info("Shutting down, bye..")
        events.quitting.fire()
        print_stats(runners.locust_runner.request_stats)
        print_percentile_stats(runners.locust_runner.request_stats)
        print_error_report()
        sys.exit(code)

    # install SIGTERM handler
    def sig_term_handler():
        logger.info("Got SIGTERM signal")
        shutdown(0)

    gevent.signal(signal.SIGTERM, sig_term_handler)

    try:
        logger.info("Starting Locust %s" % version)
        main_greenlet.join()
        shutdown(0)
    except KeyboardInterrupt as e:
        shutdown(0)
Esempio n. 2
0
def main():
    parser, options, arguments = parse_options()

    # setup logging
    setup_logging(options.loglevel, options.logfile)
    logger = logging.getLogger(__name__)

    if options.show_version:
        print "Locust %s" % (version, )
        sys.exit(0)

    locustfile = find_locustfile(options.locustfile)
    if not locustfile:
        logger.error(
            "Could not find any locustfile! Ensure file ends in '.py' and see --help for available options."
        )
        sys.exit(1)

    docstring, locusts = load_locustfile(locustfile)

    if options.list_commands:
        console_logger.info("Available Locusts:")
        for name in locusts:
            console_logger.info("    " + name)
        sys.exit(0)

    if not locusts:
        logger.error("No Locust class found!")
        sys.exit(1)

    # make sure specified Locust exists
    if arguments:
        missing = set(arguments) - set(locusts.keys())
        if missing:
            logger.error("Unknown Locust(s): %s\n" % (", ".join(missing)))
            sys.exit(1)
        else:
            names = set(arguments) & set(locusts.keys())
            locust_classes = [locusts[n] for n in names]
    else:
        locust_classes = locusts.values()

    if options.show_task_ratio:
        console_logger.info("\n Task ratio per locust class")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes)
        console_logger.info("\n Total task ratio")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes, total=True)
        sys.exit(0)
    if options.show_task_ratio_json:
        from json import dumps
        task_data = {
            "per_class": get_task_ratio_dict(locust_classes),
            "total": get_task_ratio_dict(locust_classes, total=True)
        }
        console_logger.info(dumps(task_data))
        sys.exit(0)

    # if --master is set, make sure --no-web isn't set
    if options.master and options.no_web:
        logger.error(
            "Locust can not run distributed with the web interface disabled (do not use --no-web and --master together)"
        )
        sys.exit(0)

    if not options.no_web and not options.slave:
        # spawn web greenlet
        logger.info("Starting web monitor at %s:%s" %
                    (options.web_host or "*", options.port))
        main_greenlet = gevent.spawn(web.start, locust_classes, options)

    if not options.master and not options.slave:
        runners.locust_runner = LocalLocustRunner(locust_classes, options)
        # spawn client spawning/hatching greenlet
        if options.no_web:
            runners.locust_runner.start_hatching(wait=True)
            main_greenlet = runners.locust_runner.greenlet
    elif options.master:
        runners.locust_runner = MasterLocustRunner(locust_classes, options)
    elif options.slave:
        try:
            runners.locust_runner = SlaveLocustRunner(locust_classes, options)
            main_greenlet = runners.locust_runner.greenlet
        except socket.error, e:
            logger.error("Failed to connect to the Locust master: %s", e)
            sys.exit(-1)
Esempio n. 3
0
def launch(options, locusts):
    """
    Locust entrypoint, could be called for programmatical launch:
        * options - Any object which implements field access by attribute
                    Recommended to use extended locust.config.LocustConfig object
        * locusts - list of locust classes inherited from locust.core.Locust
    """
    logger = logging.getLogger(__name__)

    if options.show_version:
        console_logger.info("Locust %s", version)
        sys.exit(0)

    if options.list_commands:
        console_logger.info("Available Locusts:")
        for locust_class in locusts:
            console_logger.info("    " + locust_class.__name__)
        sys.exit(0)

    if options.show_task_ratio:
        console_logger.info("\n Task ratio per locust class")
        console_logger.info("-" * 80)
        print_task_ratio(locusts)
        console_logger.info("\n Total task ratio")
        console_logger.info("-" * 80)
        print_task_ratio(locusts, total=True)
        sys.exit(0)

    if options.show_task_ratio_json:
        from json import dumps
        task_data = {
            "per_class": get_task_ratio_dict(locusts),
            "total": get_task_ratio_dict(locusts, total=True)
        }
        console_logger.info(dumps(task_data))
        sys.exit(0)

    # Master / Slave init
    if options.slave:
        logger.info("Starting slave node. Connecting to %s:%s",
                    options.master_host, options.master_port)
        slave = SlaveLocustRunner(locusts, options)
        runners.main = slave
        main_greenlet = runners.main.greenlet
    else:
        logger.info("Starting master node")
        master = MasterLocustRunner(locusts, options)
        runners.main = master
        main_greenlet = runners.main.greenlet

    # Headful / headless init
    if options.slave:
        logger.info("Slave connected in headless mode")
    elif options.no_web and not options.slave:
        logger.info("Starting headless execution")
        runners.main.wait_for_slaves(options.expect_slaves)
        runners.main.start_hatching(options.num_clients, options.hatch_rate)
    else:
        logger.info("Starting web monitor at %s:%s", options.web_host
                    or "localhost", options.web_port)
        gevent.spawn(web.start, locusts, options)

    #### Stats, etc
    if options.print_stats and not options.slave:
        gevent.spawn(stats_printer)
    if options.csvfilebase and not options.slave:
        gevent.spawn(stats_writer, options.csvfilebase)

    def shutdown(code=0):
        """
        Shut down locust by firing quitting event, printing/writing stats and exiting
        """
        logger.info("Shutting down (exit code %s), bye." % code)

        events.quitting.fire()
        print_stats(runners.main.request_stats)
        print_percentile_stats(runners.main.request_stats)
        print_error_report()
        sys.exit(code)

    # install SIGTERM handler
    def sig_term_handler():
        logger.info("Got SIGTERM signal")
        shutdown(0)

    gevent.signal(signal.SIGTERM, sig_term_handler)

    try:
        logger.info("Starting Locust %s" % version)
        main_greenlet.join()
        code = 0
        if len(runners.main.errors):
            code = 1
        shutdown(code=code)
    except KeyboardInterrupt:
        shutdown(0)
Esempio n. 4
0
def main():
    parser, options, arguments = parse_options()
    #print "Options:", options, dir(options)
    #print "Arguments:", arguments
    #print "largs:", parser.largs
    #print "rargs:", parser.rargs

    # setup logging
    setup_logging(options.loglevel, options.logfile)
    logger = logging.getLogger(__name__)

    if options.show_version:
        print "Locust %s" % (version)
        sys.exit(0)

    locustfile = find_locustfile(options.locustfile)
    if not locustfile:
        logger.error(
            "Could not find any locustfile! See --help for available options.")
        sys.exit(1)

    docstring, locusts = load_locustfile(locustfile)

    if options.list_commands:
        print "Available Locusts:"
        for name in locusts:
            print "    " + name
        sys.exit(0)

    if not locusts:
        logger.error("No Locust class found!")
        sys.exit(1)

    # make sure specified Locust exists
    if arguments:
        missing = set(arguments) - set(locusts.keys())
        if missing:
            logger.error("Unknown Locust(s): %s\n" % (", ".join(missing)))
            sys.exit(1)
        else:
            names = set(arguments) & set(locusts.keys())
            locust_classes = [locusts[n] for n in names]
    else:
        locust_classes = locusts.values()

    if options.show_task_ratio:
        console_logger.info("\n Task ratio per locust class")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes)
        console_logger.info("\n Total task ratio")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes, total=True)
        sys.exit(0)
    if options.show_task_ratio_json:
        from json import dumps
        task_data = {
            "per_class": get_task_ratio_dict(locust_classes),
            "total": get_task_ratio_dict(locust_classes, total=True)
        }
        console_logger.info(dumps(task_data))
        sys.exit(0)

    # if --master is set, make sure --no-web isn't set
    if options.master and options.no_web:
        logger.error(
            "Locust can not run distributed with the web interface disabled (do not use --no-web and --master together)"
        )
        sys.exit(0)

    if not options.no_web and not options.slave:
        # spawn web greenlet
        logger.info("Starting web monitor on port 8089")
        main_greenlet = gevent.spawn(web.start, locust_classes,
                                     options.hatch_rate, options.num_clients,
                                     options.num_requests, options.ramp)

    # enable/disable gzip in WebLocust's HTTP client
    WebLocust.gzip = options.gzip

    if not options.master and not options.slave:
        runners.locust_runner = LocalLocustRunner(locust_classes,
                                                  options.hatch_rate,
                                                  options.num_clients,
                                                  options.num_requests,
                                                  options.host)
        # spawn client spawning/hatching greenlet
        if options.no_web:
            runners.locust_runner.start_hatching(wait=True)
            main_greenlet = runners.locust_runner.greenlet
    elif options.master:
        runners.locust_runner = MasterLocustRunner(
            locust_classes,
            options.hatch_rate,
            options.num_clients,
            num_requests=options.num_requests,
            host=options.host,
            master_host=options.master_host)
    elif options.slave:
        runners.locust_runner = SlaveLocustRunner(
            locust_classes,
            options.hatch_rate,
            options.num_clients,
            num_requests=options.num_requests,
            host=options.host,
            master_host=options.master_host)
        main_greenlet = runners.locust_runner.greenlet

    if options.ramp:
        import rampstats
        from rampstats import on_request_success, on_report_to_master, on_slave_report
        if options.slave:
            events.report_to_master += on_report_to_master
        if options.master:
            events.slave_report += on_slave_report
        else:
            events.request_success += on_request_success

    if options.print_stats or (options.no_web and not options.slave):
        # spawn stats printing greenlet
        gevent.spawn(stats_printer)

    try:
        logger.info("Starting Locust %s" % version)
        main_greenlet.join()
    except KeyboardInterrupt, e:
        events.quitting.fire()
        time.sleep(0.2)
        print_stats(runners.locust_runner.request_stats)
        print_percentile_stats(runners.locust_runner.request_stats)
        print_error_report()
        logger.info("Got KeyboardInterrupt. Exiting, bye..")
Esempio n. 5
0
def main():
    parser, options, arguments = parse_options()

    # setup logging
    setup_logging(options.loglevel, options.logfile)
    logger = logging.getLogger(__name__)

    if options.show_version:
        print "Locust %s" % (version, )
        sys.exit(0)

    if os.path.isdir(options.locustfile):
        all_locustfiles = collect_locustfiles(options.locustfile)
    else:
        locustfile = find_locustfile(options.locustfile)
        if not locustfile:
            logger.error(
                "Could not find any locustfile! Ensure file ends in '.py' and see --help for available options."
            )
            sys.exit(1)

        all_locustfiles = load_locustfile(locustfile)

    logger.info("All available locustfiles: {}".format(all_locustfiles))

    # Use the first locustfile for the default locusts
    locusts = all_locustfiles.values()[0]

    if options.list_commands:
        console_logger.info("Available Locusts:")
        for name in locusts:
            console_logger.info("    " + name)
        sys.exit(0)

    if not locusts:
        logger.error("No Locust class found!")
        sys.exit(1)

    # make sure specified Locust exists
    if arguments:
        missing = set(arguments) - set(locusts.keys())
        if missing:
            logger.error("Unknown Locust(s): %s\n" % (", ".join(missing)))
            sys.exit(1)
        else:
            names = set(arguments) & set(locusts.keys())
            locust_classes = [locusts[n] for n in names]
    else:
        locust_classes = locusts.values()

    if options.show_task_ratio:
        console_logger.info("\n Task ratio per locust class")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes)
        console_logger.info("\n Total task ratio")
        console_logger.info("-" * 80)
        print_task_ratio(locust_classes, total=True)
        sys.exit(0)
    if options.show_task_ratio_json:
        from json import dumps
        task_data = {
            "per_class": get_task_ratio_dict(locust_classes),
            "total": get_task_ratio_dict(locust_classes, total=True)
        }
        console_logger.info(dumps(task_data))
        sys.exit(0)

    if options.master and options.no_web and not options.min_slaves:
        logger.error(
            "When running --master and --no-web, you must specify --min-slaves to be available before starting to swarm"
        )
        sys.exit(1)

    if options.master and options.no_web and not (options.timeout
                                                  or options.num_requests):
        logger.error(
            "When running --master and --no-web, you must specify either --num-request or --timeout to tell the slaves when to stop running each locustfile"
        )
        sys.exit(1)

    if not options.no_web and not options.slave:
        # spawn web greenlet
        logger.info("Starting web monitor at %s:%s" %
                    (options.web_host or "*", options.port))
        main_greenlet = gevent.spawn(web.start, locust_classes, options)

    if options.slave:
        logger.info("Waiting for master to become available")
        try:
            runners.locust_runner = polling.poll(lambda: SlaveLocustRunner(
                locust_classes, options, available_locustfiles=all_locustfiles
            ),
                                                 timeout=60,
                                                 step=1,
                                                 ignore_exceptions=(
                                                     socket.error, ))

        except polling.TimeoutException, e:
            logger.error("Failed to connect to the Locust master: %s", e.last)
            sys.exit(-1)

        main_greenlet = runners.locust_runner.greenlet