OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # Copyright 2016 Google Inc. |
| 4 # |
| 5 # Use of this source code is governed by a BSD-style license that can be |
| 6 # found in the LICENSE file. |
| 7 |
| 8 |
| 9 import default_flavor |
| 10 import os |
| 11 import posixpath |
| 12 import subprocess |
| 13 import ssh_devices |
| 14 |
| 15 |
| 16 """Utils for running tests remotely over SSH.""" |
| 17 |
| 18 |
| 19 class SSHFlavorUtils(default_flavor.DefaultFlavorUtils): |
| 20 def __init__(self, *args, **kwargs): |
| 21 super(SSHFlavorUtils, self).__init__(*args, **kwargs) |
| 22 slave_info = ssh_devices.SLAVE_INFO.get(self._bot_info.slave_name, |
| 23 ssh_devices.SLAVE_INFO['default']) |
| 24 self._host = slave_info.ssh_host |
| 25 self._port = slave_info.ssh_port |
| 26 self._user = slave_info.ssh_user |
| 27 |
| 28 @property |
| 29 def host(self): |
| 30 return self._host |
| 31 |
| 32 @property |
| 33 def port(self): |
| 34 return self._port |
| 35 |
| 36 @property |
| 37 def user(self): |
| 38 return self._user |
| 39 |
| 40 def ssh(self, cmd, **kwargs): |
| 41 """Run the given SSH command.""" |
| 42 ssh_cmd = ['ssh'] |
| 43 if self.port: |
| 44 ssh_cmd.extend(['-p', self.port]) |
| 45 dest = self.host |
| 46 if self.user: |
| 47 dest = self.user + '@' + dest |
| 48 ssh_cmd.append(dest) |
| 49 ssh_cmd.extend(cmd) |
| 50 return self._bot_info.run(ssh_cmd, **kwargs) |
| 51 |
| 52 def step(self, *args, **kwargs): |
| 53 """Run the given step over SSH.""" |
| 54 self.ssh(*args, **kwargs) |
| 55 |
| 56 def device_path_join(self, *args): |
| 57 """Like os.path.join(), but for paths on a remote machine.""" |
| 58 return posixpath.join(*args) |
| 59 |
| 60 def device_path_exists(self, path): # pragma: no cover |
| 61 """Like os.path.exists(), but for paths on a remote device.""" |
| 62 try: |
| 63 self.ssh(['test', '-e', path]) |
| 64 return True |
| 65 except subprocess.CalledProcessError: |
| 66 return False |
| 67 |
| 68 def _remove_device_dir(self, path): |
| 69 """Remove the directory on the device.""" |
| 70 self.ssh(['rm', '-rf', path]) |
| 71 |
| 72 def _create_device_dir(self, path): |
| 73 """Create the directory on the device.""" |
| 74 self.ssh(['mkdir', '-p', path]) |
| 75 |
| 76 def create_clean_device_dir(self, path): |
| 77 """Like shutil.rmtree() + os.makedirs(), but on a remote device.""" |
| 78 self._remove_device_dir(path) |
| 79 self._create_device_dir(path) |
| 80 |
| 81 def _make_scp_cmd(self, remote_path, recurse=True): |
| 82 """Prepare an SCP command. |
| 83 |
| 84 Returns a partial SCP command and an adjusted remote path. |
| 85 """ |
| 86 cmd = ['scp'] |
| 87 if recurse: |
| 88 cmd.append('-r') |
| 89 if self.port: |
| 90 cmd.extend(['-P', self.port]) |
| 91 adj_remote_path = self.host + ':' + remote_path |
| 92 if self.user: |
| 93 adj_remote_path = self.user + '@' + adj_remote_path |
| 94 return cmd, adj_remote_path |
| 95 |
| 96 def copy_directory_contents_to_device(self, host_dir, device_dir): |
| 97 """Like shutil.copytree(), but for copying to a remote device.""" |
| 98 _, remote_path = self._make_scp_cmd(device_dir) |
| 99 cmd = [os.path.join(self._bot_info.skia_dir, 'tools', |
| 100 'scp_dir_contents.sh'), |
| 101 host_dir, remote_path] |
| 102 self._bot_info.run(cmd) |
| 103 |
| 104 def copy_directory_contents_to_host(self, device_dir, host_dir): |
| 105 """Like shutil.copytree(), but for copying from a remote device.""" |
| 106 _, remote_path = self._make_scp_cmd(device_dir) |
| 107 cmd = [os.path.join(self._bot_info.skia_dir, 'tools', |
| 108 'scp_dir_contents.sh'), |
| 109 remote_path, host_dir] |
| 110 self._bot_info.run(cmd) |
| 111 |
| 112 def copy_file_to_device(self, host_path, device_path): |
| 113 """Like shutil.copyfile, but for copying to a connected device.""" |
| 114 cmd, remote_path = self._make_scp_cmd(device_path, recurse=False) |
| 115 cmd.extend([host_path, remote_path]) |
| 116 self._bot_info.run(cmd) |
| 117 |
| 118 def read_file_on_device(self, path): |
| 119 return self.ssh(['cat', path]).rstrip() |
| 120 |
| 121 def remove_file_on_device(self, path): |
| 122 """Delete the given file.""" |
| 123 return self.ssh(['rm', '-f', path]) |
OLD | NEW |