aboutsummaryrefslogtreecommitdiff
path: root/binary_search_tool
diff options
context:
space:
mode:
authorCassidy Burden <cburden@google.com>2016-08-11 15:05:38 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-08-16 10:33:25 -0700
commit4cc3dd8a3b2ab04cf861d7c71967de0298746cb9 (patch)
treeb032d8da64ed4da9ebbd170598377272cb9ae1a2 /binary_search_tool
parentb217c8a28be52f90572d26647d38dcfc9e08ce0b (diff)
downloadtoolchain-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>
Diffstat (limited to 'binary_search_tool')
-rwxr-xr-xbinary_search_tool/binary_search_perforce.py257
-rwxr-xr-xbinary_search_tool/binary_search_state.py72
-rwxr-xr-xbinary_search_tool/bisect.py81
-rw-r--r--binary_search_tool/common.py210
-rwxr-xr-xbinary_search_tool/cros_pkg/create_cleanup_script.py44
-rwxr-xr-xbinary_search_tool/test/binary_search_tool_tester.py22
-rwxr-xr-xbinary_search_tool/test/gen_init_list.py4
-rwxr-xr-xbinary_search_tool/test/gen_obj.py46
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