Esempio n. 1
0
    def test_build_download_error_60(self, mock_temp_dir, mock_koji,
                                     mock_check_output, tmpdir):
        """
        Assert that build fails when spectool throws error 60.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            b"Downloading Lectitio_Divinitatus",
            CalledProcessError(60, None),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(DownloadException) as exc:
            self.builder.build(package, opts)

        assert exc.value.message == (
            "Unable to validate the TLS certificate for one of the package's "
            "Source URLs")
Esempio n. 2
0
    def test_validate_response_not_ok(self):
        """
        Assert that validation raises HTTPException when response code is not 200.
        """
        # Mock requests_session
        response = mock.Mock()
        response.status_code = 500
        self.validator.requests_session.get.return_value = response

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        with pytest.raises(HTTPException) as ex:
            self.validator.validate(package)

        assert ex.value.error_code == 500
        assert (ex.value.message ==
                "Error encountered on request {}/_dg/anitya/rpms/{}".format(
                    self.validator.url, package.name))

        # Parameters for requests get call
        timeout = (5, 20)

        self.validator.requests_session.get.assert_called_with(
            self.validator.url + "/_dg/anitya/rpms/{}".format(package.name),
            timeout=timeout,
        )
Esempio n. 3
0
    def test_validate_retired(self):
        """
        Assert that PDC returns correct output when package is retired.
        """
        # Mock requests_session
        response = mock.Mock()
        response.status_code = 200
        response.json.return_value = {
            "count": 0,
        }
        self.validator.requests_session.get.return_value = response

        # Prepare package
        package = Package(name="test", version="1.1", distro="Fedora")

        result = self.validator.validate(package)

        # Parameters for requests get call
        timeout = (5, 20)
        params = (
            ("name", self.validator.branch),
            ("global_component", package.name),
            ("type", self.validator.package_type),
            ("active", True),
        )

        self.validator.requests_session.get.assert_called_with(
            self.validator.url + "/rest_api/v1/component-branches/",
            params=params,
            timeout=timeout,
        )

        assert result["retired"] is True
        assert result["active_branches"] == 0
Esempio n. 4
0
    def test_build_rpmdev_bumpspec_error(self, mock_temp_dir,
                                         mock_check_output, tmpdir):
        """
        Assert that build fails with BuilderException when rpmdev-bumpspec raises error.
        """
        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            CalledProcessError(1,
                               "rpmdev-bumpspec",
                               output=b"Some output",
                               stderr=b"Failed miserably"),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(BuilderException) as exc:
            self.builder.build(package, opts)

        assert (exc.value.message ==
                "Command 'rpmdev-bumpspec' returned non-zero exit status 1.")
        assert exc.value.value == {}
        assert exc.value.std_out == "Some output"
        assert exc.value.std_err == "Failed miserably"
Esempio n. 5
0
    def test_build_download_error_1(self, mock_temp_dir, mock_koji,
                                    mock_check_output, tmpdir):
        """
        Assert that build fails when spectool throws error 1.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            b"Downloading Lectitio_Divinitatus",
            CalledProcessError(1, None),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(DownloadException) as exc:
            self.builder.build(package, opts)

        assert exc.value.message == (
            "The specfile contains a Source URL with an unknown protocol; it should"
            'be "https", "http", or "ftp".')
Esempio n. 6
0
    def test_validate_no_monitoring(self):
        """
        Assert that validation returns correct output when monitoring is not set.
        """
        # Mock requests_session
        response = mock.Mock()
        response.status_code = 200
        response.json.return_value = {
            "monitoring": "no-monitoring",
        }
        self.validator.requests_session.get.return_value = response

        # Prepare package
        package = Package(name="test", version="1.1", distro="Fedora")

        result = self.validator.validate(package)

        # Parameters for requests get call
        timeout = (5, 20)

        self.validator.requests_session.get.assert_called_with(
            self.validator.url + "/_dg/anitya/rpms/{}".format(package.name),
            timeout=timeout,
        )

        assert result["monitoring"] is False
        assert result["all_versions"] is False
        assert result["stable_only"] is False
        assert result["scratch_build"] is False
Esempio n. 7
0
    def test_validate_old(self):
        """
        Assert that validation returns correct output when the version is older.
        """
        url = "http://testing.url"
        timeout = (5, 20)

        # Mock requests_session
        requests_session = mock.Mock()

        response = mock.Mock()
        response.status_code = 200
        response.json.return_value = {"version": "1.1", "release": "1.fc34"}
        requests_session.get.return_value = response

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        validator = MDApi(url, requests_session, timeout)

        result = validator.validate(package)

        requests_session.get.assert_called_with(
            url + "/koji/srcpkg/test", timeout=timeout
        )

        assert result["newer"] is False
        assert result["version"] == "1.1"
        assert result["release"] == "1.fc34"
Esempio n. 8
0
    def test_build_session_missing(self, mock_temp_dir, mock_koji,
                                   mock_check_output, tmpdir):
        """
        Assert that build fails when we can't obtain a koji session.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_session = mock.Mock()
        mock_session.krb_login.return_value = None
        mock_koji.ClientSession.return_value = mock_session
        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            b"Downloading Lectitio_Divinitatus",
            b"Downloaded: Lectitio_Divinitatus",
            b"rpmbuild foobar.srpm",
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(BuilderException) as exc:
            self.builder.build(package, opts)

        assert exc.value.message == ("Can't authenticate with Koji!")
Esempio n. 9
0
    def test_validate_response_not_ok(self):
        """
        Assert that validation raises HTTPException when response code is not 200.
        """
        url = "http://testing.url"
        timeout = (5, 20)

        # Mock requests_session
        requests_session = mock.Mock()

        response = mock.Mock()
        response.status_code = 500

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        validator = MDApi(url, requests_session, timeout)
        validator.requests_session.get.return_value = response

        with pytest.raises(HTTPException) as ex:
            validator.validate(package)

        assert ex.value.error_code == 500
        assert (
            ex.value.message
            == "Error encountered on request {}/koji/srcpkg/test".format(url)
        )

        requests_session.get.assert_called_with(
            url + "/koji/srcpkg/test", timeout=timeout
        )
Esempio n. 10
0
    def test_build_download_unexpected_error(self, mock_temp_dir, mock_koji,
                                             mock_check_output, tmpdir):
        """
        Assert that build fails when spectool throws unexpected error.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            b"Downloading Lectitio_Divinitatus",
            CalledProcessError(100, "spectool -g", output=b"Some output"),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(DownloadException) as exc:
            self.builder.build(package, opts)

        assert exc.value.message == (
            "An unexpected error occurred while downloading the new package sources; "
            "please report this as a bug on the-new-hotness issue tracker.\n"
            "Error output:\n"
            "None")
Esempio n. 11
0
    def test_build_identical_new_sources(self, mock_temp_dir, mock_koji,
                                         mock_check_output, tmpdir):
        """
        Assert that correct output is returned when sources from current package
        and new build are identical.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        # Mock patch file
        file = os.path.join(tmpdir, "patch")
        with open(file, "w") as f:
            f.write("This is a patch")
        mock_session = mock.Mock()
        mock_session.build.return_value = 1000
        mock_session.krb_login.return_value = True
        mock_koji.ClientSession.return_value = mock_session
        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            (b"Fake line\n"
             b"Downloading Lectitio_Divinitatus\n"),
            b"Downloaded: Lectitio_Divinitatus\nDownloaded: Lectitio_Divinitatus\n",
            b"rpmbuild foobar.srpm",
            "git config",
            "git config",
            "git commit",
            file.encode(),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        output = self.builder.build(package, opts)

        assert output == {
            "build_id":
            1000,
            "patch":
            "This is a patch",
            "patch_filename":
            file,
            "message":
            ("One or more of the new sources for this package are identical to "
             "the old sources. This is most likely caused either by identical source files "
             "between releases, for example service files, or the specfile does not use "
             "version macro in its source URLs. If this is the second case, then please "
             "update the specfile to use version macro in its source URLs.\n"
             "Here is the list of the files with SHA512 checksums:\n"
             "Old: ['Lectitio_Divinitatus'] -> New: ['Lectitio_Divinitatus', "
             "'Lectitio_Divinitatus'] (96140cc21155a13c9bfa03377410ac63e3"
             "f7e6aef22cc3bf09c4efbfad1c7ced45e150e391c23271dfe49df71c60f"
             "1547fbe70ed47d5bc515ff00271309939f7)\n"),
        }
    def test_submit_patch_missing_opts(self, opts):
        """
        Assert that PatcherException is raised when the opts are missing.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        patch = "Fix everything"

        with pytest.raises(PatcherException) as exc:
            self.patcher.submit_patch(package, patch, opts)

        assert exc.value.message == (
            "Additional parameters are missing! "
            "Please provide `bz_id` and `patch_filename`.")
    def test_notify(self):
        """
        Assert that message is sent correctly.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "update.drop"
        body = {"trigger": {"msg": {}, "topic": "topic"}, "reason": "Heresy"}

        opts = {"body": body}

        with mock_sends(UpdateDrop):
            output = self.notifier.notify(package, topic, opts)

            assert list(output.keys()) == ["msg_id"]
    def test_notify_missing_opts(self):
        """
        Assert that NotifierException is raised when opts are missing.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "update.drop"

        with pytest.raises(NotifierException) as exc:
            self.notifier.notify(package, topic, {})

        assert exc.value.message == (
            "Additional parameters are missing! "
            "Please provide `body` for the message."
        )
    def test_notify_connection_exception(self, mock_fm_publish):
        """
        Assert that NotifierException is raised when connection error occurs.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "update.drop"
        body = {"trigger": {"msg": "msg", "topic": "topic"}, "reason": "Heresy"}

        mock_fm_publish.side_effect = ConnectionException()

        opts = {"body": body}

        with pytest.raises(NotifierException) as exc:
            self.notifier.notify(package, topic, opts)

        assert exc.value.message.startswith("Error sending the message")
Esempio n. 16
0
    def test_build_git_commit_error(self, mock_temp_dir, mock_koji,
                                    mock_check_output, tmpdir):
        """
        Assert that build fails with BuilderException when git commit raises error.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_session = mock.Mock()
        mock_session.build.return_value = 1000
        mock_session.krb_login.return_value = True
        mock_koji.ClientSession.return_value = mock_session
        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            (b"Fake line\n"
             b"Downloading Lectitio_Divinitatus\n"),
            b"Downloaded: Lectitio_Divinitatus\n",
            b"rpmbuild foobar.srpm",
            "git config",
            "git config",
            CalledProcessError(1,
                               "git commit",
                               output=b"Some output",
                               stderr=b"Failed miserably"),
            file.encode(),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(BuilderException) as exc:
            self.builder.build(package, opts)

        assert (exc.value.message ==
                "Command 'git commit' returned non-zero exit status 1.")
        assert exc.value.value["build_id"] == 1000
        assert exc.value.std_out == "Some output"
        assert exc.value.std_err == "Failed miserably"
    def test_notify_unknown_topic(self, mock_fm_get_class):
        """
        Assert that NotifierException is raised when topic is not found.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "foobar"

        body = {"trigger": {"msg": "msg", "topic": "topic"}, "reason": "Heresy"}

        mock_fm_get_class.return_value = ""

        opts = {"body": body}

        with pytest.raises(NotifierException) as exc:
            self.notifier.notify(package, topic, opts)

        assert exc.value.message == ("Unknown topic provided 'hotness.foobar'")
    def test_submit_patch(self, mock_temp_dir, tmpdir):
        """
        Assert that submit_patch works correctly.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        patch = "Fix everything"

        opts = {"bz_id": 100, "patch_filename": "patch"}

        mock_temp_dir.return_value.__enter__.return_value = tmpdir
        filepath = os.path.join(tmpdir, "patch")

        output = self.patcher.submit_patch(package, patch, opts)

        self.patcher.bugzilla.attachfile.assert_called_with(
            100, filepath, "Update to 1.0 (#100)", is_patch=True)

        assert output == {
            "bz_id": 100,
        }
Esempio n. 19
0
    def test_validate_response_not_ok(self):
        """
        Assert that validation raises HTTPException when response code is not 200.
        """
        # Mock requests_session
        response = mock.Mock()
        response.status_code = 500
        self.validator.requests_session.get.return_value = response

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        with pytest.raises(HTTPException) as ex:
            self.validator.validate(package)

        assert ex.value.error_code == 500
        assert (
            ex.value.message
            == "Error encountered on request {}/rest_api/v1/component-branches/".format(
                self.validator.url
            )
        )

        # Parameters for requests get call
        timeout = (5, 20)
        params = (
            ("name", self.validator.branch),
            ("global_component", package.name),
            ("type", self.validator.package_type),
            ("active", True),
        )

        self.validator.requests_session.get.assert_called_with(
            self.validator.url + "/rest_api/v1/component-branches/",
            params=params,
            timeout=timeout,
        )
Esempio n. 20
0
    def test_build_rpmbuild_error(self, mock_temp_dir, mock_check_output,
                                  tmpdir):
        """
        Assert that build fails with BuilderException when rpmbuild raises error.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")

        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            (b"Fake line\n"
             b"Downloading Lectitio_Divinitatus\n"),
            b"Downloaded: Lectitio_Divinitatus\n",
            CalledProcessError(1,
                               "rpmdevbuild",
                               output=b"Some output",
                               stderr=b"Failed miserably"),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        with pytest.raises(BuilderException) as exc:
            self.builder.build(package, opts)

        assert (exc.value.message ==
                "Command 'rpmdevbuild' returned non-zero exit status 1.")
        assert exc.value.value["message"] != ""
        assert exc.value.std_out == "Some output"
        assert exc.value.std_err == "Failed miserably"
Esempio n. 21
0
    def test_build(self, mock_temp_dir, mock_koji, mock_check_output, tmpdir):
        """
        Assert that correct output is returned when build starts without issue.
        """
        # Create temporary file
        file = os.path.join(tmpdir, "Lectitio_Divinitatus")
        with open(file, "w") as f:
            f.write("The Emperor is God")
        file = os.path.join(tmpdir, "Codex_Astartes")
        with open(file, "w") as f:
            f.write("Adeptus Astartes")

        # Mock patch file
        filename = "patch"
        file = os.path.join(tmpdir, filename)
        with open(file, "w") as f:
            f.write("This is a patch")
        mock_session = mock.Mock()
        mock_session.build.return_value = 1000
        mock_session.krb_login.return_value = True
        mock_koji.ClientSession.return_value = mock_session
        mock_temp_dir.return_value.__enter__.return_value = tmpdir

        mock_check_output.side_effect = [
            "git clone",
            "rpmdev-bumpspec",
            b"Downloading Lectitio_Divinitatus",
            b"Downloaded: Codex_Astartes",
            b"rpmbuild foobar.srpm",
            "git config",
            "git config",
            "git commit",
            filename.encode(),
        ]

        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")
        opts = {"bz_id": 100}

        output = self.builder.build(package, opts)

        assert output == {
            "build_id": 1000,
            "patch": "This is a patch",
            "patch_filename": filename,
            "message": "",
        }

        mock_temp_dir.assert_called_with(prefix="thn-", dir="/var/tmp")
        mock_koji.ClientSession.assert_called_with(
            self.builder.server_url, self.builder.krb_sessionopts)
        mock_session.krb_login.assert_called_with(
            principal=self.builder.krb_principal,
            keytab=self.builder.krb_keytab,
            ccache=self.builder.krb_ccache,
            proxyuser=self.builder.krb_proxyuser,
        )
        mock_session.uploadWrapper.assert_called_once()
        mock_session.build.assert_called_once()

        mock_check_output.assert_has_calls([
            mock.call(["git", "clone", self.builder.git_url, tmpdir],
                      stderr=mock.ANY),
            mock.call(
                [
                    "/usr/bin/rpmdev-bumpspec",
                    "--new",
                    "1.0",
                    "-c",
                    "Update to 1.0 (#100)",
                    "-u",
                    self.builder.user_email[0] + " " +
                    self.builder.user_email[1],
                    tmpdir + "/test.spec",
                ],
                stderr=mock.ANY,
            ),
            mock.call(["fedpkg", "--user", "hotness", "sources"], cwd=tmpdir),
            mock.call(
                [
                    "spectool",
                    "-g",
                    str(tmpdir + "/test.spec"),
                ],
                cwd=tmpdir,
            ),
            mock.call(
                [
                    "rpmbuild",
                    "-D",
                    "_sourcedir .",
                    "-D",
                    "_topdir .",
                    "-bs",
                    tmpdir + "/test.spec",
                ],
                cwd=tmpdir,
                stderr=mock.ANY,
            ),
            mock.call(
                ["git", "config", "user.name", self.builder.user_email[0]],
                cwd=tmpdir,
                stderr=mock.ANY,
            ),
            mock.call(
                ["git", "config", "user.email", self.builder.user_email[1]],
                cwd=tmpdir,
                stderr=mock.ANY,
            ),
            mock.call(
                ["git", "commit", "-a", "-m", "Update to 1.0 (#100)"],
                cwd=tmpdir,
                stderr=mock.ANY,
            ),
            mock.call(["git", "format-patch", "HEAD^"],
                      cwd=tmpdir,
                      stderr=mock.ANY),
        ])