Merge lp:~jr/bzr/274578-smart-server-hookable-error-logging into lp:bzr

Proposed by Jonathan Riddell
Status: Merged
Approved by: Jonathan Riddell
Approved revision: no longer in the source branch.
Merged at revision: 5927
Proposed branch: lp:~jr/bzr/274578-smart-server-hookable-error-logging
Merge into: lp:bzr
Diff against target: 94 lines (+35/-4)
3 files modified
bzrlib/smart/server.py (+12/-3)
bzrlib/tests/blackbox/test_serve.py (+19/-1)
doc/en/release-notes/bzr-2.4.txt (+4/-0)
To merge this branch: bzr merge lp:~jr/bzr/274578-smart-server-hookable-error-logging
Reviewer Review Type Date Requested Status
Vincent Ladeuil Needs Fixing
Review via email: mp+62135@code.launchpad.net

Commit message

New hook server_exception in bzrlib.smart.server to catch any exception caused while running bzr serve. (Jonathan Riddell, #274578)

Description of the change

Add "server_exception" hook for bug 61728. When an exception occurs it calls the hook with sys.exc_info(). If the hook returns false or there is no hook is raises the exception as normal.

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

Looks good, thanks !

One small nit:

70 + args = []
71 + out, err = self.run_bzr_serve_then_func(args, retcode=3)

This checks that the server dies when no hook is installed (before testing the hook itself).

It would be even better to do that in a separate test to get a better defect localization (see http://xunitpatterns.com/Goals%20of%20Test%20Automation.html).

You also need to add a news entry (make sure to remerge trunk so you get the right section in the release-notes file).

BB:tweak ;)

review: Needs Fixing
Revision history for this message
Jonathan Riddell (jr) wrote :

sent to pqm by email

Revision history for this message
Jonathan Riddell (jr) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/smart/server.py'
2--- bzrlib/smart/server.py 2011-03-30 11:45:54 +0000
3+++ bzrlib/smart/server.py 2011-05-27 13:15:43 +0000
4@@ -1,4 +1,4 @@
5-# Copyright (C) 2006-2010 Canonical Ltd
6+# Copyright (C) 2006-2011 Canonical Ltd
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10@@ -254,6 +254,11 @@
11 "Called by the bzr server when it stops serving a directory. "
12 "server_stopped is called with the same parameters as the "
13 "server_started hook: (backing_urls, public_url).", (0, 16))
14+ self.add_hook('server_exception',
15+ "Called by the bzr server when an exception occurs. "
16+ "server_exception is called with the sys.exc_info() tuple "
17+ "return true for the hook if the exception has been handled, "
18+ "in which case the server will exit normally.", (2, 4))
19
20 SmartTCPServer.hooks = SmartServerHooks()
21
22@@ -373,7 +378,6 @@
23 for cleanup in reversed(self.cleanups):
24 cleanup()
25
26-
27 def serve_bzr(transport, host=None, port=None, inet=False):
28 """This is the default implementation of 'bzr serve'.
29
30@@ -385,6 +389,11 @@
31 try:
32 bzr_server.set_up(transport, host, port, inet)
33 bzr_server.smart_server.serve()
34+ except:
35+ hook_caught_exception = False
36+ for hook in SmartTCPServer.hooks['server_exception']:
37+ hook_caught_exception = hook(sys.exc_info())
38+ if not hook_caught_exception:
39+ raise
40 finally:
41 bzr_server.tear_down()
42-
43
44=== modified file 'bzrlib/tests/blackbox/test_serve.py'
45--- bzrlib/tests/blackbox/test_serve.py 2011-05-26 08:05:45 +0000
46+++ bzrlib/tests/blackbox/test_serve.py 2011-05-27 13:15:43 +0000
47@@ -81,7 +81,7 @@
48 'run_bzr_serve_then_func hook')
49 # start a TCP server
50 try:
51- out, err = self.run_bzr(['serve'] + list(serve_args))
52+ out, err = self.run_bzr(['serve'] + list(serve_args), retcode=retcode)
53 except KeyboardInterrupt, e:
54 out, err = e.args
55 return out, err
56@@ -93,6 +93,24 @@
57 super(TestBzrServe, self).setUp()
58 self.disable_missing_extensions_warning()
59
60+ def test_server_exception_with_hook(self):
61+ """test exception hook works to catch exceptions from server"""
62+ def hook(exception):
63+ from bzrlib.trace import note
64+ note("catching exception")
65+ return True
66+ SmartTCPServer.hooks.install_named_hook(
67+ 'server_exception', hook,
68+ 'test_server_except_hook hook')
69+ args = []
70+ out, err = self.run_bzr_serve_then_func(args, retcode=0)
71+ self.assertEqual('listening on port: 4155\ncatching exception\n', err)
72+
73+ def test_server_exception_no_hook(self):
74+ """test exception without hook returns error"""
75+ args = []
76+ out, err = self.run_bzr_serve_then_func(args, retcode=3)
77+
78 def assertInetServerShutsdownCleanly(self, process):
79 """Shutdown the server process looking for errors."""
80 # Shutdown the server: the server should shut down when it cannot read
81
82=== modified file 'doc/en/release-notes/bzr-2.4.txt'
83--- doc/en/release-notes/bzr-2.4.txt 2011-05-27 11:05:47 +0000
84+++ doc/en/release-notes/bzr-2.4.txt 2011-05-27 13:15:43 +0000
85@@ -20,6 +20,10 @@
86
87 .. New commands, options, etc that users may wish to try out.
88
89+* New hook server_exception in bzrlib.smart.server to catch any
90+ exception caused while running bzr serve. (Jonathan Riddell,
91+ #274578)
92+
93 Improvements
94 ************
95