From 376ca596c5a0805f4a9187e19db2b1f22f53b9f1 Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Sun, 27 Aug 2017 18:47:05 +0200 Subject: [PATCH] Add some unit tests for Copr --- tests/test_copr.py | 219 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) diff --git a/tests/test_copr.py b/tests/test_copr.py index 0ca821a6..953e9881 100644 --- a/tests/test_copr.py +++ b/tests/test_copr.py @@ -21,9 +21,15 @@ # Written by Jakub Kadlcik +import os import unittest import mock +import module_build_service.models import module_build_service.builder +from munch import Munch +from tests import conf, init_data +from module_build_service.builder.CoprModuleBuilder import CoprModuleBuilder +from copr.exceptions import CoprRequestException @unittest.skip("We need not yet released version of python-copr. Let's skip this for some time") @@ -63,3 +69,216 @@ class ResponseMock(object): @property def data(self): return self._data + + +class FakeCoprAPI(object): + @staticmethod + def get_project_details(): + return ResponseMock({ + "output": "ok", + "name": "someproject", + # ... + }) + + @staticmethod + def get_chroot(): + return ResponseMock({ + "output": "ok", + "chroot": { + "repos": "http://repo1.ex/ http://repo2.ex/", + "buildroot_pkgs": "pkg1 pkg2 pkg3" + } + }) + + +class TestCoprModuleBuilder(unittest.TestCase): + + def setUp(self): + init_data() + self.config = mock.Mock() + self.config.koji_profile = conf.koji_profile + self.config.koji_repository_url = conf.koji_repository_url + self.module = module_build_service.models.ModuleBuild.query.filter_by(id=1).one() + + def create_builder(self): + conf.copr_config = "/tmp/module_build_service/conf/copr.conf" + builder = CoprModuleBuilder(owner=self.module.owner, + module=self.module, + config=conf, + tag_name='module-nginx-1.2', + components=[]) + builder.copr = Munch(projectname="someproject", username="myself") + return builder + + #################################################################################################################### + # # + # ModuleBuilder common operations # + # e.g. finalizing the module build process # + # # + #################################################################################################################### + + @mock.patch("copr.client.CoprClient.make_module") + def test_finalize(self, make_module): + builder = self.create_builder() + builder.finalize() + args, kwargs = make_module.call_args + make_module.assert_called_with(username="myself", projectname="someproject", + modulemd=mock.ANY, create=False, build=True) + self.assertIsInstance(kwargs["modulemd"], str) + self.assertTrue(os.path.isabs(kwargs["modulemd"])) + + #################################################################################################################### + # # + # ModuleBuilder operations for connecting to the buildroot # + # e.g. creating copr projects and modules in it # + # # + #################################################################################################################### + + @mock.patch("module_build_service.builder.CoprModuleBuilder._update_chroot") + @mock.patch("module_build_service.builder.CoprModuleBuilder._get_copr_safe") + @mock.patch("module_build_service.builder.CoprModuleBuilder._create_module_safe") + def test_buildroot_connect(self, create_module_safe, get_copr_safe, update_chroot): + builder = self.create_builder() + groups = {"build": {"pkgname1", "pkgname2", "pkgname3"}} + builder.buildroot_connect(groups) + update_chroot.assert_called_with(packages=["pkgname1", "pkgname3", "pkgname2"]) + self.assertEqual(builder._CoprModuleBuilder__prep, True) + + @mock.patch("module_build_service.builder.CoprModuleBuilder._get_copr") + @mock.patch("module_build_service.builder.CoprModuleBuilder._create_copr") + def test_get_copr_safe(self, create_copr, get_copr): + builder = self.create_builder() + + builder._get_copr_safe() + get_copr.assert_called_with(ownername=self.module.owner, projectname="module-nginx-1.2") + create_copr.assert_not_called() + + get_copr.reset_mock() + create_copr.reset_mock() + + get_copr.side_effect = [CoprRequestException(), mock.DEFAULT] + builder._get_copr_safe() + get_copr.assert_called_with(ownername=self.module.owner, projectname="module-nginx-1.2") + create_copr.assert_called_with(ownername=self.module.owner, projectname="module-nginx-1.2") + self.assertEqual(get_copr.call_count, 2) + + @mock.patch("copr.client.CoprClient._fetch", return_value=FakeCoprAPI.get_project_details()) + def test_get_copr(self, get_project_details): + builder = self.create_builder() + copr = builder._get_copr("myself", "someproject") + self.assertEqual(copr.username, "myself") + self.assertEqual(copr.projectname , "someproject") + + @mock.patch("copr.client.CoprClient.create_project") + def test_create_copr(self, create_project): + builder = self.create_builder() + builder._create_copr("myself", "someproject") + create_project.called_with("myself", "someproject", ["custom-1-x86_64"]) + + @mock.patch("copr.client.CoprClient.make_module") + def test_create_module_safe(self, make_module): + builder = self.create_builder() + builder._create_module_safe() + make_module.assert_called_with(username=self.module.owner, projectname="module-nginx-1.2", + modulemd=mock.ANY, create=True, build=False) + args, kwargs = make_module.call_args + self.assertIsInstance(kwargs["modulemd"], str) + self.assertTrue(os.path.isabs(kwargs["modulemd"])) + + def test_buildroot_ready(self): + builder = self.create_builder() + self.assertTrue(builder.buildroot_ready(artifacts=["a1", "a2", "a3"])) + + #################################################################################################################### + # # + # ModuleBuilder operations with buildroot # + # e.g. adding repositories and packages into the buildroot # + # # + #################################################################################################################### + + @mock.patch("copr.client.CoprClient.get_chroot", return_value=FakeCoprAPI.get_chroot()) + @mock.patch("copr.client.CoprClient.edit_chroot") + def test_buildroot_update_chroot(self, edit_chroot, get_chroot): + builder = self.create_builder() + + # @TODO Have deterministic and reasonable order of values + # Update buildroot packages + builder._update_chroot(packages=["pkg4", "pkg5"]) + edit_chroot.assert_called_with("someproject", "custom-1-x86_64", ownername="myself", + repos="http://repo2.ex/ http://repo1.ex/", + packages="pkg4 pkg5 pkg2 pkg3 pkg1") + + # Update buildroot repos + builder._update_chroot(repos=["http://repo3.ex/"]) + edit_chroot.assert_called_with("someproject", "custom-1-x86_64", ownername="myself", + repos="http://repo2.ex/ http://repo1.ex/ http://repo3.ex/", + packages="pkg2 pkg3 pkg1") + + # Update multiple buildroot options at the same time + builder._update_chroot(packages=["pkg4", "pkg5"], repos=["http://repo3.ex/"]) + edit_chroot.assert_called_with("someproject", "custom-1-x86_64", ownername="myself", + repos="http://repo2.ex/ http://repo1.ex/ http://repo3.ex/", + packages="pkg4 pkg5 pkg2 pkg3 pkg1") + + def test_buildroot_add_artifacts(self): + pass + + @mock.patch("module_build_service.builder.CoprModuleBuilder._update_chroot") + def test_buildroot_add_repos(self, update_chroot): + builder = self.create_builder() + builder.buildroot_add_repos(["foo", "bar", "baz"]) + update_chroot.assert_called_with(repos=[ + conf.koji_repository_url + "/foo/latest/x86_64", + conf.koji_repository_url + "/bar/latest/x86_64", + conf.koji_repository_url + "/baz/latest/x86_64", + + # We always add this repo as a workaround, see the code for details + "https://kojipkgs.fedoraproject.org/compose/latest-Fedora-Modular-Rawhide/compose/Server/x86_64/os/", + ]) + + #################################################################################################################### + # # + # ModuleBuilder package build operations # + # e.g. building a package from SCM or SRPM # + # # + #################################################################################################################### + + @mock.patch("module_build_service.builder.CoprModuleBuilder.build_srpm") + @mock.patch("module_build_service.builder.CoprModuleBuilder.build_scm") + def test_build(self, build_scm, build_srpm): + builder = self.create_builder() + builder._CoprModuleBuilder__prep = True + + def reset_mock(): + build_scm.reset_mock() + build_srpm.reset_mock() + + builder.build("pkgname", "git://repo.ex/pkgname.git") + build_scm.assert_called_with("git://repo.ex/pkgname.git") + build_srpm.assert_not_called() + reset_mock() + + builder.build("pkgname", "http://repo.ex/pkgname.git") + build_scm.assert_called_with("http://repo.ex/pkgname.git") + build_srpm.assert_not_called() + reset_mock() + + builder.build("pkgname", "https://repo.ex/pkgname.git") + build_scm.assert_called_with("https://repo.ex/pkgname.git") + build_srpm.assert_not_called() + reset_mock() + + builder.build("pkgname", "/path/to/pkgname.src.rpm") + build_scm.assert_not_called() + build_srpm.assert_called_with("pkgname", "/path/to/pkgname.src.rpm") + reset_mock() + + @mock.patch("copr.client.CoprClient.create_new_build") + def test_build_srpm(self, create_new_build): + builder = self.create_builder() + builder.build_srpm("pkgname", "git://repo.ex/pkgname.git") + create_new_build.assert_called_with("someproject", ["git://repo.ex/pkgname.git"], + chroots=["custom-1-x86_64"], username="myself") + + def test_build_scm(self): + pass