Give dacapo a much needed upgrade. Move to the latest upstream version, clean up heavily the code, make it actually record performance data and performance keyvals, just like any other autotest benchmark.
In order to support this cleanup, the test_config API was slightly modified, while its doc strings were modified to comply with the current coding standards. Now it is possible to run dacapo out of the box on most systems. Signed-off-by: Lucas Meneghel Rodrigues <[email protected]> --- client/bin/test_config.py | 52 +++++++++---- client/tests/dacapo/control | 53 +++++++------ client/tests/dacapo/dacapo.py | 167 +++++++++++++++++++++-------------------- 3 files changed, 151 insertions(+), 121 deletions(-) diff --git a/client/bin/test_config.py b/client/bin/test_config.py index 6848b48..9bf6f69 100644 --- a/client/bin/test_config.py +++ b/client/bin/test_config.py @@ -1,8 +1,8 @@ """ Wrapper around ConfigParser to manage testcases configuration. -""" -__author__ = '[email protected] (Ricardo Salveti de Araujo)' +...@author [email protected] (Ricardo Salveti de Araujo) +""" from ConfigParser import ConfigParser from StringIO import StringIO @@ -13,18 +13,20 @@ from autotest_lib.client.common_lib import utils __all__ = ['config_loader'] class config_loader: - """Base class of the configuration parser""" - def __init__(self, cfg, tmpdir = '/tmp'): - """\ + """ + Base class of the configuration parser + """ + def __init__(self, cfg, tmpdir='/tmp', raise_errors=False): + """ Instantiate ConfigParser and provide the file like object that we'll use to read configuration data from. - Args: - * cfg: Where we'll get configuration data. It can be either: - * A URL containing the file - * A valid file path inside the filesystem - * A string containing configuration data - * tmpdir: Where we'll dump the temporary conf files. The default - is the /tmp directory. + @param cfg: Where we'll get configuration data. It can be either: + * A URL containing the file + * A valid file path inside the filesystem + * A string containing configuration data + @param tmpdir: Where we'll dump the temporary conf files. + @param raise_errors: Whether config value absences will raise + ValueError exceptions. """ # Base Parser self.parser = ConfigParser() @@ -54,18 +56,30 @@ class config_loader: def get(self, section, option, default=None): - """Get the value of a option. + """ + Get the value of a option. Section of the config file and the option name. You can pass a default value if the option doesn't exist. + + @param section: Configuration file section. + @param option: Option we're looking after. + @default: In case the option is not available and raise_errors is set + to False, return the default. """ if not self.parser.has_option(section, option): - return default + if raise_errors: + raise ValueError('No value for option %s. Please check your ' + 'config file "%s".' % (option, cfg)) + else: + return default + return self.parser.get(section, option) def set(self, section, option, value): - """Set an option. + """ + Set an option. This change is not persistent unless saved with 'save()'. """ @@ -75,13 +89,17 @@ class config_loader: def remove(self, section, option): - """Remove an option.""" + """ + Remove an option. + """ if self.parser.has_section(section): self.parser.remove_option(section, option) def save(self): - """Save the configuration file with all modifications""" + """ + Save the configuration file with all modifications + """ if not self.cfg: return fileobj = file(self.cfg, 'w') diff --git a/client/tests/dacapo/control b/client/tests/dacapo/control index 7c58755..960c441 100644 --- a/client/tests/dacapo/control +++ b/client/tests/dacapo/control @@ -15,57 +15,63 @@ National Science Foundation ITR Grant, CCR-0085792. dacapo_base_config = ''' [dacapo] -tarball_url = http://easynews.dl.sourceforge.net/sourceforge/dacapobench/dacapo-2006-10-MR2.jar -tarball_url_alt = http://myhost.foo.com/packages/dacapobench/dacapo-2006-10-MR2.jar -override_default_url = no -package_md5 = 35cf23b26ac1b4fb83f11445300f492f +tarball_url = http://downloads.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar +package_md5 = 3f5c11927268b567bc90629c17ec446b [global] iterations = 5 workload = large use_global = yes -[small] +[avrora] iterations = 0 workload = large -[antlr] +[batik] iterations = 0 workload = large -[bloat] +[eclipse] iterations = 0 workload = large -[chart] +[fop] iterations = 0 workload = large -[eclipse] +[h2] iterations = 0 workload = large -[fop] +[jython] iterations = 0 workload = large -[hsqldb] +[luindex] iterations = 0 workload = large -[jython] +[lusearch] iterations = 0 workload = large -[lusearch] +[pmd] iterations = 0 workload = large -[luindex] +[sunflow] iterations = 0 workload = large -[pmd] +[tomcat] +iterations = 0 +workload = large + +[tradebeans] +iterations = 0 +workload = large + +[tradesoap] iterations = 0 workload = large @@ -96,18 +102,19 @@ java_root = /usr/java/jre1.6.0_03 package_md5 = e94c47adedf329200fc975662d667307 ''' -# This shows the flexibility of our test configuration system dacapo_config = dacapo_base_config + java_config -#dacapo_config = '/tmp/dacapo.cfg' -#dacapo_config = 'http://my-host.foo.com/repository/dacapo.cfg' -# list of jvm entries inside the configuration file -jvm_list = ['ibm14-ppc64', 'ibm15-ppc64'] +# list of jvm entries inside the configuration file. 'default' means the test +# will use the jvm installed on the machine. +jvm_list = ['default'] + # list of dacapo tests that will be executed -dacapo_tests = ['antlr', 'bloat', 'chart', 'eclipse', 'fop', 'hsqldb', - 'jython', 'lusearch', 'luindex', 'pmd', 'xalan'] +dacapo_tests = ['avrora', 'batik', 'eclipse', 'fop', 'h2', 'jython', 'luindex', + 'lusearch', 'pmd', 'sunflow', 'tomcat', 'tradebeans', + 'tradesoap', 'xalan'] # No go trough the tests and jvms for jvm in jvm_list: for test in dacapo_tests: - job.run_test('dacapo', test=test, config=dacapo_config, jvm=jvm, tag = test + '-' + jvm) + t = test + '-' + jvm + job.run_test('dacapo', test=test, config=dacapo_config, jvm=jvm, tag=t) diff --git a/client/tests/dacapo/dacapo.py b/client/tests/dacapo/dacapo.py index 74d82dc..07b706a 100644 --- a/client/tests/dacapo/dacapo.py +++ b/client/tests/dacapo/dacapo.py @@ -1,104 +1,109 @@ -# Dacapo test suite wrapper -# -import os +import os, re, logging, shutil from autotest_lib.client.bin import utils, package, test from autotest_lib.client.bin.test_config import config_loader from autotest_lib.client.common_lib import error class dacapo(test.test): - version = 1 + """ + This autotest module runs the dacapo benchmark suite. + + This benchmark suite is intended as a tool for Java benchmarking by the + programming language, memory management and computer architecture + communities. It consists of a set of open source, real world applications + with non-trivial memory loads. The suite is the culmination of over five + years work at eight institutions, as part of the DaCapo research project, + which was funded by a National Science Foundation ITR Grant, CCR-0085792. + + @author: Lucas Meneghel Rodrigues ([email protected]) + @see: http://dacapobench.org/ + """ + version = 2 def set_java_environment(self, jvm, java_root): - '''\ + """ Setup java environment variables (path and classpath in order to execute a specific jvm specified by the java_root variable. java_root - Base of the java vm installation - ''' + """ if jvm.startswith('ibm'): - self.java_home = os.path.join(java_root, 'jre') + java_home = os.path.join(java_root, 'jre') else: - self.java_home = java_root - self.java_bin = os.path.join(self.java_home, 'bin') - self.java_lib = os.path.join(self.java_home, 'lib') + java_home = java_root + java_bin = os.path.join(java_home, 'bin') + java_lib = os.path.join(java_home, 'lib') os.environ['JAVA_ROOT'] = java_root - os.environ['JAVA_HOME'] = self.java_home - os.environ['JRE_HOME'] = self.java_home - os.environ['CLASSPATH'] = self.java_lib - os.environ['JAVA_BINDIR'] = self.java_bin - os.environ['PATH'] = self.java_bin + ':' + os.environ['PATH'] + os.environ['JAVA_HOME'] = java_home + os.environ['JRE_HOME'] = java_home + os.environ['CLASSPATH'] = java_lib + os.environ['JAVA_BINDIR'] = java_bin + os.environ['PATH'] = java_bin + ':' + os.environ['PATH'] - def execute(self, test = 'antlr', config = './dacapo.cfg', jvm = 'ibm14-ppc64'): - # Load the test configuration. If needed, use autotest tmpdir to write - # files. - my_config = config_loader(config, self.tmpdir) - # Directory where we will cache the dacapo jar file - # and the jvm package files - self.cachedir = os.path.join(self.bindir, 'cache') - if not os.path.isdir(self.cachedir): - os.makedirs(self.cachedir) + def run_once(self, test='antlr', config='./dacapo.cfg', jvm='default'): + cfg = config_loader(cfg=config, tmpdir=self.tmpdir, raise_errors=True) + self.test = test + cachedir = os.path.join(self.bindir, 'cache') + if not os.path.isdir(cachedir): + os.makedirs(cachedir) - # Get dacapo jar URL - # (It's possible to override the default URL that points to the - # sourceforge repository) - if my_config.get('dacapo', 'override_default_url') == 'no': - self.dacapo_url = my_config.get('dacapo', 'tarball_url') - else: - self.dacapo_url = my_config.get('dacapo', 'tarball_url_alt') - if not self.dacapo_url: - raise error.TestError('Could not read dacapo URL from conf file') - # We can cache the dacapo package file if we take some - # precautions (checking md5 sum of the downloaded file) - self.dacapo_md5 = my_config.get('dacapo', 'package_md5') - if not self.dacapo_md5: - e_msg = 'Could not read dacapo package md5sum from conf file' - raise error.TestError(e_msg) - self.dacapo_pkg = \ - utils.unmap_url_cache(self.cachedir, self.dacapo_url, - self.dacapo_md5) + dacapo_url = cfg.get('dacapo', 'tarball_url') + dacapo_md5 = cfg.get('dacapo', 'package_md5') + dacapo_pkg = utils.unmap_url_cache(cachedir, dacapo_url, dacapo_md5) - # Get jvm package URL - self.jvm_pkg_url = my_config.get(jvm, 'jvm_pkg_url') - if not self.jvm_pkg_url: - raise error.TestError('Could not read java vm URL from conf file') - # Let's cache the jvm package as well - self.jvm_pkg_md5 = my_config.get(jvm, 'package_md5') - if not self.jvm_pkg_md5: - raise error.TestError('Could not read java package_md5 from conf file') - self.jvm_pkg = \ - utils.unmap_url_cache(self.cachedir, self.jvm_pkg_url, - self.jvm_pkg_md5) + if not jvm == 'default': + # Get the jvm package + jvm_pkg_url = cfg.get(jvm, 'jvm_pkg_url') + jvm_pkg_md5 = cfg.get(jvm, 'package_md5') + jvm_pkg = utils.unmap_url_cache(cachedir, jvm_pkg_url, jvm_pkg_md5) + # Install it + package.install(jvm_pkg) + # Basic Java environment variables setup + java_root = cfg.get(jvm, 'java_root') + self.set_java_environment(jvm, java_root) - # Install the jvm pakage - package.install(self.jvm_pkg) + if cfg.get('global', 'use_global') == 'yes': + iterations = cfg.get('global', 'iterations') + workload = cfg.get('global', 'workload') + else: + iterations = cfg.get(test, 'iterations') + workload = cfg.get(test, 'workload') - # Basic Java environment variables setup - self.java_root = my_config.get(jvm, 'java_root') - if not self.java_root: - raise error.TestError('Could not read java root dir from conf file') - self.set_java_environment(jvm, self.java_root) + verbose = '-v ' + workload = '-s %s ' % workload + iterations = '-n %s ' % iterations + self.scratch = os.path.join(self.resultsdir, test) + scratch = '--scratch-directory %s ' % self.scratch + args = verbose + workload + scratch + iterations + test - # If use_global is set to 'yes', then we want to use the global - # setting instead of per test settings - if my_config.get('global', 'use_global') == 'yes': - self.iterations = my_config.get('global', 'iterations') - self.workload = my_config.get('global', 'workload') - else: - self.iterations = my_config.get(test, 'iterations') - self.workload = my_config.get(test, 'workload') + self.raw_result_file = os.path.join(self.resultsdir, + 'raw_output_%s' % self.iteration) + raw_result = open(self.raw_result_file, 'w') - self.verbose = '-v ' - self.workload = '-s %s ' % self.workload - self.iterations = '-n %s ' % self.iterations - self.scratch = '-scratch %s ' % os.path.join(self.resultsdir, test) - # Compose the arguments string - self.args = self.verbose + self.workload + self.scratch \ - + self.iterations + test - # Execute the actual test + logging.info('Running dacapo benchmark %s', test) try: - utils.system('java -jar %s %s' % (self.dacapo_pkg, self.args)) - except: - e_msg = \ - 'Test %s has failed, command line options "%s"' % (test, self.args) - raise error.TestError(e_msg) + cmd = 'java -jar %s %s' % (dacapo_pkg, args) + results = utils.run(command=cmd, stdout_tee=raw_result, + stderr_tee=raw_result) + self.results = results.stderr + raw_result.close() + except CmdError, e: + raise error.TestError('Dacapo benchmark %s has failed: %s' % + (test, e)) + + + def postprocess_iteration(self): + result_line = self.results.splitlines()[-1] + time_regexp = re.compile('PASSED in (\d+) ms') + matches = time_regexp.findall(result_line) + if len(matches) == 1: + keylist = {} + logging.info('Benchmark %s completed in %s ms', self.test, + matches[0]) + keylist[self.test] = int(matches[0]) + self.write_perf_keyval(keylist) + # Remove scratch directory + shutil.rmtree(self.scratch) + else: + logging.error('Problems executing benchmark %s, not recording ' + 'results on the perf keyval', self.test) -- 1.7.0.1 _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
