diff options
Diffstat (limited to 'harnesses/host_controller/invocation_thread.py')
-rw-r--r-- | harnesses/host_controller/invocation_thread.py | 169 |
1 files changed, 0 insertions, 169 deletions
diff --git a/harnesses/host_controller/invocation_thread.py b/harnesses/host_controller/invocation_thread.py deleted file mode 100644 index b8760f3..0000000 --- a/harnesses/host_controller/invocation_thread.py +++ /dev/null @@ -1,169 +0,0 @@ -# -# Copyright (C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import logging -import socket -import threading - -import httplib2 -from googleapiclient import errors - -from host_controller.tfc import command_attempt -from host_controller.tradefed import remote_operation - - -class InvocationThread(threading.Thread): - """The thread that remotely executes a command task. - - Attributes: - _remote_client: The RemoteClient which executes the command. - _tfc_client: The TfcClient to which the command events are sent. - _attempt: The CommandAttempt whose events are sent to TFC. - _command: A list of strings, the command and arguments. - device_serials: A list of strings, the serial numbers of the devices - which need to be allocated to the task. - _allocated_serials: A list of strings, the serial numbers of the devices - which are successfully allocated. - _tfc_heartbeat_interval: The interval of TestRunInProgress events in - seconds. - """ - - def __init__(self, - remote_client, - tfc_client, - attempt, - command, - device_serials, - tfc_heartbeat_interval=5 * 60): - """Initializes the attributes.""" - super(InvocationThread, self).__init__() - self._remote_client = remote_client - self._tfc_client = tfc_client - self._attempt = attempt - self._command = command - self.device_serials = device_serials - self._allocated_serials = None - # The value in Java implementation is 5 minutes. - self._tfc_heartbeat_interval = tfc_heartbeat_interval - - def _AllocateDevices(self): - """Allocates all of device_serial.""" - for serial in self.device_serials: - self._remote_client.SendOperation( - remote_operation.AllocateDevice(serial)) - self._allocated_serials.append(serial) - - def _StartInvocation(self): - """Starts executing command and sends the event to TFC.""" - self._remote_client.SendOperation( - remote_operation.ExecuteCommand(self.device_serials[0], - *self._command)) - event = self._attempt.CreateCommandEvent( - command_attempt.EventType.INVOCATION_STARTED) - self._tfc_client.SubmitCommandEvents([event]) - - def _WaitForCommandResult(self): - """Waits for command result and keeps sending heartbeat to TFC - - Returns: - A JSON object returned from TradeFed remote manager. - """ - while True: - result = self._remote_client.WaitForCommandResult( - self.device_serials[0], self._tfc_heartbeat_interval) - if result: - return result - event = self._attempt.CreateCommandEvent( - command_attempt.EventType.TEST_RUN_IN_PROGRESS) - self._tfc_client.SubmitCommandEvents([event]) - - def _CompleteInvocation(self, result): - """Sends InvocationCompleted event according to the result. - - Args: - result: A JSON object returned from TradeFed remote manager. - """ - if result["status"] == "INVOCATION_SUCCESS": - event = self._attempt.CreateInvocationCompletedEvent( - str(result), 1, 0) - else: - event = self._attempt.CreateInvocationCompletedEvent( - str(result), 1, 1, error=str(result)) - self._tfc_client.SubmitCommandEvents([event]) - - def _FreeAllocatedDevices(self): - """Frees allocated devices and tolerates RemoteOperationException.""" - for serial in self._allocated_serials: - try: - self._remote_client.SendOperation( - remote_operation.FreeDevice(serial)) - except remote_operation.RemoteOperationException as e: - logging.exception(e) - except socket.error as e: - logging.exception(e) - break - self._allocated_serials = [] - - def _SubmitErrorEvent(self, event_type, error_msg): - """Submits an error event and tolerates http exceptions. - - Args: - event_type: A string, the type of the command event. - error_msg: A string, the error message. - """ - try: - self._tfc_client.SubmitCommandEvents( - [self._attempt.CreateCommandEvent(event_type, error_msg)]) - except (httplib2.HttpLib2Error, errors.HttpError) as e: - logging.exception(e) - - # @Override - def run(self): - """Executes a command task with exception handling.""" - self._allocated_serials = [] - last_error = None - error_event = command_attempt.EventType.ALLOCATION_FAILED - try: - self._AllocateDevices() - error_event = command_attempt.EventType.EXECUTE_FAILED - self._StartInvocation() - result = self._WaitForCommandResult() - self._CompleteInvocation(result) - error_event = None - except errors.HttpError as e: - logging.exception(e) - last_error = e - except remote_operation.RemoteOperationException as e: - logging.exception(e) - last_error = e - # ConfigurationException on TradeFed remote manager. - if str(e).startswith("Config error: "): - error_event = command_attempt.EventType.CONFIGURATION_ERROR - except httplib2.HttpLib2Error as e: - logging.exception("Cannot communicate with TradeFed cluster: %s\n" - "Skip submitting event %s.", e, error_event) - last_error = e - error_event = None - except socket.error as e: - logging.exception("Cannot communicate with TradeFed remote " - "manager: %s\nSkip freeing devices %s.", - e, self._allocated_serials) - last_error = e - self._allocated_serials = [] - finally: - if error_event: - self._SubmitErrorEvent(error_event, str(last_error)) - self._FreeAllocatedDevices() |