Home | History | Annotate | Download | only in platform_GCC
      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 
      5 import glob, logging, os, shutil
      6 from autotest_lib.client.common_lib import error
      7 from autotest_lib.server import test, utils
      8 from optparse import OptionParser
      9 
     10 class 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