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

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

Issue 6883035: Merge remote branch 'autotest-upstream/master' into autotest-merge (Closed) Base URL: ssh://gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 8 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
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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 186
187 # set up the status logger 187 # set up the status logger
188 def client_job_record_hook(entry): 188 def client_job_record_hook(entry):
189 msg_tag = '' 189 msg_tag = ''
190 if '.' in self._logger.global_filename: 190 if '.' in self._logger.global_filename:
191 msg_tag = self._logger.global_filename.split('.', 1)[1] 191 msg_tag = self._logger.global_filename.split('.', 1)[1]
192 # send the entry to the job harness 192 # send the entry to the job harness
193 message = '\n'.join([entry.message] + entry.extra_message_lines) 193 message = '\n'.join([entry.message] + entry.extra_message_lines)
194 rendered_entry = self._logger.render_entry(entry) 194 rendered_entry = self._logger.render_entry(entry)
195 self.harness.test_status_detail(entry.status_code, entry.subdir, 195 self.harness.test_status_detail(entry.status_code, entry.subdir,
196 entry.operation, message, msg_tag) 196 entry.operation, message, msg_tag,
197 entry.fields)
197 self.harness.test_status(rendered_entry, msg_tag) 198 self.harness.test_status(rendered_entry, msg_tag)
198 # send the entry to stdout, if it's enabled 199 # send the entry to stdout, if it's enabled
199 logging.info(rendered_entry) 200 logging.info(rendered_entry)
200 self._logger = base_job.status_logger( 201 self._logger = base_job.status_logger(
201 self, status_indenter(self), record_hook=client_job_record_hook, 202 self, status_indenter(self), record_hook=client_job_record_hook,
202 tap_writer=self._tap) 203 tap_writer=self._tap)
203 204
204 def _post_record_init(self, control, options, drop_caches, 205 def _post_record_init(self, control, options, drop_caches,
205 extra_copy_cmdline): 206 extra_copy_cmdline):
206 """ 207 """
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 509
509 # dep_dir might not exist if it is not fetched from the repos 510 # dep_dir might not exist if it is not fetched from the repos
510 if not os.path.exists(dep_dir): 511 if not os.path.exists(dep_dir):
511 raise error.TestError("Dependency %s does not exist" % dep) 512 raise error.TestError("Dependency %s does not exist" % dep)
512 513
513 os.chdir(dep_dir) 514 os.chdir(dep_dir)
514 if execfile('%s.py' % dep, {}) is None: 515 if execfile('%s.py' % dep, {}) is None:
515 logging.info('Dependency %s successfuly built', dep) 516 logging.info('Dependency %s successfuly built', dep)
516 517
517 518
518 def _runtest(self, url, tag, args, dargs): 519 def _runtest(self, url, tag, timeout, args, dargs):
519 try: 520 try:
520 l = lambda : test.runtest(self, url, tag, args, dargs) 521 l = lambda : test.runtest(self, url, tag, args, dargs)
521 pid = parallel.fork_start(self.resultdir, l) 522 pid = parallel.fork_start(self.resultdir, l)
522 parallel.fork_waitfor(self.resultdir, pid) 523
524 if timeout:
525 logging.debug('Waiting for pid %d for %d seconds', pid, timeout)
526 parallel.fork_waitfor_timed(self.resultdir, pid, timeout)
527 else:
528 parallel.fork_waitfor(self.resultdir, pid)
529
523 except error.TestBaseException: 530 except error.TestBaseException:
524 # These are already classified with an error type (exit_status) 531 # These are already classified with an error type (exit_status)
525 raise 532 raise
526 except error.JobError: 533 except error.JobError:
527 raise # Caught further up and turned into an ABORT. 534 raise # Caught further up and turned into an ABORT.
528 except Exception, e: 535 except Exception, e:
529 # Converts all other exceptions thrown by the test regardless 536 # Converts all other exceptions thrown by the test regardless
530 # of phase into a TestError(TestBaseException) subclass that 537 # of phase into a TestError(TestBaseException) subclass that
531 # reports them with their full stack trace. 538 # reports them with their full stack trace.
532 raise error.UnhandledTestError(e) 539 raise error.UnhandledTestError(e)
533 540
534 541
535 @_run_test_complete_on_exit 542 def _run_test_base(self, url, *args, **dargs):
536 def run_test(self, url, *args, **dargs):
537 """ 543 """
538 Summon a test object and run it. 544 Prepares arguments and run functions to run_test and run_test_detail.
539 545
540 @param url A url that identifies the test to run. 546 @param url A url that identifies the test to run.
541 @param tag An optional keyword argument that will be added to the 547 @param tag An optional keyword argument that will be added to the
542 test and subdir name. 548 test and subdir name.
543 @param subdir_tag An optional keyword argument that will be added 549 @param subdir_tag An optional keyword argument that will be added
544 to the subdir name. 550 to the subdir name.
545 551
546 @returns True if the test passes, False otherwise. 552 @returns:
553 subdir: Test subdirectory
554 testname: Test name
555 group_func: Actual test run function
556 timeout: Test timeout
547 """ 557 """
548 group, testname = self.pkgmgr.get_package_name(url, 'test') 558 group, testname = self.pkgmgr.get_package_name(url, 'test')
549 testname, subdir, tag = self._build_tagged_test_name(testname, dargs) 559 testname, subdir, tag = self._build_tagged_test_name(testname, dargs)
550 outputdir = self._make_test_outputdir(subdir) 560 outputdir = self._make_test_outputdir(subdir)
551 561
562 timeout = dargs.pop('timeout', None)
563 if timeout:
564 logging.debug('Test has timeout: %d sec.', timeout)
565
552 def log_warning(reason): 566 def log_warning(reason):
553 self.record("WARN", subdir, testname, reason) 567 self.record("WARN", subdir, testname, reason)
554 @disk_usage_monitor.watch(log_warning, "/", self._max_disk_usage_rate) 568 @disk_usage_monitor.watch(log_warning, "/", self._max_disk_usage_rate)
555 def group_func(): 569 def group_func():
556 try: 570 try:
557 self._runtest(url, tag, args, dargs) 571 self._runtest(url, tag, timeout, args, dargs)
558 except error.TestBaseException, detail: 572 except error.TestBaseException, detail:
559 # The error is already classified, record it properly. 573 # The error is already classified, record it properly.
560 self.record(detail.exit_status, subdir, testname, str(detail)) 574 self.record(detail.exit_status, subdir, testname, str(detail))
561 raise 575 raise
562 else: 576 else:
563 self.record('GOOD', subdir, testname, 'completed successfully') 577 self.record('GOOD', subdir, testname, 'completed successfully')
564 578
579 return (subdir, testname, group_func, timeout)
580
581
582 @_run_test_complete_on_exit
583 def run_test(self, url, *args, **dargs):
584 """
585 Summon a test object and run it.
586
587 @param url A url that identifies the test to run.
588 @param tag An optional keyword argument that will be added to the
589 test and subdir name.
590 @param subdir_tag An optional keyword argument that will be added
591 to the subdir name.
592
593 @returns True if the test passes, False otherwise.
594 """
595 (subdir, testname, group_func, timeout) = self._run_test_base(url,
596 *args,
597 **dargs)
565 try: 598 try:
566 self._rungroup(subdir, testname, group_func) 599 self._rungroup(subdir, testname, group_func, timeout)
567 return True 600 return True
568 except error.TestBaseException: 601 except error.TestBaseException:
569 return False 602 return False
570 # Any other exception here will be given to the caller 603 # Any other exception here will be given to the caller
571 # 604 #
572 # NOTE: The only exception possible from the control file here 605 # NOTE: The only exception possible from the control file here
573 # is error.JobError as _runtest() turns all others into an 606 # is error.JobError as _runtest() turns all others into an
574 # UnhandledTestError that is caught above. 607 # UnhandledTestError that is caught above.
575 608
576 609
577 def _rungroup(self, subdir, testname, function, *args, **dargs): 610 @_run_test_complete_on_exit
611 def run_test_detail(self, url, *args, **dargs):
612 """
613 Summon a test object and run it, returning test status.
614
615 @param url A url that identifies the test to run.
616 @param tag An optional keyword argument that will be added to the
617 test and subdir name.
618 @param subdir_tag An optional keyword argument that will be added
619 to the subdir name.
620
621 @returns Test status
622 @see: client/common_lib/error.py, exit_status
623 """
624 (subdir, testname, group_func, timeout) = self._run_test_base(url,
625 *args,
626 **dargs)
627 try:
628 self._rungroup(subdir, testname, group_func, timeout)
629 return 'GOOD'
630 except error.TestBaseException, detail:
631 return detail.exit_status
632
633
634 def _rungroup(self, subdir, testname, function, timeout, *args, **dargs):
578 """\ 635 """\
579 subdir: 636 subdir:
580 name of the group 637 name of the group
581 testname: 638 testname:
582 name of the test to run, or support step 639 name of the test to run, or support step
583 function: 640 function:
584 subroutine to run 641 subroutine to run
585 *args: 642 *args:
586 arguments for the function 643 arguments for the function
587 644
588 Returns the result of the passed in function 645 Returns the result of the passed in function
589 """ 646 """
590 647
591 try: 648 try:
592 self.record('START', subdir, testname) 649 optional_fields = None
650 if timeout:
651 optional_fields = {}
652 optional_fields['timeout'] = timeout
653 self.record('START', subdir, testname,
654 optional_fields=optional_fields)
655
593 self._state.set('client', 'unexpected_reboot', (subdir, testname)) 656 self._state.set('client', 'unexpected_reboot', (subdir, testname))
594 try: 657 try:
595 result = function(*args, **dargs) 658 result = function(*args, **dargs)
596 self.record('END GOOD', subdir, testname) 659 self.record('END GOOD', subdir, testname)
597 return result 660 return result
598 except error.TestBaseException, e: 661 except error.TestBaseException, e:
599 self.record('END %s' % e.exit_status, subdir, testname) 662 self.record('END %s' % e.exit_status, subdir, testname)
600 raise 663 raise
601 except error.JobError, e: 664 except error.JobError, e:
602 self.record('END ABORT', subdir, testname) 665 self.record('END ABORT', subdir, testname)
(...skipping 23 matching lines...) Expand all
626 **dargs: 689 **dargs:
627 Named arguments for the function. 690 Named arguments for the function.
628 """ 691 """
629 if tag: 692 if tag:
630 name = tag 693 name = tag
631 else: 694 else:
632 name = function.__name__ 695 name = function.__name__
633 696
634 try: 697 try:
635 return self._rungroup(subdir=None, testname=name, 698 return self._rungroup(subdir=None, testname=name,
636 function=function, **dargs) 699 function=function, timeout=None, **dargs)
637 except (SystemExit, error.TestBaseException): 700 except (SystemExit, error.TestBaseException):
638 raise 701 raise
639 # If there was a different exception, turn it into a TestError. 702 # If there was a different exception, turn it into a TestError.
640 # It will be caught by step_engine or _run_step_fn. 703 # It will be caught by step_engine or _run_step_fn.
641 except Exception, e: 704 except Exception, e:
642 raise error.UnhandledTestError(e) 705 raise error.UnhandledTestError(e)
643 706
644 707
645 def cpu_count(self): 708 def cpu_count(self):
646 return utils.count_cpus() # use total system count 709 return utils.count_cpus() # use total system count
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 assert myjob._record_indent == 0 1321 assert myjob._record_indent == 0
1259 1322
1260 myjob.complete(0) 1323 myjob.complete(0)
1261 1324
1262 1325
1263 site_job = utils.import_site_class( 1326 site_job = utils.import_site_class(
1264 __file__, "autotest_lib.client.bin.site_job", "site_job", base_client_job) 1327 __file__, "autotest_lib.client.bin.site_job", "site_job", base_client_job)
1265 1328
1266 class job(site_job): 1329 class job(site_job):
1267 pass 1330 pass
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698