# Copyright (c) 2009 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import glob, logging, os, shutil from autotest_lib.client.common_lib import error from autotest_lib.server import test, utils from optparse import OptionParser class platform_GCC(test.test): """Class for running the GCC dejagnu tests.""" version = 1 results = {} TEST_STATUSES = ('PASS', 'FAIL', 'UNRESOLVED', 'UNTESTED', 'UNSUPPORTED', 'XFAIL', 'KFAIL', 'XPASS', 'KPASS') TARBALL = '/usr/local/dejagnu/gcc/tests.tar.gz' def parse_log(self, log): results = {} counts = {} log_file = open(log, 'rb') for line in log_file: if line.startswith(self.TEST_STATUSES): result, testname = line.split(': ', 1) testname = testname.strip() if testname in results: counts[testname] += 1 unique_testname = '%s (%d)' % (testname, counts[testname]) else: counts[testname] = 1 unique_testname = testname results[unique_testname] = result log_file.close() return results def compare_logs(self, baseline, new): baseline_results = self.parse_log(baseline) logging.info('%d results parsed in baseline (%s).' % (len(baseline_results), baseline)) new_results = self.parse_log(new) logging.info('%d results parsed in new log (%s).' % (len(new_results), new)) differences = [] for testname in new_results.keys(): if testname not in baseline_results: differences.append((testname, 'NOTEXECUTED', new_results[testname])) elif new_results[testname] != baseline_results[testname]: differences.append((testname, baseline_results[testname], new_results[testname])) for testname in baseline_results.keys(): if testname not in new_results: differences.append((testname, baseline_results[testname], 'NOTEXECUTED')) return differences def run_once(self, host=None, args=[]): self.client = host parser = OptionParser() parser.add_option('--gcc_dir', dest='gcc_dir', default='/var/tmp/portage/cross-*/gcc-*/work/gcc-*build*', help='Path to the gcc build directory.') parser.add_option('--test_flags', dest='test_flags', default='', help='Options to pass to dejagnu.') options, args = parser.parse_args(args) utils.system('%s %s' % (os.path.join(self.bindir, 'dejagnu_init_remote'), self.client.ip)) gcc_dirs = glob.glob(options.gcc_dir) if len(gcc_dirs) == 0: # If there is no directory present, try untarring the tarball # installed by the gcc package. logging.info('No gcc directory found, attempting to untar from %s' % self.TARBALL) os.chdir('/') os.system('tar -xzf %s' % self.TARBALL) gcc_dirs = glob.glob(options.gcc_dir) if len(gcc_dirs) == 0: raise error.TestFail('No gcc directory to test was found') gcc_dir = gcc_dirs[0] logging.info('Testing gcc in the following directory: %s' % gcc_dir) exp_file = os.path.join(self.bindir, 'site.exp') client_hostname = str(self.client.ip) test_flags = options.test_flags test_command = ('cd %s; DEJAGNU="%s" DEJAGNU_SCRIPTS=%s ' 'DEJAGNU_HOSTNAME=%s make ' 'RUNTESTFLAGS="%s" check-gcc' % (gcc_dir, exp_file, self.bindir, client_hostname, test_flags)) utils.system(test_command) error_messages = [] for log in ('gcc', 'g++'): log_from = os.path.join(gcc_dir, 'gcc/testsuite/%s/%s.log' % (log, log)) log_to = os.path.join(self.resultsdir, '%s.log' % (log)) shutil.copy(log_from, log_to) baseline = os.path.join(self.bindir, '%s.log' % (log)) differences = self.compare_logs(baseline, log_to) for difference in differences: error_string = ('(%s) "%s" Expected: "%s" Actual: "%s"' % (log_to, difference[0], difference[1], difference[2])) error_messages.append(error_string) keyname = log.replace('+', 'p') self.results['%s_differences' % keyname] = len(differences) self.write_perf_keyval(self.results) if len(error_messages) != 0: raise error.TestFail('\n'.join(error_messages)) def cleanup(self): utils.system(os.path.join(self.bindir, 'dejagnu_cleanup_remote'))