| # Copyright 2018 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Database interface for all calls from Chromite. |
| |
| BuildStore will be the interface which communicates between CIDB, |
| Buildbucket as the underlying databases and Chromite and other callers |
| as the clients of the data. |
| """ |
| |
| import os |
| |
| from chromite.lib import buildbucket_v2 |
| from chromite.lib import cidb |
| from chromite.lib import constants |
| from chromite.lib import failure_message_lib |
| from chromite.lib import fake_cidb |
| |
| |
| # Build messages |
| MESSAGE_TYPE_IGNORED_REASON = "ignored_reason" |
| # MESSSGE_TYPE_IGNORED_REASON messages store the affected build as |
| # the CIDB column message_value. |
| MESSAGE_SUBTYPE_SELF_DESTRUCTION = "self_destruction" |
| |
| |
| class BuildStoreException(Exception): |
| """General exception class for this module.""" |
| |
| |
| class BuildIdentifier: |
| """The class maintains all the IDs corresponding to a build.""" |
| |
| def __init__(self, cidb_id=None, buildbucket_id=None) -> None: |
| """Instantiate a container class for all IDs. |
| |
| Args: |
| cidb_id: ID of the build in CIDB. |
| buildbucket_id: ID of the build in Buildbucket. |
| """ |
| self.cidb_id = cidb_id |
| self.buildbucket_id = buildbucket_id |
| |
| |
| class BuildStore: |
| """BuildStore class to handle all DB calls.""" |
| |
| NUM_RESULTS_NO_LIMIT = 1000 |
| |
| def __init__( |
| self, |
| _read_from_bb=True, |
| _write_to_bb=True, |
| _write_to_cidb=True, |
| cidb_creds=None, |
| for_service=None, |
| ) -> None: |
| """Get an instance of the BuildStore. |
| |
| Args: |
| _read_from_bb: Specify the read source. |
| _write_to_bb: Determines whether information is written to |
| Buildbucket. |
| _write_to_cidb: Determines whether information is written to CIDB. |
| cidb_creds: CIDB credentials for scripts running outside cbuildbot. |
| for_service: Argument for CIDBConnection.__init__(). |
| """ |
| self._read_from_bb = _read_from_bb |
| self._write_to_bb = _write_to_bb |
| self._write_to_cidb = _write_to_cidb |
| self.cidb_creds = cidb_creds |
| self.for_service = for_service |
| self.cidb_conn = None |
| self.bb_client = None |
| self.process_id = os.getpid() |
| |
| def _IsCIDBClientMissing(self): |
| """Checks to see if CIDB client is needed and is missing. |
| |
| Returns: |
| Boolean indicating the state of CIDB client. |
| """ |
| need_for_cidb = self._write_to_cidb or not self._read_from_bb |
| cidb_is_running = self.cidb_conn is not None |
| |
| return need_for_cidb and not cidb_is_running |
| |
| def _IsBuildbucketClientMissing(self): |
| """Checks to see if Buildbucket v2 client is needed and is missing. |
| |
| Returns: |
| Boolean indicating the state of Buildbucket v2 client. |
| """ |
| need_for_bb = self._write_to_bb or self._read_from_bb |
| bb_is_running = self.bb_client is not None |
| |
| return need_for_bb and not bb_is_running |
| |
| def GetCIDBHandle(self): |
| """Retrieve cidb_conn. |
| |
| Returns: |
| self.cidb_conn if initialized. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| |
| if self.cidb_conn: |
| return self.cidb_conn |
| else: |
| raise BuildStoreException("CIDBConnection not found.") |
| |
| def InitializeClients(self): |
| """Check if underlying clients are initialized. |
| |
| Returns: |
| A boolean indicating the client statuses. |
| """ |
| pid_mismatch = self.process_id != os.getpid() |
| if self._IsCIDBClientMissing() or pid_mismatch: |
| self.process_id = os.getpid() |
| if self.cidb_creds: |
| for_service = self.for_service if self.for_service else False |
| self.cidb_conn = cidb.CIDBConnection( |
| self.cidb_creds, for_service=for_service |
| ) |
| elif not cidb.CIDBConnectionFactory.IsCIDBSetup(): |
| self.cidb_conn = None |
| else: |
| self.cidb_conn = ( |
| cidb.CIDBConnectionFactory.GetCIDBConnectionForBuilder() |
| ) |
| |
| if self._IsBuildbucketClientMissing() or pid_mismatch: |
| self.bb_client = buildbucket_v2.BuildbucketV2() |
| |
| return not ( |
| self._IsCIDBClientMissing() or self._IsBuildbucketClientMissing() |
| ) |
| |
| def AreClientsReady(self): |
| """A front-end function for InitializeClients().""" |
| return self.InitializeClients() |
| |
| def InsertBuild( |
| self, |
| builder_name, |
| build_number, |
| build_config, |
| bot_hostname, |
| master_build_id=None, |
| timeout_seconds=None, |
| important=None, |
| buildbucket_id=None, |
| branch=None, |
| ): |
| """Insert a build row. |
| |
| Args: |
| builder_name: buildbot builder name. |
| build_number: buildbot build number. |
| build_config: cbuildbot config of build |
| bot_hostname: hostname of bot running the build |
| master_build_id: primary key of master build to this build. |
| timeout_seconds: If provided, total time allocated for this build. A |
| deadline is recorded in CIDB for the current build to end. |
| important: If provided, the |important| value for this build. |
| buildbucket_id: If provided, the |buildbucket_id| value for this |
| build. |
| branch: Manifest branch name of this build. |
| |
| Returns: |
| build_id: incremental primary ID of the build in CIDB. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| build_id = 0 |
| if self._write_to_cidb: |
| build_id = self.cidb_conn.InsertBuild( |
| builder_name, |
| build_number, |
| build_config, |
| bot_hostname, |
| master_build_id, |
| timeout_seconds, |
| important, |
| buildbucket_id, |
| branch, |
| ) |
| if self._write_to_bb: |
| buildbucket_v2.UpdateSelfCommonBuildProperties( |
| critical=important, cidb_id=build_id |
| ) |
| |
| return build_id |
| |
| def GetSlaveStatuses(self, master_build_identifier): |
| """Gets the statuses of slave builders to given build. |
| |
| Args: |
| master_build_identifier: BuildIdentifier of the master build to |
| fetch the slave statuses for. |
| |
| Returns: |
| A list containing a dictionary with keys BUILD_STATUS_KEYS. |
| The list contains all child builds of the given master. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if ( |
| self._read_from_bb |
| and master_build_identifier.buildbucket_id is not None |
| ): |
| return self.bb_client.GetChildStatuses( |
| int(master_build_identifier.buildbucket_id) |
| ) |
| elif ( |
| not self._read_from_bb |
| and master_build_identifier.cidb_id is not None |
| ): |
| return self.cidb_conn.GetSlaveStatuses( |
| master_build_identifier.cidb_id, None |
| ) |
| |
| def GetKilledChildBuilds(self, build_identifier): |
| """Get the child builds that were killed by the given master. |
| |
| Args: |
| build_identifier: The master build to get children for. |
| |
| Returns: |
| A list of child buildbucket_ids of the build that were killed. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._read_from_bb: |
| if build_identifier.buildbucket_id is not None: |
| return self.bb_client.GetKilledChildBuilds( |
| int(build_identifier.buildbucket_id) |
| ) |
| else: |
| if build_identifier.cidb_id is not None: |
| return [ |
| int(message["message_value"]) |
| for message in self.cidb_conn.GetBuildMessages( |
| build_identifier.cidb_id, |
| message_type=MESSAGE_TYPE_IGNORED_REASON, |
| message_subtype=MESSAGE_SUBTYPE_SELF_DESTRUCTION, |
| ) |
| ] |
| |
| def GetBuildHistory( |
| self, |
| build_config, |
| num_results, |
| ignore_build_id=None, |
| start_date=None, |
| end_date=None, |
| branch=None, |
| platform_version=None, |
| starting_build_id=None, |
| ): |
| """Returns basic information about most recent builds for build config. |
| |
| By default, this function returns the most recent builds. Some arguments |
| can restrict the result to older builds. |
| |
| Args: |
| build_config: config name of the build to get history. |
| num_results: Number of builds to search back. |
| ignore_build_id: Ignore a specific build. This is most useful to |
| ignore the current build when querying recent past builds from a |
| build in flight. |
| start_date: Get builds that occurred on or after this date. |
| end_date: Get builds that occurred on or before this date. |
| branch: Return only results for this branch. |
| platform_version: Return only results for this platform_version. |
| starting_build_id: The oldest build_id till which builds should be |
| retrieved. |
| |
| Returns: |
| A sorted list of dicts containing up to |number| dictionaries for |
| build statuses in descending order (if |reverse| is True, ascending |
| order). |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if platform_version or not self._read_from_bb: |
| return self.cidb_conn.GetBuildHistory( |
| build_config, |
| num_results, |
| ignore_build_id=ignore_build_id, |
| start_date=start_date, |
| end_date=end_date, |
| branch=branch, |
| platform_version=platform_version, |
| starting_build_id=starting_build_id, |
| ) |
| else: |
| return self.bb_client.GetBuildHistory( |
| build_config, |
| num_results, |
| ignore_build_id=ignore_build_id, |
| start_date=start_date, |
| end_date=end_date, |
| branch=branch, |
| start_build_id=starting_build_id, |
| ) |
| |
| def InsertBuildStage( |
| self, |
| build_id, |
| name, |
| board=None, |
| status=constants.BUILDER_STATUS_PLANNED, |
| ): |
| """Insert a build stage entry into database. |
| |
| Args: |
| build_id: primary key of the build in buildTable. |
| name: Full name of build stage. |
| board: board name, if this is a board-specific stage. |
| status: stage status, one of |
| constants.BUILDER_ALL_STATUSES. |
| Default constants.BUILDER_STATUS_PLANNED. |
| |
| Returns: |
| Integer primary key of inserted stage, i.e. build_stage_id |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| return self.cidb_conn.InsertBuildStage( |
| build_id, name, board, status |
| ) |
| |
| def InsertBuildMessage( |
| self, |
| build_id, |
| message_type=MESSAGE_TYPE_IGNORED_REASON, |
| message_subtype=MESSAGE_SUBTYPE_SELF_DESTRUCTION, |
| message_value=None, |
| board=None, |
| ) -> None: |
| """Insert a build message into database. |
| |
| Args: |
| build_id: primary key of build recording this message. |
| message_type: Optional str name of message type. |
| message_subtype: Optional str name of message subtype. |
| message_value: Optional value of message. |
| board: Optional str name of the board. |
| """ |
| assert isinstance(message_value, list) |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| for buildbucket_id in message_value: |
| self.cidb_conn.InsertBuildMessage( |
| build_id, |
| message_type=message_type, |
| message_subtype=message_subtype, |
| message_value=str(buildbucket_id), |
| board=board, |
| ) |
| if self._write_to_bb: |
| buildbucket_v2.UpdateSelfCommonBuildProperties( |
| killed_child_builds=message_value |
| ) |
| |
| def UpdateLuciNotifyProperties(self, email_notify=None) -> None: |
| """Update the buildbucket build with luci-notify specific properties. |
| |
| Args: |
| email_notify: List of luci-notify email_notify values representing |
| the recipients of failure alerts to for this builder. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_bb: |
| buildbucket_v2.UpdateSelfCommonBuildProperties( |
| email_notify=email_notify |
| ) |
| |
| def FinishBuild( |
| self, |
| build_id, |
| status=None, |
| summary=None, |
| metadata_url=None, |
| strict=True, |
| ) -> None: |
| """Update the given build row, marking it as finished. |
| |
| This should be called once per build, as the last update to the build. |
| This will also mark the row's final=True. |
| |
| Args: |
| build_id: id of row to update. |
| status: Final build status, one of |
| constants.BUILDER_COMPLETED_STATUSES. |
| summary: A summary of the build (failures) collected from all |
| slaves. |
| metadata_url: google storage url to metadata.json file for this |
| build, e.g. ('gs://chromeos-image-archive/master-paladin/' |
| 'R39-6225.0.0-rc1/metadata.json') |
| strict: If |strict| is True, can only update the build status when |
| 'final' is False. |strict| can only be False when the caller |
| wants to change the entry ignoring the 'final' value (For |
| example, a build was marked as status='aborted' and |
| final='true', a cron job to adjust the finish_time will call |
| this method with strict=False). |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| self.cidb_conn.FinishBuild( |
| build_id, |
| status=status, |
| summary=summary, |
| metadata_url=metadata_url, |
| strict=strict, |
| ) |
| if self._write_to_bb: |
| buildbucket_v2.UpdateSelfCommonBuildProperties( |
| metadata_url=metadata_url |
| ) |
| |
| def FinishChildConfig(self, build_id, child_config, status=None) -> None: |
| """Marks the given child config as finished with |status|. |
| |
| This should be called before FinishBuild, on all child configs that |
| were used in a build. |
| |
| Args: |
| build_id: primary key of the build in the buildTable |
| child_config: String child_config name. |
| status: Final child_config status, one of |
| constants.BUILDER_COMPLETED_STATUSES or None |
| for default "inflight". |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| self.cidb_conn.FinishChildConfig( |
| build_id, child_config, status=status |
| ) |
| |
| def StartBuildStage(self, build_stage_id): |
| """Marks a build stage as inflight, in the database. |
| |
| Args: |
| build_stage_id: primary key of the build stage in buildStageTable. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| return self.cidb_conn.StartBuildStage(build_stage_id) |
| |
| def WaitBuildStage(self, build_stage_id): |
| """Marks a build stage as waiting, in the database. |
| |
| Args: |
| build_stage_id: primary key of the build stage in buildStageTable. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| return self.cidb_conn.WaitBuildStage(build_stage_id) |
| |
| def FinishBuildStage(self, build_stage_id, status): |
| """Marks a build stage as finished, in the database. |
| |
| Args: |
| build_stage_id: primary key of the build stage in buildStageTable. |
| status: one of constants.BUILDER_COMPLETED_STATUSES |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| return self.cidb_conn.FinishBuildStage(build_stage_id, status) |
| |
| def InsertBoardPerBuild(self, build_id, board, board_metadata=None) -> None: |
| """Inserts board-per-build into the database. |
| |
| This function redirects both InsertBoardPerBuild and |
| UpdateBoardPerBuildMetadata of CIDB. |
| |
| Args: |
| build_id: CIDB id of the build. |
| board: Board of the build. |
| board_metadata: A dict with keys - 'main-firmware-version' and |
| 'ec-firmware-version'. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if self._write_to_cidb: |
| if board_metadata is None: |
| self.cidb_conn.InsertBoardPerBuild(build_id, board) |
| else: |
| self.cidb_conn.UpdateBoardPerBuildMetadata( |
| build_id, board, board_metadata |
| ) |
| if self._write_to_bb: |
| if board_metadata is None: |
| buildbucket_v2.UpdateSelfCommonBuildProperties(board=board) |
| else: |
| buildbucket_v2.UpdateSelfCommonBuildProperties( |
| board=board, |
| main_firmware_version=board_metadata.get( |
| "main-firmware-version" |
| ), |
| ec_firmware_version=board_metadata.get( |
| "ec-firmware-version" |
| ), |
| ) |
| |
| def UpdateMetadata(self, build_id, metadata): |
| """Update the given metadata row in database. |
| |
| Args: |
| build_id: CIDB id of the build to update. |
| metadata: CBuildbotMetadata instance to update with. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| update_status = 0 |
| if self._write_to_cidb: |
| update_status = self.cidb_conn.UpdateMetadata(build_id, metadata) |
| if self._write_to_bb: |
| buildbucket_v2.UpdateBuildMetadata(metadata) |
| return update_status |
| |
| def GetBuildsFailures(self, buildbucket_ids=None): |
| """Gets the failure entries for all listed buildbucket_ids. |
| |
| Args: |
| buildbucket_ids: list of build ids of the builds to fetch failures |
| for. |
| |
| Returns: |
| A list of failure_message_lib.StageFailure instances. This will |
| change with Buildbucket implementation. |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if not buildbucket_ids: |
| return [] |
| elif self._read_from_bb: |
| failure_list = [] |
| for buildbucket_id in buildbucket_ids: |
| bb_list = self.bb_client.GetStageFailures(int(buildbucket_id)) |
| for stage in bb_list: |
| failure_list.append( |
| failure_message_lib.StageFailure( |
| id=None, |
| build_stage_id=None, |
| outer_failure_id=None, |
| exception_type=None, |
| exception_message=None, |
| exception_category=None, |
| extra_info=None, |
| timestamp=None, |
| stage_name=stage["stage_name"], |
| board=None, |
| stage_status=stage["stage_status"], |
| build_id=None, |
| master_build_id=None, |
| builder_name=None, |
| build_number=None, |
| build_config=stage["build_config"], |
| build_status=stage["build_status"], |
| important=stage["important"], |
| buildbucket_id=buildbucket_id, |
| ) |
| ) |
| return failure_list |
| else: |
| return self.cidb_conn.GetBuildsFailures(buildbucket_ids) |
| |
| def GetBuildsStages(self, buildbucket_ids): |
| """Gets all the stages for all listed build_ids. |
| |
| Args: |
| buildbucket_ids: list of Buildbucket IDs to query for. |
| |
| Returns: |
| A list containing, for each stage of the builds found, a dictionary |
| with keys (id, build_id, name, board, status, last_updated, |
| start_time, finish_time, final). |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if not buildbucket_ids: |
| return [] |
| elif self._read_from_bb: |
| stage_list = [] |
| for buildbucket_id in buildbucket_ids: |
| stage_list += self.bb_client.GetBuildStages(int(buildbucket_id)) |
| return stage_list |
| else: |
| return self.cidb_conn.GetBuildsStagesWithBuildbucketIds( |
| buildbucket_ids |
| ) |
| |
| def GetBuildStatuses(self, buildbucket_ids=None, build_ids=None): |
| """Retrieve the build statuses of list of builds. |
| |
| The two arguments are to be mutually exclusive. If both are provided, |
| an error will be raised. If both are absent, an empty list will be |
| returned. |
| |
| Args: |
| buildbucket_ids: list of buildbucket_id's to query. |
| build_ids: list of CIDB id's to query. |
| |
| Returns: |
| A list of Dictionaries with keys (id, build_config, start_time, |
| finish_time, status, platform_version, full_version, |
| milestone_version, important). |
| """ |
| if not self.InitializeClients(): |
| raise BuildStoreException( |
| "BuildStore clients could not be initialized." |
| ) |
| if buildbucket_ids and build_ids: |
| raise BuildStoreException( |
| "GetBuildStatuses: Cannot process both " |
| "buildbucket_ids and build_ids." |
| ) |
| # build_ids have to serviced from CIDB. This codepath will be defunct |
| # after CQ is shut down. |
| if build_ids: |
| return self.cidb_conn.GetBuildStatuses(build_ids) |
| elif not buildbucket_ids: |
| return [] |
| elif self._read_from_bb: |
| return [ |
| self.bb_client.GetBuildStatus(int(buildbucket_id)) |
| for buildbucket_id in buildbucket_ids |
| ] |
| elif not self._read_from_bb: |
| return self.cidb_conn.GetBuildStatusesWithBuildbucketIds( |
| buildbucket_ids |
| ) |
| |
| |
| # pylint: disable=unused-argument |
| class FakeBuildStore: |
| """Fake BuildStore class to be used only in unittests.""" |
| |
| def __init__(self, fake_cidb_conn=None) -> None: |
| super().__init__() |
| if fake_cidb_conn: |
| self.fake_cidb = fake_cidb_conn |
| else: |
| self.fake_cidb = fake_cidb.FakeCIDBConnection() |
| |
| def InitializeClients(self): |
| return True |
| |
| def AreClientsReady(self): |
| return True |
| |
| def GetCIDBHandle(self): |
| return self.fake_cidb |
| |
| def InsertBuild( |
| self, |
| builder_name, |
| build_number, |
| build_config, |
| bot_hostname, |
| master_build_id=None, |
| timeout_seconds=None, |
| status=constants.BUILDER_STATUS_PASSED, |
| important=None, |
| buildbucket_id=None, |
| milestone_version=None, |
| platform_version=None, |
| start_time=None, |
| build_type=None, |
| branch=None, |
| ): |
| build_id = self.fake_cidb.InsertBuild( |
| builder_name, |
| build_number, |
| build_config, |
| bot_hostname, |
| master_build_id, |
| timeout_seconds, |
| status, |
| important, |
| buildbucket_id, |
| milestone_version, |
| platform_version, |
| start_time, |
| build_type, |
| branch, |
| ) |
| return build_id |
| |
| def GetBuildHistory( |
| self, |
| build_config, |
| num_results, |
| ignore_build_id=None, |
| start_date=None, |
| end_date=None, |
| branch=None, |
| platform_version=None, |
| starting_build_id=None, |
| ending_build_id=None, |
| ): |
| return self.fake_cidb.GetBuildHistory( |
| build_config, |
| num_results, |
| ignore_build_id=ignore_build_id, |
| start_date=start_date, |
| end_date=end_date, |
| platform_version=platform_version, |
| starting_build_id=starting_build_id, |
| ) |
| |
| def InsertBuildStage( |
| self, |
| build_id, |
| name, |
| board=None, |
| status=constants.BUILDER_STATUS_PLANNED, |
| ): |
| build_stage_id = self.fake_cidb.InsertBuildStage( |
| build_id, name, board, status |
| ) |
| return build_stage_id |
| |
| def GetSlaveStatuses(self, master_build_id, buildbucket_ids=None): |
| return self.fake_cidb.GetSlaveStatuses(master_build_id, buildbucket_ids) |
| |
| def GetKilledChildBuilds(self, build_identifier): |
| return [ |
| m["message_value"] |
| for m in self.fake_cidb.GetBuildMessages( |
| build_identifier.cidb_id, |
| message_type=MESSAGE_TYPE_IGNORED_REASON, |
| message_subtype=MESSAGE_SUBTYPE_SELF_DESTRUCTION, |
| ) |
| ] |
| |
| def InsertBuildMessage( |
| self, |
| build_id, |
| message_type=MESSAGE_TYPE_IGNORED_REASON, |
| message_subtype=MESSAGE_SUBTYPE_SELF_DESTRUCTION, |
| message_value=None, |
| board=None, |
| ) -> None: |
| for buildbucket_id in message_value: |
| self.fake_cidb.InsertBuildMessage( |
| build_id, |
| message_type=message_type, |
| message_subtype=message_subtype, |
| message_value=str(buildbucket_id), |
| board=board, |
| ) |
| |
| def UpdateLuciNotifyProperties(self, email_notify=None) -> None: |
| return |
| |
| def FinishBuild( |
| self, |
| build_id, |
| status=None, |
| summary=None, |
| metadata_url=None, |
| strict=True, |
| ) -> None: |
| return |
| |
| def StartBuildStage(self, build_stage_id): |
| return build_stage_id |
| |
| def WaitBuildStage(self, build_stage_id): |
| return build_stage_id |
| |
| def FinishBuildStage(self, build_stage_id, status): |
| return build_stage_id |
| |
| def InsertBoardPerBuild(self, build_id, board, board_metadata=None) -> None: |
| pass |
| |
| def UpdateMetadata(self, build_id, metadata) -> None: |
| return |
| |
| def GetBuildsFailures(self, buildbucket_ids=None): |
| if buildbucket_ids: |
| return self.fake_cidb.GetBuildsFailures(buildbucket_ids) |
| else: |
| return [] |
| |
| def GetBuildsStages(self, buildbucket_ids=None, build_ids=None): |
| if buildbucket_ids: |
| return self.fake_cidb.GetBuildsStagesWithBuildbucketIds( |
| buildbucket_ids |
| ) |
| elif build_ids: |
| return self.fake_cidb.GetBuildsStages(build_ids) |
| else: |
| return [] |
| |
| def GetBuildStatuses(self, buildbucket_ids=None, build_ids=None): |
| if buildbucket_ids: |
| return self.fake_cidb.GetBuildStatusesWithBuildbucketIds( |
| buildbucket_ids |
| ) |
| elif build_ids: |
| return self.fake_cidb.GetBuildStatuses(build_ids) |
| else: |
| return [] |