예제 #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)
예제 #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)
예제 #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)
예제 #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..")
예제 #5
0
                format(options.min_slaves))
            try:
                runners.locust_runner.wait_for_slaves(options.min_slaves,
                                                      timeout=60)
            except polling.TimeoutException, e:
                logger.error(
                    "Minimum expected slaves were never available. Expected {} ({} available)"
                    .format(options.min_slaves, e.last))
                sys.exit(1)

            runners.locust_runner.slaves_start_swarming(
                max_num_requests=options.num_requests,
                max_seconds_elapsed=options.timeout)

        else:
            runners.locust_runner = MasterLocustRunner(
                locust_classes, options, available_locustfiles=all_locustfiles)

        main_greenlet = runners.locust_runner.greenlet

    if not options.only_summary and (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 (exit code %s), bye." % code)

        events.quitting.fire()