bisect.py revision 2e37b144ecd1476964e2dc72ac6b5b2a81a32018
1#!/usr/bin/python2 2"""The unified package/object bisecting tool.""" 3 4from __future__ import print_function 5 6import abc 7import argparse 8import sys 9import common 10 11from utils import command_executer 12from utils import logger 13 14import binary_search_state 15 16 17class Bisector(object): 18 """The abstract base class for Bisectors.""" 19 20 # Make Bisector an abstract class 21 __metaclass__ = abc.ABCMeta 22 23 def __init__(self, options): 24 self.options = options 25 self.logger = logger.GetLogger() 26 self.ce = command_executer.GetCommandExecuter() 27 28 @abc.abstractmethod 29 def PreRun(self): 30 pass 31 32 @abc.abstractmethod 33 def Run(self): 34 pass 35 36 @abc.abstractmethod 37 def PostRun(self): 38 pass 39 40 41class BisectPackage(Bisector): 42 """The class for package bisection steps.""" 43 44 cros_pkg_setup = 'cros_pkg/setup.sh' 45 cros_pkg_cleanup = 'cros_pkg/%s_cleanup.sh' 46 default_kwargs = { 47 'get_initial_items': 'cros_pkg/get_initial_items.sh', 48 'switch_to_good': 'cros_pkg/switch_to_good.sh', 49 'switch_to_bad': 'cros_pkg/switch_to_bad.sh', 50 'install_script': 'cros_pkg/install.sh', 51 'test_script': 'cros_pkg/interactive_test.sh', 52 'noincremental': False, 53 'prune': True, 54 'file_args': True 55 } 56 57 def __init__(self, options): 58 super(BisectPackage, self).__init__(options) 59 60 def PreRun(self): 61 cmd = ('%s %s %s' % 62 (self.cros_pkg_setup, self.options.board, self.options.remote)) 63 ret, _, _ = self.ce.RunCommandWExceptionCleanup(cmd, print_to_console=True) 64 if ret: 65 self.logger.LogError('Package bisector setup failed w/ error %d' % ret) 66 return 1 67 return 0 68 69 def Run(self): 70 return binary_search_state.Run(**self.default_kwargs) 71 72 def PostRun(self): 73 cmd = self.cros_pkg_cleanup % self.options.board 74 ret, _, _ = self.ce.RunCommandWExceptionCleanup(cmd, print_to_console=True) 75 if ret: 76 self.logger.LogError('Package bisector cleanup failed w/ error %d' % ret) 77 return 1 78 return 0 79 80 81class BisectObject(Bisector): 82 """The class for object bisection steps.""" 83 84 def __init__(self, options): 85 super(BisectObject, self).__init__(options) 86 87 def PreRun(self): 88 raise NotImplementedError('Object bisecting still WIP') 89 90 def Run(self): 91 return 1 92 93 def PostRun(self): 94 return 1 95 96 97def Run(bisector): 98 ret = bisector.PreRun() 99 if ret: 100 return ret 101 102 ret = bisector.Run() 103 if ret: 104 return ret 105 106 ret = bisector.PostRun() 107 if ret: 108 return ret 109 110 return 0 111 112 113def Main(argv): 114 parser = argparse.ArgumentParser(epilog=('Run ./bisect.py {command} --help ' 115 'for individual subcommand ' 116 'help/args.')) 117 subparsers = parser.add_subparsers(title='Bisect mode', 118 description=('Whether to package or object' 119 'bisect')) 120 121 parser_package = subparsers.add_parser('package') 122 parser_package.add_argument('board', help='Board to target') 123 parser_package.add_argument('remote', help='Remote machine to test on') 124 parser_package.set_defaults(handler=BisectPackage) 125 126 parser_object = subparsers.add_parser('object') 127 parser_object.set_defaults(handler=BisectObject) 128 129 options = parser.parse_args(argv) 130 131 subcmd = options.handler 132 del options.handler 133 134 bisector = subcmd(options) 135 return Run(bisector) 136 137 138if __name__ == '__main__': 139 os.chdir(os.path.dirname(__file__)) 140 sys.exit(Main(sys.argv[1:])) 141