def __init__(self, udid=None, bid='com.tencent.sng.test.gn', sandbox="VendContainer", lockdown=None): self.lockdown = lockdown if lockdown else LockdownClient(udid) self.bid = bid self.service = None retry = 5 while retry > 0: try: self.service = self.lockdown.startService( "com.apple.mobile.house_arrest") break except: import traceback traceback.print_exc() retry -= 1 time.sleep(5) if self.service is None: raise RuntimeError('Connect to house_arrest failed') self.service.sendPlist({"Command": sandbox, "Identifier": bid}) self.afc_shell = AFCShell(client=self) status = self.service.recvPlist() if status.has_key( 'Error') and status['Error'] == "ApplicationLookupFailed": raise RuntimeWarning('ApplicationLookupFailed') if status.has_key('Status') and status['Status'] != 'Complete': raise RuntimeWarning('House arrest service launch failed') super(SandboxClient, self).__init__(self.lockdown, service=self.service)
class AFCCrashLog(AFCClient): def __init__(self, udid=None, lockdown=None): self.lockdown = lockdown if lockdown else LockdownClient(udid) self.service = None retry = 5 while retry > 0: try: self.service = self.lockdown.startService( "com.apple.crashreportcopymobile") break except: import traceback traceback.print_exc() retry -= 1 time.sleep(10) if self.service is None: raise RuntimeError('Connect to crashreportcopymobile failed') self.afc_shell = AFCShell(client=self) super(AFCCrashLog, self).__init__(self.lockdown, service=self.service) def get_crash_log(self, procname, dest, is_delete=False): local_crashes = [] remote_crash_path = '/' for filename in self.afc_shell.dir_walk(remote_crash_path): if procname in filename: remote_crash_file = os.path.join(remote_crash_path, filename) data = self.afc_shell.get_file_contents(remote_crash_file) local_crash_file = os.path.join(dest, filename) local_crashes.append(local_crash_file) with open(local_crash_file, 'wb') as fp: fp.write(data) if is_delete: self.afc_shell.do_rm(remote_crash_file) return local_crashes
def test_exec_cmd(self): udid = self._get_device() print('udid:%s' % udid) if udid is None: print("no real device found") return AFCShell().onecmd("Hello iPhone!")
def test_get_crash_log(self): mux = USBMux() if not mux.devices: mux.process(0.1) if len(mux.devices) == 0: print("no real device found") self.no_device = True return udid = mux.devices[0].serial procname = "QQ" lockdown = LockdownClient(udid) self.service = lockdown.startService("com.apple.crashreportcopymobile") client = AFCClient(lockdown, service=self.service) afc_shell = AFCShell(client=client) remote_crash_path = '/' dest_path = '/tmp' local_crashes = [] print('udid:', udid) for _dirname, _dirs, files in afc_shell.afc.dir_walk( remote_crash_path): for filename in files: if procname in filename: remote_crash_file = os.path.join(remote_crash_path, filename) data = afc_shell.afc.get_file_contents(remote_crash_file) local_crash_file = os.path.join(dest_path, filename) local_crashes.append(local_crash_file) with open(local_crash_file, 'wb') as fp: fp.write(data) print(local_crashes)
def __init__(self, udid=None, lockdown=None): self.lockdown = lockdown if lockdown else LockdownClient(udid) self.service = None retry = 5 while retry > 0: try: self.service = self.lockdown.startService( "com.apple.crashreportcopymobile") break except: import traceback traceback.print_exc() retry -= 1 time.sleep(10) if self.service is None: raise RuntimeError('Connect to crashreportcopymobile failed') self.afc_shell = AFCShell(client=self) super(AFCCrashLog, self).__init__(self.lockdown, service=self.service)
def setUp(self): mux = USBMux() if not mux.devices: mux.process(0.1) if len(mux.devices) == 0: print("no real device found") self.no_device = True return udid = mux.devices[0].serial lockdown_client = LockdownClient(udid) self.service = lockdown_client.startService( "com.apple.mobile.house_arrest") self.service.sendPlist({ "Command": "VendContainer", "Identifier": "com.gotohack.testapp" }) status = self.service.recvPlist() if 'Error' in status and status['Error'] == "ApplicationLookupFailed": raise RuntimeWarning('ApplicationLookupFailed') if 'Status' in status and status['Status'] != 'Complete': raise RuntimeWarning('House arrest service launch failed') self.afc = AFCClient(lockdown_client, service=self.service) self.afc_shell = AFCShell(client=self.afc)
def shell(self, applicationId, cmd="VendDocuments"): res = self.send_command(applicationId, cmd="VendDocuments") if res: AFCShell(client=self.service).cmdloop()
def test_remove_file_in_sandbox(self): if self.no_device: return shell = AFCShell(client=self.house_arrest_client) shell.do_rm('/Documents/test.log')
def house_arrest_shell(lockdown, applicationId): afc = house_arrest(lockdown, applicationId) if afc: AFCShell(client=afc).cmdloop()
class HouseArrestTest(unittest.TestCase): def setUp(self): mux = USBMux() if not mux.devices: mux.process(0.1) if len(mux.devices) == 0: print("no real device found") self.no_device = True return udid = mux.devices[0].serial lockdown_client = LockdownClient(udid) self.service = lockdown_client.startService( "com.apple.mobile.house_arrest") self.service.sendPlist({ "Command": "VendContainer", "Identifier": "com.gotohack.testapp" }) status = self.service.recvPlist() if 'Error' in status and status['Error'] == "ApplicationLookupFailed": raise RuntimeWarning('ApplicationLookupFailed') if 'Status' in status and status['Status'] != 'Complete': raise RuntimeWarning('House arrest service launch failed') self.afc = AFCClient(lockdown_client, service=self.service) self.afc_shell = AFCShell(client=self.afc) def test_list_files_in_sandbox(self): if self.no_device: return sandbox_tree = [] file_path = '/Documents' for l in self.afc.read_directory(file_path): if l not in ('.', '..'): tmp_dict = {} tmp_dict['path'] = os.path.join(file_path, l) info = self.afc.get_file_info(tmp_dict['path']) tmp_dict['is_dir'] = (info is not None and info['st_ifmt'] == 'S_IFDIR') sandbox_tree.append(tmp_dict) pprint.pprint(sandbox_tree) def test_push_file_to_sandbox(self): if self.no_device: return data = b"hello sandbox!" self.afc.set_file_contents('/Documents/test.log', data) def test_pull_file_from_sandbox(self): if self.no_device: return data = b"hello sandbox!" content = self.afc.get_file_contents('/Documents/test.log') print(content) def test_remove_file_in_sandbox(self): if self.no_device: return self.afc_shell.do_rm('/Documents/test.log') def tearDown(self): if not self.no_device and self.service: self.service.close()
def shell(self, applicationId, cmd="VendContainer"): res = self.send_command(applicationId, cmd) if res: AFCShell(client=self).cmdloop()
class SandboxClient(AFCClient): ''' 访问app的sandbox的类 ''' def __init__(self, udid=None, bid='com.tencent.sng.test.gn', sandbox="VendContainer", lockdown=None): self.lockdown = lockdown if lockdown else LockdownClient(udid) self.bid = bid self.service = None retry = 5 while retry > 0: try: self.service = self.lockdown.startService( "com.apple.mobile.house_arrest") break except: import traceback traceback.print_exc() retry -= 1 time.sleep(5) if self.service is None: raise RuntimeError('Connect to house_arrest failed') self.service.sendPlist({"Command": sandbox, "Identifier": bid}) self.afc_shell = AFCShell(client=self) status = self.service.recvPlist() if status.has_key( 'Error') and status['Error'] == "ApplicationLookupFailed": raise RuntimeWarning('ApplicationLookupFailed') if status.has_key('Status') and status['Status'] != 'Complete': raise RuntimeWarning('House arrest service launch failed') super(SandboxClient, self).__init__(self.lockdown, service=self.service) def copy_to_local(self, remotepath, localpath='/tmp', is_dir=False, is_delete=False): '''拷贝手机中sandbox指定目录的文件到Mac本地 :param remotepath: sandbox上的目录或者文件,例如:/Library/Caches/QQINI/ :type remotepath: str :param localpath: 本地的目录 :type localpath: str :param is_dir: remotepath是否为目录,默认为单个文件 :type is_dir: bool :param is_delete: 是否删除,默认为单个文件 :type is_delete: bool :return: list 拷贝后的本地文件列表 ''' local_files = [] if is_dir: remotefiles = self.afc_shell.dir_walk(remotepath) else: filepath, filename = os.path.split(remotepath) remotefiles = [filename] remotepath = filepath for f in remotefiles: src = os.path.join(remotepath, f) content = self.afc_shell.get_file_contents(src) if content is None: continue dst = os.path.join(localpath, f) local_files.append(dst) with open(dst, 'wb') as fd: fd.write(content) if is_delete: self.afc_shell.do_rm(src) return local_files def copy_to_remote(self, localfile, remotepath): '''拷贝Mac本地文件到手机中sandbox的指定目录 :param localfile: Mac本地文件路径(仅限文件拷贝) :type localfile: str :param remotepath: sandbox上的目录,例如:/Library/Caches/ :type remotepath: str :return: bool ''' result = False with open(localfile, 'rb') as fd: data = fd.read() remotefile = os.path.join(remotepath, os.path.basename(localfile)) status = self.afc_shell.set_file_contents(remotefile, data) if status == 0: result = True return result def remove(self, files): '''删除sandbox中的文件或者目录 ''' self.afc_shell.do_rm(files) def close(self): '''必须显示调用该函数,否则会出现端口泄漏 ''' if self.service: self.service.close()