1# Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import glob, logging, os, shutil 6from autotest_lib.client.common_lib import error 7from autotest_lib.server import test, utils 8from optparse import OptionParser 9 10class platform_GCC(test.test): 11 """Class for running the GCC dejagnu tests.""" 12 version = 1 13 results = {} 14 15 TEST_STATUSES = ('PASS', 'FAIL', 'UNRESOLVED', 'UNTESTED', 'UNSUPPORTED', 16 'XFAIL', 'KFAIL', 'XPASS', 'KPASS') 17 TARBALL = '/usr/local/dejagnu/gcc/tests.tar.gz' 18 19 def parse_log(self, log): 20 results = {} 21 counts = {} 22 log_file = open(log, 'rb') 23 for line in log_file: 24 if line.startswith(self.TEST_STATUSES): 25 result, testname = line.split(': ', 1) 26 testname = testname.strip() 27 if testname in results: 28 counts[testname] += 1 29 unique_testname = '%s (%d)' % (testname, counts[testname]) 30 else: 31 counts[testname] = 1 32 unique_testname = testname 33 results[unique_testname] = result 34 log_file.close() 35 return results 36 37 38 def compare_logs(self, baseline, new): 39 baseline_results = self.parse_log(baseline) 40 logging.info('%d results parsed in baseline (%s).' % 41 (len(baseline_results), baseline)) 42 new_results = self.parse_log(new) 43 logging.info('%d results parsed in new log (%s).' % 44 (len(new_results), new)) 45 46 differences = [] 47 for testname in new_results.keys(): 48 if testname not in baseline_results: 49 differences.append((testname, 'NOTEXECUTED', 50 new_results[testname])) 51 elif new_results[testname] != baseline_results[testname]: 52 differences.append((testname, baseline_results[testname], 53 new_results[testname])) 54 for testname in baseline_results.keys(): 55 if testname not in new_results: 56 differences.append((testname, baseline_results[testname], 57 'NOTEXECUTED')) 58 return differences 59 60 61 def run_once(self, host=None, args=[]): 62 self.client = host 63 64 parser = OptionParser() 65 parser.add_option('--gcc_dir', 66 dest='gcc_dir', 67 default='/var/tmp/portage/cross-*/gcc-*/work/gcc-*build*', 68 help='Path to the gcc build directory.') 69 parser.add_option('--test_flags', 70 dest='test_flags', 71 default='', 72 help='Options to pass to dejagnu.') 73 74 options, args = parser.parse_args(args) 75 76 utils.system('%s %s' % 77 (os.path.join(self.bindir, 'dejagnu_init_remote'), 78 self.client.ip)) 79 80 gcc_dirs = glob.glob(options.gcc_dir) 81 if len(gcc_dirs) == 0: 82 # If there is no directory present, try untarring the tarball 83 # installed by the gcc package. 84 logging.info('No gcc directory found, attempting to untar from %s' 85 % self.TARBALL) 86 os.chdir('/') 87 os.system('tar -xzf %s' % self.TARBALL) 88 gcc_dirs = glob.glob(options.gcc_dir) 89 if len(gcc_dirs) == 0: 90 raise error.TestFail('No gcc directory to test was found') 91 92 gcc_dir = gcc_dirs[0] 93 94 logging.info('Testing gcc in the following directory: %s' % gcc_dir) 95 exp_file = os.path.join(self.bindir, 'site.exp') 96 client_hostname = str(self.client.ip) 97 test_flags = options.test_flags 98 test_command = ('cd %s; DEJAGNU="%s" DEJAGNU_SCRIPTS=%s ' 99 'DEJAGNU_HOSTNAME=%s make ' 100 'RUNTESTFLAGS="%s" check-gcc' % (gcc_dir, exp_file, 101 self.bindir, client_hostname, test_flags)) 102 utils.system(test_command) 103 104 error_messages = [] 105 for log in ('gcc', 'g++'): 106 log_from = os.path.join(gcc_dir, 'gcc/testsuite/%s/%s.log' % 107 (log, log)) 108 log_to = os.path.join(self.resultsdir, '%s.log' % (log)) 109 shutil.copy(log_from, log_to) 110 111 baseline = os.path.join(self.bindir, '%s.log' % (log)) 112 113 differences = self.compare_logs(baseline, log_to) 114 for difference in differences: 115 error_string = ('(%s) "%s" Expected: "%s" Actual: "%s"' % 116 (log_to, difference[0], 117 difference[1], difference[2])) 118 error_messages.append(error_string) 119 keyname = log.replace('+', 'p') 120 self.results['%s_differences' % keyname] = len(differences) 121 122 self.write_perf_keyval(self.results) 123 124 if len(error_messages) != 0: 125 raise error.TestFail('\n'.join(error_messages)) 126 127 def cleanup(self): 128 utils.system(os.path.join(self.bindir, 'dejagnu_cleanup_remote')) 129