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 |