cbuildbot: make Android PFQ slave builds sync properly
BUG=chromium:589551
TEST=cbuildbot_unittest
Change-Id: Idecaa6ed98ba37b5c8002d50c96692620c903eed
Reviewed-on: https://chromium-review.googlesource.com/329390
Commit-Ready: David Riley <davidriley@chromium.org>
Tested-by: David Riley <davidriley@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
diff --git a/cbuildbot/builders/android_pfq_builders.py b/cbuildbot/builders/android_pfq_builders.py
index 41172ad..bfe0476 100644
--- a/cbuildbot/builders/android_pfq_builders.py
+++ b/cbuildbot/builders/android_pfq_builders.py
@@ -12,6 +12,7 @@
from chromite.cbuildbot.stages import artifact_stages
from chromite.cbuildbot.stages import build_stages
from chromite.cbuildbot.stages import chrome_stages
+from chromite.cbuildbot.stages import completion_stages
from chromite.cbuildbot.stages import sync_stages
from chromite.cbuildbot.stages import test_stages
from chromite.lib import cros_logging as logging
@@ -20,12 +21,73 @@
class AndroidPFQBuilder(simple_builders.SimpleBuilder):
"""Builder that performs Android uprev per overlay."""
+ def __init__(self, *args, **kwargs):
+ """Initializes a Android PFQ builder."""
+ super(AndroidPFQBuilder, self).__init__(*args, **kwargs)
+ self.sync_stage = None
+ self._completion_stage = None
+
+ def IsDistributed(self):
+ """Determines if this builder is being run as a slave.
+
+ Returns:
+ True if the build is distributed (ie running as a slave).
+ """
+ return self._run.options.buildbot and self._run.config['manifest_version']
+
+ def GetSyncInstance(self):
+ """Sync using distributed or normal logic as necessary.
+
+ Returns:
+ The instance of the sync stage to run.
+ """
+ if self.IsDistributed():
+ self.sync_stage = self._GetStageInstance(
+ sync_stages.MasterSlaveLKGMSyncStage)
+ else:
+ self.sync_stage = self._GetStageInstance(sync_stages.SyncStage)
+
+ return self.sync_stage
+
+ def GetCompletionInstance(self):
+ """Returns the completion_stage_class instance that was used for this build.
+
+ Returns:
+ None if the completion_stage instance was not yet created (this
+ occurs during Publish).
+ """
+ return self._completion_stage
+
+ def Publish(self, was_build_successful):
+ """Completes build by publishing any required information.
+
+ Args:
+ was_build_successful: Whether the build succeeded.
+ """
+ self._completion_stage = self._GetStageInstance(
+ completion_stages.MasterSlaveSyncCompletionStage,
+ self.sync_stage, was_build_successful)
+ self._completion_stage.Run()
+
def RunStages(self):
"""Runs through the stages of the Android PFQ slave build."""
- self.RunEarlySyncAndSetupStages()
- self._RunStage(android_stages.SyncAndroidStage)
- self.RunBuildTestStages()
- self.RunBuildStages()
+ was_build_successful = False
+ try:
+ self.RunEarlySyncAndSetupStages()
+ self._RunStage(android_stages.SyncAndroidStage)
+ self.RunBuildTestStages()
+ self.RunBuildStages()
+ was_build_successful = results_lib.Results.BuildSucceededSoFar()
+ except SystemExit as ex:
+ # If a stage calls sys.exit(0), it's exiting with success, so that means
+ # we should mark ourselves as successful.
+ logging.info('Detected sys.exit(%s)', ex.code)
+ if ex.code == 0:
+ was_build_successful = True
+ raise
+ finally:
+ if self.IsDistributed():
+ self.Publish(was_build_successful)
class AndroidPFQMasterBuilder(simple_builders.DistributedBuilder):
@@ -51,8 +113,8 @@
try:
self._RunStage(build_stages.UprevStage)
self._RunStage(build_stages.InitSDKStage)
- # The CQ/Chrome PFQ master will not actually run the SyncChrome stage, but
- # we want the logic that gets triggered when SyncChrome stage is skipped.
+ # The PFQ master will not actually run the SyncChrome/SyncAndroid stages,
+ # but we want the logic that gets triggered when the stages are skipped.
self._RunStage(chrome_stages.SyncChromeStage)
self._RunStage(android_stages.SyncAndroidStage)
self._RunStage(test_stages.BinhostTestStage)