From 71d156c87b2b702804a8feddf406d2b60dd864e2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 29 Apr 2014 17:58:56 +0300 Subject: [PATCH] Better handling of gbs export crashes The fork_call function from obs_service_gbp_utils now raises and GbpChildBTError exception if the child function crashes with an unhandled exception. Catch this and print a traceback. Change-Id: Id406e16d326d5c4ca4d7e7359f98092e33f4a6ec Signed-off-by: Markus Lehtonen --- obs_service_gbs/command.py | 18 ++++++++++-------- packaging/obs-service-gbs.spec | 1 + tests/test_obs_service_gbs.py | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/obs_service_gbs/command.py b/obs_service_gbs/command.py index 3bebeec..037b466 100644 --- a/obs_service_gbs/command.py +++ b/obs_service_gbs/command.py @@ -22,7 +22,6 @@ import argparse import os import shutil import tempfile -import traceback from ConfigParser import SafeConfigParser from gitbuildsys.cmd_export import main as cmd_export @@ -32,8 +31,8 @@ import gbp.log as gbplog import gbp_repocache from gbp_repocache import CachedRepo, CachedRepoError -from obs_service_gbp_utils import GbpServiceError, fork_call, sanitize_uid_gid -from obs_service_gbp_utils import write_treeish_meta +from obs_service_gbp_utils import GbpServiceError, GbpChildBTError, fork_call +from obs_service_gbp_utils import sanitize_uid_gid, write_treeish_meta # Setup logging @@ -116,11 +115,14 @@ def gbs_export(repo, args, config): '%s', err) LOGGER.error('Most likely a configuration error (or a BUG)!') raise ServiceError('Failed to run GBS thread: %s' % err, 1) - except CmdError as err: - raise ServiceError('GBS export failed: %s' % err, 2) - except Exception as err: - LOGGER.debug(traceback.format_exc()) - raise ServiceError('Uncaught exception in GBS, export failed', 2) + except GbpChildBTError as err: + # CmdError and its sublasses are exptected errors + if issubclass(err.typ, CmdError): + raise ServiceError('GBS export failed: %s' % err.val, 2) + else: + LOGGER.error('Uncaught exception in GBS:\n' + '%s', err.prettyprint_tb()) + raise ServiceError('GBS crashed, export failed', 2) # Move packaging files from tmpdir to actual outdir exportdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) diff --git a/packaging/obs-service-gbs.spec b/packaging/obs-service-gbs.spec index 589b634..33389a8 100644 --- a/packaging/obs-service-gbs.spec +++ b/packaging/obs-service-gbs.spec @@ -21,6 +21,7 @@ BuildRequires: python BuildRequires: python-setuptools %if 0%{?do_unittests} BuildRequires: python-coverage +BuildRequires: python-mock BuildRequires: python-nose BuildRequires: gbs-export BuildRequires: git-buildpackage-common diff --git a/tests/test_obs_service_gbs.py b/tests/test_obs_service_gbs.py index b61de16..1958f21 100644 --- a/tests/test_obs_service_gbs.py +++ b/tests/test_obs_service_gbs.py @@ -19,6 +19,7 @@ """Tests for the GBS source service""" import grp +import mock import json import os import shutil @@ -35,6 +36,15 @@ from obs_service_gbs.command import main as export_service TEST_DATA_DIR = os.path.abspath(os.path.join('tests', 'data')) +class MockGbsError(Exception): + """Mock gbs crashes""" + pass + +def _mock_export(): + """Mock export main function for testing crashes""" + raise MockGbsError() + + def service(argv=None): """Wrapper for service""" # Set non-existent config file so that user/system settings don't affect @@ -153,6 +163,11 @@ class TestGbsService(UnitTestsBase): eq_(service(['--url', self.orig_repo.path, '--revision', 'v0.1~1']), 2) eq_(os.listdir('.'), []) + @mock.patch('obs_service_gbs.command.cmd_export', _mock_export) + def test_gbs_crash(self): + """Test crash of gbs export""" + eq_(service(['--url', self.orig_repo.path, '--revision', 'master']), 2) + def test_options_outdir(self): """Test the --outdir option""" outdir = os.path.join(self.tmpdir, 'outdir') -- 2.7.4