Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
commit a3c58d4e475b118f4bf5b2250a96261d153c10eb Author: Valentin Gologuzov vgologuz@redhat.com Date: Wed Nov 19 16:00:03 2014 +0100
[backend] unittest backend.mockremote.Mockremote
backend/backend/constants.py | 2 +- backend/backend/dispatcher.py | 16 +- backend/backend/helpers.py | 7 +- backend/backend/job.py | 2 + backend/backend/mockremote/__init__.py | 95 +++++---- backend/backend/mockremote/builder.py | 3 +- backend/backend/mockremote/callback.py | 2 +- backend/run/copr_mockremote.py | 8 +- backend/tests/mockremote/test_builder.py | 1 - backend/tests/mockremote/test_mockremote.py | 317 +++++++++++++++++++++++++++ 10 files changed, 391 insertions(+), 62 deletions(-)
diff --git a/backend/backend/constants.py b/backend/backend/constants.py index a20667a..dcb5330 100644 --- a/backend/backend/constants.py +++ b/backend/backend/constants.py @@ -8,7 +8,7 @@ DEF_REMOTE_BASEDIR = "/var/tmp" DEF_TIMEOUT = 3600 DEF_REPOS = [] DEF_CHROOT = None -DEF_USER = "mockbuilder" +DEF_BUILD_USER = "mockbuilder" DEF_DESTDIR = os.getcwd() DEF_MACROS = {} DEF_BUILDROOT_PKGS = "" diff --git a/backend/backend/dispatcher.py b/backend/backend/dispatcher.py index d653f23..1dc4614 100644 --- a/backend/backend/dispatcher.py +++ b/backend/backend/dispatcher.py @@ -571,16 +571,17 @@ class Worker(multiprocessing.Process): mr = MockRemote( builder_host=ip, job=job, - cont=True, - recurse=True, repos=chroot_repos, macros=macros, lock=self.lock, - do_sign=self.opts.do_sign, + callback=CliLogCallBack( quiet=True, logfn=chrootlogfile), - front_url=self.opts.frontend_base_url, - results_base_url=self.opts.results_baseurl + + opts=self.opts, + # do_sign=self.opts.do_sign, + # front_url=self.opts.frontend_base_url, + # results_base_url=self.opts.results_baseurl )
build_details = mr.build_pkgs() @@ -594,11 +595,6 @@ class Worker(multiprocessing.Process): # record and break self.callback.log("{0} - {1}".format(ip, e)) status = 0 # failure - # else: - # # we can"t really trace back if we just fail normally - # # check if any pkgs didn"t build - # if mr.failed: - # status = 0 # failure
self.callback.log( "Finished build: id={0} builder={1}" diff --git a/backend/backend/helpers.py b/backend/backend/helpers.py index c5b3958..116bb54 100644 --- a/backend/backend/helpers.py +++ b/backend/backend/helpers.py @@ -12,6 +12,8 @@ import sys import time
from bunch import Bunch +import datetime +from backend.constants import DEF_BUILD_USER from copr.client import CoprClient
from .exceptions import CoprBackendError @@ -103,6 +105,9 @@ class BackendConfigReader(object): opts.do_sign = _get_conf( cp, "backend", "do_sign", False, mode="bool")
+ opts.build_user = _get_conf( + cp, "backend", "build_user", DEF_BUILD_USER) + opts.build_groups_count = _get_conf( cp, "backend", "build_groups", 1, mode="int")
@@ -171,7 +176,7 @@ def get_auto_createrepo_status(front_url, username, projectname):
def log(lf, msg, quiet=None): if lf: - now = time.time() + now = datetime.datetime.utcnow().isoformat() try: with open(lf, "a") as lfh: fcntl.flock(lfh, fcntl.LOCK_EX) diff --git a/backend/backend/job.py b/backend/backend/job.py index b89349d..1f5b1b1 100644 --- a/backend/backend/job.py +++ b/backend/backend/job.py @@ -39,6 +39,8 @@ class BuildJob(object): self.status = None self.chroot = None
+ self.buildroot_pkgs = None + # TODO: validate update data for key, val in task_data.items(): key = str(key) diff --git a/backend/backend/mockremote/__init__.py b/backend/backend/mockremote/__init__.py index 5828a1f..bce9895 100755 --- a/backend/backend/mockremote/__init__.py +++ b/backend/backend/mockremote/__init__.py @@ -32,9 +32,10 @@ from __future__ import absolute_import import fcntl import urllib import os +from bunch import Bunch
from ..constants import DEF_REMOTE_BASEDIR, DEF_TIMEOUT, DEF_REPOS, \ - DEF_USER, DEF_MACROS + DEF_BUILD_USER, DEF_MACROS from ..exceptions import MockRemoteError
@@ -48,7 +49,7 @@ from .callback import DefaultCallBack
def get_target_dir(chroot_dir, pkg_name): source_basename = os.path.basename(pkg_name).replace(".src.rpm", "") - return os.path.join(chroot_dir, source_basename) + return os.path.normpath(os.path.join(chroot_dir, source_basename))
class MockRemote(object): @@ -56,16 +57,16 @@ class MockRemote(object): # mock remote now do too much things # idea: send events according to the build progress to handler
- def __init__(self, builder_host=None, user=DEF_USER, job=None, - cont=False, recurse=False, repos=None, callback=None, - remote_basedir=DEF_REMOTE_BASEDIR, remote_tempdir=None, - macros=None, lock=None, do_sign=False, - front_url=None, results_base_url=None): + def __init__(self, builder_host=None, job=None, + repos=None, + callback=None, + macros=None, + opts=None, + lock=None):
""" - :param builder_host: builder hostname or ip - :param user: user to run as/connect as on builder systems + :param backend.job.BuildJob job: Job object with the following attributes:: :ivar timeout: ssh timeout :ivar destdir: target directory to put built packages @@ -77,58 +78,67 @@ class MockRemote(object): :ivar pkg: pkg to build
- :param cont: if a pkg fails to build, continue to the next one - :param bool recurse: if more than one pkg and it fails to build, - try to build the rest and come back to it :param repos: additional repositories for mock :param backend.mockremote.callback.DefaultCallBack callback: object with hooks for notifications about build progress - :param remote_basedir: basedir on builder - :param remote_tempdir: tempdir on builder + :param macros: { "copr_username": ..., "copr_projectname": ..., "vendor": ...} :param multiprocessing.Lock lock: instance of Lock shared between Copr backend process - :param bool do_sign: enable package signing, require configured - signer host and correct /etc/sign.conf - - :param str front_url: url to the copr frontend - + :param DefaultCallback callback: build progress handler + + :param Bunch opts: builder options, used keys:: + :ivar build_user: user to run as/connect as on builder systems + :ivar do_sign: enable package signing, require configured + signer host and correct /etc/sign.conf + :ivar frontend_base_url: url to the copr frontend + :ivar results_base_url: base url for the built results + :ivar remote_basedir: basedir on builder + :ivar remote_tempdir: tempdir on builder + + # Removed: + # :param cont: if a pkg fails to build, continue to the next one-- + # :param bool recurse: if more than one pkg and it fails to build, + # try to build the rest and come back to it """ + self.opts = Bunch( + do_sign=False, + frontend_base_url=None, + results_base_url=u"", + build_user=DEF_BUILD_USER, + remote_basedir=DEF_REMOTE_BASEDIR, + remote_tempdir=None, + ) + if opts: + self.opts.update(opts)
self.max_retry_count = 2 # TODO: add config option - if repos is None: - repos = DEF_REPOS - if macros is None: - macros = DEF_MACROS
self.job = job - self.repos = repos + self.repos = repos or DEF_REPOS
# TODO: remove or re-implement # self.cont = cont # unused since we build only one pkg at time # self.recurse = recurse
self.callback = callback - self.remote_basedir = remote_basedir - self.remote_tempdir = remote_tempdir - self.macros = macros + self.macros = macros or DEF_MACROS self.lock = lock - self.do_sign = do_sign - self.front_url = front_url - self.results_base_url = results_base_url or u''
if not self.callback: self.callback = DefaultCallBack()
self.callback.log("Setting up builder: {0}".format(builder_host)) - self.builder = Builder(hostname=builder_host, username=user, chroot=self.job.chroot, + self.builder = Builder(hostname=builder_host, + username=self.opts.build_user, + chroot=self.job.chroot, timeout=self.job.timeout or DEF_TIMEOUT, buildroot_pkgs=self.job.buildroot_pkgs, callback=self.callback, - remote_basedir=self.remote_basedir, - remote_tempdir=self.remote_tempdir, + remote_basedir=self.opts.remote_basedir, + remote_tempdir=self.opts.remote_tempdir, macros=self.macros, repos=self.repos) self.builder.check()
@@ -138,8 +148,7 @@ class MockRemote(object): self.failed = [] self.finished = []
- #self.built_packages = [] - self.callback.log("self dict: {}".format(self.__dict__)) + # self.callback.log("self dict: {}".format(self.__dict__))
@property def chroot_dir(self): @@ -201,7 +210,7 @@ class MockRemote(object): get_target_dir(self.chroot_dir, self.pkg), callback=self.callback) except Exception as e: - self.callback.log( + self.callback.error( "failed to sign packages " "built from `{}` with error: \n" "{}".format(self.pkg, e) @@ -225,16 +234,16 @@ class MockRemote(object): r_log.close()
def do_createrepo(self): - base_url = "/".join([self.results_base_url, self.job.project_owner, + base_url = "/".join([self.opts.results_base_url, self.job.project_owner, self.job.project_name, self.job.chroot]) self.callback.log("Createrepo:: owner: {}; project: {}; " "front url: {}; path: {}; base_url: {}" .format(self.job.project_owner, self.job.project_name, - self.front_url, self.chroot_dir, base_url)) + self.opts.frontend_base_url, self.chroot_dir, base_url))
_, _, err = createrepo( path=self.chroot_dir, - front_url=self.front_url, + front_url=self.opts.frontend_base_url, base_url=base_url, username=self.job.project_owner, projectname=self.job.project_name, @@ -251,7 +260,7 @@ class MockRemote(object): def on_success_build(self): self.callback.log("Success building {0}".format(os.path.basename(self.pkg)))
- if self.do_sign: + if self.opts.do_sign: self.sign_built_packages()
# self.built_packages.append(self.pkg) @@ -271,6 +280,7 @@ class MockRemote(object):
def build_pkg_and_process_results(self): self.prepare_build_dir() + self.mark_dir_with_build_id()
# building self.callback.start_build(self.pkg) @@ -279,8 +289,8 @@ class MockRemote(object):
# downloading self.callback.start_download(self.pkg) - d_ret, d_out, d_err = self.builder.download(self.pkg, self.chroot_dir) - if not d_ret: + d_success, d_out, d_err = self.builder.download(self.pkg, self.chroot_dir) + if not d_success: raise MockRemoteError( "Failure to download {0}: {1}".format(self.pkg, d_out + d_err))
@@ -288,7 +298,6 @@ class MockRemote(object): self.log_to_file_safe(os.path.join(self.chroot_dir, "mockchain.log"), ["\n\n{0}\n\n".format(self.pkg), b_out], [b_err])
- self.mark_dir_with_build_id() if b_status: self.on_success_build() return build_details diff --git a/backend/backend/mockremote/builder.py b/backend/backend/mockremote/builder.py index 642a01b..228e75f 100644 --- a/backend/backend/mockremote/builder.py +++ b/backend/backend/mockremote/builder.py @@ -33,11 +33,12 @@ class Builder(object): self._remote_tempdir = remote_tempdir self._remote_basedir = remote_basedir # if we're at this point we've connected and done stuff on the host - # TODO: maybe do this lazy ? self.conn = _create_ans_conn( self.hostname, self.username, self.timeout) self.root_conn = _create_ans_conn(self.hostname, "root", self.timeout)
+ # self.callback.log("Created builder: {}".format(self.__dict__)) + # Before use: check out the host - make sure it can build/be contacted/etc # self.check()
diff --git a/backend/backend/mockremote/callback.py b/backend/backend/mockremote/callback.py index 1fdfc5f..0dfbfc9 100644 --- a/backend/backend/mockremote/callback.py +++ b/backend/backend/mockremote/callback.py @@ -30,7 +30,7 @@ class DefaultCallBack(object): class CliLogCallBack(DefaultCallBack):
def __init__(self, **kwargs): - DefaultCallBack.__init__(self, **kwargs) + super(CliLogCallBack, self).__init__(**kwargs)
def start_build(self, pkg): msg = "Start build: {0}".format(pkg) diff --git a/backend/run/copr_mockremote.py b/backend/run/copr_mockremote.py index ebbcda6..e4c4d1f 100644 --- a/backend/run/copr_mockremote.py +++ b/backend/run/copr_mockremote.py @@ -7,7 +7,7 @@ import sys import os
from backend.exceptions import MockRemoteError -from backend.mockremote import MockRemote, DEF_CHROOT, DEF_USER, DEF_REPOS, DEF_TIMEOUT, DEF_DESTDIR +from backend.mockremote import MockRemote, DEF_CHROOT, DEF_BUILD_USER, DEF_REPOS, DEF_TIMEOUT, DEF_DESTDIR from backend.helpers import SortedOptParser from backend.mockremote.callback import CliLogCallBack
@@ -45,7 +45,7 @@ def parse_args(args): " defaults to not logging") parser.add_option("-b", "--builder", dest="builder", default=None, help="builder to use") - parser.add_option("-u", dest="user", default=DEF_USER, + parser.add_option("-u", dest="user", default=DEF_BUILD_USER, help="user to run as/connect as on builder systems") parser.add_option("-t", "--timeout", dest="timeout", type="int", default=DEF_TIMEOUT, @@ -129,8 +129,8 @@ def main(args): job=job, builder_host=opts.builder, user=opts.user, - cont=opts.cont, - recurse=opts.recurse, + # cont=opts.cont, + # recurse=opts.recurse, repos=opts.repos, do_sign=opts.do_sign, callback=callback, diff --git a/backend/tests/mockremote/test_builder.py b/backend/tests/mockremote/test_builder.py index c4da674..519c022 100644 --- a/backend/tests/mockremote/test_builder.py +++ b/backend/tests/mockremote/test_builder.py @@ -34,7 +34,6 @@ def noop(*args, **kwargs): pass
- def print_all(*args, **kwargs): pprint(args) pprint(kwargs) diff --git a/backend/tests/mockremote/test_mockremote.py b/backend/tests/mockremote/test_mockremote.py index e69de29..b526d27 100644 --- a/backend/tests/mockremote/test_mockremote.py +++ b/backend/tests/mockremote/test_mockremote.py @@ -0,0 +1,317 @@ +# coding: utf-8 +import copy + +from collections import defaultdict +from pprint import pprint +from bunch import Bunch +from backend.exceptions import BuilderError, BuilderTimeOutError, MockRemoteError, CoprSignError + +import tempfile +import shutil +import os + +import six + +if six.PY3: + from unittest import mock + from unittest.mock import patch, MagicMock +else: + import mock + from mock import patch, MagicMock + +import pytest + +import backend.mockremote.builder as builder_module +from backend.mockremote.builder import Builder +from backend.mockremote import MockRemote, get_target_dir +from backend.mockremote.callback import DefaultCallBack +from backend.job import BuildJob + + +def test_get_target_dir(): + for ch_dir, pkg_name, expected in [ + ("/tmp/", "copr-backend-1.46-1.git.35.8ba18d1.fc20.src.rpm", + "/tmp/copr-backend-1.46-1.git.35.8ba18d1.fc20"), + ("/tmp/foo/../bar", "copr-backend-1.46-1.git.35.8ba18d1.fc20.src.rpm", + "/tmp/bar/copr-backend-1.46-1.git.35.8ba18d1.fc20"), + ]: + assert get_target_dir(ch_dir, pkg_name) == expected + +STDOUT = "stdout" +STDERR = "stderr" +COPR_OWNER = "copr_owner" +COPR_NAME = "copr_name" +COPR_VENDOR = "vendor" +# DESTDIR = "/dev/null" +# CHROOT = + +class CallbackTest(DefaultCallBack): + def __init__(self, log_dict, **kwargs): + """ + :param log_dict: defaultdict(list) + :return: + """ + super(CallbackTest, self).__init__(**kwargs) + self.log_dict = log_dict + + def __getattribute__(self, item): + if item in ["log", "error", "start_build", "end_build", + "start_download", "end_download"]: + def fn(msg): + self.log_dict[item].append(msg) + return fn + else: + return super(CallbackTest, self).__getattribute__(item) + + +class TestMockRemote(object): + + + + def get_callback(self): + self._cb_log = defaultdict(list) + return CallbackTest(log_dict=self._cb_log) + + @pytest.yield_fixture + def f_mock_remote(self): + self.mr_cb = self.get_callback() + patcher = mock.patch("backend.mockremote.Builder") + self.mc_builder = patcher.start() + + + + + self.mr = MockRemote(self.HOST, self.JOB, callback=self.mr_cb, + macros=self.MACROS, opts=self.OPTS) + + yield + patcher.stop() + + def setup_method(self, method): + self.test_root_path = tempfile.mkdtemp() + self.CHROOT = "fedora-20_i386" + self.DESTDIR = os.path.join(self.test_root_path, COPR_OWNER, COPR_NAME) + self.DESTDIR_CHROOT = os.path.join(self.DESTDIR, self.CHROOT) + self.FRONT_URL = "htt://front.example.com" + self.BASE_URL = "http://example.com/results" + + self.PKG_NAME = "foobar" + self.PKG_VERSION = "1.2.3" + + + self.HOST = "127.0.0.1" + self.SRC_PKG_URL = "http://example.com/%7B%7D-%7B%7D.src.rpm%22.format(self.PKG_NAME, self.PKG_VERSION) + self.JOB = BuildJob({ + "project_owner": COPR_OWNER, + "project_name": COPR_NAME, + "pkgs": self.SRC_PKG_URL, + "repos": "", + "build_id": 12345, + "chroot": self.CHROOT, + }, Bunch({ + "timeout": 1800, + "destdir": self.test_root_path, + "results_baseurl": "/tmp/", + })) + self.MACROS = { + "copr_username": COPR_OWNER, + "copr_projectname": COPR_NAME, + "vendor": COPR_VENDOR + } + self.OPTS = Bunch({ + "do_sign": False, + "results_base_url": self.BASE_URL, + "frontend_base_url": self.FRONT_URL, + }) + + def teardown_method(self, method): + shutil.rmtree(self.test_root_path) + + def test_dummy(self, f_mock_remote): + pass + + def test_default_callback(self, f_mock_remote, capsys): + mr_2 = MockRemote(self.HOST, self.JOB, macros=self.MACROS, opts=self.OPTS) + out, err = capsys.readouterr() + + assert isinstance(mr_2.callback, DefaultCallBack) + assert out + + def test_no_job_chroot(self, f_mock_remote, capsys): + job_2 = copy.deepcopy(self.JOB) + job_2.chroot = None + with pytest.raises(MockRemoteError): + mr_2 = MockRemote(self.HOST, job_2, macros=self.MACROS, opts=self.OPTS) + + out, err = capsys.readouterr() + + @mock.patch("backend.mockremote.get_pubkey") + def test_add_pubkey(self, mc_get_pubkey, f_mock_remote): + self.mr.add_pubkey() + assert mc_get_pubkey.called + expected_path = os.path.join(self.DESTDIR, self.CHROOT, "pubkey.gpg") + assert mc_get_pubkey.call_args == mock.call( + COPR_OWNER, COPR_NAME, expected_path) + + @mock.patch("backend.mockremote.get_pubkey") + def test_add_pubkey_on_exception(self, mc_get_pubkey, f_mock_remote): + mc_get_pubkey.side_effect = CoprSignError("foobar") + self.mr.add_pubkey() + assert self._cb_log["error"][-1] + assert "failed to retrieve" in self._cb_log["error"][-1] + + @mock.patch("backend.mockremote.sign_rpms_in_dir") + def test_sign_built_packages(self, mc_sign_rpms_in_dir, f_mock_remote): + self.mr.sign_built_packages() + assert mc_sign_rpms_in_dir.called + + @mock.patch("backend.mockremote.sign_rpms_in_dir") + def test_sign_built_packages_exception(self, mc_sign_rpms_in_dir, f_mock_remote): + mc_sign_rpms_in_dir.side_effect = IOError() + self.mr.sign_built_packages() + assert self._cb_log["error"][-1] + assert "failed to sign packages" in self._cb_log["error"][-1] + + @mock.patch("backend.mockremote.sign_rpms_in_dir") + def test_sign_built_packages_exception_reraise(self, mc_sign_rpms_in_dir, f_mock_remote): + mc_sign_rpms_in_dir.side_effect = MockRemoteError("foobar") + with pytest.raises(MockRemoteError): + self.mr.sign_built_packages() + + @mock.patch("backend.mockremote.createrepo") + def test_do_createrepo(self, mc_createrepo, f_mock_remote): + mc_createrepo.return_value = ("", "", "") + self.mr.do_createrepo() + assert mc_createrepo.called + expected_call = mock.call( + path=os.path.join(self.DESTDIR, self.CHROOT), + front_url=self.FRONT_URL, + base_url=u"/".join([self.BASE_URL, COPR_OWNER, COPR_NAME, self.CHROOT]), + username=COPR_OWNER, + projectname=COPR_NAME, + lock=None, + ) + assert mc_createrepo.call_args == expected_call + + @mock.patch("backend.mockremote.createrepo") + def test_do_createrepo_on_error(self, mc_createrepo, f_mock_remote): + err_msg = "error occured" + mc_createrepo.return_value = ("", "", err_msg) + self.mr.do_createrepo() + assert len(self._cb_log["error"]) > 0 + assert "Error making local repo" in self._cb_log["error"][0] + assert err_msg in self._cb_log["error"][1] + + def test_on_success_build(self, f_mock_remote): + self.mr.sign_built_packages = MagicMock() + self.mr.do_createrepo = MagicMock() + + self.mr.opts.do_sign = False + self.mr.on_success_build() + + assert not self.mr.sign_built_packages.called + assert self.mr.do_createrepo.called + + self.mr.do_createrepo.reset() + + self.mr.opts.do_sign = True + self.mr.on_success_build() + + assert self.mr.sign_built_packages.called + assert self.mr.do_createrepo.called + + def test_prepare_build_dir_erase_fail_file(self, f_mock_remote): + target_dir = os.path.join( + self.DESTDIR, self.CHROOT, + "{}-{}".format(self.PKG_NAME, self.PKG_VERSION)) + os.makedirs(target_dir) + fail_path = os.path.join(target_dir, "fail") + with open(fail_path, "w") as handle: + handle.write("1") + assert os.path.exists(fail_path) + + self.mr.prepare_build_dir() + + assert not os.path.exists(fail_path) + + def test_prepare_build_dir_creates_dirs(self, f_mock_remote): + self.mr.prepare_build_dir() + assert os.path.exists(self.DESTDIR_CHROOT) + + def test_build_pkg_and_process_results(self, f_mock_remote): + self.mr.on_success_build = MagicMock() + self.mr.mark_dir_with_build_id = MagicMock() + + build_details = MagicMock() + self.mr.builder.build.return_value = (True, STDOUT, STDERR, build_details) + self.mr.builder.download.return_value = (True, STDOUT, STDERR) + + result = self.mr.build_pkg_and_process_results() + + assert id(result) == id(build_details) + + assert self.mr.builder.build.called + assert self.mr.builder.build.call_args == mock.call(self.SRC_PKG_URL) + + assert self.mr.builder.download.called + assert self.mr.builder.download.call_args == \ + mock.call(self.SRC_PKG_URL, self.DESTDIR_CHROOT) + + assert self.mr.mark_dir_with_build_id.called + assert self.mr.on_success_build.called + + assert os.path.exists(os.path.join(self.DESTDIR_CHROOT, "mockchain.log")) + + def test_build_pkg_and_process_results_error_on_download(self, f_mock_remote): + self.mr.builder.build.return_value = (True, STDOUT, STDERR, {}) + self.mr.builder.download.return_value = (False, STDOUT, STDERR) + + self.mr.mark_dir_with_build_id = MagicMock() + self.mr.on_success_build = MagicMock() + with pytest.raises(MockRemoteError): + self.mr.build_pkg_and_process_results() + + assert not self.mr.on_success_build.called + assert self.mr.mark_dir_with_build_id.called + assert not os.path.exists(os.path.join(self.DESTDIR_CHROOT, "mockchain.log")) + + def test_build_pkg_and_process_results_error_on_build(self, f_mock_remote): + self.mr.builder.build.return_value = (False, STDOUT, STDERR, {}) + self.mr.builder.download.return_value = (True, STDOUT, STDERR) + + self.mr.mark_dir_with_build_id = MagicMock() + self.mr.on_success_build = MagicMock() + with pytest.raises(MockRemoteError): + self.mr.build_pkg_and_process_results() + + assert not self.mr.on_success_build.called + assert self.mr.mark_dir_with_build_id.called + + assert os.path.exists(os.path.join(self.DESTDIR_CHROOT, "mockchain.log")) + + def test_mark_dir_with_build_id(self, f_mock_remote): + # TODO: create real test + self.mr.mark_dir_with_build_id() + + def test_build_pkgs_ignore_error_once(self, f_mock_remote): + err_msg = "error message" + build_details = MagicMock() + + self.mr.build_pkg_and_process_results = MagicMock() + self.mr.build_pkg_and_process_results.side_effect = [ + MockRemoteError(err_msg), build_details] + + result = self.mr.build_pkgs() + assert result == build_details + assert err_msg in self._cb_log["error"][-1] + + def test_build_pkgs_exceed_retry(self, f_mock_remote): + err_msg = "error message" + + self.mr.build_pkg_and_process_results = MagicMock() + self.mr.build_pkg_and_process_results.side_effect = MockRemoteError(err_msg) + + with pytest.raises(MockRemoteError): + self.mr.build_pkgs() + +
copr-commits@lists.fedorahosted.org