diff --git a/alembic/versions/d625d6c1122f_add_identifier_to_copr_build.py b/alembic/versions/d625d6c1122f_add_identifier_to_copr_build.py new file mode 100644 index 000000000..a8f9ff816 --- /dev/null +++ b/alembic/versions/d625d6c1122f_add_identifier_to_copr_build.py @@ -0,0 +1,31 @@ +"""Add identifier to copr build + +Revision ID: d625d6c1122f +Revises: f69687c314c5 +Create Date: 2024-11-22 13:05:49.763917 + +""" + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision = "d625d6c1122f" +down_revision = "f69687c314c5" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "copr_build_targets", sa.Column("identifier", sa.String(), default="", nullable=True) + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("copr_build_targets", "identifier") + # ### end Alembic commands ### diff --git a/packit_service/models.py b/packit_service/models.py index 342a554f8..8f916f8ee 100644 --- a/packit_service/models.py +++ b/packit_service/models.py @@ -162,10 +162,10 @@ def get_submitted_time_from_model( ) -> datetime: # TODO: unify `submitted_name` (or better -> create for both models `task_accepted_time`) # to delete this mess plz - if isinstance(model, CoprBuildTargetModel): - return model.build_submitted_time - - return model.submitted_time + try: + return model.build_submitted_time # type: ignore[union-attr] + except AttributeError: + return model.submitted_time # type: ignore[union-attr] @overload @@ -202,11 +202,11 @@ def get_most_recent_targets( for model in models: submitted_time_of_current_model = get_submitted_time_from_model(model) if ( - most_recent_models.get(model.target) is None - or get_submitted_time_from_model(most_recent_models[model.target]) + most_recent_models.get((model.target, model.identifier)) is None + or get_submitted_time_from_model(most_recent_models[(model.target, model.identifier)]) < submitted_time_of_current_model ): - most_recent_models[model.target] = model + most_recent_models[(model.target, model.identifier)] = model return list(most_recent_models.values()) @@ -254,12 +254,14 @@ def filter_most_recent_target_names_by_status( Iterable["TFTTestRunTargetModel"], ], statuses_to_filter_with: list[str], -) -> Optional[set[str]]: +) -> Optional[set[tuple[str, str]]]: filtered_models = filter_most_recent_target_models_by_status( models, statuses_to_filter_with, ) - return {model.target for model in filtered_models} if filtered_models else None + return ( + {(model.target, model.identifier) for model in filtered_models} if filtered_models else None + ) # https://github.com/python/mypy/issues/2477#issuecomment-313984522 ^_^ @@ -2102,6 +2104,8 @@ class CoprBuildTargetModel(GroupAndTargetModelConnector, Base): scan = relationship("OSHScanModel", back_populates="copr_build_target") + identifier = Column(String) + def set_built_packages(self, built_packages): with sa_session_transaction(commit=True) as session: self.built_packages = built_packages @@ -2297,6 +2301,7 @@ def create( status: BuildStatus, copr_build_group: "CoprBuildGroupModel", task_accepted_time: Optional[datetime] = None, + identifier: Optional[str] = None, ) -> "CoprBuildTargetModel": with sa_session_transaction(commit=True) as session: build = cls() @@ -2307,6 +2312,7 @@ def create( build.web_url = web_url build.target = target build.task_accepted_time = task_accepted_time + build.identifier = identifier or "" session.add(build) copr_build_group.copr_build_targets.append(build) diff --git a/packit_service/worker/events/comment.py b/packit_service/worker/events/comment.py index 0708602f7..a7400f952 100644 --- a/packit_service/worker/events/comment.py +++ b/packit_service/worker/events/comment.py @@ -62,8 +62,8 @@ def __init__( comment_id: int, commit_sha: str = "", comment_object: Optional[Comment] = None, - build_targets_override: Optional[set[str]] = None, - tests_targets_override: Optional[set[str]] = None, + build_targets_override: Optional[set[tuple[str, str]]] = None, + tests_targets_override: Optional[set[tuple[str, str]]] = None, ) -> None: super().__init__( pr_id=pr_id, @@ -93,7 +93,7 @@ def comment_object(self) -> Optional[Comment]: return self._comment_object @property - def build_targets_override(self) -> Optional[set[str]]: + def build_targets_override(self) -> Optional[set[tuple[str, str]]]: if not self._build_targets_override and "rebuild-failed" in self.comment: self._build_targets_override = ( super().get_all_build_targets_by_status( @@ -104,7 +104,7 @@ def build_targets_override(self) -> Optional[set[str]]: return self._build_targets_override @property - def tests_targets_override(self) -> Optional[set[str]]: + def tests_targets_override(self) -> Optional[set[tuple[str, str]]]: if not self._tests_targets_override and "retest-failed" in self.comment: self._tests_targets_override = ( super().get_all_tf_targets_by_status( diff --git a/packit_service/worker/events/event.py b/packit_service/worker/events/event.py index 1e832d785..2942446b2 100644 --- a/packit_service/worker/events/event.py +++ b/packit_service/worker/events/event.py @@ -72,8 +72,8 @@ def __init__( event_dict: Optional[dict], issue_id: Optional[int], task_accepted_time: Optional[datetime], - build_targets_override: Optional[list[str]], - tests_targets_override: Optional[list[str]], + build_targets_override: Optional[set[tuple[str, str]]], + tests_targets_override: Optional[set[tuple[str, str]]], branches_override: Optional[list[str]], ): self.event_type = event_type @@ -119,8 +119,16 @@ def from_event_dict(cls, event: dict): time = event.get("task_accepted_time") task_accepted_time = datetime.fromtimestamp(time, timezone.utc) if time else None - build_targets_override = event.get("build_targets_override") - tests_targets_override = event.get("tests_targets_override") + build_targets_override = ( + {(target, identifier_) for [target, identifier_] in event.get("build_targets_override")} + if event.get("build_targets_override") + else set() + ) + tests_targets_override = ( + {(target, identifier_) for [target, identifier_] in event.get("tests_targets_override")} + if event.get("tests_targets_override") + else set() + ) branches_override = event.get("branches_override") return EventData( @@ -508,17 +516,19 @@ def packages_config(self): raise NotImplementedError("Please implement me!") @property - def build_targets_override(self) -> Optional[set[str]]: + def build_targets_override(self) -> Optional[set[tuple[str, str]]]: """ - Return the targets to use for building of the all targets from config + Return the targets and identifiers to use for building + of the all targets from config for the relevant events (e.g.rerunning of a single check). """ return None @property - def tests_targets_override(self) -> Optional[set[str]]: + def tests_targets_override(self) -> Optional[set[tuple[str, str]]]: """ - Return the targets to use for testing of the all targets from config + Return the targets and identifiers to use for testing + of the all targets from config for the relevant events (e.g.rerunning of a single check). """ return None @@ -638,34 +648,44 @@ def get_packages_config(self) -> Optional[PackageConfig]: def get_all_tf_targets_by_status( self, statuses_to_filter_with: list[str], - ) -> Optional[set[str]]: + ) -> Optional[set[tuple[str, str]]]: if self.commit_sha is None: return None logger.debug( - f"Getting failed Testing Farm targets for commit sha: {self.commit_sha}", + f"Getting Testing Farm targets for commit sha {self.commit_sha} " + f"and statuses {statuses_to_filter_with}", ) - return filter_most_recent_target_names_by_status( + found_targets = filter_most_recent_target_names_by_status( models=TFTTestRunTargetModel.get_all_by_commit_target( commit_sha=self.commit_sha, ), statuses_to_filter_with=statuses_to_filter_with, ) + logger.debug( + f"Testing Farm found targets {found_targets}", + ) + return found_targets def get_all_build_targets_by_status( self, statuses_to_filter_with: list[str], - ) -> Optional[set[str]]: + ) -> Optional[set[tuple[str, str]]]: if self.commit_sha is None or self.project.repo is None: return None logger.debug( - f"Getting failed COPR build targets for commit sha: {self.commit_sha}", + f"Getting COPR build targets for commit sha {self.commit_sha} " + f"and statuses {statuses_to_filter_with}", ) - return filter_most_recent_target_names_by_status( + found_targets = filter_most_recent_target_names_by_status( models=CoprBuildTargetModel.get_all_by_commit(commit_sha=self.commit_sha), statuses_to_filter_with=statuses_to_filter_with, ) + logger.debug( + f"Builds found targets {found_targets}", + ) + return found_targets def get_non_serializable_attributes(self): return [ diff --git a/packit_service/worker/events/github.py b/packit_service/worker/events/github.py index a30747a97..eb2babb1e 100644 --- a/packit_service/worker/events/github.py +++ b/packit_service/worker/events/github.py @@ -236,16 +236,24 @@ def __init__( ) self.job_identifier = job_identifier + def _parse_target_and_identifier(self, target_string: str) -> tuple[str, str]: + """Parse target and identifier from check name target string.""" + if ":" in target_string: + target, identifier = target_string.split(":") + else: + target, identifier = target_string, "" + return target, identifier + @property - def build_targets_override(self) -> Optional[set[str]]: + def build_targets_override(self) -> Optional[set[tuple[str, str]]]: if self.check_name_job in {"rpm-build", "production-build", "koji-build"}: - return {self.check_name_target} + return {self._parse_target_and_identifier(self.check_name_target)} return None @property - def tests_targets_override(self) -> Optional[set[str]]: + def tests_targets_override(self) -> Optional[set[tuple[str, str]]]: if self.check_name_job == "testing-farm": - return {self.check_name_target} + return {self._parse_target_and_identifier(self.check_name_target)} return None @property diff --git a/packit_service/worker/handlers/mixin.py b/packit_service/worker/handlers/mixin.py index dd4003560..67c7ac3bd 100644 --- a/packit_service/worker/handlers/mixin.py +++ b/packit_service/worker/handlers/mixin.py @@ -432,7 +432,7 @@ def copr_build_helper(self) -> CoprBuildJobHelper: # when reporting state of SRPM build built in Copr build_targets_override = ( { - build.target + (build.target, build.identifier) for build in CoprBuildTargetModel.get_all_by_build_id( str(self.copr_event.build_id), ) diff --git a/packit_service/worker/helpers/build/build_helper.py b/packit_service/worker/helpers/build/build_helper.py index 8228d530d..d7ca46a78 100644 --- a/packit_service/worker/helpers/build/build_helper.py +++ b/packit_service/worker/helpers/build/build_helper.py @@ -53,8 +53,8 @@ def __init__( metadata: EventData, db_project_event: ProjectEventModel, job_config: JobConfig, - build_targets_override: Optional[set[str]] = None, - tests_targets_override: Optional[set[str]] = None, + build_targets_override: Optional[set[tuple[str, str]]] = None, + tests_targets_override: Optional[set[tuple[str, str]]] = None, pushgateway: Optional[Pushgateway] = None, ): super().__init__( @@ -67,8 +67,8 @@ def __init__( pushgateway=pushgateway, ) self.run_model: Optional[PipelineModel] = None - self.build_targets_override: Optional[set[str]] = build_targets_override - self.tests_targets_override: Optional[set[str]] = tests_targets_override + self.build_targets_override: Optional[set[tuple[str, str]]] = build_targets_override + self.tests_targets_override: Optional[set[tuple[str, str]]] = tests_targets_override self.pushgateway = pushgateway # lazy properties @@ -199,7 +199,7 @@ def build_targets(self) -> set[str]: """ if self.build_targets_override: logger.debug(f"Build targets override: {self.build_targets_override}") - return self.build_targets_all & self.build_targets_override + return self.build_targets_all & {target for target, _ in self.build_targets_override} return self.build_targets_all @@ -270,13 +270,24 @@ def build_targets_for_test_job(self, test_job_config: JobConfig) -> set[str]: if self.build_targets_override: logger.debug(f"Build targets override: {self.build_targets_override}") - targets_override.update(self.build_targets_override) + targets_override.update( + [ + target + for (target, identifier) in self.build_targets_override + if identifier == (test_job_config.identifier or "") + ] + ) if self.tests_targets_override: logger.debug(f"Test targets override: {self.tests_targets_override}") targets_override.update( - self.test_target2build_target_for_test_job(target, test_job_config) - for target in self.tests_targets_override + self.test_target2build_target_for_test_job(t, test_job_config) + for t in [ + target + for (target, identifier) in self.tests_targets_override + if identifier + == (test_job_config.identifier if test_job_config.identifier else "") + ] ) return configured_targets & targets_override if targets_override else configured_targets @@ -314,14 +325,22 @@ def tests_targets_for_test_job(self, test_job_config: JobConfig) -> set[str]: if self.build_targets_override: logger.debug(f"Build targets override: {self.build_targets_override}") - for target in self.build_targets_override: - targets_override.update( - self.build_target2test_targets_for_test_job(target, test_job_config), - ) + for target, identifier in self.build_targets_override: + if identifier == (test_job_config.identifier if test_job_config.identifier else ""): + targets_override.update( + self.build_target2test_targets_for_test_job(target, test_job_config), + ) if self.tests_targets_override: logger.debug(f"Test targets override: {self.tests_targets_override}") - targets_override.update(self.tests_targets_override) + targets_override.update( + [ + target + for target, identifier in self.tests_targets_override + if identifier + == (test_job_config.identifier if test_job_config.identifier else "") + ] + ) return ( configured_targets & targets_override diff --git a/packit_service/worker/helpers/build/copr_build.py b/packit_service/worker/helpers/build/copr_build.py index 4061e0d53..88b8d832d 100644 --- a/packit_service/worker/helpers/build/copr_build.py +++ b/packit_service/worker/helpers/build/copr_build.py @@ -80,8 +80,8 @@ def __init__( metadata: EventData, db_project_event: ProjectEventModel, job_config: JobConfig, - build_targets_override: Optional[set[str]] = None, - tests_targets_override: Optional[set[str]] = None, + build_targets_override: Optional[set[tuple[str, str]]] = None, + tests_targets_override: Optional[set[tuple[str, str]]] = None, pushgateway: Optional[Pushgateway] = None, celery_task: Optional[CeleryTask] = None, copr_build_group_id: Optional[int] = None, @@ -605,6 +605,7 @@ def _get_or_create_build_group(self) -> CoprBuildGroupModel: status=BuildStatus.waiting_for_srpm, copr_build_group=group, task_accepted_time=self.metadata.task_accepted_time, + identifier=self.job_config.identifier, ) if unprocessed_chroots: diff --git a/packit_service/worker/helpers/build/koji_build.py b/packit_service/worker/helpers/build/koji_build.py index 6f0683fb6..67b37766b 100644 --- a/packit_service/worker/helpers/build/koji_build.py +++ b/packit_service/worker/helpers/build/koji_build.py @@ -47,8 +47,8 @@ def __init__( metadata: EventData, db_project_event: ProjectEventModel, job_config: JobConfig, - build_targets_override: Optional[set[str]] = None, - tests_targets_override: Optional[set[str]] = None, + build_targets_override: Optional[set[tuple[str, str]]] = None, + tests_targets_override: Optional[set[tuple[str, str]]] = None, ): super().__init__( service_config=service_config, diff --git a/packit_service/worker/helpers/testing_farm.py b/packit_service/worker/helpers/testing_farm.py index b47c45198..b0db5c210 100644 --- a/packit_service/worker/helpers/testing_farm.py +++ b/packit_service/worker/helpers/testing_farm.py @@ -162,8 +162,8 @@ def __init__( metadata: EventData, db_project_event: ProjectEventModel, job_config: JobConfig, - build_targets_override: Optional[set[str]] = None, - tests_targets_override: Optional[set[str]] = None, + build_targets_override: Optional[set[tuple[str, str]]] = None, + tests_targets_override: Optional[set[tuple[str, str]]] = None, celery_task: Optional[CeleryTask] = None, ): super().__init__( @@ -323,7 +323,10 @@ def is_copr_build_comment_event(self) -> bool: ) def is_test_comment_event(self) -> bool: - return self.is_comment_event() and self.comment_arguments.packit_command == "test" + return self.is_comment_event() and self.comment_arguments.packit_command in ( + "test", + "retest-failed", + ) def is_test_comment_pr_argument_present(self): return self.is_test_comment_event() and self.comment_arguments.pr_argument diff --git a/tests/integration/test_babysit.py b/tests/integration/test_babysit.py index bd9eacb9d..04914c56a 100644 --- a/tests/integration/test_babysit.py +++ b/tests/integration/test_babysit.py @@ -299,6 +299,7 @@ def test_check_copr_build_waiting_srpm_failed(add_pull_request_event_with_sha_12 status=BuildStatus.waiting_for_srpm, build_submitted_time=datetime.datetime.utcnow(), target="the-target", + identifier="the-identifier", owner="the-owner", project_name="the-namespace-repo_name-5", commit_sha="123456", diff --git a/tests/integration/test_check_rerun.py b/tests/integration/test_check_rerun.py index 1845f6abd..8aa705219 100644 --- a/tests/integration/test_check_rerun.py +++ b/tests/integration/test_check_rerun.py @@ -305,7 +305,7 @@ def test_check_rerun_pr_testing_farm_handler( processing_results, ) assert json.dumps(event_dict) - assert event_dict["tests_targets_override"] == ["fedora-rawhide-x86_64"] + assert event_dict["tests_targets_override"] == [("fedora-rawhide-x86_64", "")] results = run_testing_farm_handler( package_config=package_config, event=event_dict, @@ -363,7 +363,7 @@ def test_check_rerun_pr_koji_build_handler( processing_results, ) assert json.dumps(event_dict) - assert event_dict["build_targets_override"] == ["f34"] + assert event_dict["build_targets_override"] == [("f34", "")] results = run_koji_build_handler( package_config=package_config, @@ -438,7 +438,7 @@ def test_check_rerun_pr_koji_build_handler_old_job_name( processing_results, ) assert json.dumps(event_dict) - assert event_dict["build_targets_override"] == ["f34"] + assert event_dict["build_targets_override"] == [("f34", "")] results = run_koji_build_handler( package_config=package_config, @@ -521,7 +521,7 @@ def test_check_rerun_push_testing_farm_handler( event_dict, job, job_config, package_config = get_parameters_from_results( processing_results, ) - assert event_dict["tests_targets_override"] == ["fedora-rawhide-x86_64"] + assert event_dict["tests_targets_override"] == [("fedora-rawhide-x86_64", "")] assert json.dumps(event_dict) results = run_testing_farm_handler( package_config=package_config, @@ -581,7 +581,7 @@ def test_check_rerun_push_koji_build_handler( event_dict, job, job_config, package_config = get_parameters_from_results( processing_results, ) - assert event_dict["build_targets_override"] == ["f34"] + assert event_dict["build_targets_override"] == [("f34", "")] assert json.dumps(event_dict) results = run_koji_build_handler( @@ -640,7 +640,7 @@ def test_check_rerun_release_koji_build_handler( event_dict, job, job_config, package_config = get_parameters_from_results( processing_results, ) - assert event_dict["build_targets_override"] == ["f34"] + assert event_dict["build_targets_override"] == [("f34", "")] assert json.dumps(event_dict) results = run_koji_build_handler( diff --git a/tests/integration/test_listen_to_fedmsg.py b/tests/integration/test_listen_to_fedmsg.py index 09fe42d2e..ba966bdce 100644 --- a/tests/integration/test_listen_to_fedmsg.py +++ b/tests/integration/test_listen_to_fedmsg.py @@ -818,7 +818,7 @@ def test_copr_build_end_testing_farm(copr_build_end, copr_build_pr): flexmock(CoprBuildTargetModel).should_receive("get_all_by").and_return( [copr_build_pr], ) - event_dict["tests_targets_override"] = ["fedora-rawhide-x86_64"] + event_dict["tests_targets_override"] = [("fedora-rawhide-x86_64", "")] run_testing_farm_handler( package_config=package_config, event=event_dict, @@ -2084,7 +2084,7 @@ def test_copr_build_end_failed_testing_farm(copr_build_end, copr_build_pr): job_config=job_config, ) - event_dict["tests_targets_override"] = ["fedora-rawhide-x86_64"] + event_dict["tests_targets_override"] = [("fedora-rawhide-x86_64", "")] run_testing_farm_handler( package_config=package_config, event=event_dict, @@ -2270,7 +2270,7 @@ def test_copr_build_end_failed_testing_farm_no_json(copr_build_end, copr_build_p job_config=job_config, ) - event_dict["tests_targets_override"] = ["fedora-rawhide-x86_64"] + event_dict["tests_targets_override"] = [("fedora-rawhide-x86_64", "")] task = run_testing_farm_handler.__wrapped__.__func__ task( flexmock( @@ -2695,7 +2695,7 @@ def test_srpm_build_end(srpm_build_end, pc_build_pr, srpm_build_model): ) flexmock(CoprBuildTargetModel).should_receive("get_all_by_build_id").and_return( [ - flexmock(target="fedora-33-x86_64") + flexmock(target="fedora-33-x86_64", identifier="") .should_receive("set_status") .with_args(BuildStatus.pending) .mock(), @@ -2762,7 +2762,7 @@ def test_srpm_build_end_failure(srpm_build_end, pc_build_pr, srpm_build_model): Client(config={"username": "packit", "copr_url": "https://dummy.url"}), ) flexmock(CoprBuildTargetModel).should_receive("get_all_by_build_id").and_return( - [flexmock(target="fedora-33-x86_64")], + [flexmock(target="fedora-33-x86_64", identifier="")], ) ( flexmock(CoprBuildJobHelper) @@ -2825,7 +2825,7 @@ def test_srpm_build_start(srpm_build_start, pc_build_pr, srpm_build_model): Client(config={"username": "packit", "copr_url": "https://dummy.url"}), ) flexmock(CoprBuildTargetModel).should_receive("get_all_by_build_id").and_return( - [flexmock(target="fedora-33-x86_64")], + [flexmock(target="fedora-33-x86_64", identifier="")], ) flexmock(Pushgateway).should_receive("push").times(2).and_return() diff --git a/tests/integration/test_pr_comment.py b/tests/integration/test_pr_comment.py index c1ea5c480..7ef27a0a0 100644 --- a/tests/integration/test_pr_comment.py +++ b/tests/integration/test_pr_comment.py @@ -1807,7 +1807,7 @@ def test_retest_failed( ).with_args( statuses_to_filter_with=[TestingFarmResult.failed, TestingFarmResult.error], ).and_return( - {"some_tf_target"}, + {("some_tf_target", "")}, ) flexmock(packit_service.models).should_receive( "filter_most_recent_target_names_by_status", @@ -1815,7 +1815,7 @@ def test_retest_failed( models=[model], statuses_to_filter_with=[TestingFarmResult.failed, TestingFarmResult.error], ).and_return( - {"some_target"}, + {("some_target", "")}, ) flexmock(Pushgateway).should_receive("push").times(3).and_return() @@ -1832,7 +1832,7 @@ def test_retest_failed( event_dict, job, job_config, package_config = get_parameters_from_results( processing_results, ) - assert event_dict["tests_targets_override"] == ["some_tf_target"] + assert event_dict["tests_targets_override"] == [("some_tf_target", "")] assert json.dumps(event_dict) run_testing_farm_handler( diff --git a/tests/unit/events/conftest.py b/tests/unit/events/conftest.py index 9981b9b9d..cd509782c 100644 --- a/tests/unit/events/conftest.py +++ b/tests/unit/events/conftest.py @@ -26,17 +26,14 @@ def mock_config(): def tf_models(): time = datetime(2000, 4, 28, 14, 9, 33, 860293) latest_time = datetime.utcnow() - fake_tf = flexmock(pipeline_id="1", submitted_time=time, target="target") - flexmock(TFTTestRunTargetModel).new_instances(fake_tf) - tf = TFTTestRunTargetModel() - tf.__class__ = TFTTestRunTargetModel - - another_fake_tf = flexmock( - pipeline_id="2", - submitted_time=latest_time, - target="target", - ) - flexmock(TFTTestRunTargetModel).new_instances(another_fake_tf) - another_tf = TFTTestRunTargetModel() - another_tf.__class__ = TFTTestRunTargetModel + tf = flexmock(TFTTestRunTargetModel).new_instances().mock() + tf.pipeline_id = "1" + tf.submitted_time = time + tf.target = "target" + + another_tf = flexmock(TFTTestRunTargetModel).new_instances().mock() + another_tf.pipeline_id = "2" + another_tf.submitted_time = latest_time + another_tf.target = "target" + yield [tf, another_tf] diff --git a/tests/unit/events/test_copr.py b/tests/unit/events/test_copr.py index 4bbdeb24e..540715e36 100644 --- a/tests/unit/events/test_copr.py +++ b/tests/unit/events/test_copr.py @@ -32,19 +32,15 @@ def copr_build_results_end(): def copr_models(): time = datetime(2000, 4, 28, 14, 9, 33, 860293) latest_time = datetime.utcnow() - fake_copr = flexmock(build_id="1", build_submitted_time=time, target="target") - flexmock(CoprBuildTargetModel).new_instances(fake_copr) - copr = CoprBuildTargetModel() - copr.__class__ = CoprBuildTargetModel - - another_fake_copr = flexmock( - build_id="2", - build_submitted_time=latest_time, - target="target", - ) - flexmock(CoprBuildTargetModel).new_instances(another_fake_copr) - another_copr = CoprBuildTargetModel() - another_copr.__class__ = CoprBuildTargetModel + copr = flexmock(CoprBuildTargetModel).new_instances().mock() + copr.build_id = "1" + copr.build_submitted_time = time + copr.target = "target" + + another_copr = flexmock(CoprBuildTargetModel).new_instances().mock() + another_copr.build_id = "2" + another_copr.build_submitted_time = latest_time + another_copr.target = "target" yield [copr, another_copr] diff --git a/tests/unit/events/test_github.py b/tests/unit/events/test_github.py index c09987c20..e5d0c2437 100644 --- a/tests/unit/events/test_github.py +++ b/tests/unit/events/test_github.py @@ -279,7 +279,7 @@ def test_parse_check_rerun_commit(check_rerun): ).once() assert event_object.packages_config assert event_object.build_targets_override is None - assert event_object.tests_targets_override == {"fedora-rawhide-x86_64"} + assert event_object.tests_targets_override == {("fedora-rawhide-x86_64", "")} assert event_object.actor == "lbarcziova" @@ -321,7 +321,7 @@ def test_parse_check_rerun_pull_request(check_rerun): ).once() assert event_object.packages_config assert event_object.build_targets_override is None - assert event_object.tests_targets_override == {"fedora-rawhide-x86_64"} + assert event_object.tests_targets_override == {("fedora-rawhide-x86_64", "")} def test_parse_check_rerun_release(check_rerun): @@ -347,7 +347,7 @@ def test_parse_check_rerun_release(check_rerun): assert event_object.check_name_job == "testing-farm" assert event_object.check_name_target == "fedora-rawhide-x86_64" assert event_object.build_targets_override is None - assert event_object.tests_targets_override == {"fedora-rawhide-x86_64"} + assert event_object.tests_targets_override == {("fedora-rawhide-x86_64", "")} assert event_object.actor == "lbarcziova" diff --git a/tests/unit/test_build_helper.py b/tests/unit/test_build_helper.py index a6fd16e8a..651721978 100644 --- a/tests/unit/test_build_helper.py +++ b/tests/unit/test_build_helper.py @@ -885,7 +885,8 @@ def test_deduced_copr_targets(): @pytest.mark.parametrize( - "jobs,job_config_trigger_type,build_targets_override," "tests_targets_override,build_targets", + "jobs,job_config_trigger_type,build_targets_override," + "tests_targets_override,build_targets,build_targets_for_job,tests_targets_for_job", [ pytest.param( [ @@ -905,9 +906,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"fedora-32-x86_64"}, + {("fedora-32-x86_64", "")}, None, {"fedora-32-x86_64"}, + [{"fedora-32-x86_64"}], + [{"fedora-32-x86_64"}], id="target_in_config_for_both", ), pytest.param( @@ -923,9 +926,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"fedora-32-x86_64"}, + {("fedora-32-x86_64", "")}, None, {"fedora-32-x86_64"}, + [{"fedora-32-x86_64"}], + None, id="target_in_config", ), pytest.param( @@ -941,9 +946,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"fedora-33-x86_64"}, + {("fedora-33-x86_64", "")}, None, set(), + [set()], + None, id="target_not_in_config", ), pytest.param( @@ -962,8 +969,10 @@ def test_deduced_copr_targets(): ], JobConfigTriggerType.pull_request, None, - {"centos-7-x86_64"}, + {("centos-7-x86_64", "")}, {"epel-7-x86_64"}, + None, + [{"centos-7-x86_64"}], id="build_test_mapping_test_overrides", ), pytest.param( @@ -981,9 +990,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"epel-7-x86_64"}, + {("epel-7-x86_64", "")}, None, {"epel-7-x86_64"}, + None, + [{"centos-7-x86_64", "rhel-7-x86_64"}], id="build_test_mapping_build_overrides", ), pytest.param( @@ -1000,8 +1011,10 @@ def test_deduced_copr_targets(): ], JobConfigTriggerType.pull_request, None, + {("centos-stream-8-x86_64", "")}, {"centos-stream-8-x86_64"}, - {"centos-stream-8-x86_64"}, + None, + [{"centos-stream-8-x86_64"}], id="targets_in_tests_no_mapping", ), pytest.param( @@ -1023,8 +1036,10 @@ def test_deduced_copr_targets(): ], JobConfigTriggerType.pull_request, None, + {("centos-stream-8-x86_64", "")}, {"centos-stream-8-x86_64"}, - {"centos-stream-8-x86_64"}, + [{"centos-stream-8-x86_64"}], + [{"centos-stream-8-x86_64"}], id="targets_in_build_no_mapping", ), pytest.param( @@ -1040,9 +1055,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"epel-7-x86_64"}, + {("epel-7-x86_64", "")}, None, {"epel-7-x86_64"}, + None, + [{"centos-7-x86_64"}], id="default_mapping_build_override", ), pytest.param( @@ -1059,8 +1076,10 @@ def test_deduced_copr_targets(): ], JobConfigTriggerType.pull_request, None, - {"centos-7-x86_64"}, + {("centos-7-x86_64", "")}, {"epel-7-x86_64"}, + None, + [{"centos-7-x86_64"}], id="default_mapping_test_override", ), pytest.param( @@ -1076,9 +1095,11 @@ def test_deduced_copr_targets(): ), ], JobConfigTriggerType.pull_request, - {"epel-7-ppc64le"}, + {("epel-7-ppc64le", "")}, None, {"epel-7-ppc64le"}, + None, + [{"centos-7-ppc64le"}], id="default_mapping_build_override_different_arch", ), pytest.param( @@ -1095,10 +1116,100 @@ def test_deduced_copr_targets(): ], JobConfigTriggerType.pull_request, None, - {"centos-7-ppc64le"}, + {("centos-7-ppc64le", "")}, {"epel-7-ppc64le"}, + None, + [{"centos-7-ppc64le"}], id="default_mapping_test_override_different_arch", ), + pytest.param( + [ + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-41-x86_64"], identifier="latest" + ), + }, + ), + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-rawhide-x86_64"], + ), + }, + ), + ], + JobConfigTriggerType.pull_request, + {("fedora-rawhide-x86_64", "")}, + None, + {"fedora-rawhide-x86_64"}, + None, + [{"fedora-rawhide-x86_64"}, set()], + id="rebuild_default_job_targets", + ), + pytest.param( + [ + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-41-x86_64"], identifier="latest" + ), + }, + ), + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-rawhide-x86_64"], + ), + }, + ), + ], + JobConfigTriggerType.pull_request, + {("fedora-41-x86_64", "latest")}, + None, + {"fedora-41-x86_64"}, + None, + [set(), {"fedora-41-x86_64"}], + id="rebuild_latest_job_targets", + ), + pytest.param( + [ + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-41-x86_64", "fedora-rawhide-x86_64"], + identifier="latest", + ), + }, + ), + JobConfig( + type=JobType.tests, + trigger=JobConfigTriggerType.pull_request, + packages={ + "package": CommonPackageConfig( + _targets=["fedora-rawhide-x86_64"], + ), + }, + ), + ], + JobConfigTriggerType.pull_request, + {("fedora-41-x86_64", "latest")}, + None, + {"fedora-41-x86_64"}, + None, + [set(), {"fedora-41-x86_64"}], + id="rebuild_latest_job_targets_for_job_with_identifier", + ), ], ) def test_build_targets_overrides( @@ -1107,6 +1218,8 @@ def test_build_targets_overrides( build_targets_override, tests_targets_override, build_targets, + build_targets_for_job, + tests_targets_for_job, ): copr_build_helper = CoprBuildJobHelper( service_config=ServiceConfig.get_service_config(), @@ -1149,7 +1262,30 @@ def test_build_targets_overrides( "centos-stream-8", default=None, ).and_return({"centos-stream-8-x86_64"}) + flexmock(CoprHelper).should_receive("get_valid_build_targets").with_args( + "fedora-rawhide-x86_64", + "fedora-41-x86_64", + default=None, + ).and_return({"fedora-rawhide-x86_64", "fedora-41-x86_64"}) + flexmock(CoprHelper).should_receive("get_valid_build_targets").with_args( + "fedora-41-x86_64", + default=None, + ).and_return({"fedora-41-x86_64"}) + flexmock(CoprHelper).should_receive("get_valid_build_targets").with_args( + "fedora-rawhide-x86_64", + default=None, + ).and_return({"fedora-rawhide-x86_64"}) + flexmock(CoprHelper).should_receive("get_valid_build_targets").with_args( + "fedora-41-x86_64", + "fedora-rawhide-x86_64", + default=None, + ).and_return({"fedora-rawhide-x86_64", "fedora-41-x86_64"}) + assert copr_build_helper.build_targets == build_targets + for job in [job for job in jobs if job.type == JobType.copr_build]: + assert copr_build_helper.build_targets_for_test_job(job) == build_targets_for_job.pop() + for job in [job for job in jobs if job.type == JobType.tests]: + assert copr_build_helper.tests_targets_for_test_job(job) == tests_targets_for_job.pop() @pytest.mark.parametrize( @@ -1173,7 +1309,7 @@ def test_build_targets_overrides( ), ], JobConfigTriggerType.pull_request, - {"fedora-32-x86_64"}, + {("fedora-32-x86_64", "")}, None, {"fedora-32-x86_64"}, id="target_in_config_for_both", @@ -1194,7 +1330,7 @@ def test_build_targets_overrides( ], JobConfigTriggerType.pull_request, None, - {"centos-7-x86_64"}, + {("centos-7-x86_64", "")}, {"centos-7-x86_64"}, id="build_test_mapping_test_overrides", ), @@ -1213,7 +1349,7 @@ def test_build_targets_overrides( ), ], JobConfigTriggerType.pull_request, - {"epel-7-x86_64"}, + {("epel-7-x86_64", "")}, None, {"centos-7-x86_64", "rhel-7-x86_64"}, id="build_test_mapping_build_overrides", @@ -1232,7 +1368,7 @@ def test_build_targets_overrides( ], JobConfigTriggerType.pull_request, None, - {"centos-stream-8-x86_64"}, + {("centos-stream-8-x86_64", "")}, {"centos-stream-8-x86_64"}, id="targets_in_tests_no_mapping", ), @@ -1255,7 +1391,7 @@ def test_build_targets_overrides( ], JobConfigTriggerType.pull_request, None, - {"centos-stream-8-x86_64"}, + {("centos-stream-8-x86_64", "")}, {"centos-stream-8-x86_64"}, id="targets_in_build_no_mapping", ), @@ -1272,7 +1408,7 @@ def test_build_targets_overrides( ), ], JobConfigTriggerType.pull_request, - {"epel-7-x86_64"}, + {("epel-7-x86_64", "")}, None, {"centos-7-x86_64"}, id="default_mapping_build_override", @@ -1291,7 +1427,7 @@ def test_build_targets_overrides( ], JobConfigTriggerType.pull_request, None, - {"centos-7-x86_64"}, + {("centos-7-x86_64", "")}, {"centos-7-x86_64"}, id="default_mapping_test_override", ), @@ -1308,7 +1444,7 @@ def test_build_targets_overrides( ), ], JobConfigTriggerType.pull_request, - {"epel-7-ppc64le"}, + {("epel-7-ppc64le", "")}, None, {"centos-7-ppc64le"}, id="default_mapping_build_override_different_arch", @@ -1327,7 +1463,7 @@ def test_build_targets_overrides( ], JobConfigTriggerType.pull_request, None, - {"centos-7-ppc64le"}, + {("centos-7-ppc64le", "")}, {"centos-7-ppc64le"}, id="default_mapping_test_override_different_arch", ), @@ -1344,7 +1480,7 @@ def test_build_targets_overrides( ), ], JobConfigTriggerType.pull_request, - {"fedora-rawhide-x86_64"}, + {("fedora-rawhide-x86_64", "")}, None, set(), id="build-target-not-in-test", @@ -1782,7 +1918,7 @@ def test_copr_test_target2build_target(job_config, test_target, build_target): ), ], JobConfigTriggerType.pull_request, - {"f32"}, + {("f32", "")}, {"f32"}, id="target_in_config", ), @@ -1799,7 +1935,7 @@ def test_copr_test_target2build_target(job_config, test_target, build_target): ), ], JobConfigTriggerType.pull_request, - {"f33"}, + {("f33", "")}, set(), id="target_not_in_config", ), diff --git a/tests/unit/test_koji_build.py b/tests/unit/test_koji_build.py index 7056f9e1c..b7ea4935c 100644 --- a/tests/unit/test_koji_build.py +++ b/tests/unit/test_koji_build.py @@ -518,7 +518,7 @@ def test_koji_build_targets_override( _targets=["bright-future", "dark-past"], scratch=True, db_project_event=db_project_event, - build_targets_override={"bright-future"}, + build_targets_override={("bright-future", "")}, ) flexmock(koji_build).should_receive("get_all_koji_targets").and_return( ["dark-past", "bright-future"], diff --git a/tests/unit/test_models.py b/tests/unit/test_models.py index 973440873..6b51cce03 100644 --- a/tests/unit/test_models.py +++ b/tests/unit/test_models.py @@ -17,30 +17,35 @@ def models(): model1 = flexmock( target="target-a", + identifier="", submitted_time=datetime.now() - timedelta(hours=2), status=TestingFarmResult.passed, ) model2 = flexmock( target="target-a", + identifier="", submitted_time=datetime.now(), status=TestingFarmResult.passed, ) model3 = flexmock( target="target-a", + identifier="", submitted_time=datetime.now() - timedelta(hours=1), status=TestingFarmResult.failed, ) model4 = flexmock( target="target-b", + identifier="", submitted_time=datetime.now(), status=TestingFarmResult.failed, ) model5 = flexmock( target="target-b", + identifier="", submitted_time=datetime.now() - timedelta(hours=1), status=TestingFarmResult.passed, ) @@ -59,4 +64,4 @@ def test_filter_most_recent_target_names_by_status(models): assert filter_most_recent_target_names_by_status( models, [TestingFarmResult.passed], - ) == {"target-a"} + ) == {("target-a", "")}