From 6f7a5efee6d02e8800ec39613cdf65c07ff95882 Mon Sep 17 00:00:00 2001 From: dave00galloway Date: Tue, 3 Apr 2018 16:29:26 +0100 Subject: [PATCH 1/5] 1 - make pycharm happy --- multimechanize/utilities/run.py | 65 ++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/multimechanize/utilities/run.py b/multimechanize/utilities/run.py index f667414..99d25d2 100755 --- a/multimechanize/utilities/run.py +++ b/multimechanize/utilities/run.py @@ -8,12 +8,10 @@ # - import ConfigParser import multiprocessing import optparse import os -# -- NOT-NEEDED: import Queue import shutil import subprocess import sys @@ -30,17 +28,18 @@ import multimechanize.core as core import multimechanize.results as results -import multimechanize.resultswriter as resultswriter +import multimechanize.resultswriter as results_writer import multimechanize.progressbar as progressbar -from multimechanize import __version__ as VERSION +from multimechanize import __version__ as mm_version + def main(): """ - Main function to run multimechanize benchmark/performance test. + Main function to run multi-mechanize benchmark/performance test. """ usage = 'Usage: %prog [options]' - parser = optparse.OptionParser(usage=usage, version=VERSION) + parser = optparse.OptionParser(usage=usage, version=mm_version) parser.add_option('-p', '--port', dest='port', type='int', help='rpc listener port') parser.add_option('-r', '--results', dest='results_dir', help='results directory to reprocess') parser.add_option('-b', '--bind-addr', dest='bind_addr', help='rpc bind address', default='localhost') @@ -68,20 +67,21 @@ def main(): return - def run_test(project_name, cmd_opts, remote_starter=None): if remote_starter is not None: remote_starter.test_running = True remote_starter.output_dir = None - run_time, rampup, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, xml_report, user_group_configs = configure(project_name, cmd_opts) + run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, \ + xml_report, user_group_configs = configure(project_name, cmd_opts) run_localtime = time.localtime() - output_dir = '%s/%s/results/results_%s' % (cmd_opts.projects_dir, project_name, time.strftime('%Y.%m.%d_%H.%M.%S/', run_localtime)) + output_dir = '%s/%s/results/results_%s' % ( + cmd_opts.projects_dir, project_name, time.strftime('%Y.%m.%d_%H.%M.%S/', run_localtime)) # this queue is shared between all processes/threads queue = multiprocessing.Queue() - rw = resultswriter.ResultsWriter(queue, output_dir, console_logging) + rw = results_writer.ResultsWriter(queue, output_dir, console_logging) rw.daemon = True rw.start() @@ -89,10 +89,11 @@ def run_test(project_name, cmd_opts, remote_starter=None): script_prefix = os.path.normpath(script_prefix) user_groups = [] + ug_config = None for i, ug_config in enumerate(user_group_configs): script_file = os.path.join(script_prefix, ug_config.script_file) ug = core.UserGroup(queue, i, ug_config.name, ug_config.num_threads, - script_file, run_time, rampup) + script_file, run_time, ramp_up) user_groups.append(ug) for user_group in user_groups: user_group.start() @@ -112,31 +113,34 @@ def run_test(project_name, cmd_opts, remote_starter=None): while elapsed < (run_time + 1): p.update_time(elapsed) if sys.platform.startswith('win'): - print '%s transactions: %i timers: %i errors: %i\r' % (p, rw.trans_count, rw.timer_count, rw.error_count), + print '%s transactions: %i timers: %i errors: %i\r' % ( + p, rw.trans_count, rw.timer_count, rw.error_count), else: - print '%s transactions: %i timers: %i errors: %i' % (p, rw.trans_count, rw.timer_count, rw.error_count) - sys.stdout.write(chr(27) + '[A' ) + print '%s transactions: %i timers: %i errors: %i' % ( + p, rw.trans_count, rw.timer_count, rw.error_count) + sys.stdout.write(chr(27) + '[A') time.sleep(1) elapsed = time.time() - start_time print p - while [user_group for user_group in user_groups if user_group.is_alive()] != []: + while [user_group for user_group in user_groups if user_group.is_alive()]: if progress_bar: if sys.platform.startswith('win'): print 'waiting for all requests to finish...\r', else: print 'waiting for all requests to finish...\r' - sys.stdout.write(chr(27) + '[A' ) + sys.stdout.write(chr(27) + '[A') time.sleep(.5) if not sys.platform.startswith('win'): print # all agents are done running at this point - time.sleep(.2) # make sure the writer queue is flushed + time.sleep(.2) # make sure the writer queue is flushed print '\n\nanalyzing results...\n' - results.output_results(output_dir, 'results.csv', run_time, rampup, results_ts_interval, user_group_configs, xml_report) + results.output_results(output_dir, 'results.csv', run_time, ramp_up, results_ts_interval, user_group_configs, + xml_report) print 'created: %sresults.html\n' % output_dir if xml_report: print 'created: %sresults.jtl' % output_dir @@ -151,7 +155,7 @@ def run_test(project_name, cmd_opts, remote_starter=None): print 'loading results into database: %s\n' % results_database import multimechanize.resultsloader multimechanize.resultsloader.load_results_database(project_name, run_localtime, output_dir, results_database, - run_time, rampup, results_ts_interval, user_group_configs) + run_time, ramp_up, results_ts_interval, user_group_configs) if post_run_script is not None: print 'running post_run_script: %s\n' % post_run_script @@ -166,21 +170,24 @@ def run_test(project_name, cmd_opts, remote_starter=None): return - def rerun_results(project_name, cmd_opts, results_dir): output_dir = '%s/%s/results/%s/' % (cmd_opts.projects_dir, project_name, results_dir) saved_config = '%s/config.cfg' % output_dir - run_time, rampup, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, xml_report, user_group_configs = configure(project_name, cmd_opts, config_file=saved_config) + run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, \ + xml_report, user_group_configs = configure(project_name, cmd_opts, config_file=saved_config) print '\n\nanalyzing results...\n' - results.output_results(output_dir, 'results.csv', run_time, rampup, results_ts_interval, user_group_configs, xml_report) + results.output_results(output_dir, 'results.csv', run_time, ramp_up, results_ts_interval, user_group_configs, + xml_report) print 'created: %sresults.html\n' % output_dir if xml_report: print 'created: %sresults.jtl' % output_dir print 'created: last_results.jtl\n' - def configure(project_name, cmd_opts, config_file=None): + # noinspection PyUnusedLocal + (run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, + xml_report, user_group_configs) = (None for i in range(9)) user_group_configs = [] config = ConfigParser.ConfigParser() if config_file is None: @@ -189,7 +196,7 @@ def configure(project_name, cmd_opts, config_file=None): for section in config.sections(): if section == 'global': run_time = config.getint(section, 'run_time') - rampup = config.getint(section, 'rampup') + ramp_up = config.getint(section, 'rampup') results_ts_interval = config.getint(section, 'results_ts_interval') try: console_logging = config.getboolean(section, 'console_logging') @@ -201,12 +208,12 @@ def configure(project_name, cmd_opts, config_file=None): progress_bar = True try: results_database = config.get(section, 'results_database') - if results_database == 'None': results_database = None + results_database = None if results_database == 'None' else results_database except ConfigParser.NoOptionError: results_database = None try: post_run_script = config.get(section, 'post_run_script') - if post_run_script == 'None': post_run_script = None + post_run_script = None if post_run_script == 'None' else post_run_script except ConfigParser.NoOptionError: post_run_script = None try: @@ -220,8 +227,9 @@ def configure(project_name, cmd_opts, config_file=None): ug_config = UserGroupConfig(threads, user_group_name, script) user_group_configs.append(ug_config) - return (run_time, rampup, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, xml_report, user_group_configs) - + return ( + run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, + xml_report, user_group_configs) class UserGroupConfig(object): @@ -231,6 +239,5 @@ def __init__(self, num_threads, name, script_file): self.script_file = script_file - if __name__ == '__main__': main() From 4027ebac8d026aa7889b68456cb964e4861ebd0c Mon Sep 17 00:00:00 2001 From: dave00galloway Date: Wed, 4 Apr 2018 10:09:31 +0100 Subject: [PATCH 2/5] 1 - skip creating results for timer_name items that have no custom_timer_points. But why are there any? --- multimechanize/results.py | 214 +++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 108 deletions(-) diff --git a/multimechanize/results.py b/multimechanize/results.py index dd95693..998dada 100644 --- a/multimechanize/results.py +++ b/multimechanize/results.py @@ -9,13 +9,14 @@ import time from collections import defaultdict + import graph import reportwriter import reportwriterxml - -def output_results(results_dir, results_file, run_time, rampup, ts_interval, user_group_configs=None, xml_reports=False): +def output_results(results_dir, results_file, run_time, rampup, ts_interval, user_group_configs=None, + xml_reports=False): results = Results(results_dir + results_file, run_time) report = reportwriter.Report(results_dir) @@ -49,7 +50,7 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use report.write_line('group namethreadsscript name') for user_group_config in user_group_configs: report.write_line('%s%d%s' % - (user_group_config.name, user_group_config.num_threads, user_group_config.script_file)) + (user_group_config.name, user_group_config.num_threads, user_group_config.script_file)) report.write_line('') report.write_line('') @@ -66,20 +67,21 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use report.write_line('

Transaction Response Summary (secs)

') report.write_line('') - report.write_line('') - report.write_line('' % ( - results.total_transactions, - min(trans_timer_vals), - average(trans_timer_vals), - percentile(trans_timer_vals, 80), - percentile(trans_timer_vals, 90), - percentile(trans_timer_vals, 95), - max(trans_timer_vals), - standard_dev(trans_timer_vals), - )) + report.write_line( + '') + report.write_line( + '' % ( + results.total_transactions, + min(trans_timer_vals), + average(trans_timer_vals), + percentile(trans_timer_vals, 80), + percentile(trans_timer_vals, 90), + percentile(trans_timer_vals, 95), + max(trans_timer_vals), + standard_dev(trans_timer_vals), + )) report.write_line('
countminavg80pct90pct95pctmaxstdev
%i%.3f%.3f%.3f%.3f%.3f%.3f%.3f
countminavg80pct90pct95pctmaxstdev
%i%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') - # all transactions - interval details avg_resptime_points = {} # {intervalnumber: avg_resptime} percentile_80_resptime_points = {} # {intervalnumber: 80pct_resptime} @@ -88,13 +90,16 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use splat_series = split_series(trans_timer_points, interval_secs) report.write_line('

Interval Details (secs)

') report.write_line('') - report.write_line('') + report.write_line( + '') for i, bucket in enumerate(splat_series): interval_start = int((i + 1) * interval_secs) cnt = len(bucket) if cnt == 0: - report.write_line('' % (i + 1)) + report.write_line( + '' % ( + i + 1)) else: rate = cnt / float(interval_secs) mn = min(bucket) @@ -104,15 +109,17 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use pct_95 = percentile(bucket, 95) mx = max(bucket) stdev = standard_dev(bucket) - report.write_line('' % (i + 1, cnt, rate, mn, avg, pct_80, pct_90, pct_95, mx, stdev)) + report.write_line( + '' % ( + i + 1, cnt, rate, mn, avg, pct_80, pct_90, pct_95, mx, stdev)) avg_resptime_points[interval_start] = avg percentile_80_resptime_points[interval_start] = pct_80 percentile_90_resptime_points[interval_start] = pct_90 report.write_line('
intervalcountrateminavg80pct90pct95pctmaxstdev
intervalcountrateminavg80pct90pct95pctmaxstdev
%i00N/AN/AN/AN/AN/AN/AN/A
%i00N/AN/AN/AN/AN/AN/AN/A
%i%i%.2f%.3f%.3f%.3f%.3f%.3f%.3f%.3f
%i%i%.2f%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') - graph.resp_graph(avg_resptime_points, percentile_80_resptime_points, percentile_90_resptime_points, 'All_Transactions_response_times_intervals.png', results_dir) - + graph.resp_graph(avg_resptime_points, percentile_80_resptime_points, percentile_90_resptime_points, + 'All_Transactions_response_times_intervals.png', results_dir) report.write_line('

Graphs

') report.write_line('

Response Time: %s sec time-series

' % ts_interval) @@ -122,8 +129,6 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use report.write_line('

Throughput: 5 sec time-series

') report.write_line('') - - # all transactions - throughput throughput_points = {} # {intervalnumber: numberofrequests} interval_secs = ts_interval @@ -132,8 +137,6 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use throughput_points[int((i + 1) * interval_secs)] = (len(bucket) / interval_secs) graph.tp_graph(throughput_points, 'All_Transactions_throughput.png', results_dir) - - # custom timers for timer_name in sorted(results.uniq_timer_names): custom_timer_vals = [] @@ -145,81 +148,87 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use custom_timer_vals.append(val) except KeyError: pass - graph.resp_graph_raw(custom_timer_points, timer_name + '_response_times.png', results_dir) - - throughput_points = {} # {intervalnumber: numberofrequests} - interval_secs = ts_interval - splat_series = split_series(custom_timer_points, interval_secs) - for i, bucket in enumerate(splat_series): - throughput_points[int((i + 1) * interval_secs)] = (len(bucket) / interval_secs) - graph.tp_graph(throughput_points, timer_name + '_throughput.png', results_dir) - - report.write_line('
') - report.write_line('

Custom Timer: %s

' % timer_name) - - report.write_line('

Timer Summary (secs)

') - - report.write_line('') - report.write_line('') - report.write_line('' % ( - len(custom_timer_vals), - min(custom_timer_vals), - average(custom_timer_vals), - percentile(custom_timer_vals, 80), - percentile(custom_timer_vals, 90), - percentile(custom_timer_vals, 95), - max(custom_timer_vals), - standard_dev(custom_timer_vals) - )) - report.write_line('
countminavg80pct90pct95pctmaxstdev
%i%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') - - - # custom timers - interval details - avg_resptime_points = {} # {intervalnumber: avg_resptime} - percentile_80_resptime_points = {} # {intervalnumber: 80pct_resptime} - percentile_90_resptime_points = {} # {intervalnumber: 90pct_resptime} - interval_secs = ts_interval - splat_series = split_series(custom_timer_points, interval_secs) - report.write_line('

Interval Details (secs)

') - report.write_line('') - report.write_line('') - for i, bucket in enumerate(splat_series): - interval_start = int((i + 1) * interval_secs) - cnt = len(bucket) - - if cnt == 0: - report.write_line('' % (i + 1)) - else: - rate = cnt / float(interval_secs) - mn = min(bucket) - avg = average(bucket) - pct_80 = percentile(bucket, 80) - pct_90 = percentile(bucket, 90) - pct_95 = percentile(bucket, 95) - mx = max(bucket) - stdev = standard_dev(bucket) - - report.write_line('' % (i + 1, cnt, rate, mn, avg, pct_80, pct_90, pct_95, mx, stdev)) - - avg_resptime_points[interval_start] = avg - percentile_80_resptime_points[interval_start] = pct_80 - percentile_90_resptime_points[interval_start] = pct_90 - report.write_line('
intervalcountrateminavg80pct90pct95pctmaxstdev
%i00N/AN/AN/AN/AN/AN/AN/A
%i%i%.2f%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') - graph.resp_graph(avg_resptime_points, percentile_80_resptime_points, percentile_90_resptime_points, timer_name + '_response_times_intervals.png', results_dir) - - - report.write_line('

Graphs

') - report.write_line('

Response Time: %s sec time-series

' % ts_interval) - report.write_line('' % timer_name) - report.write_line('

Response Time: raw data (all points)

') - report.write_line('' % timer_name) - report.write_line('

Throughput: %s sec time-series

' % ts_interval) - report.write_line('' % timer_name) - - + if len(custom_timer_points) > 0: + + graph.resp_graph_raw(custom_timer_points, timer_name + '_response_times.png', results_dir) + + throughput_points = {} # {intervalnumber: numberofrequests} + interval_secs = ts_interval + splat_series = split_series(custom_timer_points, interval_secs) + for i, bucket in enumerate(splat_series): + throughput_points[int((i + 1) * interval_secs)] = (len(bucket) / interval_secs) + graph.tp_graph(throughput_points, timer_name + '_throughput.png', results_dir) + + report.write_line('
') + report.write_line('

Custom Timer: %s

' % timer_name) + + report.write_line('

Timer Summary (secs)

') + + report.write_line('') + report.write_line( + '') + report.write_line( + '' % ( + len(custom_timer_vals), + min(custom_timer_vals), + average(custom_timer_vals), + percentile(custom_timer_vals, 80), + percentile(custom_timer_vals, 90), + percentile(custom_timer_vals, 95), + max(custom_timer_vals), + standard_dev(custom_timer_vals) + )) + report.write_line('
countminavg80pct90pct95pctmaxstdev
%i%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') + + # custom timers - interval details + avg_resptime_points = {} # {intervalnumber: avg_resptime} + percentile_80_resptime_points = {} # {intervalnumber: 80pct_resptime} + percentile_90_resptime_points = {} # {intervalnumber: 90pct_resptime} + interval_secs = ts_interval + splat_series = split_series(custom_timer_points, interval_secs) + report.write_line('

Interval Details (secs)

') + report.write_line('') + report.write_line( + '') + for i, bucket in enumerate(splat_series): + interval_start = int((i + 1) * interval_secs) + cnt = len(bucket) + + if cnt == 0: + report.write_line( + '' % ( + i + 1)) + else: + rate = cnt / float(interval_secs) + mn = min(bucket) + avg = average(bucket) + pct_80 = percentile(bucket, 80) + pct_90 = percentile(bucket, 90) + pct_95 = percentile(bucket, 95) + mx = max(bucket) + stdev = standard_dev(bucket) + + report.write_line( + '' % ( + i + 1, cnt, rate, mn, avg, pct_80, pct_90, pct_95, mx, stdev)) + + avg_resptime_points[interval_start] = avg + percentile_80_resptime_points[interval_start] = pct_80 + percentile_90_resptime_points[interval_start] = pct_90 + report.write_line('
intervalcountrateminavg80pct90pct95pctmaxstdev
%i00N/AN/AN/AN/AN/AN/AN/A
%i%i%.2f%.3f%.3f%.3f%.3f%.3f%.3f%.3f
') + graph.resp_graph(avg_resptime_points, percentile_80_resptime_points, percentile_90_resptime_points, + timer_name + '_response_times_intervals.png', results_dir) + + report.write_line('

Graphs

') + report.write_line('

Response Time: %s sec time-series

' % ts_interval) + report.write_line('' % timer_name) + report.write_line('

Response Time: raw data (all points)

') + report.write_line('' % timer_name) + report.write_line('

Throughput: %s sec time-series

' % ts_interval) + report.write_line('' % timer_name) ## user group times - #for user_group_name in sorted(results.uniq_user_group_names): + # for user_group_name in sorted(results.uniq_user_group_names): # ug_timer_vals = [] # for resp_stats in results.resp_stats_list: # if resp_stats.user_group_name == user_group_name: @@ -237,8 +246,6 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use report.write_closing_html() - - class Results(object): def __init__(self, results_file_name, run_time): self.results_file_name = results_file_name @@ -255,8 +262,6 @@ def __init__(self, results_file_name, run_time): self.start_datetime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.epoch_start)) self.finish_datetime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.epoch_finish)) - - def __parse_file(self): f = open(self.results_file_name, 'rb') resp_stats_list = [] @@ -300,7 +305,6 @@ def __parse_file(self): return resp_stats_list - class ResponseStats(object): def __init__(self, request_num, elapsed_time, epoch_secs, user_group_name, trans_time, error, custom_timers): self.request_num = request_num @@ -312,7 +316,6 @@ def __init__(self, request_num, elapsed_time, epoch_secs, user_group_name, trans self.custom_timers = custom_timers - def split_series(points, interval): offset = points[0][0] maxval = int((points[-1][0] - offset) // interval) @@ -323,13 +326,11 @@ def split_series(points, interval): return series - def average(seq): avg = (float(sum(seq)) / len(seq)) return avg - def standard_dev(seq): avg = average(seq) sdsq = sum([(i - avg) ** 2 for i in seq]) @@ -340,14 +341,11 @@ def standard_dev(seq): return stdev - def percentile(seq, percentile): i = int(len(seq) * (percentile / 100.0)) seq.sort() return seq[i] - - if __name__ == '__main__': output_results('./', 'results.csv', 60, 30, 10) From bcfd77f3ac872e090315334c4a8e1e3d6550562d Mon Sep 17 00:00:00 2001 From: dave00galloway Date: Wed, 4 Apr 2018 10:34:23 +0100 Subject: [PATCH 3/5] 1 - mystery solved, the list of timer names includes timers that happened after the test run was supposed to have finished --- .gitignore | 1 + multimechanize/results.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1696b96..4f8a334 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ _build build dist .tox +/.idea \ No newline at end of file diff --git a/multimechanize/results.py b/multimechanize/results.py index 998dada..f5b9368 100644 --- a/multimechanize/results.py +++ b/multimechanize/results.py @@ -17,6 +17,7 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, user_group_configs=None, xml_reports=False): + invalid_timers = [] results = Results(results_dir + results_file, run_time) report = reportwriter.Report(results_dir) @@ -226,6 +227,8 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use report.write_line('' % timer_name) report.write_line('

Throughput: %s sec time-series

' % ts_interval) report.write_line('' % timer_name) + else: + invalid_timers.append(timer_name) ## user group times # for user_group_name in sorted(results.uniq_user_group_names): @@ -243,6 +246,12 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use # print '' report.write_line('
') + if len(invalid_timers) > 0: + report.write_line('

Invalid Timers

') + report.write_line('
    ') + for t in invalid_timers: + report.write_line('
  • ' + t + '
  • ') + report.write_line('
') report.write_closing_html() @@ -294,8 +303,8 @@ def __parse_file(self): r = ResponseStats(request_num, elapsed_time, epoch_secs, user_group_name, trans_time, error, custom_timers) - if elapsed_time < self.run_time: # drop all times that appear after the last request was sent (incomplete interval) - resp_stats_list.append(r) + # if elapsed_time < self.run_time: # drop all times that appear after the last request was sent (incomplete interval) + resp_stats_list.append(r) if error != '': self.total_errors += 1 From 17bccc61e3a62cd7aa77b9b26700ada798969867 Mon Sep 17 00:00:00 2001 From: dave00galloway Date: Wed, 4 Apr 2018 11:32:29 +0100 Subject: [PATCH 4/5] 1 - added config option allow_overrun which defaults to True --- multimechanize/results.py | 12 +++++++----- multimechanize/utilities/run.py | 16 ++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/multimechanize/results.py b/multimechanize/results.py index f5b9368..1b88f25 100644 --- a/multimechanize/results.py +++ b/multimechanize/results.py @@ -16,9 +16,9 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, user_group_configs=None, - xml_reports=False): + xml_reports=False, allow_overrun=True): invalid_timers = [] - results = Results(results_dir + results_file, run_time) + results = Results(results_dir + results_file, run_time, allow_overrun) report = reportwriter.Report(results_dir) @@ -256,7 +256,8 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use class Results(object): - def __init__(self, results_file_name, run_time): + def __init__(self, results_file_name, run_time, allow_overrun=True): + self.allow_overrun = allow_overrun self.results_file_name = results_file_name self.run_time = run_time self.total_transactions = 0 @@ -303,8 +304,9 @@ def __parse_file(self): r = ResponseStats(request_num, elapsed_time, epoch_secs, user_group_name, trans_time, error, custom_timers) - # if elapsed_time < self.run_time: # drop all times that appear after the last request was sent (incomplete interval) - resp_stats_list.append(r) + # drop all times that appear after the last request was sent (incomplete interval) unless overrun allowed + if self.allow_overrun or elapsed_time < self.run_time: + resp_stats_list.append(r) if error != '': self.total_errors += 1 diff --git a/multimechanize/utilities/run.py b/multimechanize/utilities/run.py index 99d25d2..6413be2 100755 --- a/multimechanize/utilities/run.py +++ b/multimechanize/utilities/run.py @@ -73,7 +73,7 @@ def run_test(project_name, cmd_opts, remote_starter=None): remote_starter.output_dir = None run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, \ - xml_report, user_group_configs = configure(project_name, cmd_opts) + xml_report, user_group_configs, allow_overrun = configure(project_name, cmd_opts) run_localtime = time.localtime() output_dir = '%s/%s/results/results_%s' % ( @@ -140,7 +140,7 @@ def run_test(project_name, cmd_opts, remote_starter=None): time.sleep(.2) # make sure the writer queue is flushed print '\n\nanalyzing results...\n' results.output_results(output_dir, 'results.csv', run_time, ramp_up, results_ts_interval, user_group_configs, - xml_report) + xml_report, allow_overrun) print 'created: %sresults.html\n' % output_dir if xml_report: print 'created: %sresults.jtl' % output_dir @@ -174,10 +174,10 @@ def rerun_results(project_name, cmd_opts, results_dir): output_dir = '%s/%s/results/%s/' % (cmd_opts.projects_dir, project_name, results_dir) saved_config = '%s/config.cfg' % output_dir run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, \ - xml_report, user_group_configs = configure(project_name, cmd_opts, config_file=saved_config) + xml_report, user_group_configs, allow_overrun = configure(project_name, cmd_opts, config_file=saved_config) print '\n\nanalyzing results...\n' results.output_results(output_dir, 'results.csv', run_time, ramp_up, results_ts_interval, user_group_configs, - xml_report) + xml_report, allow_overrun) print 'created: %sresults.html\n' % output_dir if xml_report: print 'created: %sresults.jtl' % output_dir @@ -187,7 +187,7 @@ def rerun_results(project_name, cmd_opts, results_dir): def configure(project_name, cmd_opts, config_file=None): # noinspection PyUnusedLocal (run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, - xml_report, user_group_configs) = (None for i in range(9)) + xml_report, user_group_configs, allow_overrun) = (None for i in range(10)) user_group_configs = [] config = ConfigParser.ConfigParser() if config_file is None: @@ -220,6 +220,10 @@ def configure(project_name, cmd_opts, config_file=None): xml_report = config.getboolean(section, 'xml_report') except ConfigParser.NoOptionError: xml_report = False + try: + allow_overrun = config.getboolean(section, 'allow_overrun') + except ConfigParser.NoOptionError: + allow_overrun = True else: threads = config.getint(section, 'threads') script = config.get(section, 'script') @@ -229,7 +233,7 @@ def configure(project_name, cmd_opts, config_file=None): return ( run_time, ramp_up, results_ts_interval, console_logging, progress_bar, results_database, post_run_script, - xml_report, user_group_configs) + xml_report, user_group_configs, allow_overrun) class UserGroupConfig(object): From d459b4ca7699864df1997d81ff8089393c841c19 Mon Sep 17 00:00:00 2001 From: dave00galloway Date: Wed, 4 Apr 2018 11:43:09 +0100 Subject: [PATCH 5/5] 1 - updated .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4f8a334..9864ead 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ _build build dist .tox -/.idea \ No newline at end of file +/.idea +*.log \ No newline at end of file