aboutsummaryrefslogtreecommitdiff
path: root/deprecated/automation/server/job_executer.py
diff options
context:
space:
mode:
authorTiancong Wang <tcwang@google.com>2020-02-13 21:08:49 +0000
committerTiancong Wang <tcwang@google.com>2020-02-13 21:08:49 +0000
commitb75f321fc8978b92ce3db6886ccb966768f0c7a8 (patch)
tree35fa0fbaeaaddd9cc2a126a05eee3527b51e83a8 /deprecated/automation/server/job_executer.py
parentcddd960b0ba2eb62c372c0d3176c75f0bd05d5e8 (diff)
parente617e3393dd24003aa976ece5050bb291070041c (diff)
downloadtoolchain-utils-b75f321fc8978b92ce3db6886ccb966768f0c7a8.tar.gz
Merging 18 commit(s) from Chromium's toolchain-utils am: 0ae38c8498 am: 2a19d36a82 am: e617e3393dr_aml_301500702android-mainline-12.0.0_r55android-mainline-11.0.0_r9android-mainline-11.0.0_r8android-mainline-11.0.0_r7android-mainline-11.0.0_r6android-mainline-11.0.0_r5android-mainline-11.0.0_r45android-mainline-11.0.0_r44android-mainline-11.0.0_r43android-mainline-11.0.0_r42android-mainline-11.0.0_r41android-mainline-11.0.0_r40android-mainline-11.0.0_r4android-mainline-11.0.0_r39android-mainline-11.0.0_r38android-mainline-11.0.0_r37android-mainline-11.0.0_r36android-mainline-11.0.0_r35android-mainline-11.0.0_r34android-mainline-11.0.0_r33android-mainline-11.0.0_r32android-mainline-11.0.0_r31android-mainline-11.0.0_r30android-mainline-11.0.0_r3android-mainline-11.0.0_r29android-mainline-11.0.0_r28android-mainline-11.0.0_r27android-mainline-11.0.0_r26android-mainline-11.0.0_r25android-mainline-11.0.0_r24android-mainline-11.0.0_r23android-mainline-11.0.0_r22android-mainline-11.0.0_r21android-mainline-11.0.0_r20android-mainline-11.0.0_r2android-mainline-11.0.0_r19android-mainline-11.0.0_r18android-mainline-11.0.0_r17android-mainline-11.0.0_r16android-mainline-11.0.0_r15android-mainline-11.0.0_r14android-mainline-11.0.0_r13android-mainline-11.0.0_r12android-mainline-11.0.0_r10android-mainline-11.0.0_r1android-11.0.0_r48android-11.0.0_r47android-11.0.0_r46android-11.0.0_r45android-11.0.0_r44android-11.0.0_r43android-11.0.0_r42android-11.0.0_r41android-11.0.0_r40android-11.0.0_r39android-11.0.0_r38android-11.0.0_r37android-11.0.0_r36android-11.0.0_r35android-11.0.0_r34android-11.0.0_r33android-11.0.0_r32android-11.0.0_r31android-11.0.0_r30android-11.0.0_r29android-11.0.0_r28android-11.0.0_r27android-11.0.0_r26android-11.0.0_r24android-11.0.0_r23android-11.0.0_r22android-11.0.0_r21android-11.0.0_r20android-11.0.0_r19android-11.0.0_r18android-11.0.0_r16android11-qpr3-s1-releaseandroid11-qpr3-releaseandroid11-qpr2-releaseandroid11-qpr1-s2-releaseandroid11-qpr1-s1-releaseandroid11-qpr1-releaseandroid11-qpr1-d-s1-releaseandroid11-qpr1-d-releaseandroid11-qpr1-c-releaseandroid11-mainline-tethering-releaseandroid11-mainline-sparse-2021-jan-releaseandroid11-mainline-sparse-2020-dec-releaseandroid11-mainline-releaseandroid11-mainline-permission-releaseandroid11-mainline-os-statsd-releaseandroid11-mainline-networkstack-releaseandroid11-mainline-media-swcodec-releaseandroid11-mainline-media-releaseandroid11-mainline-extservices-releaseandroid11-mainline-documentsui-releaseandroid11-mainline-conscrypt-releaseandroid11-mainline-cellbroadcast-releaseandroid11-mainline-captiveportallogin-releaseandroid11-devandroid11-d2-releaseandroid11-d1-b-release
Change-Id: I3f25c7ee034b2e20e37ed941b8eae24eec7043eb
Diffstat (limited to 'deprecated/automation/server/job_executer.py')
-rw-r--r--deprecated/automation/server/job_executer.py138
1 files changed, 138 insertions, 0 deletions
diff --git a/deprecated/automation/server/job_executer.py b/deprecated/automation/server/job_executer.py
new file mode 100644
index 00000000..30b59463
--- /dev/null
+++ b/deprecated/automation/server/job_executer.py
@@ -0,0 +1,138 @@
+# Copyright 2010 Google Inc. All Rights Reserved.
+#
+
+import logging
+import os.path
+import threading
+
+from automation.common import command as cmd
+from automation.common import job
+from automation.common import logger
+from automation.common.command_executer import LoggingCommandExecuter
+from automation.common.command_executer import CommandTerminator
+
+
+class JobExecuter(threading.Thread):
+
+ def __init__(self, job_to_execute, machines, listeners):
+ threading.Thread.__init__(self)
+
+ assert machines
+
+ self.job = job_to_execute
+ self.listeners = listeners
+ self.machines = machines
+
+ # Set Thread name.
+ self.name = '%s-%s' % (self.__class__.__name__, self.job.id)
+
+ self._logger = logging.getLogger(self.__class__.__name__)
+ self._executer = LoggingCommandExecuter(self.job.dry_run)
+ self._terminator = CommandTerminator()
+
+ def _RunRemotely(self, command, fail_msg, command_timeout=1 * 60 * 60):
+ exit_code = self._executer.RunCommand(command,
+ self.job.primary_machine.hostname,
+ self.job.primary_machine.username,
+ command_terminator=self._terminator,
+ command_timeout=command_timeout)
+ if exit_code:
+ raise job.JobFailure(fail_msg, exit_code)
+
+ def _RunLocally(self, command, fail_msg, command_timeout=1 * 60 * 60):
+ exit_code = self._executer.RunCommand(command,
+ command_terminator=self._terminator,
+ command_timeout=command_timeout)
+ if exit_code:
+ raise job.JobFailure(fail_msg, exit_code)
+
+ def Kill(self):
+ self._terminator.Terminate()
+
+ def CleanUpWorkDir(self):
+ self._logger.debug('Cleaning up %r work directory.', self.job)
+ self._RunRemotely(cmd.RmTree(self.job.work_dir), 'Cleanup workdir failed.')
+
+ def CleanUpHomeDir(self):
+ self._logger.debug('Cleaning up %r home directory.', self.job)
+ self._RunLocally(cmd.RmTree(self.job.home_dir), 'Cleanup homedir failed.')
+
+ def _PrepareRuntimeEnvironment(self):
+ self._RunRemotely(
+ cmd.MakeDir(self.job.work_dir, self.job.logs_dir, self.job.results_dir),
+ 'Creating new job directory failed.')
+
+ # The log directory is ready, so we can prepare to log command's output.
+ self._executer.OpenLog(os.path.join(self.job.logs_dir,
+ self.job.log_filename_prefix))
+
+ def _SatisfyFolderDependencies(self):
+ for dependency in self.job.folder_dependencies:
+ to_folder = os.path.join(self.job.work_dir, dependency.dest)
+ from_folder = os.path.join(dependency.job.work_dir, dependency.src)
+ from_machine = dependency.job.primary_machine
+
+ if from_machine == self.job.primary_machine and dependency.read_only:
+ # No need to make a copy, just symlink it
+ self._RunRemotely(
+ cmd.MakeSymlink(from_folder, to_folder),
+ 'Failed to create symlink to required directory.')
+ else:
+ self._RunRemotely(
+ cmd.RemoteCopyFrom(from_machine.hostname,
+ from_folder,
+ to_folder,
+ username=from_machine.username),
+ 'Failed to copy required files.')
+
+ def _LaunchJobCommand(self):
+ command = self.job.GetCommand()
+
+ self._RunRemotely('%s; %s' % ('PS1=. TERM=linux source ~/.bashrc',
+ cmd.Wrapper(command,
+ cwd=self.job.work_dir)),
+ "Command failed to execute: '%s'." % command,
+ self.job.timeout)
+
+ def _CopyJobResults(self):
+ """Copy test results back to directory."""
+ self._RunLocally(
+ cmd.RemoteCopyFrom(self.job.primary_machine.hostname,
+ self.job.results_dir,
+ self.job.home_dir,
+ username=self.job.primary_machine.username),
+ 'Failed to copy results.')
+
+ def run(self):
+ self.job.status = job.STATUS_SETUP
+ self.job.machines = self.machines
+ self._logger.debug('Executing %r on %r in directory %s.', self.job,
+ self.job.primary_machine.hostname, self.job.work_dir)
+
+ try:
+ self.CleanUpWorkDir()
+
+ self._PrepareRuntimeEnvironment()
+
+ self.job.status = job.STATUS_COPYING
+
+ self._SatisfyFolderDependencies()
+
+ self.job.status = job.STATUS_RUNNING
+
+ self._LaunchJobCommand()
+ self._CopyJobResults()
+
+ # If we get here, the job succeeded.
+ self.job.status = job.STATUS_SUCCEEDED
+ except job.JobFailure as ex:
+ self._logger.error('Job failed. Exit code %s. %s', ex.exit_code, ex)
+ if self._terminator.IsTerminated():
+ self._logger.info('%r was killed', self.job)
+
+ self.job.status = job.STATUS_FAILED
+
+ self._executer.CloseLog()
+
+ for listener in self.listeners:
+ listener.NotifyJobComplete(self.job)