diff options
Diffstat (limited to 'deprecated/dejagnu/run_dejagnu.py')
-rwxr-xr-x | deprecated/dejagnu/run_dejagnu.py | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/deprecated/dejagnu/run_dejagnu.py b/deprecated/dejagnu/run_dejagnu.py deleted file mode 100755 index 7b6e6fa3..00000000 --- a/deprecated/dejagnu/run_dejagnu.py +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/python2 -# -# Copyright 2010 Google Inc. All Rights Reserved. -"""Tool script for auto dejagnu.""" - -__author__ = 'shenhan@google.com (Han Shen)' - -import getpass -import optparse -import os -from os import path -import re -import shutil -import stat -import sys -import tempfile -import time - -import lock_machine -import tc_enter_chroot -from cros_utils import command_executer -from cros_utils import constants -from cros_utils import logger -from cros_utils import misc - - -def ProcessArguments(argv): - """Processing/validating script arguments.""" - parser = optparse.OptionParser(description=( - 'Launches gcc dejagnu test in chroot for chromeos toolchain, compares ' - 'the test result with a repository baseline and prints out the result.'), - usage='run_dejagnu options') - parser.add_option('-c', - '--chromeos_root', - dest='chromeos_root', - help='Required. Specify chromeos root') - parser.add_option('-m', - '--mount', - dest='mount', - help=('Specify gcc source to mount instead of "auto". ' - 'Under "auto" mode, which is the default - gcc is ' - 'checked out and built automatically at default ' - 'directories. Under "mount" mode ' - '- the gcc_source is set to "$chromeos_' - 'root/chroot/usr/local/toolchain_root/gcc", which is ' - 'the mount point for this option value, the ' - 'gcc-build-dir then is computed as ' - '"${gcc_source_dir}-build-${ctarget}". In this mode, ' - 'a complete gcc build must be performed in the ' - 'computed gcc-build-dir beforehand.')) - parser.add_option('-b', - '--board', - dest='board', - help=('Required. Specify board.')) - parser.add_option('-r', - '--remote', - dest='remote', - help=('Required. Specify addresses/names of the board, ' - 'seperate each address/name using comma(\',\').')) - parser.add_option('-f', - '--flags', - dest='flags', - help='Optional. Extra run test flags to pass to dejagnu.') - parser.add_option('-k', - '--keep', - dest='keep_intermediate_files', - action='store_true', - default=False, - help=('Optional. Default to false. Do not remove dejagnu ' - 'intermediate files after test run.')) - parser.add_option('--cleanup', - dest='cleanup', - default=None, - help=('Optional. Values to this option could be ' - '\'mount\' (unmount gcc source and ' - 'directory directory, ' - 'only valid when --mount is given), ' - '\'chroot\' (delete chroot) and ' - '\'chromeos\' (delete the whole chromeos tree).')) - parser.add_option('-t', - '--tools', - dest='tools', - default='gcc,g++', - help=('Optional. Specify which tools to check, using ' - '","(comma) as separator. A typical value would be ' - '"g++" so that only g++ tests are performed. ' - 'Defaults to "gcc,g++".')) - - options, args = parser.parse_args(argv) - - if not options.chromeos_root: - raise SyntaxError('Missing argument for --chromeos_root.') - if not options.remote: - raise SyntaxError('Missing argument for --remote.') - if not options.board: - raise SyntaxError('Missing argument for --board.') - if options.cleanup == 'mount' and not options.mount: - raise SyntaxError('--cleanup=\'mount\' not valid unless --mount is given.') - if options.cleanup and not ( - options.cleanup == 'mount' or \ - options.cleanup == 'chroot' or options.cleanup == 'chromeos'): - raise ValueError('Invalid option value for --cleanup') - if options.cleanup and options.keep_intermediate_files: - raise SyntaxError('Only one of --keep and --cleanup could be given.') - - return options - - -class DejagnuExecuter(object): - """The class wrapper for dejagnu test executer.""" - - def __init__(self, base_dir, mount, chromeos_root, remote, board, flags, - keep_intermediate_files, tools, cleanup): - self._l = logger.GetLogger() - self._chromeos_root = chromeos_root - self._chromeos_chroot = path.join(chromeos_root, 'chroot') - if mount: - self._gcc_source_dir_to_mount = mount - self._gcc_source_dir = path.join(constants.MOUNTED_TOOLCHAIN_ROOT, 'gcc') - else: - self._gcc_source_dir = None - - self._remote = remote - self._board = board - ## Compute target from board - self._target = misc.GetCtargetFromBoard(board, chromeos_root) - if not self._target: - raise ValueError('Unsupported board "%s"' % board) - self._executer = command_executer.GetCommandExecuter() - self._flags = flags or '' - self._base_dir = base_dir - self._tmp_abs = None - self._keep_intermediate_files = keep_intermediate_files - self._tools = tools.split(',') - self._cleanup = cleanup - - def SetupTestingDir(self): - self._tmp_abs = tempfile.mkdtemp( - prefix='dejagnu_', - dir=path.join(self._chromeos_chroot, 'tmp')) - self._tmp = self._tmp_abs[len(self._chromeos_chroot):] - self._tmp_testing_rsa = path.join(self._tmp, 'testing_rsa') - self._tmp_testing_rsa_abs = path.join(self._tmp_abs, 'testing_rsa') - - def MakeCheckString(self): - return ' '.join(['check-{0}'.format(t) for t in self._tools if t]) - - def CleanupIntermediateFiles(self): - if self._tmp_abs and path.isdir(self._tmp_abs): - if self._keep_intermediate_files: - self._l.LogOutput( - 'Your intermediate dejagnu files are kept, you can re-run ' - 'inside chroot the command:') - self._l.LogOutput( - ' DEJAGNU={0} make -C {1} {2} RUNTESTFLAGS="--target_board={3} {4}"' \ - .format(path.join(self._tmp, 'site.exp'), self._gcc_build_dir, - self.MakeCheckString(), self._board, self._flags)) - else: - self._l.LogOutput('[Cleanup] - Removing temp dir - {0}'.format( - self._tmp_abs)) - shutil.rmtree(self._tmp_abs) - - def Cleanup(self): - if not self._cleanup: - return - - # Optionally cleanup mounted diretory, chroot and chromeos tree. - if self._cleanup == 'mount' or self._cleanup == 'chroot' or \ - self._cleanup == 'chromeos': - # No exceptions are allowed from this method. - try: - self._l.LogOutput('[Cleanup] - Unmounting directories ...') - self.MountGccSourceAndBuildDir(unmount=True) - except: - print 'Warning: failed to unmount gcc source/build directory.' - - if self._cleanup == 'chroot' or self._cleanup == 'chromeos': - self._l.LogOutput('[Cleanup]: Deleting chroot inside \'{0}\''.format( - self._chromeos_root)) - command = 'cd %s; cros_sdk --delete' % self._chromeos_root - rv = self._executer.RunCommand(command) - if rv: - self._l.LogWarning('Warning - failed to delete chroot.') - # Delete .cache - crosbug.com/34956 - command = 'sudo rm -fr %s' % os.path.join(self._chromeos_root, '.cache') - rv = self._executer.RunCommand(command) - if rv: - self._l.LogWarning('Warning - failed to delete \'.cache\'.') - - if self._cleanup == 'chromeos': - self._l.LogOutput('[Cleanup]: Deleting chromeos tree \'{0}\' ...'.format( - self._chromeos_root)) - command = 'rm -fr {0}'.format(self._chromeos_root) - rv = self._executer.RunCommand(command) - if rv: - self._l.LogWarning('Warning - failed to remove chromeos tree.') - - def PrepareTestingRsaKeys(self): - if not path.isfile(self._tmp_testing_rsa_abs): - shutil.copy( - path.join(self._chromeos_root, - 'src/scripts/mod_for_test_scripts/ssh_keys/testing_rsa'), - self._tmp_testing_rsa_abs) - os.chmod(self._tmp_testing_rsa_abs, stat.S_IRUSR) - - def PrepareTestFiles(self): - """Prepare site.exp and board exp files.""" - # Create the boards directory. - os.mkdir('%s/boards' % self._tmp_abs) - - # Generate the chromeos.exp file. - with open('%s/chromeos.exp.in' % self._base_dir, 'r') as template_file: - content = template_file.read() - substitutions = dict({ - '__boardname__': self._board, - '__board_hostname__': self._remote, - '__tmp_testing_rsa__': self._tmp_testing_rsa, - '__tmp_dir__': self._tmp - }) - for pat, sub in substitutions.items(): - content = content.replace(pat, sub) - - board_file_name = '%s/boards/%s.exp' % (self._tmp_abs, self._board) - with open(board_file_name, 'w') as board_file: - board_file.write(content) - - # Generate the site file - with open('%s/site.exp' % self._tmp_abs, 'w') as site_file: - site_file.write('set target_list "%s"\n' % self._board) - - def PrepareGcc(self): - if self._gcc_source_dir: - self.PrepareGccFromCustomizedPath() - else: - self.PrepareGccDefault() - self._l.LogOutput('Gcc source dir - {0}'.format(self._gcc_source_dir)) - self._l.LogOutput('Gcc build dir - {0}'.format(self._gcc_top_build_dir)) - - def PrepareGccFromCustomizedPath(self): - """Prepare gcc source, build directory from mounted source.""" - # We have these source directories - - # _gcc_source_dir - # e.g. '/usr/local/toolchain_root/gcc' - # _gcc_source_dir_abs - # e.g. '/somewhere/chromeos.live/chroot/usr/local/toolchain_root/gcc' - # _gcc_source_dir_to_mount - # e.g. '/somewhere/gcc' - self._gcc_source_dir_abs = path.join(self._chromeos_chroot, - self._gcc_source_dir.lstrip('/')) - if not path.isdir(self._gcc_source_dir_abs) and \ - self._executer.RunCommand( - 'sudo mkdir -p {0}'.format(self._gcc_source_dir_abs)): - raise RuntimeError("Failed to create \'{0}\' inside chroot.".format( - self._gcc_source_dir)) - if not (path.isdir(self._gcc_source_dir_to_mount) and - path.isdir(path.join(self._gcc_source_dir_to_mount, 'gcc'))): - raise RuntimeError('{0} is not a valid gcc source tree.'.format( - self._gcc_source_dir_to_mount)) - - # We have these build directories - - # _gcc_top_build_dir - # e.g. '/usr/local/toolchain_root/gcc-build-x86_64-cros-linux-gnu' - # _gcc_top_build_dir_abs - # e.g. '/somewhere/chromeos.live/chroo/tusr/local/toolchain_root/ - # gcc-build-x86_64-cros-linux-gnu' - # _gcc_build_dir - # e.g. '/usr/local/toolchain_root/gcc-build-x86_64-cros-linux-gnu/gcc' - # _gcc_build_dir_to_mount - # e.g. '/somewhere/gcc-build-x86_64-cros-linux-gnu' - self._gcc_top_build_dir = '{0}-build-{1}'.format( - self._gcc_source_dir.rstrip('/'), self._target) - self._gcc_build_dir = path.join(self._gcc_top_build_dir, 'gcc') - self._gcc_build_dir_to_mount = '{0}-build-{1}'.format( - self._gcc_source_dir_to_mount, self._target) - self._gcc_top_build_dir_abs = path.join(self._chromeos_chroot, - self._gcc_top_build_dir.lstrip('/')) - if not path.isdir(self._gcc_top_build_dir_abs) and \ - self._executer.RunCommand( - 'sudo mkdir -p {0}'.format(self._gcc_top_build_dir_abs)): - raise RuntimeError('Failed to create \'{0}\' inside chroot.'.format( - self._gcc_top_build_dir)) - if not (path.isdir(self._gcc_build_dir_to_mount) and path.join( - self._gcc_build_dir_to_mount, 'gcc')): - raise RuntimeError('{0} is not a valid gcc build tree.'.format( - self._gcc_build_dir_to_mount)) - - # All check passed. Now mount gcc source and build directories. - self.MountGccSourceAndBuildDir() - - def PrepareGccDefault(self): - """Auto emerging gcc for building purpose only.""" - ret = self._executer.ChrootRunCommandWOutput( - self._chromeos_root, 'equery w cross-%s/gcc' % self._target)[1] - ret = path.basename(ret.strip()) - # ret is expected to be something like 'gcc-4.6.2-r11.ebuild' or - # 'gcc-9999.ebuild' parse it. - matcher = re.match('((.*)-r\d+).ebuild', ret) - if matcher: - gccrevision, gccversion = matcher.group(1, 2) - elif ret == 'gcc-9999.ebuild': - gccrevision = 'gcc-9999' - gccversion = 'gcc-9999' - else: - raise RuntimeError('Failed to get gcc version.') - - gcc_portage_dir = '/var/tmp/portage/cross-%s/%s/work' % (self._target, - gccrevision) - self._gcc_source_dir = path.join(gcc_portage_dir, gccversion) - self._gcc_top_build_dir = (gcc_portage_dir + '/%s-build-%s') % ( - gccversion, self._target) - self._gcc_build_dir = path.join(self._gcc_top_build_dir, 'gcc') - gcc_build_dir_abs = path.join(self._chromeos_root, 'chroot', - self._gcc_build_dir.lstrip('/')) - if not path.isdir(gcc_build_dir_abs): - ret = self._executer.ChrootRunCommand(self._chromeos_root, ( - 'ebuild $(equery w cross-%s/gcc) clean prepare compile' % ( - self._target))) - if ret: - raise RuntimeError('ebuild gcc failed.') - - def MakeCheck(self): - self.MountGccSourceAndBuildDir() - cmd = ('cd %s ; ' - 'DEJAGNU=%s make %s RUNTESTFLAGS="--target_board=%s %s"' % - (self._gcc_build_dir, path.join(self._tmp, 'site.exp'), - self.MakeCheckString(), self._board, self._flags)) - self._executer.ChrootRunCommand(self._chromeos_root, cmd) - - def ValidateFailures(self): - validate_failures_py = path.join( - self._gcc_source_dir, - 'contrib/testsuite-management/validate_failures.py') - cmd = 'cd {0} ; {1} --build_dir={0}'.format(self._gcc_top_build_dir, - validate_failures_py) - self.MountGccSourceAndBuildDir() - ret = self._executer.ChrootRunCommandWOutput(self._chromeos_root, cmd) - if ret[0] != 0: - self._l.LogWarning('*** validate_failures.py exited with non-zero code,' - 'please run it manually inside chroot - \n' - ' ' + cmd) - return ret - - # This method ensures necessary mount points before executing chroot comamnd. - def MountGccSourceAndBuildDir(self, unmount=False): - mount_points = [tc_enter_chroot.MountPoint(self._gcc_source_dir_to_mount, - self._gcc_source_dir_abs, - getpass.getuser(), 'ro'), - tc_enter_chroot.MountPoint(self._gcc_build_dir_to_mount, - self._gcc_top_build_dir_abs, - getpass.getuser(), 'rw')] - for mp in mount_points: - if unmount: - if mp.UnMount(): - raise RuntimeError('Failed to unmount {0}'.format(mp.mount_dir)) - else: - self._l.LogOutput('{0} unmounted successfully.'.format(mp.mount_dir)) - elif mp.DoMount(): - raise RuntimeError( - 'Failed to mount {0} onto {1}'.format(mp.external_dir, - mp.mount_dir)) - else: - self._l.LogOutput('{0} mounted successfully.'.format(mp.mount_dir)) - -# The end of class DejagnuExecuter - - -def TryAcquireMachine(remotes): - available_machine = None - for r in remotes.split(','): - machine = lock_machine.Machine(r) - if machine.TryLock(timeout=300, exclusive=True): - available_machine = machine - break - else: - logger.GetLogger().LogWarning( - '*** Failed to lock machine \'{0}\'.'.format(r)) - if not available_machine: - raise RuntimeError("Failed to acquire one machine from \'{0}\'.".format( - remotes)) - return available_machine - - -def Main(argv): - opts = ProcessArguments(argv) - available_machine = TryAcquireMachine(opts.remote) - executer = DejagnuExecuter( - misc.GetRoot(argv[0])[0], opts.mount, opts.chromeos_root, - available_machine._name, opts.board, opts.flags, - opts.keep_intermediate_files, opts.tools, opts.cleanup) - # Return value is a 3- or 4-element tuple - # element#1 - exit code - # element#2 - stdout - # element#3 - stderr - # element#4 - exception infor - # Some other scripts need these detailed information. - ret = (1, '', '') - try: - executer.SetupTestingDir() - executer.PrepareTestingRsaKeys() - executer.PrepareTestFiles() - executer.PrepareGcc() - executer.MakeCheck() - ret = executer.ValidateFailures() - except Exception as e: - # At least log the exception on console. - print e - # The #4 element encodes the runtime exception. - ret = (1, '', '', 'Exception happened during execution: \n' + str(e)) - finally: - available_machine.Unlock(exclusive=True) - executer.CleanupIntermediateFiles() - executer.Cleanup() - return ret - - -if __name__ == '__main__': - retval = Main(sys.argv)[0] - sys.exit(retval) |