diff --git a/Scripts/README b/Scripts/README
new file mode 100644
index 0000000..eb774b3
--- /dev/null
+++ b/Scripts/README
@@ -0,0 +1,3 @@
+pip installs these scripts without including
+if __name__=="__main__":
+which is bad. Copy these files to PYTHON_DIR\Scripts\
diff --git a/Scripts/multimech-gridgui-script.py b/Scripts/multimech-gridgui-script.py
new file mode 100644
index 0000000..156e982
--- /dev/null
+++ b/Scripts/multimech-gridgui-script.py
@@ -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')()
+ )
diff --git a/Scripts/multimech-newproject-script.py b/Scripts/multimech-newproject-script.py
new file mode 100644
index 0000000..8368503
--- /dev/null
+++ b/Scripts/multimech-newproject-script.py
@@ -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')()
+ )
diff --git a/Scripts/multimech-run-script.py b/Scripts/multimech-run-script.py
new file mode 100644
index 0000000..987d2a1
--- /dev/null
+++ b/Scripts/multimech-run-script.py
@@ -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')()
+ )
diff --git a/multimechanize/core.py b/multimechanize/core.py
index 285c76a..f1305bf 100644
--- a/multimechanize/core.py
+++ b/multimechanize/core.py
@@ -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)
@@ -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
diff --git a/multimechanize/results.py b/multimechanize/results.py
index dd95693..bcaadd5 100644
--- a/multimechanize/results.py
+++ b/multimechanize/results.py
@@ -6,7 +6,7 @@
# This file is part of Multi-Mechanize | Performance Test Framework
#
-
+import os
import time
from collections import defaultdict
import graph
@@ -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)
@@ -159,17 +159,19 @@ def output_results(results_dir, results_file, run_time, rampup, ts_interval, use
report.write_line('
Timer Summary (secs)
')
+ custom_len = len(custom_timer_vals)
+
report.write_line('')
report.write_line('| count | min | avg | 80pct | 90pct | 95pct | max | stdev |
')
report.write_line('| %i | %.3f | %.3f | %.3f | %.3f | %.3f | %.3f | %.3f |
' % (
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('
')
@@ -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
@@ -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)
diff --git a/multimechanize/script_loader.py b/multimechanize/script_loader.py
index 105f79b..5d8907a 100644
--- a/multimechanize/script_loader.py
+++ b/multimechanize/script_loader.py
@@ -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."""
diff --git a/multimechanize/utilities/run.py b/multimechanize/utilities/run.py
index f667414..e84645b 100755
--- a/multimechanize/utilities/run.py
+++ b/multimechanize/utilities/run.py
@@ -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()
@@ -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)
@@ -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)
@@ -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':