예제 #1
0
def cli(ctx, output_to_json, path):
    """Prints out the current builder state
    """
    builder_data.register_context(ctx, auto_reset=False)

    output = builder_data.get(
    ) if output_to_json else builder_data.convert_builder_to_yaml(
        builder_data.get())

    if path is not None:
        builder_data.write_to_path(path, output)

    else:
        print(output)
예제 #2
0
def cli(ctx, name, jsonpath, xpath, regexp, from_, match_number, template,
        decode, extract_once, default, throw_error):
    """Defines an extractor for the most recent request
    """
    builder_data.register_context(ctx)

    if jsonpath is None and xpath is None and regexp is None:
        raise ValueError(
            "Extractor '{}' must have either jsonpath or xpath or regexp defined."
            .format(name))

    builder = builder_data.get() \
        .add(builder_data.Extractor(
            name=name,
            jsonpath=jsonpath,
            xpath=xpath,
            regexp=regexp,
            from_=from_,
            match_number=match_number,
            template=template,
            decode=decode,
            extract_once=extract_once,
            default=default,
            throw_error=throw_error)
        ) \
        .save()
예제 #3
0
def cli(ctx, get, post, put, patch, delete, option, body):
    """Adds an HTTP request to the builder queue
    """
    builder_data.register_context(ctx)

    details = None
    if details is None: details = process_details("GET", get)
    if details is None: details = process_details("POST", post)
    if details is None: details = process_details("PUT", put)
    if details is None: details = process_details("PATCH", patch)
    if details is None: details = process_details("DELETE", delete)
    if details is None: details = process_details("OPTION", option)

    if details is None:
        raise cli_exception.CliException(
            "You have not provided a proper argument to create the HTTP action from"
        )
    else:
        if body == "-":
            logging.debug("http subcommand using stdin")
            stdin_text = click.get_text_stream('stdin')
            body = stdin_text.read()

        details['body'] = body

    builder = builder_data.get() \
        .add(builder_data.HttpRequest(details)) \
        .save()
예제 #4
0
def cli(ctx, to, by, per, duration):
    """Defines a ramp-up policy for the current User Path
    """
    builder_data.register_context(ctx)

    builder = builder_data.get() \
        .add(builder_data.RampPolicy(to=to, by=by, per=per, duration=duration)) \
        .save()
예제 #5
0
def cli(ctx, duration):
    """Defines a duration policy for the current scenario
    """
    builder_data.register_context(ctx)

    builder = builder_data.get() \
        .add(builder_data.DurationPolicy(duration=duration)) \
        .save()
예제 #6
0
def cli(ctx, duration, vus):
    """Defines a constant load policy for the current User Path
    """
    builder_data.register_context(ctx)

    builder = builder_data.get() \
        .add(builder_data.ConstantPolicy(vus, duration=duration)) \
        .save()
예제 #7
0
def cli(ctx, back):
    """Rolls back the prior [back] number of builder commands
    """
    builder_data.register_context(ctx, auto_reset=False)

    data = builder_data.get()
    for i in range(0, back):
        if len(data.stack) > 0:
            data.stack.pop()

    data.save()
예제 #8
0
def cli(ctx, duration):
    """Adds a delay (think time) to the builder queue
    """
    builder_data.register_context(ctx)

    if duration is None:
        raise cli_exception.CliException(
            "You must provide a time for this delay")

    builder = builder_data.get() \
        .add(builder_data.Delay(time=duration)) \
        .save()
예제 #9
0
def cli(ctx, name, description, inside):
    """Adds a transaction to the builder queue; do before requests
    """
    builder_data.register_context(ctx)

    if name is None:
        raise cli_exception.CliException(
            "You must provide a name for this transaction")

    builder = builder_data.get() \
        .add(builder_data.Transaction(name=name, description=description, inside=inside)) \
        .save()
예제 #10
0
def cli(ctx, file):
    """Uses the local NeoLoad installation to try a project
    """
    builder_data.register_context(ctx, auto_reset=False)

    yaml_str = None
    if file is None:
        yaml_str = builder_data.convert_builder_to_yaml(builder_data.get())
    else:
        yaml_str = open(file, encoding="UTF-8").read()

    full_path = None
    tmp = tempfile.TemporaryDirectory()
    dir = tmp.name
    full_path = builder_data.write_to_path(dir, yaml_str)

    nlg_app = find_nlg_app()

    event = SubprocessEvent()

    do_it = lambda app=nlg_app, project=full_path, event=event: launch_app(app,project,event)
    action_thread = Thread(target=do_it)

    # Here we start the thread and we wait 5 seconds before the code continues to execute.
    action_thread.start()
    action_thread.join(timeout=20)

    # We send a signal that the other thread should stop.
    event.set()

    msg = "This test project is valid."

    retcode = event.proc.returncode if event.proc is not None else 0
    logging.debug("EXIT_CODE: {}".format(retcode))
    if retcode is not None and retcode != 0:
        if event.stdout is not None:
            msg = event.stdout.decode("UTF-8")
        else:
            msg = "Check console for error details."

    if retcode is None:
        event.proc.kill()

    tools.system_exit({'code': 0 if retcode is None else retcode,'message':msg})
    return
예제 #11
0
def per_interval(avg_resp_time, avg_elt_per_sec, avg_throughput_per_sec,
                 errors_per_sec, error_rate, warn, fail):
    """Create a per-interval threshold
    """

    if not (avg_resp_time or avg_elt_per_sec or avg_throughput_per_sec
            or errors_per_sec or error_rate):
        tools.system_exit({
            'code': 1,
            'message': "At least one KPY flag must be provided"
        })
        return

    if warn is None and fail is None:
        tools.system_exit({
            'code':
            1,
            'message':
            "Either one or both 'warn' and 'fail' flags must be provided"
        })
        return

    global current_name

    builder = builder_data.get() \
        .add(builder_data.SLAThreshold(
            name=current_name,
            scope="per interval",
            warn=warn,
            fail=fail,
            kpis={
                'avg-resp-time': avg_resp_time,
                'avg-elt-per-sec': avg_elt_per_sec,
                'avg-throughput-per-sec': avg_throughput_per_sec,
                'errors-per-sec': errors_per_sec,
                'error-rate': error_rate
            }
        )
        ) \
        .save()
예제 #12
0
def cli(ctx, spec, name, value, all):
    """Defines a header for one or more request
    """
    builder_data.register_context(ctx)

    if name == "-":
        name = None

    if name and not value or value and not name:
        raise ValueError("If you specify either name or value arguments, you must provide both.")

    if spec and (name or value):
        raise ValueError("If you specify a name/value spec, you must specify a '-' for the spec.")

    if spec:
        parts = spec.split("=")
        name = parts[0]
        value = "=".join(parts[1:])

    builder = builder_data.get() \
        .add(builder_data.Header(name=name, value=value, all=all)) \
        .save()
예제 #13
0
def cli(ctx, name_or_id, zone, scenario, save, just_report_last):
    """Runs whatever is in the current buffer
    """
    builder_data.register_context(ctx, auto_reset=False)

    neoload_base_cmd = "neoload " + ("--debug " if common.get_debug() else "")

    template = get_resource(__name__,
                            "resources/dist/jinja/builtin-console-summary.j2")
    if template is not None:
        logging.debug("Using template: {}".format(template))

    if not just_report_last:
        if name_or_id and save:
            config.test_setting(name_or_id)
        if zone and save:
            config.zone(zone)

        if not name_or_id:
            name_or_id = profile.get().default_test_setting
            if not name_or_id:
                tools.system_exit({
                    'code':
                    3,
                    'message':
                    "No test settings [name_or_id] provided and no default test-setting configured!"
                })
                return

        if not zone:
            zone = profile.get().default_zone

        if zone == "any":
            proc = os_return(neoload_base_cmd + " zones", status=False)
            (stdout, strerr) = proc.communicate()
            result = json.loads(stdout)
            availables = list(
                filter(
                    lambda z: any(
                        filter(lambda c: c['status'] == "AVAILABLE", z[
                            'controllers'])) and any(
                                filter(lambda lg: lg['status'] == "AVAILABLE",
                                       z['loadgenerators'])), result))
            if len(availables) > 0:
                availables = sorted(availables,
                                    key=lambda z: 0
                                    if z['type'] == "STATIC" else 1)
                zone = availables[0]['id']
                print(
                    "Because zone is 'any', the zone '{}' ({}) has been automatically selected."
                    .format(zone, availables[0]['name']))
            else:
                tools.system_exit({
                    'code':
                    3,
                    'message':
                    "There are no zones with available load generators and controllers!!!"
                })
                return

        if not zone:
            tools.system_exit({
                'code':
                3,
                'message':
                "No --zone provided and no default zone configured!"
            })
            return

        if not os_run(neoload_base_cmd + " status", status=False):
            return

        yaml_str = builder_data.convert_builder_to_yaml(builder_data.get())
        data = yaml.safe_load(yaml_str)

        if not scenario:
            scenario = data['scenarios'][0]['name']

        dir = None
        with tempfile.TemporaryDirectory() as tmp:
            dir = tmp
            builder_data.write_to_path(dir, yaml_str)

            if not os_run(
                    neoload_base_cmd +
                    " test-settings --zone {} --lgs 1 --scenario {} createorpatch {}"
                    .format(zone, scenario, name_or_id),
                    status=True):
                return

            if not os_run(
                    neoload_base_cmd + " project --path {} up".format(dir),
                    status=True):
                return

        if not os_run(neoload_base_cmd + " run".format(scenario),
                      print_stdout=True,
                      print_line_check=check_run_line):
            print("Test failed.")

    proc = os_return(neoload_base_cmd + " report --help", status=False)
    (stdout, strerr) = proc.communicate()
    outtext = stdout.decode("UTF-8")
    if proc.returncode != 0 or 'Error:' in outtext or 'failed to start' in outtext:
        print(
            "Test ran, but could not produce final (pretty) report. {}".format(
                "" if strerr is None else strerr))
    else:
        if template is not None:
            if not os_run(
                    neoload_base_cmd +
                    " report --template {} --filter '{}' cur".format(
                        template,
                        'exclude=events,slas,all_requests,ext_data,controller_points'
                    ),
                    status=True,
                    print_stdout=True):
                return