Better handling of gbs export crashes
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 29 Apr 2014 14:58:56 +0000 (17:58 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 29 Apr 2014 15:53:54 +0000 (18:53 +0300)
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 <markus.lehtonen@linux.intel.com>
obs_service_gbs/command.py
packaging/obs-service-gbs.spec
tests/test_obs_service_gbs.py

index 3bebeec..037b466 100644 (file)
@@ -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])
index 589b634..33389a8 100644 (file)
@@ -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
index b61de16..1958f21 100644 (file)
@@ -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')