Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Scripts/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pip installs these scripts without including
if __name__=="__main__":
which is bad. Copy these files to PYTHON_DIR\Scripts\
10 changes: 10 additions & 0 deletions Scripts/multimech-gridgui-script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!c:\python27\python.exe
# EASY-INSTALL-ENTRY-SCRIPT: 'multi-mechanize==1.2.0.1','console_scripts','multimech-gridgui'
__requires__ = 'multi-mechanize==1.2.0.1'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
sys.exit(
load_entry_point('multi-mechanize==1.2.0.1', 'console_scripts', 'multimech-gridgui')()
)
10 changes: 10 additions & 0 deletions Scripts/multimech-newproject-script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!c:\python27\python.exe
# EASY-INSTALL-ENTRY-SCRIPT: 'multi-mechanize==1.2.0.1','console_scripts','multimech-newproject'
__requires__ = 'multi-mechanize==1.2.0.1'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
sys.exit(
load_entry_point('multi-mechanize==1.2.0.1', 'console_scripts', 'multimech-newproject')()
)
10 changes: 10 additions & 0 deletions Scripts/multimech-run-script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!c:\python27\python.exe
# EASY-INSTALL-ENTRY-SCRIPT: 'multi-mechanize==1.2.0.1','console_scripts','multimech-run'
__requires__ = 'multi-mechanize==1.2.0.1'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
sys.exit(
load_entry_point('multi-mechanize==1.2.0.1', 'console_scripts', 'multimech-run')()
)
9 changes: 6 additions & 3 deletions multimechanize/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
import time

from multimechanize.script_loader import ScriptLoader
import os.path


def init(projects_dir, project_name):
"""
Sanity check that all test scripts can be loaded.
"""
scripts_path = '%s/%s/test_scripts' % (projects_dir, project_name)
scripts_path = os.path.join(projects_dir, project_name, 'test_scripts')
if not os.path.exists(scripts_path):
sys.stderr.write('\nERROR: can not find project: %s\n\n' % project_name)
sys.exit(1)
Expand Down Expand Up @@ -95,7 +95,10 @@ def __init__(self, queue, process_num, thread_num, start_time, run_time,

def run(self):
elapsed = 0
trans = self.script_module.Transaction()
try:
trans = self.script_module.Transaction()
except TypeError, e:
trans = self.script_module.Transaction(self.process_num, self.thread_num)
trans.custom_timers = {}

# scripts have access to these vars, which can be useful for loading unique data
Expand Down
24 changes: 15 additions & 9 deletions multimechanize/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# This file is part of Multi-Mechanize | Performance Test Framework
#


import os
import time
from collections import defaultdict
import graph
Expand All @@ -16,7 +16,7 @@


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)
results = Results(os.path.join(results_dir, results_file), run_time)

report = reportwriter.Report(results_dir)

Expand Down Expand Up @@ -159,17 +159,19 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use

report.write_line('<h3>Timer Summary (secs)</h3>')

custom_len = len(custom_timer_vals)

report.write_line('<table>')
report.write_line('<tr><th>count</th><th>min</th><th>avg</th><th>80pct</th><th>90pct</th><th>95pct</th><th>max</th><th>stdev</th></tr>')
report.write_line('<tr><td>%i</td><td>%.3f</td><td>%.3f</td><td>%.3f</td><td>%.3f</td><td>%.3f</td><td>%.3f</td><td>%.3f</td></tr>' % (
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)
min(custom_timer_vals) if custom_len else 0,
average(custom_timer_vals) if custom_len else 0,
percentile(custom_timer_vals, 80) if custom_len else 0,
percentile(custom_timer_vals, 90) if custom_len else 0,
percentile(custom_timer_vals, 95) if custom_len else 0,
max(custom_timer_vals) if custom_len else 0,
standard_dev(custom_timer_vals) if custom_len else 0
))
report.write_line('</table>')

Expand Down Expand Up @@ -249,6 +251,7 @@ def __init__(self, results_file_name, run_time):
self.uniq_user_group_names = set()

self.resp_stats_list = self.__parse_file()
assert self.resp_stats_list, "no transactions completed in the specified time"

self.epoch_start = self.resp_stats_list[0].epoch_secs
self.epoch_finish = self.resp_stats_list[-1].epoch_secs
Expand Down Expand Up @@ -314,6 +317,9 @@ def __init__(self, request_num, elapsed_time, epoch_secs, user_group_name, trans


def split_series(points, interval):
if not points:
return points

offset = points[0][0]
maxval = int((points[-1][0] - offset) // interval)
vals = defaultdict(list)
Expand Down
3 changes: 2 additions & 1 deletion multimechanize/script_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ def ensure_module_valid(cls, module):
"""
problem = cls.check_module_invalid(module)
if problem:
raise InvalidScriptError, problem
sys.stderr.write("Cannot import: {0}: {1}\n"
.format(module, problem))

class ScriptLoader(object):
"""Utility class to load scripts as python modules."""
Expand Down
17 changes: 9 additions & 8 deletions multimechanize/utilities/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def run_test(project_name, cmd_opts, remote_starter=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_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 = os.path.join(cmd_opts.projects_dir, project_name, 'results',
'results_' + time.strftime('%Y.%m.%d_%H.%M.%S/', run_localtime))

# this queue is shared between all processes/threads
queue = multiprocessing.Queue()
Expand Down Expand Up @@ -123,10 +124,8 @@ def run_test(project_name, cmd_opts, remote_starter=None):

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'
print 'waiting for all requests to finish...\r',
if not sys.platform.startswith('win'):
sys.stdout.write(chr(27) + '[A' )
time.sleep(.5)

Expand Down Expand Up @@ -168,8 +167,10 @@ def run_test(project_name, cmd_opts, remote_starter=None):


def rerun_results(project_name, cmd_opts, results_dir):
output_dir = '%s/%s/results/%s/' % (cmd_opts.projects_dir, project_name, results_dir)
output_dir = os.path.join(cmd_opts.projects_dir, project_name, results_dir)

saved_config = '%s/config.cfg' % output_dir
saved_config = os.path.join(output_dir, 'config.cfg')
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)
print '\n\nanalyzing results...\n'
results.output_results(output_dir, 'results.csv', run_time, rampup, results_ts_interval, user_group_configs, xml_report)
Expand All @@ -183,8 +184,8 @@ def rerun_results(project_name, cmd_opts, results_dir):
def configure(project_name, cmd_opts, config_file=None):
user_group_configs = []
config = ConfigParser.ConfigParser()
if config_file is None:
config_file = '%s/%s/config.cfg' % (cmd_opts.projects_dir, project_name)
config_file = os.path.join(cmd_opts.projects_dir,
project_name, 'config.cfg')
config.read(config_file)
for section in config.sections():
if section == 'global':
Expand Down