| # SPDX-License-Identifier: Apache-2.0 |
| # |
| # Copyright (C) 2015, ARM Limited and contributors. |
| # |
| # 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 os |
| |
| SCRIPT_NAME = 'remote_script.sh' |
| |
| class TargetScript(object): |
| """ |
| This class provides utility to create and run a script |
| directly on a devlib target. |
| |
| The execute() method is made to look like Devlib's, so a Target instance can |
| be swapped with an instance of this TargetScript class, and the commands |
| will be accumulated for later use instead of being executed straight away. |
| |
| :param env: Reference TestEnv instance. Will be used for some commands |
| that must really be executed instead of accumulated. |
| :type env: TestEnv |
| |
| :param script_name: Name of the script that will be pushed on the target, |
| defaults to "remote_script.sh" |
| :type script_name: str |
| """ |
| |
| _target_attrs = ['screen_resolution', 'android_id', 'abi', 'os_version', 'model'] |
| |
| def __init__(self, env, script_name=SCRIPT_NAME): |
| self._env = env |
| self._target = env.target |
| self._script_name = script_name |
| self.commands = [] |
| |
| # This is made to look like the devlib Target execute() |
| def execute(self, cmd): |
| """ |
| Accumulate command for later execution. |
| |
| :param cmd: Command that would be run on the target |
| :type cmd: str |
| """ |
| self.append(cmd) |
| |
| def append(self, cmd): |
| """ |
| Append a command to the script. |
| |
| :param cmd: Command string to append |
| :type cmd: str |
| """ |
| self.commands.append(cmd) |
| |
| # Some commands may require some info about the real target. |
| # For instance, System.{h,v}swipe needs to get the value of |
| # screen_resolution to generate a swipe command at a given |
| # screen coordinate percentage. |
| # Thus, if such a property is called on this object, |
| # it will be fetched from the 'real' target object. |
| def __getattr__(self, name): |
| if name in self._target_attrs: |
| return getattr(self._target, name) |
| |
| return getattr(super, name) |
| |
| def push(self): |
| """ |
| Push a script to the target |
| |
| The script is created and stored on the host, |
| and is then sent to the target. |
| |
| :param path: Path where the script will be locally created |
| :type path: str |
| :param actions: List of actions(commands) to run |
| :type actions: list(str) |
| """ |
| |
| actions = ['set -e'] + self.commands + ['set +e'] |
| actions = ['#!{} sh'.format(self._target.busybox)] + actions |
| actions = str.join('\n', actions) |
| |
| self._remote_path = self._target.path.join(self._target.executables_directory, |
| self._script_name) |
| self._local_path = os.path.join(self._env.res_dir, self._script_name) |
| |
| # Create script locally |
| with open(self._local_path, 'w') as script: |
| script.write(actions) |
| |
| # Push it on target |
| self._target.push(self._local_path, self._remote_path) |
| self._target.execute('chmod +x {}'.format(self._remote_path)) |
| |
| def run(self): |
| """ |
| Run the previously pushed script |
| """ |
| |
| if self._target.file_exists(self._remote_path): |
| self._target.execute(self._remote_path) |
| else: |
| raise IOError('Remote script was not found on target device') |