1 # Copyright 2014 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.
5 """Module containing the AFDO stages."""
7 from __future__ import print_function
9 from chromite.cbuildbot import afdo
10 from chromite.cbuildbot import constants
11 from chromite.lib import alerts
12 from chromite.lib import cros_build_lib
13 from chromite.lib import gs
14 from chromite.lib import portage_util
15 from chromite.cbuildbot.stages import generic_stages
18 class AFDODataGenerateStage(generic_stages.BoardSpecificBuilderStage,
19 generic_stages.ForgivingBuilderStage):
20 """Stage that generates AFDO profile data from a perf profile."""
22 def _GetCurrentArch(self):
23 """Get architecture for the current board being built."""
24 return self._GetPortageEnvVar('ARCH', self._current_board)
26 def PerformStage(self):
27 """After collecting a 'perf' profile, generate the profile in AFDO format.
29 super(AFDODataGenerateStage, self).PerformStage()
31 board = self._current_board
32 if not afdo.CanGenerateAFDOData(board):
33 cros_build_lib.Warning('Board %s cannot generate its own AFDO profile.',
37 arch = self._GetCurrentArch()
38 buildroot = self._build_root
39 gs_context = gs.GSContext()
40 cpv = portage_util.BestVisible(constants.CHROME_CP,
44 # Generation of AFDO could fail for different reasons.
45 # We will ignore the failures and let the master PFQ builder try
46 # to find an older AFDO profile.
48 if afdo.WaitForAFDOPerfData(cpv, arch, buildroot, gs_context):
49 afdo_file = afdo.GenerateAFDOData(cpv, arch, board,
50 buildroot, gs_context)
52 cros_build_lib.Info('Generated %s AFDO profile %s',
55 raise afdo.MissingAFDOData('Could not find current "perf" profile. '
56 'Master PFQ builder will try to use stale '
58 # Will let system-exiting exceptions through.
60 cros_build_lib.PrintBuildbotStepWarnings()
61 cros_build_lib.Warning('AFDO profile generation failed with exception ',
64 alert_msg = ('Please triage. This will become a fatal error.\n\n'
65 'arch=%s buildroot=%s\n\nURL=%s' %
66 (arch, buildroot, self._run.ConstructDashboardURL()))
67 subject_msg = ('Failure in generation of AFDO Data for builder %s' %
68 self._run.config.name)
69 alerts.SendEmailLog(subject_msg,
70 afdo.AFDO_ALERT_RECIPIENTS,
71 smtp_server=constants.GOLO_SMTP_SERVER,
73 # Re-raise whatever exception we got here. This stage will only
74 # generate a warning but we want to make sure the warning is
79 class AFDOUpdateEbuildStage(generic_stages.BuilderStage):
80 """Updates the Chrome ebuild with the names of the AFDO profiles."""
82 def PerformStage(self):
83 buildroot = self._build_root
84 gs_context = gs.GSContext()
85 cpv = portage_util.BestVisible(constants.CHROME_CP,
87 version_number = cpv.version
89 # We need the name of one board that has been setup in this
90 # builder to find the Chrome ebuild. The chrome ebuild should be
91 # the same for all the boards, so just use the first one.
92 # If we don't have any boards, leave the called function to guess.
93 board = self._boards[0] if self._boards else None
95 for arch in afdo.AFDO_ARCH_GENERATORS:
96 afdo_file = afdo.GetLatestAFDOFile(cpv, arch, buildroot, gs_context)
98 raise afdo.MissingAFDOData('Could not find appropriate AFDO profile')
99 state = 'current' if version_number in afdo_file else 'previous'
100 cros_build_lib.Info('Found %s %s AFDO profile %s',
101 state, arch, afdo_file)
102 arch_profiles[arch] = afdo_file
104 # Now update the Chrome ebuild file with the AFDO profiles we found
105 # for each architecture.
106 afdo.UpdateChromeEbuildAFDOFile(board, arch_profiles)