Commit c4b9e628 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Reorganize the code and fix relative imports

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk/utils@46012 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b1c9c4db
##############################################################################
#
# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved.
# Arnaud Fontaine <arnaud.fontaine@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import argparse
import functools
class ArgumentType(object):
@classmethod
def directoryType(cls, path):
if not (os.path.isdir(path) and os.access(path, os.W_OK)):
raise argparse.ArgumentTypeError("'%s' is not a valid directory or is "\
"not writable" % path)
return path
@classmethod
def objectFromModule(cls, module_name, object_name=None,
callable_object=False):
if module_name.endswith('.py'):
module_name = module_name[:-3]
if not object_name:
object_name = module_name
import sys
sys.path.append(os.getcwd())
try:
module = __import__(module_name, globals(), locals(), [object_name], -1)
except Exception, e:
raise argparse.ArgumentTypeError("Cannot import '%s.%s': %s" % \
(module_name, object_name, str(e)))
try:
obj = getattr(module, object_name)
except AttributeError:
raise argparse.ArgumentTypeError("Could not get '%s' in '%s'" % \
(object_name, module_name))
if callable_object and not callable(obj):
raise argparse.ArgumentTypeError(
"'%s.%s' is not callable" % (module_name, object_name))
return obj
@classmethod
def strictlyPositiveIntType(cls, value):
try:
converted_value = int(value)
except ValueError:
pass
else:
if converted_value > 0:
return converted_value
raise argparse.ArgumentTypeError('expects a strictly positive integer')
@classmethod
def strictlyPositiveIntOrRangeType(cls, value):
try:
return cls.strictlyPositiveIntType(value)
except argparse.ArgumentTypeError:
try:
min_max_list = value.split(',')
except ValueError:
pass
else:
if len(min_max_list) == 2:
minimum, maximum = cls.strictlyPositiveIntType(min_max_list[0]), \
cls.strictlyPositiveIntType(min_max_list[1])
if minimum >= maximum:
raise argparse.ArgumentTypeError('%d >= %d' % (minimum, maximum))
return (minimum, maximum)
raise argparse.ArgumentTypeError(
'expects either a strictly positive integer or a range of strictly '
'positive integer separated by a comma')
@classmethod
def ERP5UrlType(cls, url):
if url[-1] == '/':
url_list = url.rsplit('/', 2)[:-1]
else:
url_list = url.rsplit('/', 1)
url_list[0] = url_list[0] + '/'
if len(url_list) != 2:
raise argparse.ArgumentTypeError("Invalid URL given")
return url_list
...@@ -34,7 +34,9 @@ import sys ...@@ -34,7 +34,9 @@ import sys
import multiprocessing import multiprocessing
import xmlrpclib import xmlrpclib
from benchmark import ArgumentType, BenchmarkProcess, ERP5BenchmarkResult from erp5.utils.benchmark.argument import ArgumentType
from erp5.utils.benchmark.process import BenchmarkProcess
from erp5.utils.benchmark.result import ERP5BenchmarkResult, CSVBenchmarkResult
class PerformanceTester(object): class PerformanceTester(object):
def __init__(self, namespace=None): def __init__(self, namespace=None):
...@@ -166,10 +168,8 @@ class PerformanceTester(object): ...@@ -166,10 +168,8 @@ class PerformanceTester(object):
def getResultClass(self): def getResultClass(self):
if self._argument_namespace.erp5_publish_url: if self._argument_namespace.erp5_publish_url:
from benchmark import ERP5BenchmarkResult
return ERP5BenchmarkResult return ERP5BenchmarkResult
else: else:
from benchmark import CSVBenchmarkResult
return CSVBenchmarkResult return CSVBenchmarkResult
def preRun(self): def preRun(self):
......
##############################################################################
#
# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved.
# Arnaud Fontaine <arnaud.fontaine@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import multiprocessing
import csv
import traceback
import os
import logging
import signal
import sys
from erp5.utils.test_browser.browser import Browser
class BenchmarkProcess(multiprocessing.Process):
def __init__(self, exit_msg_queue, result_klass, argument_namespace,
nb_users, user_index, *args, **kwargs):
self._exit_msg_queue = exit_msg_queue
self._result_klass = result_klass
self._argument_namespace = argument_namespace
self._nb_users = nb_users
self._user_index = user_index
# Initialized when running the test
self._browser = None
self._current_repeat = 1
super(BenchmarkProcess, self).__init__(*args, **kwargs)
def stopGracefully(self, *args, **kwargs):
raise StopIteration, "Interrupted by user"
def getBrowser(self, log_file):
info_list = tuple(self._argument_namespace.url) + \
tuple(self._argument_namespace.user_tuple[self._user_index])
return Browser(*info_list,
is_debug=self._argument_namespace.enable_debug,
log_file=log_file,
is_legacy_listbox=self._argument_namespace.is_legacy_listbox)
def runBenchmarkSuiteList(self, result):
for target_idx, target in enumerate(self._argument_namespace.benchmark_suite_list):
self._logger.debug("EXECUTE: %s" % target)
result.enterSuite(target.__name__)
try:
target(result, self._browser)
except:
msg = "%s: %s" % (target, traceback.format_exc())
if self._argument_namespace.enable_debug:
try:
msg += self._browser.normalized_contents
except:
pass
if self._current_repeat == 1:
self._logger.error(msg)
raise
self._logger.warning(msg)
for stat in result.getCurrentSuiteStatList():
mean = stat.mean
self._logger.info("%s: min=%.3f, mean=%.3f (+/- %.3f), max=%.3f" % \
(stat.full_label,
stat.minimum,
mean,
stat.standard_deviation,
stat.maximum))
if self._argument_namespace.max_global_average and \
mean > self._argument_namespace.max_global_average:
self._logger.info("Stopping as mean is greater than maximum "
"global average")
raise StopIteration
result.exitSuite()
result.iterationFinished()
def run(self):
result_instance = self._result_klass(self._argument_namespace,
self._nb_users,
self._user_index)
self._logger = result_instance.getLogger()
if self._argument_namespace.repeat != -1:
signal.signal(signal.SIGTERM, self.stopGracefully)
exit_status = 0
exit_msg = None
try:
with result_instance as result:
self._browser = self.getBrowser(result_instance.log_file)
while self._current_repeat != (self._argument_namespace.repeat + 1):
self._logger.info("Iteration: %d" % self._current_repeat)
self.runBenchmarkSuiteList(result)
self._current_repeat += 1
if self._current_repeat == 100:
result.flush()
except StopIteration, e:
exit_msg = str(e)
exit_status = 1
except BaseException, e:
exit_msg = e
exit_status = 2
self._exit_msg_queue.put(exit_msg)
sys.exit(exit_status)
...@@ -63,7 +63,7 @@ def parseArguments(): ...@@ -63,7 +63,7 @@ def parseArguments():
import csv import csv
from benchmark import BenchmarkResultStatistic from erp5.utils.benchmark.result import BenchmarkResultStatistic
def computeStatisticFromFilenameList(argument_namespace, filename_list): def computeStatisticFromFilenameList(argument_namespace, filename_list):
reader_list = [] reader_list = []
......
...@@ -26,98 +26,11 @@ ...@@ -26,98 +26,11 @@
# #
############################################################################## ##############################################################################
import argparse
import functools
class ArgumentType(object):
@classmethod
def directoryType(cls, path):
if not (os.path.isdir(path) and os.access(path, os.W_OK)):
raise argparse.ArgumentTypeError("'%s' is not a valid directory or is "\
"not writable" % path)
return path
@classmethod
def objectFromModule(cls, module_name, object_name=None,
callable_object=False):
if module_name.endswith('.py'):
module_name = module_name[:-3]
if not object_name:
object_name = module_name
import sys
sys.path.append(os.getcwd())
try:
module = __import__(module_name, globals(), locals(), [object_name], -1)
except Exception, e:
raise argparse.ArgumentTypeError("Cannot import '%s.%s': %s" % \
(module_name, object_name, str(e)))
try:
obj = getattr(module, object_name)
except AttributeError:
raise argparse.ArgumentTypeError("Could not get '%s' in '%s'" % \
(object_name, module_name))
if callable_object and not callable(obj):
raise argparse.ArgumentTypeError(
"'%s.%s' is not callable" % (module_name, object_name))
return obj
@classmethod
def strictlyPositiveIntType(cls, value):
try:
converted_value = int(value)
except ValueError:
pass
else:
if converted_value > 0:
return converted_value
raise argparse.ArgumentTypeError('expects a strictly positive integer')
@classmethod
def strictlyPositiveIntOrRangeType(cls, value):
try:
return cls.strictlyPositiveIntType(value)
except argparse.ArgumentTypeError:
try:
min_max_list = value.split(',')
except ValueError:
pass
else:
if len(min_max_list) == 2:
minimum, maximum = cls.strictlyPositiveIntType(min_max_list[0]), \
cls.strictlyPositiveIntType(min_max_list[1])
if minimum >= maximum:
raise argparse.ArgumentTypeError('%d >= %d' % (minimum, maximum))
return (minimum, maximum)
raise argparse.ArgumentTypeError(
'expects either a strictly positive integer or a range of strictly '
'positive integer separated by a comma')
@classmethod
def ERP5UrlType(cls, url):
if url[-1] == '/':
url_list = url.rsplit('/', 2)[:-1]
else:
url_list = url.rsplit('/', 1)
url_list[0] = url_list[0] + '/'
if len(url_list) != 2:
raise argparse.ArgumentTypeError("Invalid URL given")
return url_list
import sys import sys
import math import math
import os
import csv
import logging
class BenchmarkResultStatistic(object): class BenchmarkResultStatistic(object):
def __init__(self, suite, label): def __init__(self, suite, label):
...@@ -375,118 +288,3 @@ class ERP5BenchmarkResult(BenchmarkResult): ...@@ -375,118 +288,3 @@ class ERP5BenchmarkResult(BenchmarkResult):
result.BenchmarkResult_completed(error_message_set and 'FAIL' or 'PASS', result.BenchmarkResult_completed(error_message_set and 'FAIL' or 'PASS',
error_message_set) error_message_set)
import multiprocessing
import csv
import traceback
import os
import logging
import signal
import sys
from erp5.utils.test_browser.browser import Browser
class BenchmarkProcess(multiprocessing.Process):
def __init__(self, exit_msg_queue, result_klass, argument_namespace,
nb_users, user_index, *args, **kwargs):
self._exit_msg_queue = exit_msg_queue
self._result_klass = result_klass
self._argument_namespace = argument_namespace
self._nb_users = nb_users
self._user_index = user_index
# Initialized when running the test
self._browser = None
self._current_repeat = 1
super(BenchmarkProcess, self).__init__(*args, **kwargs)
def stopGracefully(self, *args, **kwargs):
raise StopIteration, "Interrupted by user"
def getBrowser(self, log_file):
info_list = tuple(self._argument_namespace.url) + \
tuple(self._argument_namespace.user_tuple[self._user_index])
return Browser(*info_list,
is_debug=self._argument_namespace.enable_debug,
log_file=log_file,
is_legacy_listbox=self._argument_namespace.is_legacy_listbox)
def runBenchmarkSuiteList(self, result):
for target_idx, target in enumerate(self._argument_namespace.benchmark_suite_list):
self._logger.debug("EXECUTE: %s" % target)
result.enterSuite(target.__name__)
try:
target(result, self._browser)
except:
msg = "%s: %s" % (target, traceback.format_exc())
if self._argument_namespace.enable_debug:
try:
msg += self._browser.normalized_contents
except:
pass
if self._current_repeat == 1:
self._logger.error(msg)
raise
self._logger.warning(msg)
for stat in result.getCurrentSuiteStatList():
mean = stat.mean
self._logger.info("%s: min=%.3f, mean=%.3f (+/- %.3f), max=%.3f" % \
(stat.full_label,
stat.minimum,
mean,
stat.standard_deviation,
stat.maximum))
if self._argument_namespace.max_global_average and \
mean > self._argument_namespace.max_global_average:
self._logger.info("Stopping as mean is greater than maximum "
"global average")
raise StopIteration
result.exitSuite()
result.iterationFinished()
def run(self):
result_instance = self._result_klass(self._argument_namespace,
self._nb_users,
self._user_index)
self._logger = result_instance.getLogger()
if self._argument_namespace.repeat != -1:
signal.signal(signal.SIGTERM, self.stopGracefully)
exit_status = 0
exit_msg = None
try:
with result_instance as result:
self._browser = self.getBrowser(result_instance.log_file)
while self._current_repeat != (self._argument_namespace.repeat + 1):
self._logger.info("Iteration: %d" % self._current_repeat)
self.runBenchmarkSuiteList(result)
self._current_repeat += 1
if self._current_repeat == 100:
result.flush()
except StopIteration, e:
exit_msg = str(e)
exit_status = 1
except BaseException, e:
exit_msg = e
exit_status = 2
self._exit_msg_queue.put(exit_msg)
sys.exit(exit_status)
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
# #
############################################################################## ##############################################################################
from benchmark import CSVBenchmarkResult from erp5.utils.benchmark.result import CSVBenchmarkResult
class CSVScalabilityBenchmarkResult(CSVBenchmarkResult): class CSVScalabilityBenchmarkResult(CSVBenchmarkResult):
def flush(self, partial=True): def flush(self, partial=True):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment