blob: 8e657d9824db2cf4aa748aebd89c787025fcc9eb [file] [log] [blame]
Chris Masone2d61ca22012-04-02 16:52:46 -07001# 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
Chris Masone96f16632012-04-04 18:36:03 -07005import logging, time
Chris Masone2d61ca22012-04-02 16:52:46 -07006
Chris Masonefe5a5092012-04-11 18:29:07 -07007import board_enumerator, deduping_scheduler, forgiving_config_parser
8import manifest_versions, task, timed_event
Chris Masone2d61ca22012-04-02 16:52:46 -07009
10
11class Driver(object):
12 """Implements the main loop of the suite_scheduler.
13
Chris Masonefe5a5092012-04-11 18:29:07 -070014 @var _LOOP_INTERVAL_SECONDS: seconds to wait between loop iterations.
Chris Masone2d61ca22012-04-02 16:52:46 -070015
16 @var _scheduler: a DedupingScheduler, used to schedule jobs with the AFE.
Chris Masone3fba86f2012-04-03 10:06:56 -070017 @var _enumerator: a BoardEnumerator, used to list plaforms known to
Chris Masone2d61ca22012-04-02 16:52:46 -070018 the AFE
19 @var _events: list of BaseEvents to be handled each time through main loop.
20 """
21
Chris Masonefe5a5092012-04-11 18:29:07 -070022 _LOOP_INTERVAL_SECONDS = 5 * 60
Chris Masone2d61ca22012-04-02 16:52:46 -070023
24
Chris Masone96f16632012-04-04 18:36:03 -070025 def __init__(self, afe):
Chris Masone2d61ca22012-04-02 16:52:46 -070026 """Constructor
27
28 @param afe: an instance of AFE as defined in server/frontend.py.
29 @param config: an instance of ForgivingConfigParser.
30 """
31 self._scheduler = deduping_scheduler.DedupingScheduler(afe)
Chris Masone3fba86f2012-04-03 10:06:56 -070032 self._enumerator = board_enumerator.BoardEnumerator(afe)
Chris Masonefe5a5092012-04-11 18:29:07 -070033 self._mv = manifest_versions.ManifestVersions()
Chris Masone2d61ca22012-04-02 16:52:46 -070034
Chris Masone2d61ca22012-04-02 16:52:46 -070035
Chris Masone96f16632012-04-04 18:36:03 -070036 def SetUpEventsAndTasks(self, config):
37 """Constructor
38 @param config: an instance of ForgivingConfigParser.
39 """
40 self._events = [timed_event.Nightly.CreateFromConfig(config),
41 timed_event.Weekly.CreateFromConfig(config)]
42
43 tasks = self.TasksFromConfig(config)
44
45 for event in self._events:
46 if event.keyword in tasks:
47 event.tasks = tasks[event.keyword]
48 # TODO(cmasone): warn about unknown keywords?
49
50
51 def TasksFromConfig(self, config):
52 """Generate a dict of {event_keyword: [tasks]} mappings from |config|.
53
54 For each section in |config| that encodes a Task, instantiate a Task
55 object. Determine the event that Task is supposed to run_on and
56 append the object to a list associated with the appropriate event
57 keyword. Return a dictionary of these keyword: list of task mappings.
58
59 @param config: a ForgivingConfigParser containing tasks to be parsed.
60 @return dict of {event_keyword: [tasks]} mappings.
61 @raise MalformedConfigEntry on a task parsing error.
62 """
63 tasks = {}
64 for section in config.sections():
65 if not timed_event.TimedEvent.HonorsSection(section):
66 try:
67 keyword, new_task = task.Task.CreateFromConfigSection(
68 config, section)
69 except task.MalformedConfigEntry as e:
70 logging.warn('%s is malformed: %s', section, e)
71 continue
72 tasks.setdefault(keyword, []).append(new_task)
73 return tasks
Chris Masone2d61ca22012-04-02 16:52:46 -070074
75
76 def RunForever(self):
77 """Main loop of the scheduler. Runs til the process is killed."""
Chris Masonefe5a5092012-04-11 18:29:07 -070078 self._mv.Initialize()
Chris Masone2d61ca22012-04-02 16:52:46 -070079 while True:
80 self.HandleEventsOnce()
Chris Masonefe5a5092012-04-11 18:29:07 -070081 self._mv.Update()
82 time.sleep(self._LOOP_INTERVAL_SECONDS)
Chris Masone2d61ca22012-04-02 16:52:46 -070083
84
85 def HandleEventsOnce(self):
86 """One turn through the loop. Separated out for unit testing."""
Chris Masone92874d32012-04-03 10:13:04 -070087 boards = self._enumerator.Enumerate()
Chris Masone2d61ca22012-04-02 16:52:46 -070088
89 for e in self._events:
90 if e.ShouldHandle():
Chris Masone96f16632012-04-04 18:36:03 -070091 for board in boards:
Chris Masonefe5a5092012-04-11 18:29:07 -070092 branch_builds = e.GetBranchBuildsForBoard(board, self._mv)
Chris Masone96f16632012-04-04 18:36:03 -070093 e.Handle(self._scheduler, branch_builds, board)