deduping_scheduler.py revision b493555db2d43e79d96e793cae9d1ffb822dd6c1
1# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6from autotest_lib.server.cros.dynamic_suite import frontend_wrappers 7from autotest_lib.server import frontend 8 9 10class DedupingSchedulerException(Exception): 11 """Base class for exceptions from this module.""" 12 pass 13 14 15class ScheduleException(DedupingSchedulerException): 16 """Raised when an error is returned from the AFE during scheduling.""" 17 pass 18 19 20class DedupException(DedupingSchedulerException): 21 """Raised when an error occurs while checking for duplicate jobs.""" 22 pass 23 24 25class DedupingScheduler(object): 26 """A class that will schedule suites to run on a given board, build. 27 28 Includes logic to check whether or not a given (suite, board, build) 29 has already been run. If so, it will skip scheduling that suite. 30 31 @var _afe: a frontend.AFE instance used to talk to autotest. 32 """ 33 34 35 def __init__(self, afe=None): 36 """Constructor 37 38 @param afe: an instance of AFE as defined in server/frontend.py. 39 Defaults to a frontend_wrappers.RetryingAFE instance. 40 """ 41 self._afe = afe or frontend_wrappers.RetryingAFE(timeout_min=30, 42 delay_sec=10, 43 debug=False) 44 45 46 def _ShouldScheduleSuite(self, suite, board, build): 47 """Return True if |suite| has not yet been run for |build| on |board|. 48 49 True if |suite| has not been run for |build| on |board|. 50 False if it has been. 51 52 @param suite: the name of the suite to run, e.g. 'bvt' 53 @param board: the board to run the suite on, e.g. x86-alex 54 @param build: the build to install e.g. 55 x86-alex-release/R18-1655.0.0-a1-b1584. 56 @return False if the suite was already scheduled, True if not 57 @raise DedupException if the AFE raises while searching for jobs. 58 """ 59 try: 60 return not self._afe.get_jobs(name__startswith=build, 61 name__endswith='control.'+suite) 62 except Exception as e: 63 raise DedupException(e) 64 65 66 def _Schedule(self, suite, board, build, pool, num): 67 """Schedule |suite|, if it hasn't already been run. 68 69 @param suite: the name of the suite to run, e.g. 'bvt' 70 @param board: the board to run the suite on, e.g. x86-alex 71 @param build: the build to install e.g. 72 x86-alex-release/R18-1655.0.0-a1-b1584. 73 @param pool: the pool of machines to use for scheduling purposes. 74 Default: None 75 @param num: the number of devices across which to shard the test suite. 76 Default: None (uses sharding factor in global_config.ini). 77 @return True if the suite got scheduled 78 @raise ScheduleException if an error occurs while scheduling. 79 """ 80 try: 81 logging.info('Scheduling %s on %s against %s (pool: %s)', 82 suite, build, board, pool) 83 if self._afe.run('create_suite_job', 84 suite_name=suite, 85 board=board, 86 build=build, 87 check_hosts=False, 88 num=num, 89 pool=pool) is not None: 90 return True 91 else: 92 raise ScheduleException( 93 "Can't schedule %s for %s." % (suite, build)) 94 except Exception as e: 95 raise ScheduleException(e) 96 97 98 def ScheduleSuite(self, suite, board, build, pool, num, force=False): 99 """Schedule |suite|, if it hasn't already been run. 100 101 If |suite| has not already been run against |build| on |board|, 102 schedule it and return True. If it has, return False. 103 104 @param suite: the name of the suite to run, e.g. 'bvt' 105 @param board: the board to run the suite on, e.g. x86-alex 106 @param build: the build to install e.g. 107 x86-alex-release/R18-1655.0.0-a1-b1584. 108 @param pool: the pool of machines to use for scheduling purposes. 109 @param num: the number of devices across which to shard the test suite. 110 @param force: Always schedule the suite. 111 @return True if the suite got scheduled, False if not 112 @raise DedupException if we can't check for dups. 113 @raise ScheduleException if the suite cannot be scheduled. 114 """ 115 if force or self._ShouldScheduleSuite(suite, board, build): 116 return self._Schedule(suite, board, build, pool, num) 117 return False 118 119 120 def GetHosts(self, *args, **kwargs): 121 """Forward a request to get hosts onto the AFE instance's get_hosts.""" 122 return self._afe.get_hosts(*args, **kwargs) 123