| OLD | NEW | 
|---|
| 1 """The main job wrapper | 1 """The main job wrapper | 
| 2 | 2 | 
| 3 This is the core infrastructure. | 3 This is the core infrastructure. | 
| 4 | 4 | 
| 5 Copyright Andy Whitcroft, Martin J. Bligh 2006 | 5 Copyright Andy Whitcroft, Martin J. Bligh 2006 | 
| 6 """ | 6 """ | 
| 7 | 7 | 
| 8 import copy, os, platform, re, shutil, sys, time, traceback, types, glob | 8 import copy, os, platform, re, shutil, sys, time, traceback, types, glob | 
| 9 import logging, getpass, errno, weakref | 9 import logging, getpass, errno, weakref | 
| 10 import cPickle as pickle | 10 import cPickle as pickle | 
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 172             verbose=options.verbose) | 172             verbose=options.verbose) | 
| 173         logging.info('Writing results to %s', self.resultdir) | 173         logging.info('Writing results to %s', self.resultdir) | 
| 174 | 174 | 
| 175         # init_group_level needs the state | 175         # init_group_level needs the state | 
| 176         self.control = os.path.realpath(control) | 176         self.control = os.path.realpath(control) | 
| 177         self._is_continuation = options.cont | 177         self._is_continuation = options.cont | 
| 178         self._current_step_ancestry = [] | 178         self._current_step_ancestry = [] | 
| 179         self._next_step_index = 0 | 179         self._next_step_index = 0 | 
| 180         self._load_state() | 180         self._load_state() | 
| 181 | 181 | 
| 182         # harness is chosen by following rules: | 182         _harness = self.handle_persistent_option(options, 'harness') | 
| 183         # 1. explicitly specified via command line | 183         _harness_args = self.handle_persistent_option(options, 'harness_args') | 
| 184         # 2. harness stored in state file (if continuing job '-c') |  | 
| 185         # 3. default harness |  | 
| 186         selected_harness = None |  | 
| 187         if options.harness: |  | 
| 188             selected_harness = options.harness |  | 
| 189             self._state.set('client', 'harness', selected_harness) |  | 
| 190         else: |  | 
| 191             stored_harness = self._state.get('client', 'harness', None) |  | 
| 192             if stored_harness: |  | 
| 193                 selected_harness = stored_harness |  | 
| 194 | 184 | 
| 195         self.harness = harness.select(selected_harness, self) | 185         self.harness = harness.select(_harness, self, _harness_args) | 
| 196 | 186 | 
| 197         # set up the status logger | 187         # set up the status logger | 
| 198         def client_job_record_hook(entry): | 188         def client_job_record_hook(entry): | 
| 199             msg_tag = '' | 189             msg_tag = '' | 
| 200             if '.' in self._logger.global_filename: | 190             if '.' in self._logger.global_filename: | 
| 201                 msg_tag = self._logger.global_filename.split('.', 1)[1] | 191                 msg_tag = self._logger.global_filename.split('.', 1)[1] | 
| 202             # send the entry to the job harness | 192             # send the entry to the job harness | 
| 203             message = '\n'.join([entry.message] + entry.extra_message_lines) | 193             message = '\n'.join([entry.message] + entry.extra_message_lines) | 
| 204             rendered_entry = self._logger.render_entry(entry) | 194             rendered_entry = self._logger.render_entry(entry) | 
| 205             self.harness.test_status_detail(entry.status_code, entry.subdir, | 195             self.harness.test_status_detail(entry.status_code, entry.subdir, | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 381 | 371 | 
| 382 | 372 | 
| 383     def control_get(self): | 373     def control_get(self): | 
| 384         return self.control | 374         return self.control | 
| 385 | 375 | 
| 386 | 376 | 
| 387     def control_set(self, control): | 377     def control_set(self, control): | 
| 388         self.control = os.path.abspath(control) | 378         self.control = os.path.abspath(control) | 
| 389 | 379 | 
| 390 | 380 | 
| 391     def harness_select(self, which): | 381     def harness_select(self, which, harness_args): | 
| 392         self.harness = harness.select(which, self) | 382         self.harness = harness.select(which, self, harness_args) | 
| 393 | 383 | 
| 394 | 384 | 
| 395     def config_set(self, name, value): | 385     def config_set(self, name, value): | 
| 396         self._config.set(name, value) | 386         self._config.set(name, value) | 
| 397 | 387 | 
| 398 | 388 | 
| 399     def config_get(self, name): | 389     def config_get(self, name): | 
| 400         return self._config.get(name) | 390         return self._config.get(name) | 
| 401 | 391 | 
| 402 | 392 | 
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 594                 subroutine to run | 584                 subroutine to run | 
| 595         *args: | 585         *args: | 
| 596                 arguments for the function | 586                 arguments for the function | 
| 597 | 587 | 
| 598         Returns the result of the passed in function | 588         Returns the result of the passed in function | 
| 599         """ | 589         """ | 
| 600 | 590 | 
| 601         try: | 591         try: | 
| 602             self.record('START', subdir, testname) | 592             self.record('START', subdir, testname) | 
| 603             self._state.set('client', 'unexpected_reboot', (subdir, testname)) | 593             self._state.set('client', 'unexpected_reboot', (subdir, testname)) | 
| 604             result = function(*args, **dargs) | 594             try: | 
| 605             self.record('END GOOD', subdir, testname) | 595                 result = function(*args, **dargs) | 
| 606             return result | 596                 self.record('END GOOD', subdir, testname) | 
| 607         except error.TestBaseException, e: | 597                 return result | 
| 608             self.record('END %s' % e.exit_status, subdir, testname) | 598             except error.TestBaseException, e: | 
| 609             raise | 599                 self.record('END %s' % e.exit_status, subdir, testname) | 
| 610         except error.JobError, e: | 600                 raise | 
| 611             self.record('END ABORT', subdir, testname) | 601             except error.JobError, e: | 
| 612             raise | 602                 self.record('END ABORT', subdir, testname) | 
| 613         except Exception, e: | 603                 raise | 
| 614             # This should only ever happen due to a bug in the given | 604             except Exception, e: | 
| 615             # function's code.  The common case of being called by | 605                 # This should only ever happen due to a bug in the given | 
| 616             # run_test() will never reach this.  If a control file called | 606                 # function's code.  The common case of being called by | 
| 617             # run_group() itself, bugs in its function will be caught | 607                 # run_test() will never reach this.  If a control file called | 
| 618             # here. | 608                 # run_group() itself, bugs in its function will be caught | 
| 619             err_msg = str(e) + '\n' + traceback.format_exc() | 609                 # here. | 
| 620             self.record('END ERROR', subdir, testname, err_msg) | 610                 err_msg = str(e) + '\n' + traceback.format_exc() | 
| 621             raise | 611                 self.record('END ERROR', subdir, testname, err_msg) | 
|  | 612                 raise | 
| 622         finally: | 613         finally: | 
| 623             self._state.discard('client', 'unexpected_reboot') | 614             self._state.discard('client', 'unexpected_reboot') | 
| 624 | 615 | 
| 625 | 616 | 
| 626     def run_group(self, function, tag=None, **dargs): | 617     def run_group(self, function, tag=None, **dargs): | 
| 627         """ | 618         """ | 
| 628         Run a function nested within a group level. | 619         Run a function nested within a group level. | 
| 629 | 620 | 
| 630         function: | 621         function: | 
| 631                 Callable to run. | 622                 Callable to run. | 
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 917         has_steps = self._state.has('client', 'steps') | 908         has_steps = self._state.has('client', 'steps') | 
| 918         if not self._is_continuation and has_steps: | 909         if not self._is_continuation and has_steps: | 
| 919             raise RuntimeError('Loaded state can only contain client.steps if ' | 910             raise RuntimeError('Loaded state can only contain client.steps if ' | 
| 920                                'this is a continuation') | 911                                'this is a continuation') | 
| 921 | 912 | 
| 922         if not has_steps: | 913         if not has_steps: | 
| 923             logging.info('Initializing the state engine') | 914             logging.info('Initializing the state engine') | 
| 924             self._state.set('client', 'steps', []) | 915             self._state.set('client', 'steps', []) | 
| 925 | 916 | 
| 926 | 917 | 
|  | 918     def handle_persistent_option(self, options, option_name): | 
|  | 919         """ | 
|  | 920         Select option from command line or persistent state. | 
|  | 921         Store selected option to allow standalone client to continue | 
|  | 922         after reboot with previously selected options. | 
|  | 923         Priority: | 
|  | 924         1. explicitly specified via command line | 
|  | 925         2. stored in state file (if continuing job '-c') | 
|  | 926         3. default == None | 
|  | 927         """ | 
|  | 928         option = None | 
|  | 929         cmd_line_option = getattr(options, option_name) | 
|  | 930         if cmd_line_option: | 
|  | 931             option = cmd_line_option | 
|  | 932             self._state.set('client', option_name, option) | 
|  | 933         else: | 
|  | 934             stored_option = self._state.get('client', option_name, None) | 
|  | 935             if stored_option: | 
|  | 936                 option = stored_option | 
|  | 937         logging.debug('Persistent option %s now set to %s', option_name, option) | 
|  | 938         return option | 
|  | 939 | 
|  | 940 | 
| 927     def __create_step_tuple(self, fn, args, dargs): | 941     def __create_step_tuple(self, fn, args, dargs): | 
| 928         # Legacy code passes in an array where the first arg is | 942         # Legacy code passes in an array where the first arg is | 
| 929         # the function or its name. | 943         # the function or its name. | 
| 930         if isinstance(fn, list): | 944         if isinstance(fn, list): | 
| 931             assert(len(args) == 0) | 945             assert(len(args) == 0) | 
| 932             assert(len(dargs) == 0) | 946             assert(len(dargs) == 0) | 
| 933             args = fn[1:] | 947             args = fn[1:] | 
| 934             fn = fn[0] | 948             fn = fn[0] | 
| 935         # Pickling actual functions is hairy, thus we have to call | 949         # Pickling actual functions is hairy, thus we have to call | 
| 936         # them by name.  Unfortunately, this means only functions | 950         # them by name.  Unfortunately, this means only functions | 
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1244     assert myjob._record_indent == 0 | 1258     assert myjob._record_indent == 0 | 
| 1245 | 1259 | 
| 1246     myjob.complete(0) | 1260     myjob.complete(0) | 
| 1247 | 1261 | 
| 1248 | 1262 | 
| 1249 site_job = utils.import_site_class( | 1263 site_job = utils.import_site_class( | 
| 1250     __file__, "autotest_lib.client.bin.site_job", "site_job", base_client_job) | 1264     __file__, "autotest_lib.client.bin.site_job", "site_job", base_client_job) | 
| 1251 | 1265 | 
| 1252 class job(site_job): | 1266 class job(site_job): | 
| 1253     pass | 1267     pass | 
| OLD | NEW | 
|---|