blob: 3b3cd00ad356c8354dab7fc2169f3eb65c8e9e1b [file] [log] [blame]
Xixuan Wu40998892017-08-29 14:32:26 -07001# Copyright 2017 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
5"""Module for cron job to trigger events for suite scheduler."""
6
7import logging
8
Xixuan Wu40998892017-08-29 14:32:26 -07009import config_reader
10import constants
11import datastore_client
Xixuan Wu40998892017-08-29 14:32:26 -070012import file_getter
13import rest_client
Brigit Rossbacheb611ac2020-09-24 14:55:24 -060014import StringIO
Xixuan Wu51bb7102019-03-18 14:51:44 -070015import task_config_reader
Xixuan Wu40998892017-08-29 14:32:26 -070016
17
18class TriggerReceiver(object):
19 """The class for receiving event triggers."""
20
Brigit Rossbach50d086f2020-09-17 13:29:49 -060021 def __init__(self, fake=False):
Xixuan Wu40998892017-08-29 14:32:26 -070022 """Initialize a trigger receiver.
23
24 Its job is to fetch triggers from config files and trigger them.
25 """
Xixuan Wuc6819012019-05-23 11:34:59 -070026 self._build_client = rest_client.BuildBucketBigqueryClient(
27 rest_client.BaseRestClient(
28 constants.RestClient.BIGQUERY_CLIENT.scopes,
29 constants.RestClient.BIGQUERY_CLIENT.service_name,
30 constants.RestClient.BIGQUERY_CLIENT.service_version))
Xixuan Wu40998892017-08-29 14:32:26 -070031 self._last_exec_client = datastore_client.LastExecutionRecordStore()
32 self._android_client = rest_client.AndroidBuildRestClient(
33 rest_client.BaseRestClient(
34 constants.RestClient.ANDROID_BUILD_CLIENT.scopes,
35 constants.RestClient.ANDROID_BUILD_CLIENT.service_name,
36 constants.RestClient.ANDROID_BUILD_CLIENT.service_version))
Brigit Rossbach50d086f2020-09-17 13:29:49 -060037 if fake:
38 self._task_config = task_config_reader.TaskConfig(
39 config_reader.ConfigReader(
40 file_getter.TEST_SUITE_SCHEDULER_CONFIG_FILE))
41 fake_lab_config_reader = config_reader.ConfigReader(
Dhanya Ganesh23dbb202020-09-30 16:11:01 +000042 file_getter.TEST_LAB_CONFIG_FILE)
Brigit Rossbach50d086f2020-09-17 13:29:49 -060043 self._lab_config = config_reader.LabConfig(fake_lab_config_reader)
Jack Neus8f0edb42022-03-17 20:21:39 +000044 fake_rubik_config_reader = config_reader.ConfigReader(
45 file_getter.TEST_RUBIK_CONFIG_FILE)
46 self._rubik_config = config_reader.RubikConfig(fake_rubik_config_reader)
Brigit Rossbach50d086f2020-09-17 13:29:49 -060047 else:
48 file_getter.clone_config()
49 self._task_config = task_config_reader.TaskConfig(
Dhanya Ganesh643a49e2020-09-25 18:14:22 +000050 config_reader.ConfigReader(
51 file_getter.NEW_SUITE_SCHEDULER_CONFIG_FILE))
52 lab_config_reader = config_reader.ConfigReader(file_getter.NEW_LAB_CONFIG_FILE)
Brigit Rossbach50d086f2020-09-17 13:29:49 -060053 self._lab_config = config_reader.LabConfig(lab_config_reader)
Jack Neus8f0edb42022-03-17 20:21:39 +000054 rubik_config_reader = config_reader.ConfigReader(file_getter.NEW_RUBIK_CONFIG_FILE)
55 self._rubik_config = config_reader.RubikConfig(rubik_config_reader)
Xixuan Wu40998892017-08-29 14:32:26 -070056
Xixuan Wu40998892017-08-29 14:32:26 -070057 # Initialize events
58 self.events = {}
Xixuan Wu51bb7102019-03-18 14:51:44 -070059 for keyword, klass in task_config_reader.EVENT_CLASSES.iteritems():
Xixuan Wu40998892017-08-29 14:32:26 -070060 logging.info('Initializing %s event', keyword)
61 new_event = klass(
62 self._task_config.get_event_setting(klass.section_name()),
63 self._last_exec_client.get_last_execute_time(klass.KEYWORD))
64
65 if new_event.should_handle:
66 new_event.set_task_list(
Xixuan Wu4ac56dd2017-10-12 11:59:30 -070067 self._task_config.get_tasks_by_keyword(klass.KEYWORD)['tasks'])
Xixuan Wu40998892017-08-29 14:32:26 -070068 logging.info('Got %d tasks for %s event',
69 len(new_event.task_list), klass.KEYWORD)
70
71 self.events[keyword] = new_event
72
73 self.event_results = {}
74
75 def cron(self):
76 """The cron job to scheduler suite jobs by config.
77
78 This cron job executes:
79 1. Filter out the tasks that shoud be run at this round.
80 2. Fetch launch_control_build for Android boards from API.
Xixuan Wu6ec23e32019-05-23 11:56:02 -070081 3. Fetch cros_builds for ChromeOS boards from Buildbucket bigquery.
Xixuan Wu40998892017-08-29 14:32:26 -070082 4. Schedule corresponding jobs with fetched builds.
83 5. Reset event when it's finished.
84 """
85 for keyword, event in self.events.iteritems():
86 logging.info('Handling %s event in cron job', keyword)
87
88 event.filter_tasks()
89 if event.task_list:
90 logging.info('Processing %d tasks.', len(event.task_list))
91 self._schedule_tasks(event)
92 else:
93 logging.info('No task list found')
94 event.finish()
95
96 def _schedule_tasks(self, event):
97 """Schedule tasks based on given event.
98
99 Args:
100 event: a kind of event, which contains its tasks that should be
101 scheduled.
102 """
Jack Neus8f0edb42022-03-17 20:21:39 +0000103 # TODO(b/225382624): Remove all Rubik logic once Rubik is fully rolled out.
Jack Neus2cbdc432022-06-24 20:21:30 +0000104 stable_rubik_milestones = self._rubik_config.get_stable_rubik_milestones()
Craig Bergstrom58263d32018-04-26 14:11:35 -0600105 cros_builds_tuple = event.get_cros_builds(
Jack Neus2cbdc432022-06-24 20:21:30 +0000106 self._lab_config, self._build_client, stable_rubik_milestones=stable_rubik_milestones)
Craig Bergstrom58263d32018-04-26 14:11:35 -0600107 logging.debug('Found CrOS builds: %r', cros_builds_tuple)
Garry Wang4e29b512021-08-26 19:32:59 -0700108 # Set delta to 3 days here as we only build once per day for non tot
109 # builds, so a single failure on secondary boards may cause a skip
110 # of primary board.
111 recent_cros_builds_tuple = event.get_recent_cros_builds(
Jack Neus8f0edb42022-03-17 20:21:39 +0000112 self._lab_config, self._build_client, delta_days=3,
Jack Neus2cbdc432022-06-24 20:21:30 +0000113 stable_rubik_milestones=stable_rubik_milestones)
Garry Wang4e29b512021-08-26 19:32:59 -0700114 logging.debug('Found recent CrOS builds: %r', recent_cros_builds_tuple)
Xixuan Wu40998892017-08-29 14:32:26 -0700115 launch_control_builds = event.get_launch_control_builds(
116 self._lab_config, self._android_client)
117 logging.debug('Found launch_control_builds: %r', launch_control_builds)
Xinan Lin8b291982019-12-16 10:03:56 -0800118 firmware_builds = None
119 if [x for x in event.task_list if (x.firmware_rw_build_spec or
120 x.firmware_ro_build_spec)]:
121 firmware_builds = event.get_firmware_builds(self._build_client)
Xixuan Wu40998892017-08-29 14:32:26 -0700122
123 self.event_results[event.KEYWORD] = event.process_tasks(
124 launch_control_builds=launch_control_builds,
Craig Bergstrom58263d32018-04-26 14:11:35 -0600125 cros_builds_tuple=cros_builds_tuple,
Xinan Lin028f9582019-12-11 10:55:33 -0800126 firmware_builds=firmware_builds,
Garry Wangdce77572021-07-18 19:33:35 -0700127 configs=config_reader.Configs(lab_config=self._lab_config),
Garry Wang4e29b512021-08-26 19:32:59 -0700128 recent_cros_builds_tuple=recent_cros_builds_tuple)
Xixuan Wu40998892017-08-29 14:32:26 -0700129 logging.info('Finished processing all tasks')