diff options
author | Cassidy Burden <cburden@google.com> | 2016-08-11 15:05:38 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-16 10:33:25 -0700 |
commit | 4cc3dd8a3b2ab04cf861d7c71967de0298746cb9 (patch) | |
tree | b032d8da64ed4da9ebbd170598377272cb9ae1a2 | |
parent | b217c8a28be52f90572d26647d38dcfc9e08ce0b (diff) | |
download | toolchain-utils-4cc3dd8a3b2ab04cf861d7c71967de0298746cb9.tar.gz |
binary search tool: Run tc_pyformat on all python scripts
REFACTOR WARNING! Run tc_pyformat on all python scripts.
TEST=Run unit tests, Android bisection
Change-Id: I9624e7be2670bdb29bcdb59404bf9e8c2f7d81c5
Reviewed-on: https://chrome-internal-review.googlesource.com/274615
Commit-Ready: Caroline Tice <cmtice@google.com>
Tested-by: Caroline Tice <cmtice@google.com>
Reviewed-by: Caroline Tice <cmtice@google.com>
-rwxr-xr-x | binary_search_tool/binary_search_perforce.py | 257 | ||||
-rwxr-xr-x | binary_search_tool/binary_search_state.py | 72 | ||||
-rwxr-xr-x | binary_search_tool/bisect.py | 81 | ||||
-rw-r--r-- | binary_search_tool/common.py | 210 | ||||
-rwxr-xr-x | binary_search_tool/cros_pkg/create_cleanup_script.py | 44 | ||||
-rwxr-xr-x | binary_search_tool/test/binary_search_tool_tester.py | 22 | ||||
-rwxr-xr-x | binary_search_tool/test/gen_init_list.py | 4 | ||||
-rwxr-xr-x | binary_search_tool/test/gen_obj.py | 46 |
8 files changed, 391 insertions, 345 deletions
diff --git a/binary_search_tool/binary_search_perforce.py b/binary_search_tool/binary_search_perforce.py index 3c1e9b51..7ac2fba6 100755 --- a/binary_search_tool/binary_search_perforce.py +++ b/binary_search_tool/binary_search_perforce.py @@ -14,55 +14,58 @@ from cros_utils import logger verbose = True + def _GetP4ClientSpec(client_name, p4_paths): - p4_string = "" + p4_string = '' for p4_path in p4_paths: - if " " not in p4_path: - p4_string += " -a %s" % p4_path + if ' ' not in p4_path: + p4_string += ' -a %s' % p4_path else: - p4_string += " -a \"" + (" //" + client_name + "/").join(p4_path) + "\"" + p4_string += " -a \"" + (' //' + client_name + '/').join(p4_path) + "\"" return p4_string -def GetP4Command(client_name, p4_port, p4_paths, checkoutdir, - p4_snapshot=""): - command = "" +def GetP4Command(client_name, p4_port, p4_paths, checkoutdir, p4_snapshot=''): + command = '' if p4_snapshot: - command += "mkdir -p " + checkoutdir + command += 'mkdir -p ' + checkoutdir for p4_path in p4_paths: real_path = p4_path[1] - if real_path.endswith("..."): - real_path = real_path.replace("/...", "") - command += ("; mkdir -p " + checkoutdir + "/" + - os.path.dirname(real_path)) - command += ("&& rsync -lr " + p4_snapshot + "/" + real_path + - " " + checkoutdir + "/" + os.path.dirname(real_path)) + if real_path.endswith('...'): + real_path = real_path.replace('/...', '') + command += ( + '; mkdir -p ' + checkoutdir + '/' + os.path.dirname(real_path)) + command += ('&& rsync -lr ' + p4_snapshot + '/' + real_path + ' ' + + checkoutdir + '/' + os.path.dirname(real_path)) return command - command += " export P4CONFIG=.p4config" - command += " && mkdir -p " + checkoutdir - command += " && cd " + checkoutdir - command += " && cp ${HOME}/.p4config ." - command += " && chmod u+w .p4config" + command += ' export P4CONFIG=.p4config' + command += ' && mkdir -p ' + checkoutdir + command += ' && cd ' + checkoutdir + command += ' && cp ${HOME}/.p4config .' + command += ' && chmod u+w .p4config' command += " && echo \"P4PORT=" + p4_port + "\" >> .p4config" command += " && echo \"P4CLIENT=" + client_name + "\" >> .p4config" - command += (" && g4 client " + - _GetP4ClientSpec(client_name, p4_paths)) - command += " && g4 sync " - command += " && cd -" + command += (' && g4 client ' + _GetP4ClientSpec(client_name, p4_paths)) + command += ' && g4 sync ' + command += ' && cd -' return command + class BinarySearchPoint(object): """Class of binary search point.""" + def __init__(self, revision, status, tag=None): self.revision = revision self.status = status self.tag = tag + class BinarySearcher(object): """Class of binary searcher.""" + def __init__(self, logger_to_set=None): self.sorted_list = [] self.index_log = [] @@ -85,14 +88,12 @@ class BinarySearcher(object): self.lo = 0 self.points = {} for i in range(len(self.sorted_list)): - bsp = BinarySearchPoint(self.sorted_list[i], -1, "Not yet done.") + bsp = BinarySearchPoint(self.sorted_list[i], -1, 'Not yet done.') self.points[i] = bsp def SetStatus(self, status, tag=None): - message = ("Revision: %s index: %d returned: %d" % - (self.sorted_list[self.current], - self.current, - status)) + message = ('Revision: %s index: %d returned: %d' % + (self.sorted_list[self.current], self.current, status)) self.logger.LogOutput(message, print_to_console=verbose) assert status == 0 or status == 1 or status == 125 self.index_log.append(self.current) @@ -108,14 +109,12 @@ class BinarySearcher(object): self.lo = self.current + 1 elif status == 1: self.hi = self.current - self.logger.LogOutput("lo: %d hi: %d\n" % (self.lo, self.hi)) - self.current = (self.lo + self.hi)/2 + self.logger.LogOutput('lo: %d hi: %d\n' % (self.lo, self.hi)) + self.current = (self.lo + self.hi) / 2 if self.lo == self.hi: - message = ("Search complete. First bad version: %s" - " at index: %d" % - (self.sorted_list[self.current], - self.lo)) + message = ('Search complete. First bad version: %s' + ' at index: %d' % (self.sorted_list[self.current], self.lo)) self.logger.LogOutput(message) return True @@ -123,7 +122,7 @@ class BinarySearcher(object): if index not in self.skipped_indices: return False self.logger.LogOutput( - "All skipped indices between: %d and %d\n" % (self.lo, self.hi), + 'All skipped indices between: %d and %d\n' % (self.lo, self.hi), print_to_console=verbose) return True @@ -143,7 +142,7 @@ class BinarySearcher(object): else: self.current = element[1] return - assert len(q), "Queue should never be 0-size!" + assert len(q), 'Queue should never be 0-size!' def GetNextFlakyLinear(self): current_hi = self.current @@ -168,54 +167,58 @@ class BinarySearcher(object): self.GetNextFlakyBinary() # TODO: Add an estimated time remaining as well. - message = ("Estimated tries: min: %d max: %d\n" % + message = ('Estimated tries: min: %d max: %d\n' % (1 + math.log(self.hi - self.lo, 2), self.hi - self.lo - len(self.skipped_indices))) self.logger.LogOutput(message, print_to_console=verbose) - message = ("lo: %d hi: %d current: %d version: %s\n" % - (self.lo, self.hi, self.current, - self.sorted_list[self.current])) + message = ('lo: %d hi: %d current: %d version: %s\n' % + (self.lo, self.hi, self.current, self.sorted_list[self.current])) self.logger.LogOutput(message, print_to_console=verbose) self.logger.LogOutput(str(self), print_to_console=verbose) return self.sorted_list[self.current] def SetLoRevision(self, lo_revision): self.lo = self.sorted_list.index(lo_revision) + def SetHiRevision(self, hi_revision): self.hi = self.sorted_list.index(hi_revision) + def GetAllPoints(self): - to_return = "" + to_return = '' for i in range(len(self.sorted_list)): - to_return += ("%d %d %s\n" % - (self.points[i].status, - i, - self.points[i].revision)) + to_return += ('%d %d %s\n' % (self.points[i].status, i, + self.points[i].revision)) return to_return + def __str__(self): - to_return = "" - to_return += "Current: %d\n" % self.current - to_return += str(self.index_log) + "\n" + to_return = '' + to_return += 'Current: %d\n' % self.current + to_return += str(self.index_log) + '\n' revision_log = [] for index in self.index_log: revision_log.append(self.sorted_list[index]) - to_return += str(revision_log) + "\n" - to_return += str(self.status_log) + "\n" - to_return += "Skipped indices:\n" - to_return += str(self.skipped_indices) + "\n" + to_return += str(revision_log) + '\n' + to_return += str(self.status_log) + '\n' + to_return += 'Skipped indices:\n' + to_return += str(self.skipped_indices) + '\n' to_return += self.GetAllPoints() return to_return + class RevisionInfo(object): """Class of reversion info.""" + def __init__(self, date, client, description): self.date = date self.client = client self.description = description self.status = -1 + class VCSBinarySearcher(object): """Class of VCS binary searcher.""" + def __init__(self): self.bs = BinarySearcher() self.rim = {} @@ -225,27 +228,35 @@ class VCSBinarySearcher(object): def Initialize(self): pass + def GetNextRevision(self): pass + def CheckoutRevision(self, revision): pass + def SetStatus(self, status): pass + def Cleanup(self): pass + def SetGoodRevision(self, revision): if revision is None: return assert revision in self.bs.sorted_list self.bs.SetLoRevision(revision) + def SetBadRevision(self, revision): if revision is None: return assert revision in self.bs.sorted_list self.bs.SetHiRevision(revision) + class P4BinarySearcher(VCSBinarySearcher): """Class of P4 binary searcher.""" + def __init__(self, p4_port, p4_paths, test_command): VCSBinarySearcher.__init__(self) self.p4_port = p4_port @@ -253,19 +264,19 @@ class P4BinarySearcher(VCSBinarySearcher): self.test_command = test_command self.checkout_dir = tempfile.mkdtemp() self.ce = command_executer.GetCommandExecuter() - self.client_name = "binary-searcher-$HOSTNAME-$USER" - self.job_log_root = "/home/asharif/www/coreboot_triage/" + self.client_name = 'binary-searcher-$HOSTNAME-$USER' + self.job_log_root = '/home/asharif/www/coreboot_triage/' self.changes = None def Initialize(self): self.Cleanup() - command = GetP4Command(self.client_name, self.p4_port, - self.p4_paths, 1, self.checkout_dir) + command = GetP4Command(self.client_name, self.p4_port, self.p4_paths, 1, + self.checkout_dir) self.ce.RunCommand(command) - command = "cd %s && g4 changes ..." % self.checkout_dir + command = 'cd %s && g4 changes ...' % self.checkout_dir _, out, _ = self.ce.RunCommandWOutput(command) - self.changes = re.findall(r"Change (\d+)", out) - change_infos = re.findall(r"Change (\d+) on ([\d/]+) by " + self.changes = re.findall(r'Change (\d+)', out) + change_infos = re.findall(r'Change (\d+) on ([\d/]+) by ' r"([^\s]+) ('[^']*')", out) for change_info in change_infos: ri = RevisionInfo(change_info[1], change_info[2], change_info[3]) @@ -273,34 +284,37 @@ class P4BinarySearcher(VCSBinarySearcher): # g4 gives changes in reverse chronological order. self.changes.reverse() self.bs.SetSortedList(self.changes) + def SetStatus(self, status): self.rim[self.current_revision].status = status return self.bs.SetStatus(status) + def GetNextRevision(self): next_revision = self.bs.GetNext() self.current_revision = next_revision return next_revision + def CleanupCLs(self): - if not os.path.isfile(self.checkout_dir + "/.p4config"): - command = "cd %s" % self.checkout_dir - command += " && cp ${HOME}/.p4config ." + if not os.path.isfile(self.checkout_dir + '/.p4config'): + command = 'cd %s' % self.checkout_dir + command += ' && cp ${HOME}/.p4config .' command += " && echo \"P4PORT=" + self.p4_port + "\" >> .p4config" command += " && echo \"P4CLIENT=" + self.client_name + "\" >> .p4config" self.ce.RunCommand(command) - command = "cd %s" % self.checkout_dir - command += "; g4 changes -c %s" % self.client_name + command = 'cd %s' % self.checkout_dir + command += '; g4 changes -c %s' % self.client_name _, out, _ = self.ce.RunCommandWOUTPUOT(command) - changes = re.findall(r"Change (\d+)", out) + changes = re.findall(r'Change (\d+)', out) if len(changes) != 0: - command = "cd %s" % self.checkout_dir + command = 'cd %s' % self.checkout_dir for change in changes: - command += "; g4 revert -c %s" % change + command += '; g4 revert -c %s' % change self.ce.RunCommand(command) def CleanupClient(self): - command = "cd %s" % self.checkout_dir - command += "; g4 revert ..." - command += "; g4 client -d %s" % self.client_name + command = 'cd %s' % self.checkout_dir + command += '; g4 revert ...' + command += '; g4 client -d %s' % self.client_name self.ce.RunCommand(command) def Cleanup(self): @@ -308,27 +322,23 @@ class P4BinarySearcher(VCSBinarySearcher): self.CleanupClient() def __str__(self): - to_return = "" + to_return = '' for change in self.changes: ri = self.rim[change] if ri.status == -1: - to_return = "%s\t%d\n" % (change, ri.status) + to_return = '%s\t%d\n' % (change, ri.status) else: - to_return += ("%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\n" % - (change, - ri.status, - ri.date, - ri.client, - ri.description, - self.job_log_root + change + ".cmd", - self.job_log_root + change + ".out", - self.job_log_root + change + ".err")) + to_return += ('%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\n' % + (change, ri.status, ri.date, ri.client, ri.description, + self.job_log_root + change + '.cmd', + self.job_log_root + change + '.out', + self.job_log_root + change + '.err')) return to_return - class P4GCCBinarySearcher(P4BinarySearcher): """Class of P4 gcc binary searcher.""" + # TODO: eventually get these patches from g4 instead of creating them manually def HandleBrokenCLs(self, current_revision): cr = int(current_revision) @@ -336,30 +346,29 @@ class P4GCCBinarySearcher(P4BinarySearcher): problematic_ranges.append([44528, 44539]) problematic_ranges.append([44528, 44760]) problematic_ranges.append([44335, 44882]) - command = "pwd" + command = 'pwd' for pr in problematic_ranges: if cr in range(pr[0], pr[1]): - patch_file = "/home/asharif/triage_tool/%d-%d.patch" % (pr[0], pr[1]) + patch_file = '/home/asharif/triage_tool/%d-%d.patch' % (pr[0], pr[1]) f = open(patch_file) patch = f.read() f.close() - files = re.findall("--- (//.*)", patch) - command += "; cd %s" % self.checkout_dir + files = re.findall('--- (//.*)', patch) + command += '; cd %s' % self.checkout_dir for f in files: - command += "; g4 open %s" % f - command += "; patch -p2 < %s" % patch_file + command += '; g4 open %s' % f + command += '; patch -p2 < %s' % patch_file self.current_ce.RunCommand(command) def CheckoutRevision(self, current_revision): - job_logger = logger.Logger(self.job_log_root, - current_revision, - True, subdir="") + job_logger = logger.Logger( + self.job_log_root, current_revision, True, subdir='') self.current_ce = command_executer.GetCommandExecuter(job_logger) self.CleanupCLs() # Change the revision of only the gcc part of the toolchain. - command = ("cd %s/gcctools/google_vendor_src_branch/gcc " - "&& g4 revert ...; g4 sync @%s" % + command = ('cd %s/gcctools/google_vendor_src_branch/gcc ' + '&& g4 revert ...; g4 sync @%s' % (self.checkout_dir, current_revision)) self.current_ce.RunCommand(command) @@ -369,30 +378,36 @@ class P4GCCBinarySearcher(P4BinarySearcher): def Main(argv): """The main function.""" # Common initializations -### command_executer.InitCommandExecuter(True) + ### command_executer.InitCommandExecuter(True) ce = command_executer.GetCommandExecuter() parser = argparse.ArgumentParser() - parser.add_argument("-n", "--num_tries", dest="num_tries", - default="100", - help="Number of tries.") - parser.add_argument("-g", "--good_revision", dest="good_revision", - help="Last known good revision.") - parser.add_argument("-b", "--bad_revision", dest="bad_revision", - help="Last known bad revision.") - parser.add_argument("-s", - "--script", - dest="script", - help="Script to run for every version.") + parser.add_argument( + '-n', + '--num_tries', + dest='num_tries', + default='100', + help='Number of tries.') + parser.add_argument( + '-g', + '--good_revision', + dest='good_revision', + help='Last known good revision.') + parser.add_argument( + '-b', + '--bad_revision', + dest='bad_revision', + help='Last known bad revision.') + parser.add_argument( + '-s', '--script', dest='script', help='Script to run for every version.') options = parser.parse_args(argv) # First get all revisions - p4_paths = ["//depot2/gcctools/google_vendor_src_branch/gcc/gcc-4.4.3/...", - "//depot2/gcctools/google_vendor_src_branch/binutils/" - "binutils-2.20.1-mobile/...", - "//depot2/gcctools/google_vendor_src_branch/" - "binutils/binutils-20100303/..."] - p4gccbs = P4GCCBinarySearcher("perforce2:2666", p4_paths, "") - + p4_paths = ['//depot2/gcctools/google_vendor_src_branch/gcc/gcc-4.4.3/...', + '//depot2/gcctools/google_vendor_src_branch/binutils/' + 'binutils-2.20.1-mobile/...', + '//depot2/gcctools/google_vendor_src_branch/' + 'binutils/binutils-20100303/...'] + p4gccbs = P4GCCBinarySearcher('perforce2:2666', p4_paths, '') # Main loop: terminated = False @@ -408,9 +423,9 @@ def Main(argv): # Now run command to get the status ce = command_executer.GetCommandExecuter() - command = "%s %s" % (script, p4gccbs.checkout_dir) + command = '%s %s' % (script, p4gccbs.checkout_dir) status = ce.RunCommand(command) - message = ("Revision: %s produced: %d status\n" % + message = ('Revision: %s produced: %d status\n' % (current_revision, status)) logger.GetLogger().LogOutput(message, print_to_console=verbose) terminated = p4gccbs.SetStatus(status) @@ -418,17 +433,15 @@ def Main(argv): logger.GetLogger().LogOutput(str(p4gccbs), print_to_console=verbose) if not terminated: - logger.GetLogger().LogOutput("Tries: %d expired." % num_tries, - print_to_console=verbose) - logger.GetLogger().LogOutput(str(p4gccbs.bs), - print_to_console=verbose) + logger.GetLogger().LogOutput( + 'Tries: %d expired.' % num_tries, print_to_console=verbose) + logger.GetLogger().LogOutput(str(p4gccbs.bs), print_to_console=verbose) except (KeyboardInterrupt, SystemExit): - logger.GetLogger().LogOutput("Cleaning up...") + logger.GetLogger().LogOutput('Cleaning up...') finally: - logger.GetLogger().LogOutput(str(p4gccbs.bs), - print_to_console=verbose) + logger.GetLogger().LogOutput(str(p4gccbs.bs), print_to_console=verbose) status = p4gccbs.Cleanup() -if __name__ == "__main__": +if __name__ == '__main__': Main(sys.argv[1:]) diff --git a/binary_search_tool/binary_search_state.py b/binary_search_tool/binary_search_state.py index f78e768c..a04d04da 100755 --- a/binary_search_tool/binary_search_state.py +++ b/binary_search_tool/binary_search_state.py @@ -29,6 +29,7 @@ STATE_FILE = '%s.state' % sys.argv[0] HIDDEN_STATE_FILE = os.path.join( os.path.dirname(STATE_FILE), '.%s' % os.path.basename(STATE_FILE)) + class Error(Exception): """The general binary search tool error class.""" pass @@ -97,20 +98,22 @@ class BinarySearchState(object): def SwitchToGood(self, item_list): """Switch given items to "good" set.""" if self.incremental: - self.l.LogOutput('Incremental set. Wanted to switch %s to good' % - str(item_list), print_to_console=self.verbose) + self.l.LogOutput( + 'Incremental set. Wanted to switch %s to good' % str(item_list), + print_to_console=self.verbose) incremental_items = [ item for item in item_list if item not in self.currently_good_items ] item_list = incremental_items - self.l.LogOutput('Incremental set. Actually switching %s to good' % - str(item_list), print_to_console=self.verbose) + self.l.LogOutput( + 'Incremental set. Actually switching %s to good' % str(item_list), + print_to_console=self.verbose) if not item_list: return - self.l.LogOutput('Switching %s to good' % str(item_list), - print_to_console=self.verbose) + self.l.LogOutput( + 'Switching %s to good' % str(item_list), print_to_console=self.verbose) self.RunSwitchScript(self.switch_to_good, item_list) self.currently_good_items = self.currently_good_items.union(set(item_list)) self.currently_bad_items.difference_update(set(item_list)) @@ -118,20 +121,22 @@ class BinarySearchState(object): def SwitchToBad(self, item_list): """Switch given items to "bad" set.""" if self.incremental: - self.l.LogOutput('Incremental set. Wanted to switch %s to bad' % - str(item_list), print_to_console=self.verbose) + self.l.LogOutput( + 'Incremental set. Wanted to switch %s to bad' % str(item_list), + print_to_console=self.verbose) incremental_items = [ item for item in item_list if item not in self.currently_bad_items ] item_list = incremental_items - self.l.LogOutput('Incremental set. Actually switching %s to bad' % - str(item_list), print_to_console=self.verbose) + self.l.LogOutput( + 'Incremental set. Actually switching %s to bad' % str(item_list), + print_to_console=self.verbose) if not item_list: return - self.l.LogOutput('Switching %s to bad' % str(item_list), - print_to_console=self.verbose) + self.l.LogOutput( + 'Switching %s to bad' % str(item_list), print_to_console=self.verbose) self.RunSwitchScript(self.switch_to_bad, item_list) self.currently_bad_items = self.currently_bad_items.union(set(item_list)) self.currently_good_items.difference_update(set(item_list)) @@ -213,8 +218,7 @@ class BinarySearchState(object): Perform full search until prune_iterations number of bad items are found. """ - while (True and - len(self.all_items) > 1 and + while (True and len(self.all_items) > 1 and self.prune_cycles < self.prune_iterations): terminated = self.DoBinarySearch() self.prune_cycles += 1 @@ -231,12 +235,12 @@ class BinarySearchState(object): # If already seen item we have no new bad items to find, finish up if self.all_items[prune_index] in self.found_items: - self.l.LogOutput('Found item already found before: %s.' % - self.all_items[prune_index], - print_to_console=self.verbose) + self.l.LogOutput( + 'Found item already found before: %s.' % + self.all_items[prune_index], + print_to_console=self.verbose) self.l.LogOutput('No more bad items remaining. Done searching.') - self.l.LogOutput('Bad items are: %s' % - ' '.join(self.found_items)) + self.l.LogOutput('Bad items are: %s' % ' '.join(self.found_items)) break new_all_items = list(self.all_items) @@ -252,9 +256,10 @@ class BinarySearchState(object): self.known_good.update(new_all_items[:prune_index]) new_all_items = new_all_items[prune_index:] - self.l.LogOutput('Old list: %s. New list: %s' % (str(self.all_items), - str(new_all_items)), - print_to_console=self.verbose) + self.l.LogOutput( + 'Old list: %s. New list: %s' % (str(self.all_items), + str(new_all_items)), + print_to_console=self.verbose) if not self.prune: self.l.LogOutput('Not continuning further, --prune is not set') @@ -307,9 +312,8 @@ class BinarySearchState(object): command: path to executable that will enumerate items. """ ce = command_executer.GetCommandExecuter() - _, out, _ = ce.RunCommandWExceptionCleanup(command, - return_output=True, - print_to_console=self.verbose) + _, out, _ = ce.RunCommandWExceptionCleanup( + command, return_output=True, print_to_console=self.verbose) all_items = out.split() self.PopulateItemsUsingList(all_items) @@ -437,8 +441,7 @@ class BinarySearchState(object): '%s\n') out = out % (self.search_cycles + 1, math.ceil(math.log(len(self.all_items), 2)), - self.prune_cycles + 1, - self.prune_iterations, + self.prune_cycles + 1, self.prune_iterations, ', '.join(self.found_items)) self._OutputProgress(out) @@ -488,9 +491,18 @@ def _CanonicalizeScript(script_name): return os.path.join('.', script_name) -def Run(get_initial_items, switch_to_good, switch_to_bad, test_script, - test_setup_script=None, iterations=50, prune=False, noincremental=False, - file_args=False, verify=True, prune_iterations=100, verbose=False, +def Run(get_initial_items, + switch_to_good, + switch_to_bad, + test_script, + test_setup_script=None, + iterations=50, + prune=False, + noincremental=False, + file_args=False, + verify=True, + prune_iterations=100, + verbose=False, resume=False): """Run binary search tool. Equivalent to running through terminal. diff --git a/binary_search_tool/bisect.py b/binary_search_tool/bisect.py index f6928115..383fa265 100755 --- a/binary_search_tool/bisect.py +++ b/binary_search_tool/bisect.py @@ -250,7 +250,7 @@ class BisectAndroid(Bisector): self.options.dir = os.environ.get('BISECT_DIR', self.default_dir) num_jobs = "NUM_JOBS='%s'" % self.options.num_jobs - device_id = "" + device_id = '' if self.options.device_id: device_id = "ANDROID_SERIAL='%s'" % self.options.device_id @@ -317,21 +317,23 @@ See below for full override argument reference: def Main(argv): - override_parser = argparse.ArgumentParser(add_help=False, - argument_default=argparse.SUPPRESS, - usage='bisect.py {mode} [options]') + override_parser = argparse.ArgumentParser( + add_help=False, + argument_default=argparse.SUPPRESS, + usage='bisect.py {mode} [options]') common.BuildArgParser(override_parser, override=True) epilog = _HELP_EPILOG + override_parser.format_help() - parser = argparse.ArgumentParser(epilog=epilog, - formatter_class=RawTextHelpFormatter) - subparsers = parser.add_subparsers(title='Bisect mode', - description=('Which bisection method to ' - 'use. Each method has ' - 'specific setup and ' - 'arguments. Please consult ' - 'the README for more ' - 'information.')) + parser = argparse.ArgumentParser( + epilog=epilog, formatter_class=RawTextHelpFormatter) + subparsers = parser.add_subparsers( + title='Bisect mode', + description=('Which bisection method to ' + 'use. Each method has ' + 'specific setup and ' + 'arguments. Please consult ' + 'the README for more ' + 'information.')) parser_package = subparsers.add_parser('package') parser_package.add_argument('board', help='Board to target') @@ -342,34 +344,39 @@ def Main(argv): parser_object.add_argument('board', help='Board to target') parser_object.add_argument('remote', help='Remote machine to test on') parser_object.add_argument('package', help='Package to emerge and test') - parser_object.add_argument('--dir', - help=('Bisection directory to use, sets ' - '$BISECT_DIR if provided. Defaults to ' - 'current value of $BISECT_DIR (or ' - '/tmp/sysroot_bisect if $BISECT_DIR is ' - 'empty).')) + parser_object.add_argument( + '--dir', + help=('Bisection directory to use, sets ' + '$BISECT_DIR if provided. Defaults to ' + 'current value of $BISECT_DIR (or ' + '/tmp/sysroot_bisect if $BISECT_DIR is ' + 'empty).')) parser_object.set_defaults(handler=BisectObject) parser_android = subparsers.add_parser('android') parser_android.add_argument('android_src', help='Path to android source tree') - parser_android.add_argument('--dir', - help=('Bisection directory to use, sets ' - '$BISECT_DIR if provided. Defaults to ' - 'current value of $BISECT_DIR (or ' - '~/ANDROID_BISECT/ if $BISECT_DIR is ' - 'empty).')) - parser_android.add_argument('-j', '--num_jobs', - type=int, - default=1, - help=('Number of jobs that make and various ' - 'scripts for bisector can spawn. Setting ' - 'this value too high can freeze up your ' - 'machine!')) - parser_android.add_argument('--device_id', - default='', - help=('Device id for device used for testing. ' - 'Use this if you have multiple Android ' - 'devices plugged into your machine.')) + parser_android.add_argument( + '--dir', + help=('Bisection directory to use, sets ' + '$BISECT_DIR if provided. Defaults to ' + 'current value of $BISECT_DIR (or ' + '~/ANDROID_BISECT/ if $BISECT_DIR is ' + 'empty).')) + parser_android.add_argument( + '-j', + '--num_jobs', + type=int, + default=1, + help=('Number of jobs that make and various ' + 'scripts for bisector can spawn. Setting ' + 'this value too high can freeze up your ' + 'machine!')) + parser_android.add_argument( + '--device_id', + default='', + help=('Device id for device used for testing. ' + 'Use this if you have multiple Android ' + 'devices plugged into your machine.')) parser_android.set_defaults(handler=BisectAndroid) options, remaining = parser.parse_known_args(argv) diff --git a/binary_search_tool/common.py b/binary_search_tool/common.py index 11c6cef1..945270be 100644 --- a/binary_search_tool/common.py +++ b/binary_search_tool/common.py @@ -28,8 +28,8 @@ if os.path.isabs(sys.argv[0]): os.path.dirname(sys.argv[0]))) else: wdir = os.getcwd() - utils_pythonpath = os.path.abspath('{0}/{1}/..'.format( - wdir, os.path.dirname(sys.argv[0]))) + utils_pythonpath = os.path.abspath('{0}/{1}/..'.format(wdir, os.path.dirname( + sys.argv[0]))) sys.path.append(utils_pythonpath) @@ -78,8 +78,7 @@ class ArgumentDict(collections.OrderedDict): for key in kwargs: if key not in self._POSSIBLE_OPTIONS: - raise TypeError('Invalid option "%s" for argument %s' % - (key, args[0])) + raise TypeError('Invalid option "%s" for argument %s' % (key, args[0])) self[args] = kwargs @@ -132,118 +131,131 @@ def StrToBool(str_in): def _BuildArgsDict(args): """Populate ArgumentDict with all arguments""" - args.AddArgument('-n', - '--iterations', - dest='iterations', - type=int, - help='Number of iterations to try in the search.', - default=50) - args.AddArgument('-i', - '--get_initial_items', - dest='get_initial_items', - help=('Script to run to get the initial objects. ' - 'If your script requires user input ' - 'the --verbose option must be used')) - args.AddArgument('-g', - '--switch_to_good', - dest='switch_to_good', - help=('Script to run to switch to good. ' - 'If your switch script requires user input ' - 'the --verbose option must be used')) - args.AddArgument('-b', - '--switch_to_bad', - dest='switch_to_bad', - help=('Script to run to switch to bad. ' - 'If your switch script requires user input ' - 'the --verbose option must be used')) - args.AddArgument('-I', - '--test_setup_script', - dest='test_setup_script', - help=('Optional script to perform building, flashing, ' - 'and other setup before the test script runs.')) - args.AddArgument('-t', - '--test_script', - dest='test_script', - help=('Script to run to test the ' - 'output after packages are built.')) + args.AddArgument( + '-n', + '--iterations', + dest='iterations', + type=int, + help='Number of iterations to try in the search.', + default=50) + args.AddArgument( + '-i', + '--get_initial_items', + dest='get_initial_items', + help=('Script to run to get the initial objects. ' + 'If your script requires user input ' + 'the --verbose option must be used')) + args.AddArgument( + '-g', + '--switch_to_good', + dest='switch_to_good', + help=('Script to run to switch to good. ' + 'If your switch script requires user input ' + 'the --verbose option must be used')) + args.AddArgument( + '-b', + '--switch_to_bad', + dest='switch_to_bad', + help=('Script to run to switch to bad. ' + 'If your switch script requires user input ' + 'the --verbose option must be used')) + args.AddArgument( + '-I', + '--test_setup_script', + dest='test_setup_script', + help=('Optional script to perform building, flashing, ' + 'and other setup before the test script runs.')) + args.AddArgument( + '-t', + '--test_script', + dest='test_script', + help=('Script to run to test the ' + 'output after packages are built.')) # No input (evals to False), # --prune (evals to True), # --prune=False, # --prune=True - args.AddArgument('-p', - '--prune', - dest='prune', - nargs='?', - const=True, - default=False, - type=StrToBool, - metavar='bool', - help=('If True, continue until all bad items are found. ' - 'Defaults to False.')) + args.AddArgument( + '-p', + '--prune', + dest='prune', + nargs='?', + const=True, + default=False, + type=StrToBool, + metavar='bool', + help=('If True, continue until all bad items are found. ' + 'Defaults to False.')) # No input (evals to False), # --noincremental (evals to True), # --noincremental=False, # --noincremental=True - args.AddArgument('-c', - '--noincremental', - dest='noincremental', - nargs='?', - const=True, - default=False, - type=StrToBool, - metavar='bool', - help=('If True, don\'t propagate good/bad changes ' - 'incrementally. Defaults to False.')) + args.AddArgument( + '-c', + '--noincremental', + dest='noincremental', + nargs='?', + const=True, + default=False, + type=StrToBool, + metavar='bool', + help=('If True, don\'t propagate good/bad changes ' + 'incrementally. Defaults to False.')) # No input (evals to False), # --file_args (evals to True), # --file_args=False, # --file_args=True - args.AddArgument('-f', - '--file_args', - dest='file_args', - nargs='?', - const=True, - default=False, - type=StrToBool, - metavar='bool', - help=('Whether to use a file to pass arguments to scripts. ' - 'Defaults to False.')) + args.AddArgument( + '-f', + '--file_args', + dest='file_args', + nargs='?', + const=True, + default=False, + type=StrToBool, + metavar='bool', + help=('Whether to use a file to pass arguments to scripts. ' + 'Defaults to False.')) # No input (evals to True), # --verify (evals to True), # --verify=False, # --verify=True - args.AddArgument('--verify', - dest='verify', - nargs='?', - const=True, - default=True, - type=StrToBool, - metavar='bool', - help=('Whether to run verify iterations before searching. ' - 'Defaults to True.')) - args.AddArgument('-N', - '--prune_iterations', - dest='prune_iterations', - type=int, - help='Number of prune iterations to try in the search.', - default=100) + args.AddArgument( + '--verify', + dest='verify', + nargs='?', + const=True, + default=True, + type=StrToBool, + metavar='bool', + help=('Whether to run verify iterations before searching. ' + 'Defaults to True.')) + args.AddArgument( + '-N', + '--prune_iterations', + dest='prune_iterations', + type=int, + help='Number of prune iterations to try in the search.', + default=100) # No input (evals to False), # --verbose (evals to True), # --verbose=False, # --verbose=True - args.AddArgument('-V', - '--verbose', - dest='verbose', - nargs='?', - const=True, - default=False, - type=StrToBool, - metavar='bool', - help='If True, print full output to console.') - args.AddArgument('-r', - '--resume', - dest='resume', - action='store_true', - help=('Resume bisection tool execution from state file.' - 'Useful if the last bisection was terminated ' - 'before it could properly finish.')) + args.AddArgument( + '-V', + '--verbose', + dest='verbose', + nargs='?', + const=True, + default=False, + type=StrToBool, + metavar='bool', + help='If True, print full output to console.') + args.AddArgument( + '-r', + '--resume', + dest='resume', + action='store_true', + help=('Resume bisection tool execution from state file.' + 'Useful if the last bisection was terminated ' + 'before it could properly finish.')) diff --git a/binary_search_tool/cros_pkg/create_cleanup_script.py b/binary_search_tool/cros_pkg/create_cleanup_script.py index dc05d1ba..32a1f160 100755 --- a/binary_search_tool/cros_pkg/create_cleanup_script.py +++ b/binary_search_tool/cros_pkg/create_cleanup_script.py @@ -40,26 +40,30 @@ def Main(argv): """ parser = argparse.ArgumentParser() - parser.add_argument('--board', - dest='board', - required=True, - help='Chromeos board for packages/image.') - - parser.add_argument('--old_tree_missing', - dest='tree_existed', - action='store_false', - help='Did /build/${BOARD} exist.', - default=True) - - parser.add_argument('--renamed_tree', - dest='renamed_tree', - action='store_true', - help='Was /build/${BOARD} saved & renamed.', - default=False) - - parser.add_argument('--old_link', - dest='old_link', - help=('The original build tree soft link.')) + parser.add_argument( + '--board', + dest='board', + required=True, + help='Chromeos board for packages/image.') + + parser.add_argument( + '--old_tree_missing', + dest='tree_existed', + action='store_false', + help='Did /build/${BOARD} exist.', + default=True) + + parser.add_argument( + '--renamed_tree', + dest='renamed_tree', + action='store_true', + help='Was /build/${BOARD} saved & renamed.', + default=False) + + parser.add_argument( + '--old_link', + dest='old_link', + help=('The original build tree soft link.')) options = parser.parse_args(argv[1:]) diff --git a/binary_search_tool/test/binary_search_tool_tester.py b/binary_search_tool/test/binary_search_tool_tester.py index ddf302b0..775c1715 100755 --- a/binary_search_tool/test/binary_search_tool_tester.py +++ b/binary_search_tool/test/binary_search_tool_tester.py @@ -127,10 +127,8 @@ class BisectingUtilsTest(unittest.TestCase): except OSError: pass - cleanup_list = ['./is_setup', - binary_search_state.STATE_FILE, - 'noinc_prune_bad', - 'noinc_prune_good'] + cleanup_list = ['./is_setup', binary_search_state.STATE_FILE, + 'noinc_prune_bad', 'noinc_prune_good'] for f in cleanup_list: if os.path.exists(f): os.remove(f) @@ -296,14 +294,13 @@ class BisectingUtilsTest(unittest.TestCase): self.assertEquals(bad_objs[found_obj], 1) def test_set_file(self): - binary_search_state.Run( - get_initial_items='./gen_init_list.py', - switch_to_good='./switch_to_good_set_file.py', - switch_to_bad='./switch_to_bad_set_file.py', - test_script='./is_good.py', - prune=True, - file_args=True, - verify=True) + binary_search_state.Run(get_initial_items='./gen_init_list.py', + switch_to_good='./switch_to_good_set_file.py', + switch_to_bad='./switch_to_bad_set_file.py', + test_script='./is_good.py', + prune=True, + file_args=True, + verify=True) self.check_output() def test_noincremental_prune(self): @@ -373,7 +370,6 @@ class BisectStressTest(unittest.TestCase): self.assertEquals(ret, 0) self.check_output() - def check_output(self): _, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput( ('grep "Bad items are: " logs/binary_search_tool_tester.py.out | ' diff --git a/binary_search_tool/test/gen_init_list.py b/binary_search_tool/test/gen_init_list.py index 10db5240..4a79a1b1 100755 --- a/binary_search_tool/test/gen_init_list.py +++ b/binary_search_tool/test/gen_init_list.py @@ -11,8 +11,8 @@ import common def Main(): ce = command_executer.GetCommandExecuter() - _, l, _ = ce.RunCommandWOutput('cat {0} | wc -l'.format(common.OBJECTS_FILE), - print_to_console=False) + _, l, _ = ce.RunCommandWOutput( + 'cat {0} | wc -l'.format(common.OBJECTS_FILE), print_to_console=False) for i in range(0, int(l)): print(i) diff --git a/binary_search_tool/test/gen_obj.py b/binary_search_tool/test/gen_obj.py index 1c060e01..265729d2 100755 --- a/binary_search_tool/test/gen_obj.py +++ b/binary_search_tool/test/gen_obj.py @@ -28,25 +28,28 @@ def Main(argv): 0 always. """ parser = argparse.ArgumentParser() - parser.add_argument('-n', - '--obj_num', - dest='obj_num', - default=common.DEFAULT_OBJECT_NUMBER, - help=('Number of total objects.')) - parser.add_argument('-b', - '--bad_obj_num', - dest='bad_obj_num', - default=common.DEFAULT_BAD_OBJECT_NUMBER, - help=('Number of bad objects. Must be great than or ' - 'equal to zero and less than total object ' - 'number.')) - parser.add_argument('-o', - '--obj_list', - dest='obj_list', - default='', - help=('List of comma seperated objects to generate. ' - 'A 0 means the object is good, a 1 means the ' - 'object is bad.')) + parser.add_argument( + '-n', + '--obj_num', + dest='obj_num', + default=common.DEFAULT_OBJECT_NUMBER, + help=('Number of total objects.')) + parser.add_argument( + '-b', + '--bad_obj_num', + dest='bad_obj_num', + default=common.DEFAULT_BAD_OBJECT_NUMBER, + help=('Number of bad objects. Must be great than or ' + 'equal to zero and less than total object ' + 'number.')) + parser.add_argument( + '-o', + '--obj_list', + dest='obj_list', + default='', + help=('List of comma seperated objects to generate. ' + 'A 0 means the object is good, a 1 means the ' + 'object is bad.')) options = parser.parse_args(argv) obj_num = int(options.obj_num) @@ -83,9 +86,8 @@ def Main(argv): obj_num = len(obj_list) bad_obj_num = obj_list.count('1') - print('Generated {0} object files, with {1} bad ones.'.format( - obj_num, bad_obj_num)) - + print('Generated {0} object files, with {1} bad ones.'.format(obj_num, + bad_obj_num)) return 0 |