Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: client/bin/job.py

Issue 6539001: Merge remote branch 'cros/upstream' into master. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/bin/harness_unittest.py ('k') | client/bin/job_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « client/bin/harness_unittest.py ('k') | client/bin/job_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698