diff options
Diffstat (limited to 'binary_search_tool/binary_search_state.py')
-rwxr-xr-x | binary_search_tool/binary_search_state.py | 135 |
1 files changed, 66 insertions, 69 deletions
diff --git a/binary_search_tool/binary_search_state.py b/binary_search_tool/binary_search_state.py index f6c8ac7c..1ddd65ce 100755 --- a/binary_search_tool/binary_search_state.py +++ b/binary_search_tool/binary_search_state.py @@ -1,10 +1,12 @@ -#!/usr/bin/env python2 - -# Copyright 2018 The Chromium OS Authors. All rights reserved. +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2020 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. + """The binary search wrapper.""" +from __future__ import division from __future__ import print_function import argparse @@ -20,15 +22,14 @@ import tempfile import time # Adds cros_utils to PYTHONPATH -import common +from binary_search_tool import binary_search_perforce +from binary_search_tool import common +from binary_search_tool import pass_mapping # Now we do import from cros_utils from cros_utils import command_executer from cros_utils import logger -import binary_search_perforce -import pass_mapping - GOOD_SET_VAR = 'BISECT_GOOD_SET' BAD_SET_VAR = 'BISECT_BAD_SET' @@ -37,11 +38,6 @@ 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 - - @contextlib.contextmanager def SetFile(env_var, items): """Generate set files that can be used by switch/test scripts. @@ -59,7 +55,7 @@ def SetFile(env_var, items): env_var: What environment variable to store the file name in. items: What items are in this set. """ - with tempfile.NamedTemporaryFile() as f: + with tempfile.NamedTemporaryFile('w', encoding='utf-8') as f: os.environ[env_var] = f.name f.write('\n'.join(items)) f.flush() @@ -100,10 +96,10 @@ class BinarySearchState(object): self.cmd_script = None self.mode = None self.PopulateItemsUsingCommand(self.get_initial_items) - self.currently_good_items = set([]) - self.currently_bad_items = set([]) - self.found_items = set([]) - self.known_good = set([]) + self.currently_good_items = set() + self.currently_bad_items = set() + self.found_items = set() + self.known_good = set() self.start_time = time.time() @@ -161,7 +157,7 @@ class BinarySearchState(object): item_list: list of all items to be switched """ if self.file_args: - with tempfile.NamedTemporaryFile() as f: + with tempfile.NamedTemporaryFile('w', encoding='utf-8') as f: f.write('\n'.join(item_list)) f.flush() command = '%s %s' % (switch_script, f.name) @@ -174,9 +170,8 @@ class BinarySearchState(object): command, print_to_console=self.verbose) except OSError as e: if e.errno == errno.E2BIG: - raise Error('Too many arguments for switch script! Use --file_args') - else: - raise + raise RuntimeError('Too many arguments for switch script! Use ' + '--file_args') assert ret == 0, 'Switch script %s returned %d' % (switch_script, ret) def TestScript(self): @@ -349,12 +344,12 @@ class BinarySearchState(object): return None def BuildWithPassLimit(self, limit, generate_ir=False): - """ Rebuild bad item with pass level bisect limit + """Rebuild bad item with pass level bisect limit Run command line script generated by GenerateBadCommandScript(), with pass level limit flags. - Return: + Returns: pass_num: current number of the pass, or total number of passes if limit set to -1. pass_name: The debugcounter name of current limit pass. @@ -389,7 +384,7 @@ class BinarySearchState(object): break pass_num += 1 last_pass = l - if limit != -1 and pass_num != limit: + if limit not in (-1, pass_num): raise ValueError('[Error] While building, limit number does not match.') return pass_num, self.CollectPassName(last_pass) @@ -398,16 +393,19 @@ class BinarySearchState(object): pass_name=None, pass_limit=-1, generate_ir=False): - """ Rebuild bad item with transformation level bisect limit + """Rebuild bad item with transformation level bisect limit Run command line script generated by GenerateBadCommandScript(), with pass level limit flags and transformation level limit flags. Args: - limit: transformation level limit for bad item - pass_name: name of bad pass debugcounter from pass level bisect result - pass_limit: pass level limit from pass level bisect result - Return: Total number of transformations if limit set to -1, else return 0. + limit: transformation level limit for bad item. + pass_name: name of bad pass debugcounter from pass level bisect result. + pass_limit: pass level limit from pass level bisect result. + generate_ir: Whether to generate IR comparison. + + Returns: + Total number of transformations if limit set to -1, else return 0. """ counter_name = pass_name @@ -513,7 +511,7 @@ class BinarySearchState(object): 'Total %s number: %d' % (self.mode, self.binary_search.total)) trans_index, _ = self.DoBinarySearchBadPass(pass_index, pass_name) - if (trans_index == 0): + if trans_index == 0: raise ValueError('Bisecting %s cannot reproduce good result.' % pass_name) if self.ir_diff: @@ -530,13 +528,15 @@ class BinarySearchState(object): Args: pass_index: Works for transformation level bisection, indicates the limit - number of pass from pass level bisecting result. + number of pass from pass level bisecting result. pass_name: Works for transformation level bisection, indicates - DebugCounter name of the bad pass from pass level bisecting result. - Return: + DebugCounter name of the bad pass from pass level bisecting + result. + + Returns: index: Index of problematic pass/transformation. pass_name: Works for pass level bisection, returns DebugCounter name for - bad pass. + bad pass. """ # If in resume mode don't reset search_cycles if not self.resumed: @@ -609,7 +609,7 @@ class BinarySearchState(object): new data. Raises: - Error if STATE_FILE already exists but is not a symlink. + OSError if STATE_FILE already exists but is not a symlink. """ ce, l = self.ce, self.l self.ce, self.l, self.binary_search.logger = None, None, None @@ -623,8 +623,8 @@ class BinarySearchState(object): if os.path.islink(STATE_FILE): old_state = os.readlink(STATE_FILE) else: - raise Error(('%s already exists and is not a symlink!\n' - 'State file saved to %s' % (STATE_FILE, path))) + raise OSError(('%s already exists and is not a symlink!\n' + 'State file saved to %s' % (STATE_FILE, path))) # Create new link and atomically overwrite old link temp_link = '%s.link' % HIDDEN_STATE_FILE @@ -642,26 +642,27 @@ class BinarySearchState(object): if not os.path.isfile(STATE_FILE): return None try: - bss = pickle.load(file(STATE_FILE)) - bss.l = logger.GetLogger() - bss.ce = command_executer.GetCommandExecuter() - bss.binary_search.logger = bss.l - bss.start_time = time.time() - - # Set resumed to be True so we can enter DoBinarySearch without the method - # resetting our current search_cycles to 0. - bss.resumed = True - - # Set currently_good_items and currently_bad_items to empty so that the - # first iteration after resuming will always be non-incremental. This is - # just in case the environment changes, the user makes manual changes, or - # a previous switch_script corrupted the environment. - bss.currently_good_items = set([]) - bss.currently_bad_items = set([]) - - binary_search_perforce.verbose = bss.verbose - return bss - except StandardError: + with open(STATE_FILE, 'rb') as f: + bss = pickle.load(f) + bss.l = logger.GetLogger() + bss.ce = command_executer.GetCommandExecuter() + bss.binary_search.logger = bss.l + bss.start_time = time.time() + + # Set resumed to be True so we can enter DoBinarySearch without the + # method resetting our current search_cycles to 0. + bss.resumed = True + + # Set currently_good_items and currently_bad_items to empty so that the + # first iteration after resuming will always be non-incremental. This + # is just in case the environment changes, the user makes manual + # changes, or a previous switch_script corrupted the environment. + bss.currently_good_items = set() + bss.currently_bad_items = set() + + binary_search_perforce.verbose = bss.verbose + return bss + except Exception: return None def RemoveState(self): @@ -686,8 +687,8 @@ class BinarySearchState(object): """Return h m s format of elapsed time since execution has started.""" diff = int(time.time() - self.start_time) seconds = diff % 60 - minutes = (diff / 60) % 60 - hours = diff / (60 * 60) + minutes = (diff // 60) % 60 + hours = diff // (60 * 60) seconds = str(seconds).rjust(2) minutes = str(minutes).rjust(2) @@ -871,16 +872,12 @@ def Run(get_initial_items, verify, file_args, verbose) bss.DoVerify() - try: - bss.DoSearchBadItems() - if pass_bisect: - bss.DoSearchBadPass() - bss.RemoveState() - logger.GetLogger().LogOutput( - 'Total execution time: %s' % bss.ElapsedTimeString()) - except Error as e: - logger.GetLogger().LogError(e) - return 1 + bss.DoSearchBadItems() + if pass_bisect: + bss.DoSearchBadPass() + bss.RemoveState() + logger.GetLogger().LogOutput( + 'Total execution time: %s' % bss.ElapsedTimeString()) return 0 |