예제 #1
0
def test_copr_and_koji_build_for_one_trigger(clean_before_and_after):
    pr1 = PullRequestModel.get_or_create(
        pr_id=1,
        namespace="the-namespace",
        repo_name="the-repo-name",
        project_url="https://github.com/the-namespace/the-repo-name",
    )
    # SRPMBuildModel is (sadly) not shared between Koji and Copr builds.
    srpm_build_for_copr, run_model_for_copr = SRPMBuildModel.create_with_new_run(
        trigger_model=pr1, commit_sha="687abc76d67d")
    srpm_build_for_copr.set_logs("asd\nqwe\n")
    srpm_build_for_copr.set_status("success")

    srpm_build_for_koji, run_model_for_koji = SRPMBuildModel.create_with_new_run(
        trigger_model=pr1, commit_sha="687abc76d67d")
    srpm_build_for_copr.set_logs("asd\nqwe\n")
    srpm_build_for_copr.set_status("success")

    copr_build = CoprBuildModel.create(
        build_id="123456",
        commit_sha="687abc76d67d",
        project_name="SomeUser-hello-world-9",
        owner="packit",
        web_url="https://copr.something.somewhere/123456",
        target=SampleValues.target,
        status="pending",
        run_model=run_model_for_copr,
    )
    koji_build = KojiBuildModel.create(
        build_id="987654",
        commit_sha="687abc76d67d",
        web_url="https://copr.something.somewhere/123456",
        target=SampleValues.target,
        status="pending",
        run_model=run_model_for_koji,
    )

    assert copr_build in pr1.get_copr_builds()
    assert koji_build in pr1.get_koji_builds()

    assert srpm_build_for_copr in pr1.get_srpm_builds()
    assert srpm_build_for_koji in pr1.get_srpm_builds()

    assert copr_build.get_job_trigger_model(
    ) == koji_build.get_job_trigger_model()

    assert srpm_build_for_copr.get_trigger_object() == pr1
    assert srpm_build_for_koji.get_trigger_object() == pr1
    assert copr_build.get_trigger_object() == pr1
    assert koji_build.get_trigger_object() == pr1

    assert len(koji_build.runs) == 1
    assert koji_build.runs[0] == run_model_for_koji
    assert len(copr_build.runs) == 1
    assert copr_build.runs[0] == run_model_for_copr
예제 #2
0
def test_get_srpm_logs(client):
    srpm_build = SRPMBuildModel()
    srpm_build.id = 2
    srpm_build.logs = "asd\nqwe"

    flexmock(SRPMBuildModel).should_receive("get_by_id").and_return(srpm_build)

    url = "/srpm-build/2/logs"
    logs_url = get_srpm_log_url_from_flask(2)
    assert logs_url.endswith(url)

    resp = client.get(url).data.decode()
    assert srpm_build.logs in resp
    assert f"build {srpm_build.id}" in resp
예제 #3
0
def test_get_logs(client):
    chroot = "foo-1-x86_64"
    state = "pending"
    build_id = 2

    project = GitProjectModel()
    project.namespace = "john-foo"
    project.repo_name = "bar"

    pr = PullRequestModel()
    pr.pr_id = 234
    pr.project = project

    srpm_build = SRPMBuildModel()
    srpm_build.logs = "asd<br>qwe"

    c = CoprBuildModel()
    c.target = chroot
    c.build_id = str(build_id)
    c.srpm_build = srpm_build
    c.status = state
    c.web_url = (
        "https://copr.fedorainfracloud.org/coprs/john-foo-bar/john-foo-bar/build/2/"
    )
    c.build_logs_url = "https://localhost:5000/build/2/foo-1-x86_64/logs"

    flexmock(CoprBuildModel).should_receive("get_by_id").and_return(c)
    flexmock(CoprBuildModel).should_receive("get_project").and_return(project)
    flexmock(CoprBuildModel).should_receive("job_trigger").and_return(
        flexmock(get_trigger_object=lambda: pr))

    url = f"/copr-build/1/logs"
    logs_url = get_copr_build_log_url_from_flask(1)
    assert logs_url.endswith(url)

    resp = client.get(url)
    expected = (
        "<html><head>"
        f"<title>COPR build {project.namespace}/{project.repo_name}:"
        f" PR #{pr.pr_id}</title></head><body>"
        f"COPR build ID: {c.build_id}<br>"
        f"Submitted: {optional_time(c.build_submitted_time)}<br>"
        f"State: {c.status}<br><br>"
        f'Build web interface URL: <a href="{c.web_url}">{c.web_url}</a><br>'
        f'Build logs: <a href="{c.build_logs_url}">{c.build_logs_url}</a><br>'
        "SRPM creation logs:<br><br>"
        f"<pre>{c.srpm_build.logs}</pre>"
        "<br></body></html>")
    assert resp.data == expected.encode()
예제 #4
0
def test_get_logs(client):
    chroot = "foo-1-x86_64"
    state = "success"
    build_id = 2

    project = GitProjectModel()
    project.namespace = "john-foo"
    project.repo_name = "bar"

    pr = PullRequestModel()
    pr.pr_id = 234
    pr.project = project

    srpm = SRPMBuildModel()
    srpm.url = "https://some.random.copr.subdomain.org/my_srpm.srpm"

    c = CoprBuildModel()
    c.target = chroot
    c.build_id = str(build_id)
    c.srpm_build_id = 11
    c.status = state
    c.srpm_build = srpm
    c.web_url = (
        "https://copr.fedorainfracloud.org/coprs/john-foo-bar/john-foo-bar/build/2/"
    )
    c.build_logs_url = "https://localhost:5000/build/2/foo-1-x86_64/logs"
    c.owner = "packit"
    c.project_name = "example_project"

    flexmock(CoprBuildModel).should_receive("get_by_id").and_return(c)
    flexmock(CoprBuildModel).should_receive("get_project").and_return(project)
    flexmock(CoprBuildModel).should_receive("job_trigger").and_return(
        flexmock(get_trigger_object=lambda: pr))

    url = "/copr-build/1"
    logs_url = get_copr_build_info_url_from_flask(1)
    assert logs_url.endswith(url)

    resp = client.get(url).data.decode()
    assert f"srpm-build/{c.srpm_build_id}/logs" in resp
    assert c.web_url in resp
    assert c.build_logs_url in resp
    assert c.target in resp
    assert "Status: success" in resp
    assert "You can install" in resp

    assert "Download SRPM" in resp
    assert srpm.url in resp
예제 #5
0
def test_koji_build_target_not_supported(github_pr_event):
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(
        flexmock(job_config_trigger_type=JobConfigTriggerType.release))
    helper = build_helper(
        event=github_pr_event,
        metadata=JobMetadataConfig(targets=["nonexisting-target"]),
    )
    flexmock(koji_build).should_receive("get_all_koji_targets").and_return(
        ["dark-past", "bright-future"]).once()

    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/production-build-nonexisting-target",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.error,
        description="Target not supported: nonexisting-target",
        check_name="packit-stg/production-build-nonexisting-target",
        url=get_srpm_log_url_from_flask(1),
    ).and_return()

    flexmock(GitProject).should_receive(
        "set_commit_status").and_return().never()
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(id=1, success=True))
    flexmock(KojiBuildModel).should_receive("get_or_create").and_return(
        KojiBuildModel(id=1))
    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    response = helper.run_koji_build()
    assert not response["success"]
    assert ("Target not supported: nonexisting-target" == response["details"]
            ["errors"]["nonexisting-target"])
예제 #6
0
def test_copr_and_koji_build_for_one_trigger(clean_before_and_after):
    pr1 = PullRequestModel.get_or_create(
        pr_id=1, namespace="the-namespace", repo_name="the-repo-name"
    )
    pr1_trigger = JobTriggerModel.get_or_create(
        type=JobTriggerModelType.pull_request, trigger_id=pr1.id
    )
    srpm_build = SRPMBuildModel.create("asd\nqwe\n")
    copr_build = CoprBuildModel.get_or_create(
        build_id="123456",
        commit_sha="687abc76d67d",
        project_name="SomeUser-hello-world-9",
        owner="packit",
        web_url="https://copr.something.somewhere/123456",
        target=TARGET,
        status="pending",
        srpm_build=srpm_build,
        trigger_model=pr1,
    )
    koji_build = KojiBuildModel.get_or_create(
        build_id="987654",
        commit_sha="687abc76d67d",
        web_url="https://copr.something.somewhere/123456",
        target=TARGET,
        status="pending",
        srpm_build=srpm_build,
        trigger_model=pr1,
    )

    assert copr_build in pr1_trigger.copr_builds
    assert koji_build in pr1_trigger.koji_builds

    assert copr_build.job_trigger.get_trigger_object() == pr1
    assert koji_build.job_trigger.get_trigger_object() == pr1
예제 #7
0
    def get(self):
        """List all SRPM builds."""

        result = []

        first, last = indices()
        for build in SRPMBuildModel.get(first, last):
            build_dict = {
                "srpm_build_id":
                build.id,
                "success":
                build.success,
                "log_url":
                get_srpm_build_info_url(build.id),
                "build_submitted_time":
                optional_timestamp(build.build_submitted_time),
            }
            project = build.get_project()

            # Its possible that jobtrigger isnt stored in db
            if project:
                build_dict["repo_namespace"] = project.namespace
                build_dict["repo_name"] = project.repo_name
                build_dict["project_url"] = project.project_url
                build_dict["pr_id"] = build.get_pr_id()
                build_dict["branch_name"] = build.get_branch_name()

            result.append(build_dict)

        resp = response_maker(
            result,
            status=HTTPStatus.PARTIAL_CONTENT.value,
        )
        resp.headers["Content-Range"] = f"srpm-builds {first + 1}-{last}/*"
        return resp
예제 #8
0
def test_copr_build_check_names(pull_request_event):
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(
        flexmock(job_config_trigger_type=JobConfigTriggerType.release)
    )
    helper = build_helper(
        event=pull_request_event,
        metadata=JobMetadataConfig(targets=["bright-future-x86_64"], owner="nobody"),
    )
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/rpm-build-bright-future-x86_64",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building RPM ...",
        check_name="packit-stg/rpm-build-bright-future-x86_64",
        url="https://localhost:5000/copr-build/1/logs",
    ).and_return()

    flexmock(GitProject).should_receive("set_commit_status").and_return().never()
    flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel())
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1)
    )
    flexmock(PullRequestEvent).should_receive("db_trigger").and_return(flexmock())
    flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None)
    flexmock(Celery).should_receive("send_task").once()

    config = ServiceConfig.get_service_config()
    config.disable_sentry = True
    assert helper.run_copr_build()["success"]
예제 #9
0
def test_copr_build_for_release(release_event):
    # status is set for each build-target (4x):
    #  - Building SRPM ...
    #  - Building RPM ...
    branch_build_job = JobConfig(
        type=JobType.build,
        trigger=JobConfigTriggerType.release,
        metadata=JobMetadataConfig(
            targets=[
                "fedora-29-x86_64",
                "fedora-30-x86_64",
                "fedora-31-x86_64",
                "fedora-rawhide-x86_64",
            ],
            owner="nobody",
            dist_git_branches=["build-branch"],
        ),
    )
    flexmock(AddReleaseDbTrigger).should_receive("db_trigger").and_return(
        flexmock(job_config_trigger_type=JobConfigTriggerType.release)
    )
    helper = build_helper(jobs=[branch_build_job], event=release_event)
    flexmock(ReleaseEvent).should_receive("get_project").and_return(helper.project)
    flexmock(GitProject).should_receive("set_commit_status").and_return().times(8)
    flexmock(GitProject).should_receive("get_sha_from_tag").and_return("123456").once()
    flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel())
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1)
    )
    flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None).once()
    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]
예제 #10
0
def test_copr_build_fails_in_packit(pull_request_event):
    # status is set for each build-target (4x):
    #  - Building SRPM ...
    #  - Build failed, check latest comment for details.
    helper = build_helper(event=pull_request_event)
    templ = "packit-stg/rpm-build-fedora-{ver}-x86_64"
    for v in ["29", "30", "31", "rawhide"]:
        flexmock(GitProject).should_receive("set_commit_status").with_args(
            "528b803be6f93e19ca4130bf4976f2800a3004c4",
            CommitStatus.pending,
            "",
            "Building SRPM ...",
            templ.format(ver=v),
            trim=True,
        ).and_return().once()
    for v in ["29", "30", "31", "rawhide"]:
        flexmock(GitProject).should_receive("set_commit_status").with_args(
            "528b803be6f93e19ca4130bf4976f2800a3004c4",
            CommitStatus.failure,
            "https://localhost:5000/srpm-build/2/logs",
            "SRPM build failed, check the logs for details.",
            templ.format(ver=v),
            trim=True,
        ).and_return().once()
    flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel(id=2))
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1)
    )
    flexmock(sentry_integration).should_receive("send_to_sentry").and_return().once()
    flexmock(PackitAPI).should_receive("run_copr_build").and_raise(
        FailedCreateSRPM, "some error"
    )
    assert not helper.run_copr_build()["success"]
예제 #11
0
    def get(self, id):
        """A specific SRPM build details."""
        build = SRPMBuildModel.get_by_id(int(id))
        if not build:
            return response_maker(
                {"error": "No info about build stored in DB"},
                status=HTTPStatus.NOT_FOUND.value,
            )

        build_dict = {
            "status": build.status,
            "build_submitted_time":
            optional_timestamp(build.build_submitted_time),
            "build_start_time": optional_timestamp(build.build_start_time),
            "build_finished_time":
            optional_timestamp(build.build_finished_time),
            "url": build.url,
            "logs": build.logs,
            "logs_url": build.logs_url,
            "copr_build_id": build.copr_build_id,
            "copr_web_url": build.copr_web_url,
            "run_ids": sorted(run.id for run in build.runs),
        }

        build_dict.update(get_project_info_from_build(build))
        return response_maker(build_dict)
예제 #12
0
def multiple_koji_builds(pr_trigger_model, different_pr_trigger_model):
    srpm_build = SRPMBuildModel.create("asd\nqwe\n")
    yield [
        KojiBuildModel.get_or_create(
            build_id="123456",
            commit_sha="687abc76d67d",
            web_url="https://copr.something.somewhere/123456",
            target="fedora-42-x86_64",
            status="pending",
            srpm_build=srpm_build,
            trigger_model=pr_trigger_model,
        ),
        # Same build_id but different chroot
        KojiBuildModel.get_or_create(
            build_id="123456",
            commit_sha="687abc76d67d",
            web_url="https://copr.something.somewhere/123456",
            target="fedora-43-x86_64",
            status="pending",
            srpm_build=srpm_build,
            trigger_model=pr_trigger_model,
        ),
        # Completely different build
        KojiBuildModel.get_or_create(
            build_id="987654",
            commit_sha="987def76d67e",
            web_url="https://copr.something.somewhere/987654",
            target="fedora-43-x86_64",
            status="pending",
            srpm_build=srpm_build,
            trigger_model=different_pr_trigger_model,
        ),
    ]
예제 #13
0
def test_koji_build_failed_srpm(github_pr_event):
    trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.release, id=123)
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger)
    helper = build_helper(
        event=github_pr_event,
        metadata=JobMetadataConfig(targets=["bright-future"]),
        db_trigger=trigger,
    )
    srpm_build_url = get_srpm_log_url_from_flask(2)
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/production-build-bright-future",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.failure,
        description="SRPM build failed, check the logs for details.",
        check_name="packit-stg/production-build-bright-future",
        url=srpm_build_url,
    ).and_return()

    flexmock(GitProject).should_receive("set_commit_status").and_return().never()
    flexmock(PackitAPI).should_receive("create_srpm").and_raise(Exception, "some error")
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(id=2, success=False)
    )
    flexmock(KojiBuildModel).should_receive("get_or_create").never()
    flexmock(sentry_integration).should_receive("send_to_sentry").and_return().once()

    result = helper.run_koji_build()
    assert not result["success"]
    assert "SRPM build failed" in result["details"]["msg"]
예제 #14
0
    def from_build_id(
        cls,
        topic: str,
        build_id: int,
        chroot: str,
        status: int,
        owner: str,
        project_name: str,
        pkg: str,
        timestamp,
    ) -> Optional["AbstractCoprBuildEvent"]:
        """Return cls instance or None if build_id not in CoprBuildDB"""
        build: Optional[Union[SRPMBuildModel, CoprBuildModel]]
        if chroot == COPR_SRPM_CHROOT:
            build = SRPMBuildModel.get_by_copr_build_id(str(build_id))
        else:
            build = CoprBuildModel.get_by_build_id(str(build_id), chroot)

        if not build:
            logger.warning(
                f"Build id {build_id} not in "
                f"{'SRPMBuildDB' if chroot == COPR_SRPM_CHROOT else 'CoprBuildDB'}."
            )
            return None

        return cls(topic, build_id, build, chroot, status, owner, project_name,
                   pkg, timestamp)
예제 #15
0
def test_copr_build_success(github_pr_event):
    # status is set for each build-target (4x):
    #  - Building SRPM ...
    #  - Starting RPM build...
    helper = build_helper(event=github_pr_event)
    flexmock(GitProject).should_receive("set_commit_status").and_return().times(8)
    flexmock(GitProject).should_receive("get_pr").and_return(flexmock())
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True)
    )
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1)
    )
    flexmock(PullRequestGithubEvent).should_receive("db_trigger").and_return(flexmock())

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive("create_copr_project_if_not_exists").and_return(
        None
    )
    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock()
            .should_receive("create_from_file")
            .and_return(
                flexmock(id=2, projectname="the-project-name", ownername="the-owner")
            )
            .mock(),
        )
    )

    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]
예제 #16
0
    def _create_srpm(self):
        # we want to get packit logs from the SRPM creation process
        # so we stuff them into a StringIO buffer
        stream = StringIO()
        handler = logging.StreamHandler(stream)
        packit_logger = logging.getLogger("packit")
        packit_logger.setLevel(logging.DEBUG)
        packit_logger.addHandler(handler)
        formatter = PackitFormatter(None, "%H:%M:%S")
        handler.setFormatter(formatter)

        srpm_success = True
        exception: Optional[Exception] = None
        extra_logs: str = ""

        try:
            self._srpm_path = Path(
                self.api.create_srpm(srpm_dir=self.api.up.local_project.working_dir)
            )
        except SandcastleTimeoutReached as ex:
            exception = ex
            extra_logs = f"\nYou have reached 10-minute timeout while creating SRPM.\n"
        except ApiException as ex:
            exception = ex
            # this is an internal error: let's not expose anything to public
            extra_logs = (
                "\nThere was a problem in the environment the packit-service is running in.\n"
                "Please hang tight, the help is coming."
            )
        except Exception as ex:
            exception = ex

        # collect the logs now
        packit_logger.removeHandler(handler)
        stream.seek(0)
        srpm_logs = stream.read()

        if exception:
            logger.info(f"exception while running SRPM build: {exception}")
            logger.debug(f"{exception!r}")

            srpm_success = False

            # when do we NOT want to send stuff to sentry?
            sentry_integration.send_to_sentry(exception)

            # this needs to be done AFTER we gather logs
            # so that extra logs are after actual logs
            srpm_logs += extra_logs
            if hasattr(exception, "output"):
                output = getattr(exception, "output", "")  # mypy
                srpm_logs += f"\nOutput of the command in the sandbox:\n{output}\n"

            srpm_logs += (
                f"\nMessage: {exception}\nException: {exception!r}\n{self.msg_retrigger}"
                "\nPlease join the freenode IRC channel #packit for the latest info.\n"
            )

        self._srpm_model = SRPMBuildModel.create(logs=srpm_logs, success=srpm_success)
예제 #17
0
def test_copr_build_check_names(github_pr_event):
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(
        flexmock(job_config_trigger_type=JobConfigTriggerType.release))
    helper = build_helper(
        event=github_pr_event,
        metadata=JobMetadataConfig(targets=["bright-future-x86_64"],
                                   owner="nobody"),
    )

    flexmock(copr_build).should_receive(
        "get_copr_build_log_url_from_flask").and_return("https://test.url")
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/rpm-build-bright-future-x86_64",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Starting RPM build...",
        check_name="packit-stg/rpm-build-bright-future-x86_64",
        url="https://test.url",
    ).and_return()

    flexmock(GitProject).should_receive(
        "set_commit_status").and_return().never()
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True))
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1))
    flexmock(PullRequestGithubEvent).should_receive("db_trigger").and_return(
        flexmock())

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive(
        "create_copr_project_if_not_exists").with_args(
            project="the-example-namespace-the-example-repo-342-stg",
            chroots=["bright-future-x86_64"],
            owner="nobody",
            description=None,
            instructions=None,
        ).and_return(None)

    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock().should_receive(
                "create_from_file").and_return(
                    flexmock(id=2,
                             projectname="the-project-name",
                             ownername="the-owner")).mock(),
        ))

    flexmock(Celery).should_receive("send_task").once()

    assert helper.run_copr_build()["success"]
예제 #18
0
def process_runs(runs):
    """
    Process `RunModel`s and construct a JSON that is returned from the endpoints
    that return merged chroots.

    Args:
        runs: Iterator over merged `RunModel`s.

    Returns:
        List of JSON objects where each represents pipelines run on single SRPM.
    """
    result = []

    for pipeline in runs:
        response_dict = {
            "merged_run_id": pipeline.merged_id,
            "srpm": None,
            "copr": [],
            "koji": [],
            "test_run": [],
        }

        srpm_build = SRPMBuildModel.get_by_id(pipeline.srpm_build_id)
        if srpm_build:
            response_dict["srpm"] = {
                "packit_id": srpm_build.id,
                "status": srpm_build.status,
            }
            response_dict["time_submitted"] = optional_timestamp(
                srpm_build.build_submitted_time)
            response_dict["trigger"] = get_project_info_from_build(srpm_build)

        for model_type, Model, packit_ids in (
            ("copr", CoprBuildModel, pipeline.copr_build_id),
            ("koji", KojiBuildModel, pipeline.koji_build_id),
            ("test_run", TFTTestRunModel, pipeline.test_run_id),
        ):
            for packit_id in set(
                    filter(None, map(lambda ids: ids[0], packit_ids))):
                row = Model.get_by_id(packit_id)
                if row.status == "waiting_for_srpm":
                    continue
                response_dict[model_type].append({
                    "packit_id": packit_id,
                    "target": row.target,
                    "status": row.status,
                })
                if "trigger" not in response_dict:
                    submitted_time = (row.submitted_time if isinstance(
                        row, TFTTestRunModel) else row.build_submitted_time)
                    response_dict["time_submitted"] = optional_timestamp(
                        submitted_time)
                    response_dict["trigger"] = get_project_info_from_build(row)

        result.append(response_dict)

    return result
예제 #19
0
def test_get_srpm_logs(client):
    srpm_build = SRPMBuildModel()
    srpm_build.id = 2
    srpm_build.logs = "asd\nqwe"

    flexmock(SRPMBuildModel).should_receive("get_by_id").and_return(srpm_build)

    url = f"/srpm-build/2/logs"
    logs_url = get_srpm_log_url(2)
    assert logs_url.endswith(url)

    resp = client.get(url)
    expected = ("<html><head>"
                "<title>SRPM Build id=2</title></head><body>"
                "SRPM creation logs:<br><br>"
                "<pre>asd\nqwe</pre>"
                "<br></body></html>")
    assert resp.data == expected.encode()
예제 #20
0
def test_copr_build_for_release(release_event):
    # status is set for each build-target (4x):
    #  - Building SRPM ...
    #  - Starting RPM build...
    branch_build_job = JobConfig(
        type=JobType.build,
        trigger=JobConfigTriggerType.release,
        metadata=JobMetadataConfig(
            targets=[
                "fedora-29-x86_64",
                "fedora-30-x86_64",
                "fedora-31-x86_64",
                "fedora-rawhide-x86_64",
            ],
            owner="nobody",
            dist_git_branches=["build-branch"],
        ),
    )
    trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.release, id=123)
    flexmock(AddReleaseDbTrigger).should_receive("db_trigger").and_return(trigger)
    flexmock(release_event.project).should_receive("get_sha_from_tag").and_return(
        "123456"
    )
    helper = build_helper(
        jobs=[branch_build_job],
        event=release_event,
        db_trigger=trigger,
    )
    flexmock(ReleaseEvent).should_receive("get_project").and_return(helper.project)
    flexmock(GitProject).should_receive("set_commit_status").and_return().times(8)
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True)
    )
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1)
    )

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive("create_copr_project_if_not_exists").and_return(
        None
    )
    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock()
            .should_receive("create_from_file")
            .and_return(
                flexmock(id=2, projectname="the-project-name", ownername="the-owner")
            )
            .mock(),
        )
    )

    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]
예제 #21
0
 def build(self):
     if not self._build:
         build_id = str(self.copr_event.build_id)
         if self.copr_event.chroot == COPR_SRPM_CHROOT:
             self._build = SRPMBuildModel.get_by_copr_build_id(build_id)
         else:
             self._build = CoprBuildModel.get_by_build_id(
                 build_id, self.copr_event.chroot)
     return self._build
예제 #22
0
def get_srpm_build_logs_by_id(id_):
    log_service_versions()
    srpm_build = SRPMBuildModel.get_by_id(id_)
    if srpm_build:
        response = ("<html><head>"
                    f"<title>SRPM Build id={id_}</title></head><body>"
                    "SRPM creation logs:<br><br>"
                    f"<pre>{srpm_build.logs}</pre>"
                    "<br></body></html>")
        return response
    return f"We can't find any info about SRPM build {id_}.\n"
예제 #23
0
def a_koji_build(pr_model):
    srpm_build = SRPMBuildModel.create("asd\nqwe\n")
    yield KojiBuildModel.get_or_create(
        build_id="123456",
        commit_sha="687abc76d67d",
        web_url="https://copr.something.somewhere/123456",
        target=TARGET,
        status="pending",
        srpm_build=srpm_build,
        trigger_model=pr_model,
    )
예제 #24
0
def test_koji_build_check_names(github_pr_event):
    trigger = flexmock(
        job_config_trigger_type=JobConfigTriggerType.pull_request, id=123
    )
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger)
    helper = build_helper(
        event=github_pr_event,
        metadata=JobMetadataConfig(targets=["bright-future"], scratch=True),
        db_trigger=trigger,
    )
    flexmock(koji_build).should_receive("get_all_koji_targets").and_return(
        ["dark-past", "bright-future"]
    ).once()

    koji_build_url = get_koji_build_info_url_from_flask(1)
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/production-build-bright-future",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building RPM ...",
        check_name="packit-stg/production-build-bright-future",
        url=koji_build_url,
    ).and_return()

    flexmock(GitProject).should_receive("get_pr").and_return(
        flexmock(source_project=flexmock())
    )
    flexmock(GitProject).should_receive("set_commit_status").and_return().never()
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(id=1, success=True)
    )
    flexmock(KojiBuildModel).should_receive("get_or_create").and_return(
        KojiBuildModel(id=1)
    )
    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # koji build
    flexmock(Upstream).should_receive("koji_build").and_return(
        "Uploading srpm: /python-ogr-0.11.1"
        ".dev21+gf2dec9b-1.20200407142424746041.21.gf2dec9b.fc31.src.rpm\n"
        "[====================================] 100% 00:00:11   1.67 MiB 148.10 KiB/sec\n"
        "Created task: 43429338\n"
        "Task info: https://koji.fedoraproject.org/koji/taskinfo?taskID=43429338\n"
    )

    flexmock(PackitAPI).should_receive("init_kerberos_ticket").once()

    assert helper.run_koji_build()["success"]
예제 #25
0
def test_koji_build_failed_kerberos(github_pr_event):
    trigger = flexmock(
        job_config_trigger_type=JobConfigTriggerType.pull_request, id=123
    )
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger)
    helper = build_helper(
        event=github_pr_event,
        metadata=JobMetadataConfig(targets=["bright-future"], scratch=True),
        db_trigger=trigger,
    )
    flexmock(koji_build).should_receive("get_all_koji_targets").and_return(
        ["dark-past", "bright-future"]
    ).never()

    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.pending,
        description="Building SRPM ...",
        check_name="packit-stg/production-build-bright-future",
        url="",
    ).and_return()
    flexmock(StatusReporter).should_receive("set_status").with_args(
        state=CommitStatus.error,
        description="Kerberos authentication error: the bad authentication error",
        check_name="packit-stg/production-build-bright-future",
        url=get_srpm_log_url_from_flask(1),
    ).and_return()

    flexmock(GitProject).should_receive("get_pr").and_return(
        flexmock(source_project=flexmock())
    )
    flexmock(GitProject).should_receive("set_commit_status").and_return().never()
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(id=1, success=True)
    )
    flexmock(KojiBuildModel).should_receive("get_or_create").and_return(
        KojiBuildModel(id=1)
    )
    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    flexmock(PackitAPI).should_receive("init_kerberos_ticket").and_raise(
        PackitCommandFailedError,
        "Command failed",
        stdout_output="",
        stderr_output="the bad authentication error",
    )

    response = helper.run_koji_build()
    assert not response["success"]
    assert (
        "Kerberos authentication error: the bad authentication error"
        == response["details"]["msg"]
    )
예제 #26
0
def test_copr_build_for_branch(branch_push_event):
    # status is set for each build-target (4x):
    #  - Building SRPM ...
    #  - Starting RPM build...
    branch_build_job = JobConfig(
        type=JobType.build,
        trigger=JobConfigTriggerType.commit,
        metadata=JobMetadataConfig(
            targets=DEFAULT_TARGETS,
            owner="nobody",
            dist_git_branches=["build-branch"],
        ),
    )
    trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.commit,
                       id=123)
    flexmock(AddBranchPushDbTrigger).should_receive("db_trigger").and_return(
        trigger)
    helper = build_helper(
        jobs=[branch_build_job],
        event=branch_push_event,
        db_trigger=trigger,
    )
    flexmock(GitProject).should_receive(
        "set_commit_status").and_return().times(8)
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True))
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1))
    flexmock(PushGitHubEvent).should_receive("db_trigger").and_return(
        flexmock())

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive(
        "create_copr_project_if_not_exists").and_return(None)
    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock().should_receive(
                "create_from_file").and_return(
                    flexmock(id=2,
                             projectname="the-project-name",
                             ownername="the-owner")).mock(),
            mock_chroot_proxy=flexmock().should_receive("get_list").and_return(
                {target: ""
                 for target in DEFAULT_TARGETS}).mock(),
        ))
    flexmock(Pushgateway).should_receive("push_copr_build_created")

    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]
예제 #27
0
def a_copr_build_for_release(release_model):
    srpm_build = SRPMBuildModel.create("asd\nqwe\n")
    yield CoprBuildModel.get_or_create(
        build_id="123456",
        commit_sha="687abc76d67d",
        project_name="SomeUser-hello-world-9",
        owner="packit",
        web_url="https://copr.something.somewhere/123456",
        target=TARGET,
        status="pending",
        srpm_build=srpm_build,
        trigger_model=release_model,
    )
예제 #28
0
def discard_old_srpm_build_logs():
    """Called periodically (see celery_config.py) to discard logs of old SRPM builds."""
    logger.info("About to discard old SRPM build logs & artifact urls.")
    outdated_after_days = getenv("SRPMBUILDS_OUTDATED_AFTER_DAYS",
                                 SRPMBUILDS_OUTDATED_AFTER_DAYS)
    ago = timedelta(days=int(outdated_after_days))
    for build in SRPMBuildModel.get_older_than(ago):
        age = datetime.utcnow() - build.build_submitted_time
        logger.debug(
            f"SRPM build {build.id}, age '{age}' is older than '{ago}'. "
            "Discarding log and artifact url.")
        build.set_logs(None)
        build.set_url(None)
예제 #29
0
def test_copr_build_success_set_test_check(github_pr_event):
    # status is set for each test-target (2x):
    #  - Building SRPM ...
    #  - Starting RPM build...
    test_job = JobConfig(
        type=JobType.tests,
        trigger=JobConfigTriggerType.pull_request,
        metadata=JobMetadataConfig(
            owner="nobody",
            targets=["bright-future-x86_64", "brightest-future-x86_64"]),
    )
    trigger = flexmock(
        job_config_trigger_type=JobConfigTriggerType.pull_request, id=123)
    flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(
        trigger)
    helper = build_helper(
        jobs=[test_job],
        event=github_pr_event,
        db_trigger=trigger,
    )
    flexmock(GitProject).should_receive(
        "set_commit_status").and_return().times(4)
    flexmock(GitProject).should_receive("get_pr").and_return(flexmock())
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True))
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1))

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive(
        "create_copr_project_if_not_exists").and_return(None)
    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock().should_receive(
                "create_from_file").and_return(
                    flexmock(id=2,
                             projectname="the-project-name",
                             ownername="the-owner")).mock(),
            mock_chroot_proxy=flexmock().should_receive("get_list").and_return(
                {
                    "bright-future-x86_64": "",
                    "brightest-future-x86_64": ""
                }).mock(),
        ))
    flexmock(Pushgateway).should_receive("push_copr_build_created")

    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]
예제 #30
0
    def run_copr_build(self) -> HandlerResults:

        if not (self.job_build or self.job_tests):
            msg = "No copr_build or tests job defined."
            # we can't report it to end-user at this stage
            return HandlerResults(success=False, details={"msg": msg})

        self.report_status_to_all(description="Building SRPM ...",
                                  state=CommitStatus.pending)

        build_metadata = self._run_copr_build_and_save_output()

        srpm_build_model = SRPMBuildModel.create(build_metadata.srpm_logs)

        if build_metadata.srpm_failed:
            msg = "SRPM build failed, check the logs for details."
            self.report_status_to_all(
                state=CommitStatus.failure,
                description=msg,
                url=get_srpm_log_url(srpm_build_model.id),
            )
            return HandlerResults(success=False, details={"msg": msg})

        for chroot in self.build_chroots:
            copr_build = CoprBuildModel.get_or_create(
                build_id=str(build_metadata.copr_build_id),
                commit_sha=self.event.commit_sha,
                project_name=self.job_project,
                owner=self.job_owner,
                web_url=build_metadata.copr_web_url,
                target=chroot,
                status="pending",
                srpm_build=srpm_build_model,
                trigger_model=self.event.db_trigger,
            )
            url = get_log_url(id_=copr_build.id)
            self.report_status_to_all_for_chroot(
                state=CommitStatus.pending,
                description="Building RPM ...",
                url=url,
                chroot=chroot,
            )

        # release the hounds!
        celery_app.send_task(
            "task.babysit_copr_build",
            args=(build_metadata.copr_build_id, ),
            countdown=120,  # do the first check in 120s
        )

        return HandlerResults(success=True, details={})