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 9import default_flavor 10import os 11import subprocess 12 13 14"""iOS flavor utils, used for building for and running tests on iOS.""" 15 16 17class iOSFlavorUtils(default_flavor.DefaultFlavorUtils): 18 def __init__(self, bot_info): 19 super(iOSFlavorUtils, self).__init__(bot_info) 20 self.ios_bin = os.path.join(self._bot_info.skia_dir, 'platform_tools', 21 'ios', 'bin') 22 23 def step(self, cmd, **kwargs): 24 args = [os.path.join(self.ios_bin, 'ios_run_skia')] 25 26 # Convert 'dm' and 'nanobench' from positional arguments 27 # to flags, which is what iOSShell expects to select which 28 # one is being run. 29 cmd = ["--" + c if c in ['dm', 'nanobench'] else c 30 for c in cmd] 31 return self._bot_info.run(args + cmd, **kwargs) 32 33 def compile(self, target): 34 """Build the given target.""" 35 cmd = [os.path.join(self.ios_bin, 'ios_ninja')] 36 self._bot_info.run(cmd) 37 38 def device_path_join(self, *args): 39 """Like os.path.join(), but for paths on a connected iOS device.""" 40 return '/'.join(args) 41 42 def device_path_exists(self, path): 43 """Like os.path.exists(), but for paths on a connected device.""" 44 return self._bot_info.run( 45 [os.path.join(self.ios_bin, 'ios_path_exists'), path], 46 ) # pragma: no cover 47 48 def _remove_device_dir(self, path): 49 """Remove the directory on the device.""" 50 return self._bot_info.run( 51 [os.path.join(self.ios_bin, 'ios_rm'), path], 52 ) 53 54 def _create_device_dir(self, path): 55 """Create the directory on the device.""" 56 return self._bot_info.run( 57 [os.path.join(self.ios_bin, 'ios_mkdir'), path], 58 ) 59 60 def copy_directory_contents_to_device(self, host_dir, device_dir): 61 """Like shutil.copytree(), but for copying to a connected device.""" 62 return self._bot_info.run([ 63 os.path.join(self.ios_bin, 'ios_push_if_needed'), 64 host_dir, device_dir 65 ]) 66 67 def copy_directory_contents_to_host(self, device_dir, host_dir): 68 """Like shutil.copytree(), but for copying from a connected device.""" 69 return self._bot_info.run( 70 [os.path.join(self.ios_bin, 'ios_pull_if_needed'), 71 device_dir, host_dir], 72 ) 73 74 def copy_file_to_device(self, host_path, device_path): 75 """Like shutil.copyfile, but for copying to a connected device.""" 76 self._bot_info.run( 77 [os.path.join(self.ios_bin, 'ios_push_file'), host_path, device_path], 78 ) # pragma: no cover 79 80 def create_clean_device_dir(self, path): 81 """Like shutil.rmtree() + os.makedirs(), but on a connected device.""" 82 self._remove_device_dir(path) 83 self._create_device_dir(path) 84 85 def install(self): 86 """Run device-specific installation steps.""" 87 self._bot_info.run([os.path.join(self.ios_bin, 'ios_install')]) 88 89 def cleanup_steps(self): 90 """Run any device-specific cleanup steps.""" 91 self._bot_info.run([os.path.join(self.ios_bin, 'ios_restart')]) 92 self._bot_info.run(['sleep', '20']) 93 94 def read_file_on_device(self, path): 95 """Read the given file.""" 96 return subprocess.check_output( 97 [os.path.join(self.ios_bin, 'ios_cat_file'), path]).rstrip() 98 99 def remove_file_on_device(self, path): 100 """Remove the file on the device.""" 101 return self._bot_info.run( 102 [os.path.join(self.ios_bin, 'ios_rm'), path], 103 ) 104 105 def get_device_dirs(self): 106 """ Set the directories which will be used by the build steps.""" 107 prefix = self.device_path_join('skiabot', 'skia_') 108 return default_flavor.DeviceDirs( 109 dm_dir=prefix + 'dm', 110 perf_data_dir=prefix + 'perf', 111 resource_dir=prefix + 'resources', 112 images_dir=prefix + 'images', 113 skp_dir=prefix + 'skp/skps', 114 tmp_dir=prefix + 'tmp_dir') 115