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)
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()
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()
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()
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()
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()
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()
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()
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()
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
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()
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()
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