def copy_test_to_device(build_dir, device_dir, abi): abi_dir = os.path.join(build_dir, 'libs', abi) if not os.path.isdir(abi_dir): raise RuntimeError('No libraries for {}'.format(abi)) test_cases = [] for test_file in os.listdir(abi_dir): if test_file in ('gdbserver', 'gdb.setup'): continue if not test_file.endswith('.so'): test_cases.append(test_file) # TODO(danalbert): Libs with the same name will clobber each other. # This was the case with the old shell based script too. I'm trying not # to change too much in the translation. lib_path = os.path.join(abi_dir, test_file) adb.push(lib_path, device_dir) # TODO(danalbert): Sync data. # The libc++ tests contain a DATA file that lists test names and their # dependencies on file system data. These files need to be copied to # the device. if len(test_cases) == 0: raise RuntimeError('Could not find any test executables.') return test_cases
def generate_tmp_file(): """Generates temp file and pushes it to target""" global tmp_file if not tmp_file: tmp_file = tempfile.NamedTemporaryFile(delete=True) print('*** preparing temporary file with name ' + tmp_file.name) adb.push(tmp_file.name, DEST_FOLDER_TARGET) #gets full path on target for tmp_file global tmp_file_on_target tmp_file_on_target = (DEST_FOLDER_TARGET + os.path.basename(tmp_file.name)) print('*** getting path to tmp_file ' + str(tmp_file.name)) #gets path to dest_folder_host global tmp_file global dest_folder_host dest_folder_host = os.path.dirname(tmp_file.name) print('*** getting path to dest_folder_host ' + dest_folder_host)
def _copy_test_to_device(build_dir, device_dir, abi, test_filters, test_name): abi_dir = os.path.join(build_dir, 'libs', abi) if not os.path.isdir(abi_dir): raise RuntimeError('No libraries for {}'.format(abi)) test_cases = [] for test_file in os.listdir(abi_dir): if test_file in ('gdbserver', 'gdb.setup'): continue file_is_lib = False if not test_file.endswith('.so'): file_is_lib = True case_name = _make_subtest_name(test_name, test_file) if not test_filters.filter(case_name): continue test_cases.append(test_file) # TODO(danalbert): Libs with the same name will clobber each other. # This was the case with the old shell based script too. I'm trying not # to change too much in the translation. lib_path = os.path.join(abi_dir, test_file) print('\tPushing {} to {}...'.format(lib_path, device_dir)) adb.push(lib_path, device_dir) # Binaries pushed from Windows may not have execute permissions. if not file_is_lib: file_path = posixpath.join(device_dir, test_file) adb.shell('chmod +x ' + file_path) # TODO(danalbert): Sync data. # The libc++ tests contain a DATA file that lists test names and their # dependencies on file system data. These files need to be copied to # the device. if len(test_cases) == 0: raise RuntimeError('Could not find any test executables.') return test_cases
def test_push_n_invalid_source_folder(self): global tmp_file result = adb.push(NON_EXISTING_DIR, DEST_FOLDER_TARGET) self.assertNotEqual(str(result), 0)
def test_push_n_invalid_2_sparameter(self): global tmp_file result = adb.push(tmp_file.name,None) self.assertNotEqual(str(result), 0)
def test_push_n_invalid_1_parameter(self): global tmp_file result = adb.push(None,DEST_FOLDER_TARGET) self.assertNotEqual(str(result), 0)
def test_push_p(self): global tmp_file global positive_exp_result_wo_output result = adb.push(tmp_file.name, DEST_FOLDER_TARGET) self.assertEqual(result, positive_exp_result_wo_output)
def _launchAndAttach(self): # name of child binary CHILD_EXECUTABLE = 'plugin-container' # 'file' command argument for parent process PARENT_FILE_PATH = os.path.join(self.libdir, 'bin', 'app_process') # 'file' command argument for child process if self.objdir: CHILD_FILE_PATH = os.path.join(self.objdir, 'dist', 'bin', CHILD_EXECUTABLE) else: CHILD_FILE_PATH = None # launch pkg = self._getPackageName() sys.stdout.write('Launching %s... ' % pkg) sys.stdout.flush() out = adb.call(['shell', 'am', 'start', '-a', 'org.mozilla.gecko.DEBUG', '-n', pkg + '/.App']) if 'error' in out.lower(): print '' print out raise gdb.GdbError('Error while launching %s.' % pkg) # FIXME sleep for 1s to allow time to launch time.sleep(1) # wait for launch to complete pkgProcs = [] while not [True for x in pkgProcs if CHILD_EXECUTABLE not in x]: ps = adb.call(['shell', 'ps']).splitlines() # get parent/child processes that are waiting ('S' state) pkgProcs = [x for x in ps if pkg in x and ('S' in x.split() or 'T' in x.split())] print 'Done' # get parent/child(ren) pid's pidParent = next((x.split()[1] for x in pkgProcs if CHILD_EXECUTABLE not in x)) pidChild = [x.split()[1] for x in pkgProcs if CHILD_EXECUTABLE in x] pidChildParent = pidParent # see if any gdbserver instance is running, and discard # the debuggee from our list because it's already taken for proc in [x.split() for x in ps if 'gdbserver' in x]: # get the program being debugged by examine gdbserver cmdline cmdline = adb.call(['shell', 'cat', '/proc/' + proc[1] + '/cmdline']).split('\0') if '--attach' not in cmdline: continue # this should be the pid pid = next((x for x in reversed(cmdline) if x.isdigit())) if pid == pidParent: pidParent = None elif pid in pidChild: pidChild.remove(pid) if pidParent: # the parent is not being debugged, pick the parent pidAttach = pidParent sys.stdout.write('Attaching to parent (pid %s)... ' % pidAttach) sys.stdout.flush() elif not pidChild: # ok, no child is available. assume the user # wants to wait for child to start up pkgProcs = None print 'Waiting for child process...' while not pkgProcs: ps = adb.call(['shell', 'ps']).splitlines() # check for 'S' state, for right parent, and for right child pkgProcs = [x for x in ps if ('S' in x or 'T' in x) and \ pidChildParent in x and CHILD_EXECUTABLE in x] pidChild = [x.split()[1] for x in pkgProcs] # if the parent was not picked, pick the right child if not pidParent and len(pidChild) == 1: # that is easy pidAttach = pidChild[0] sys.stdout.write('Attaching to child (pid %s)... ' % pidAttach) sys.stdout.flush() elif not pidParent: # should not happen for now, because we only use one child pidAttach = None while pidAttach not in pidChild: print 'WTF multiple child processes found:' for i in range(len(pidChild)): print '%d. pid %s' % (i + 1, pidChild[i]) pidAttach = readinput.call('Child pid: ', '-l', str(pidChild)) if pidAttach.isdigit() and int(pidAttach) > 0 \ and int(pidAttach) <= len(pidChild): pidAttach = pidChild[pidAttach] sys.stdout.write('Attaching... ') sys.stdout.flush() self.pid = pidAttach # push gdbserver if it's not there gdbserverPath = '/data/local/tmp/gdbserver' if not adb.pathExists(gdbserverPath): adb.push(os.path.join(self.bindir, 'gdbserver'), gdbserverPath) # run this after fork() and before exec(gdbserver) # so 'adb shell gdbserver' doesn't get gdb's signals def gdbserverPreExec(): os.setpgrp() # can we run as root? if 'uid=0' in adb.call(['shell', 'id']): gdbserverProc = adb.call(['shell', gdbserverPath, '--attach', ':0', pidAttach], stderr=subprocess.PIPE, async=True, preexec_fn=gdbserverPreExec) else: sys.stdout.write('as non-root... ') sys.stdout.flush() gdbserverProc = adb.call(['shell', 'run-as', pkg, gdbserverPath, '--attach', ':0', pidAttach], stderr=subprocess.PIPE, async=True, preexec_fn=gdbserverPreExec) # we passed ':0' to gdbserver so it'll pick a port for us # but that means we have to find the port from stdout # while this complicates things a little, it allows us to # have multiple gdbservers running port = None while not port: if gdbserverProc.poll() is not None: print '' print gdbserverProc.stdout.read() raise gdb.GdbError('gdbserver exited unexpectedly') line = gdbserverProc.stdout.readline().split() # kind of hacky, assume the port number comes after 'port' if 'port' in line: port = line[line.index('port') + 1] self.port = port self.gdbserver = gdbserverProc # collect output from gdbserver in another thread def makeGdbserverWait(obj, proc): def gdbserverWait(): obj.gdbserverOut = proc.communicate(); return gdbserverWait; threading.Thread( target = makeGdbserverWait(self, gdbserverProc)).start() # forward the port that gdbserver gave us adb.forward('tcp:' + port, 'tcp:' + port) print 'Done' sys.stdout.write('Setting up remote debugging... ') sys.stdout.flush() # load the right file gdb.execute('file ' + (PARENT_FILE_PATH if pidParent else CHILD_FILE_PATH), False, True) gdb.execute('target remote :' + port, False, True) print 'Done\n' if pidParent: print 'Run another gdb session to debug child process.\n' print 'Ready. Use "continue" to resume execution.'
def test_push_n_invalid_2_sparameter(self): global tmp_file result = adb.push(tmp_file.name, None) self.assertNotEqual(str(result), 0)
def test_push_n_invalid_1_parameter(self): global tmp_file result = adb.push(None, DEST_FOLDER_TARGET) self.assertNotEqual(str(result), 0)