Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: infra/bots/recipe_modules/flavor/android_flavor.py

Issue 2198173002: Re-organize Skia recipes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix missing dependency Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « infra/bots/recipe_modules/flavor/__init__.py ('k') | infra/bots/recipe_modules/flavor/api.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 5
6 # pylint: disable=W0201 6 # pylint: disable=W0201
7 7
8 8
9 import android_devices
10 import copy 9 import copy
11 import default_flavor 10 import default_flavor
12 11
13 12
14 """Android flavor utils, used for building for and running tests on Android.""" 13 """Android flavor utils, used for building for and running tests on Android."""
15 14
16 15
17 class _ADBWrapper(object): 16 class _ADBWrapper(object):
18 """Wrapper for the ADB recipe module. 17 """Wrapper for the ADB recipe module.
19 18
20 The ADB recipe module looks for the ADB binary at a path we don't have checked 19 The ADB recipe module looks for the ADB binary at a path we don't have checked
21 out on our bots. This wrapper ensures that we set a custom ADB path before 20 out on our bots. This wrapper ensures that we set a custom ADB path before
22 attempting to use the module. 21 attempting to use the module.
23 """ 22 """
24 def __init__(self, adb_api, path_to_adb, serial_args, android_flavor): 23 def __init__(self, m, path_to_adb, serial_args, android_flavor):
25 self._adb = adb_api 24 self.m = m
26 self._adb.set_adb_path(path_to_adb) 25 self.m.adb.set_adb_path(path_to_adb)
27 self._has_root = False # This is set in install(). 26 self._has_root = False # This is set in install().
28 self._serial_args = serial_args 27 self._serial_args = serial_args
29 self._wait_count = 0 28 self._wait_count = 0
30 self._android_flavor = android_flavor 29 self._android_flavor = android_flavor
31 30
32 def wait_for_device(self): 31 def wait_for_device(self):
33 """Run 'adb wait-for-device'.""" 32 """Run 'adb wait-for-device'."""
34 self._wait_count += 1 33 self._wait_count += 1
35 cmd = [ 34 cmd = [
36 self._android_flavor.android_bin.join('adb_wait_for_device') 35 self._android_flavor.android_bin.join('adb_wait_for_device')
37 ] + self._serial_args 36 ] + self._serial_args
38 self._android_flavor._skia_api.run( 37 self.m.run(
39 self._android_flavor._skia_api.m.step, 38 self.m.step,
40 name='wait for device (%d)' % self._wait_count, 39 name='wait for device (%d)' % self._wait_count,
41 cmd=cmd, 40 cmd=cmd,
42 env=self._android_flavor._default_env, 41 env=self._android_flavor._default_env,
43 infra_step=True) 42 infra_step=True)
44 43
45 cmd = [ 44 cmd = [
46 self._android_flavor.android_bin.join('adb_wait_for_charge'), 45 self._android_flavor.android_bin.join('adb_wait_for_charge'),
47 ] + self._serial_args 46 ] + self._serial_args
48 self._android_flavor._skia_api.run( 47 self.m.run(
49 self._android_flavor._skia_api.m.step, 48 self.m.step,
50 name='wait for charge (%d)' % self._wait_count, 49 name='wait for charge (%d)' % self._wait_count,
51 cmd=cmd, 50 cmd=cmd,
52 env=self._android_flavor._default_env, 51 env=self._android_flavor._default_env,
53 infra_step=True) 52 infra_step=True)
54 53
55 def maybe_wait_for_device(self): 54 def maybe_wait_for_device(self):
56 """Run 'adb wait-for-device' if it hasn't already been run.""" 55 """Run 'adb wait-for-device' if it hasn't already been run."""
57 if self._wait_count == 0: 56 if self._wait_count == 0:
58 self.wait_for_device() 57 self.wait_for_device()
59 58
60 def __call__(self, *args, **kwargs): 59 def __call__(self, *args, **kwargs):
61 self.maybe_wait_for_device() 60 self.maybe_wait_for_device()
62 return self._android_flavor._skia_api.run(self._adb, *args, **kwargs) 61 return self.m.run(self.m.adb, *args, **kwargs)
63 62
64 63
65 class AndroidFlavorUtils(default_flavor.DefaultFlavorUtils): 64 class AndroidFlavorUtils(default_flavor.DefaultFlavorUtils):
66 def __init__(self, skia_api): 65 def __init__(self, m):
67 super(AndroidFlavorUtils, self).__init__(skia_api) 66 super(AndroidFlavorUtils, self).__init__(m)
68 self.device = self._skia_api.builder_spec['device_cfg'] 67 self.device = self.m.vars.builder_spec['device_cfg']
69 self.android_bin = self._skia_api.skia_dir.join( 68 self.android_bin = self.m.vars.skia_dir.join(
70 'platform_tools', 'android', 'bin') 69 'platform_tools', 'android', 'bin')
71 self._android_sdk_root = self._skia_api.slave_dir.join( 70 self._android_sdk_root = self.m.vars.slave_dir.join(
72 'android_sdk', 'android-sdk') 71 'android_sdk', 'android-sdk')
73 self.serial = None 72 self.serial = None
74 self.serial_args = [] 73 self.serial_args = []
75 try: 74 try:
76 path_to_adb = self._skia_api.m.step( 75 path_to_adb = self.m.step(
77 'which adb', 76 'which adb',
78 cmd=['which', 'adb'], 77 cmd=['which', 'adb'],
79 stdout=self._skia_api.m.raw_io.output(), 78 stdout=self.m.raw_io.output(),
80 infra_step=True).stdout.rstrip() 79 infra_step=True).stdout.rstrip()
81 except self._skia_api.m.step.StepFailure: 80 except self.m.step.StepFailure:
82 path_to_adb = self._skia_api.m.path.join(self._android_sdk_root, 81 path_to_adb = self.m.path.join(self._android_sdk_root,
83 'platform-tools', 'adb') 82 'platform-tools', 'adb')
84 self._adb = _ADBWrapper( 83 self._adb = _ADBWrapper(
85 self._skia_api.m.adb, path_to_adb, self.serial_args, self) 84 self.m, path_to_adb, self.serial_args, self)
86 self._default_env = {'ANDROID_SDK_ROOT': self._android_sdk_root, 85 self._default_env = {'ANDROID_SDK_ROOT': self._android_sdk_root,
87 'ANDROID_HOME': self._android_sdk_root, 86 'ANDROID_HOME': self._android_sdk_root,
88 'SKIA_ANDROID_VERBOSE_SETUP': 1} 87 'SKIA_ANDROID_VERBOSE_SETUP': 1}
89 88
90 def step(self, name, cmd, env=None, **kwargs): 89 def step(self, name, cmd, env=None, **kwargs):
91 self._adb.maybe_wait_for_device() 90 self._adb.maybe_wait_for_device()
92 args = [ 91 args = [
93 self.android_bin.join('android_run_skia'), 92 self.android_bin.join('android_run_skia'),
94 '--verbose', 93 '--verbose',
95 '--logcat', 94 '--logcat',
96 '-d', self.device, 95 '-d', self.device,
97 ] + self.serial_args + [ 96 ] + self.serial_args + [
98 '-t', self._skia_api.configuration, 97 '-t', self.m.vars.configuration,
99 ] 98 ]
100 env = dict(env or {}) 99 env = dict(env or {})
101 env.update(self._default_env) 100 env.update(self._default_env)
102 101
103 return self._skia_api.run(self._skia_api.m.step, name=name, cmd=args + cmd, 102 return self.m.run(self.m.step, name=name, cmd=args + cmd,
104 env=env, **kwargs) 103 env=env, **kwargs)
105 104
106 def compile(self, target): 105 def compile(self, target):
107 """Build the given target.""" 106 """Build the given target."""
108 env = dict(self._default_env) 107 env = dict(self._default_env)
109 ccache = self._skia_api.ccache() 108 ccache = self.m.run.ccache()
110 if ccache: 109 if ccache:
111 env['ANDROID_MAKE_CCACHE'] = ccache 110 env['ANDROID_MAKE_CCACHE'] = ccache
112 111
113 cmd = [self.android_bin.join('android_ninja'), target, '-d', self.device] 112 cmd = [self.android_bin.join('android_ninja'), target, '-d', self.device]
114 if 'Clang' in self._skia_api.builder_name: 113 if 'Clang' in self.m.vars.builder_name:
115 cmd.append('--clang') 114 cmd.append('--clang')
116 if 'GCC' in self._skia_api.builder_name: 115 if 'GCC' in self.m.vars.builder_name:
117 cmd.append('--gcc') 116 cmd.append('--gcc')
118 if 'Vulkan' in self._skia_api.builder_name: 117 if 'Vulkan' in self.m.vars.builder_name:
119 cmd.append('--vulkan') 118 cmd.append('--vulkan')
120 self._skia_api.run(self._skia_api.m.step, 'build %s' % target, cmd=cmd, 119 self.m.run(self.m.step, 'build %s' % target, cmd=cmd,
121 env=env, cwd=self._skia_api.m.path['checkout']) 120 env=env, cwd=self.m.path['checkout'])
122 121
123 def device_path_join(self, *args): 122 def device_path_join(self, *args):
124 """Like os.path.join(), but for paths on a connected Android device.""" 123 """Like os.path.join(), but for paths on a connected Android device."""
125 return '/'.join(args) 124 return '/'.join(args)
126 125
127 def device_path_exists(self, path): 126 def device_path_exists(self, path):
128 """Like os.path.exists(), but for paths on a connected device.""" 127 """Like os.path.exists(), but for paths on a connected device."""
129 exists_str = 'FILE_EXISTS' 128 exists_str = 'FILE_EXISTS'
130 return exists_str in self._adb( 129 return exists_str in self._adb(
131 name='exists %s' % self._skia_api.m.path.basename(path), 130 name='exists %s' % self.m.path.basename(path),
132 serial=self.serial, 131 serial=self.serial,
133 cmd=['shell', 'if', '[', '-e', path, '];', 132 cmd=['shell', 'if', '[', '-e', path, '];',
134 'then', 'echo', exists_str + ';', 'fi'], 133 'then', 'echo', exists_str + ';', 'fi'],
135 stdout=self._skia_api.m.raw_io.output(), 134 stdout=self.m.raw_io.output(),
136 infra_step=True 135 infra_step=True
137 ).stdout 136 ).stdout
138 137
139 def _remove_device_dir(self, path): 138 def _remove_device_dir(self, path):
140 """Remove the directory on the device.""" 139 """Remove the directory on the device."""
141 self._adb(name='rmdir %s' % self._skia_api.m.path.basename(path), 140 self._adb(name='rmdir %s' % self.m.path.basename(path),
142 serial=self.serial, 141 serial=self.serial,
143 cmd=['shell', 'rm', '-r', path], 142 cmd=['shell', 'rm', '-r', path],
144 infra_step=True) 143 infra_step=True)
145 # Sometimes the removal fails silently. Verify that it worked. 144 # Sometimes the removal fails silently. Verify that it worked.
146 if self.device_path_exists(path): 145 if self.device_path_exists(path):
147 raise Exception('Failed to remove %s!' % path) # pragma: no cover 146 raise Exception('Failed to remove %s!' % path) # pragma: no cover
148 147
149 def _create_device_dir(self, path): 148 def _create_device_dir(self, path):
150 """Create the directory on the device.""" 149 """Create the directory on the device."""
151 self._adb(name='mkdir %s' % self._skia_api.m.path.basename(path), 150 self._adb(name='mkdir %s' % self.m.path.basename(path),
152 serial=self.serial, 151 serial=self.serial,
153 cmd=['shell', 'mkdir', '-p', path], 152 cmd=['shell', 'mkdir', '-p', path],
154 infra_step=True) 153 infra_step=True)
155 154
156 def copy_directory_contents_to_device(self, host_dir, device_dir): 155 def copy_directory_contents_to_device(self, host_dir, device_dir):
157 """Like shutil.copytree(), but for copying to a connected device.""" 156 """Like shutil.copytree(), but for copying to a connected device."""
158 self._skia_api.run( 157 self.m.run(
159 self._skia_api.m.step, 158 self.m.step,
160 name='push %s' % self._skia_api.m.path.basename(host_dir), 159 name='push %s' % self.m.path.basename(host_dir),
161 cmd=[ 160 cmd=[
162 self.android_bin.join('adb_push_if_needed'), '--verbose', 161 self.android_bin.join('adb_push_if_needed'), '--verbose',
163 ] + self.serial_args + [ 162 ] + self.serial_args + [
164 host_dir, device_dir, 163 host_dir, device_dir,
165 ], 164 ],
166 env=self._default_env, 165 env=self._default_env,
167 infra_step=True) 166 infra_step=True)
168 167
169 def copy_directory_contents_to_host(self, device_dir, host_dir): 168 def copy_directory_contents_to_host(self, device_dir, host_dir):
170 """Like shutil.copytree(), but for copying from a connected device.""" 169 """Like shutil.copytree(), but for copying from a connected device."""
171 self._skia_api.run( 170 self.m.run(
172 self._skia_api.m.step, 171 self.m.step,
173 name='pull %s' % self._skia_api.m.path.basename(device_dir), 172 name='pull %s' % self.m.path.basename(device_dir),
174 cmd=[ 173 cmd=[
175 self.android_bin.join('adb_pull_if_needed'), '--verbose', 174 self.android_bin.join('adb_pull_if_needed'), '--verbose',
176 ] + self.serial_args + [ 175 ] + self.serial_args + [
177 device_dir, host_dir, 176 device_dir, host_dir,
178 ], 177 ],
179 env=self._default_env, 178 env=self._default_env,
180 infra_step=True) 179 infra_step=True)
181 180
182 def copy_file_to_device(self, host_path, device_path): 181 def copy_file_to_device(self, host_path, device_path):
183 """Like shutil.copyfile, but for copying to a connected device.""" 182 """Like shutil.copyfile, but for copying to a connected device."""
184 self._adb(name='push %s' % self._skia_api.m.path.basename(host_path), 183 self._adb(name='push %s' % self.m.path.basename(host_path),
185 serial=self.serial, 184 serial=self.serial,
186 cmd=['push', host_path, device_path], 185 cmd=['push', host_path, device_path],
187 infra_step=True) 186 infra_step=True)
188 187
189 def create_clean_device_dir(self, path): 188 def create_clean_device_dir(self, path):
190 """Like shutil.rmtree() + os.makedirs(), but on a connected device.""" 189 """Like shutil.rmtree() + os.makedirs(), but on a connected device."""
191 self._remove_device_dir(path) 190 self._remove_device_dir(path)
192 self._create_device_dir(path) 191 self._create_device_dir(path)
193 192
194 def has_root(self): 193 def has_root(self):
195 """Determine if we have root access on this device.""" 194 """Determine if we have root access on this device."""
196 # Special case: GalaxyS3 hangs on `adb root`. Don't bother. 195 # Special case: GalaxyS3 hangs on `adb root`. Don't bother.
197 if 'GalaxyS3' in self._skia_api.builder_name: 196 if 'GalaxyS3' in self.m.vars.builder_name:
198 return False 197 return False
199 198
200 # Determine if we have root access. 199 # Determine if we have root access.
201 has_root = False 200 has_root = False
202 try: 201 try:
203 output = self._adb(name='adb root', 202 output = self._adb(name='adb root',
204 serial=self.serial, 203 serial=self.serial,
205 cmd=['root'], 204 cmd=['root'],
206 stdout=self._skia_api.m.raw_io.output(), 205 stdout=self.m.raw_io.output(),
207 infra_step=True).stdout.rstrip() 206 infra_step=True).stdout.rstrip()
208 if ('restarting adbd as root' in output or 207 if ('restarting adbd as root' in output or
209 'adbd is already running as root' in output): 208 'adbd is already running as root' in output):
210 has_root = True 209 has_root = True
211 except self._skia_api.m.step.StepFailure: # pragma: nocover 210 except self.m.step.StepFailure: # pragma: nocover
212 pass 211 pass
213 # Wait for the device to reconnect. 212 # Wait for the device to reconnect.
214 self._skia_api.run( 213 self.m.run(
215 self._skia_api.m.step, 214 self.m.step,
216 name='wait', 215 name='wait',
217 cmd=['sleep', '10'], 216 cmd=['sleep', '10'],
218 infra_step=True) 217 infra_step=True)
219 self._adb.wait_for_device() 218 self._adb.wait_for_device()
220 return has_root 219 return has_root
221 220
222 def install(self): 221 def install(self):
223 """Run device-specific installation steps.""" 222 """Run device-specific installation steps."""
223 device_scratch_dir = self._adb(
224 name='get EXTERNAL_STORAGE dir',
225 serial=self.serial,
226 cmd=['shell', 'echo', '$EXTERNAL_STORAGE'],
227 stdout=self.m.raw_io.output(),
228 infra_step=True,
229 ).stdout.rstrip()
230 prefix = self.device_path_join(device_scratch_dir, 'skiabot', 'skia_')
231 self.device_dirs = default_flavor.DeviceDirs(
232 dm_dir=prefix + 'dm',
233 perf_data_dir=prefix + 'perf',
234 resource_dir=prefix + 'resources',
235 images_dir=prefix + 'images',
236 skp_dir=prefix + 'skp/skps',
237 tmp_dir=prefix + 'tmp_dir')
238
224 self._has_root = self.has_root() 239 self._has_root = self.has_root()
225 self._skia_api.run(self._skia_api.m.step, 240 self.m.run(self.m.step,
226 name='kill skia', 241 name='kill skia',
227 cmd=[ 242 cmd=[
228 self.android_bin.join('android_kill_skia'), 243 self.android_bin.join('android_kill_skia'),
229 '--verbose', 244 '--verbose',
230 ] + self.serial_args, 245 ] + self.serial_args,
231 env=self._default_env, 246 env=self._default_env,
232 infra_step=True) 247 infra_step=True)
233 if self._has_root: 248 if self._has_root:
234 self._adb(name='stop shell', 249 self._adb(name='stop shell',
235 serial=self.serial, 250 serial=self.serial,
(...skipping 14 matching lines...) Expand all
250 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'], 265 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'],
251 infra_step=True) 266 infra_step=True)
252 self._adb(name='cat cpu_freq', 267 self._adb(name='cat cpu_freq',
253 serial=self.serial, 268 serial=self.serial,
254 cmd=['shell', 'cat', 269 cmd=['shell', 'cat',
255 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'], 270 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'],
256 infra_step=True) 271 infra_step=True)
257 272
258 def cleanup_steps(self): 273 def cleanup_steps(self):
259 """Run any device-specific cleanup steps.""" 274 """Run any device-specific cleanup steps."""
260 if self._skia_api.do_test_steps or self._skia_api.do_perf_steps: 275 if self.m.vars.do_test_steps or self.m.vars.do_perf_steps:
261 self._adb(name='final battery stats', 276 self._adb(name='final battery stats',
262 serial=self.serial, 277 serial=self.serial,
263 cmd=['shell', 'dumpsys', 'batteryproperties'], 278 cmd=['shell', 'dumpsys', 'batteryproperties'],
264 infra_step=True) 279 infra_step=True)
265 self._adb(name='reboot', 280 self._adb(name='reboot',
266 serial=self.serial, 281 serial=self.serial,
267 cmd=['reboot'], 282 cmd=['reboot'],
268 infra_step=True) 283 infra_step=True)
269 self._skia_api.run( 284 self.m.run(
270 self._skia_api.m.step, 285 self.m.step,
271 name='wait for reboot', 286 name='wait for reboot',
272 cmd=['sleep', '10'], 287 cmd=['sleep', '10'],
273 infra_step=True) 288 infra_step=True)
274 self._adb.wait_for_device() 289 self._adb.wait_for_device()
275 # The ADB binary conflicts with py-adb used by swarming. Kill it 290 # The ADB binary conflicts with py-adb used by swarming. Kill it
276 # when finished to play nice. 291 # when finished to play nice.
277 self._adb(name='kill-server', 292 self._adb(name='kill-server',
278 serial=self.serial, 293 serial=self.serial,
279 cmd=['kill-server'], 294 cmd=['kill-server'],
280 infra_step=True) 295 infra_step=True)
281 296
282 def read_file_on_device(self, path, *args, **kwargs): 297 def read_file_on_device(self, path, *args, **kwargs):
283 """Read the given file.""" 298 """Read the given file."""
284 return self._adb(name='read %s' % self._skia_api.m.path.basename(path), 299 return self._adb(name='read %s' % self.m.path.basename(path),
285 serial=self.serial, 300 serial=self.serial,
286 cmd=['shell', 'cat', path], 301 cmd=['shell', 'cat', path],
287 stdout=self._skia_api.m.raw_io.output(), 302 stdout=self.m.raw_io.output(),
288 infra_step=True).stdout.rstrip() 303 infra_step=True).stdout.rstrip()
289 304
290 def remove_file_on_device(self, path, *args, **kwargs): 305 def remove_file_on_device(self, path, *args, **kwargs):
291 """Delete the given file.""" 306 """Delete the given file."""
292 return self._adb(name='rm %s' % self._skia_api.m.path.basename(path), 307 return self._adb(name='rm %s' % self.m.path.basename(path),
293 serial=self.serial, 308 serial=self.serial,
294 cmd=['shell', 'rm', '-f', path], 309 cmd=['shell', 'rm', '-f', path],
295 infra_step=True, 310 infra_step=True,
296 *args, 311 *args,
297 **kwargs) 312 **kwargs)
298
299 def get_device_dirs(self):
300 """ Set the directories which will be used by the build steps."""
301 device_scratch_dir = self._adb(
302 name='get EXTERNAL_STORAGE dir',
303 serial=self.serial,
304 cmd=['shell', 'echo', '$EXTERNAL_STORAGE'],
305 stdout=self._skia_api.m.raw_io.output(),
306 infra_step=True,
307 ).stdout.rstrip()
308 prefix = self.device_path_join(device_scratch_dir, 'skiabot', 'skia_')
309 return default_flavor.DeviceDirs(
310 dm_dir=prefix + 'dm',
311 perf_data_dir=prefix + 'perf',
312 resource_dir=prefix + 'resources',
313 images_dir=prefix + 'images',
314 skp_dir=prefix + 'skp/skps',
315 tmp_dir=prefix + 'tmp_dir')
316
OLDNEW
« no previous file with comments | « infra/bots/recipe_modules/flavor/__init__.py ('k') | infra/bots/recipe_modules/flavor/api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698