Merge lp:~nataliabidart/ubuntuone-client/server-rescan-handles-errors-from-server into lp:ubuntuone-client

Proposed by Natalia Bidart
Status: Merged
Approved by: dobey
Approved revision: 490
Merged at revision: not available
Proposed branch: lp:~nataliabidart/ubuntuone-client/server-rescan-handles-errors-from-server
Merge into: lp:ubuntuone-client
Diff against target: 198 lines (+123/-25)
2 files modified
tests/syncdaemon/test_action_queue.py (+90/-0)
ubuntuone/syncdaemon/action_queue.py (+33/-25)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/server-rescan-handles-errors-from-server
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Facundo Batista (community) Approve
Review via email: mp+23260@code.launchpad.net

Commit message

Refactored ActionQueue.server_rescan so generic error handling is made.

Description of the change

Refactored ActionQueue.server_rescan so generic error handling is made.

The erro handling is done usingthe generic helper added in former branches. Please note that the special case of firing or not the self.deferred should be removed once Bug #561736 is resolved.

To post a comment you must log in.
Revision history for this message
Facundo Batista (facundo) wrote :

Like it!

review: Approve
Revision history for this message
Guillermo Gonzalez (verterok) :
review: Approve
Revision history for this message
John Lenton (chipaca) wrote :
Download full text (8.5 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-client/server-rescan-handles-errors-from-server into lp:ubuntuone-client failed.Below is the output from the failed tests.

Using saved parent location: bzr+ssh://bazaar.launchpad.net/~ubuntuone-control-tower/ubuntuone-storage-protocol/trunk/
No revisions to pull.
/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
(B testing autoconf2.50... not found.
  testing autoconf... found 2.65
checking for automake >= 1.10...
(B testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
(B testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
(B testing intltoolize... found 0.41.0
checking for pkg-config >= 0.14.0...
(B testing pkg-config... found 0.22
Checking for required M4 macros...
(BChecking for forbidden M4 macros...
(BProcessing ./configure.ac
(BRunning libtoolize...
(Blibtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
(BRunning aclocal-1.11...
(BRunning autoconf...
(BRunning autoheader...
(BRunning automake-1.11...
(BRunning ./configure --prefix=/home/john/canonical/ubuntuone-storage-protocol/trunk ...
(Bchecking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of comm...

Read more...

Revision history for this message
John Lenton (chipaca) wrote :
Download full text (10.2 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-client/server-rescan-handles-errors-from-server into lp:ubuntuone-client failed.Below is the output from the failed tests.

Using saved parent location: bzr+ssh://bazaar.launchpad.net/~ubuntuone-control-tower/ubuntuone-storage-protocol/trunk/
No revisions to pull.
/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
(B testing autoconf2.50... not found.
  testing autoconf... found 2.65
checking for automake >= 1.10...
(B testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
(B testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
(B testing intltoolize... found 0.41.0
checking for pkg-config >= 0.14.0...
(B testing pkg-config... found 0.22
Checking for required M4 macros...
(BChecking for forbidden M4 macros...
(BProcessing ./configure.ac
(BRunning libtoolize...
(Blibtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
(BRunning aclocal-1.11...
(BRunning autoconf...
(BRunning autoheader...
(BRunning automake-1.11...
(BRunning ./configure --with-protocol=/home/john/canonical/ubuntuone-storage-protocol/trunk ...
(Bchecking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length ...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/syncdaemon/test_action_queue.py'
2--- tests/syncdaemon/test_action_queue.py 2010-04-12 15:55:43 +0000
3+++ tests/syncdaemon/test_action_queue.py 2010-04-12 19:44:26 +0000
4@@ -1935,6 +1935,25 @@
5 self.assertFalse(self.action_queue.deferred.called)
6
7 @defer.inlineCallbacks
8+ def test_send_request_and_handle_errors_when_fire_deferred_false(self):
9+ """_send_request_and_handle_errors doesn't fire the deferred."""
10+
11+ event = 'SYS_SPECIFIC_ERROR'
12+ EVENTS[event] = ('error',) # add event to the global valid events list
13+ self.addCleanup(lambda: EVENTS.pop(event))
14+
15+ exc = SpecificException('The request failed!')
16+ request = self.fail_please(exc)
17+ kwargs = dict(request=request, request_error=SpecificException,
18+ event_error=event, event_ok='YADDA_YADDA',
19+ fire_deferred=False)
20+ d = self.action_queue._send_request_and_handle_errors(**kwargs)
21+ yield d
22+
23+ # assert internal deferred wasn't fired
24+ self.assertFalse(self.action_queue.deferred.called)
25+
26+ @defer.inlineCallbacks
27 def test_check_version_when_unsupported_version_exception(self):
28 """Test error handling after UnsupportedVersionError."""
29 # raise a UnsupportedVersionError
30@@ -2059,3 +2078,74 @@
31
32 # assert internal deferred was fired
33 self.assertTrue(self.action_queue.deferred.called)
34+
35+ @defer.inlineCallbacks
36+ def test_server_rescan_as_a_whole(self):
37+ """Test error handling after server_rescan with no error."""
38+
39+ def faked_get_root(marker):
40+ """Fake the action_queue.get_root."""
41+ root_id=object()
42+ self.action_queue.event_queue.push('SYS_ROOT_RECEIVED',
43+ root_id=root_id)
44+ return root_id
45+
46+ self.patch(self.action_queue, 'get_root', faked_get_root)
47+
48+ self.action_queue.client.query = \
49+ self.succeed_please(result=self.action_queue.client)
50+ yield self.action_queue.server_rescan(root_mdid=object(), data_gen=list)
51+ event = ('SYS_SERVER_RESCAN_DONE', (), {})
52+ self.assertEqual(event, self.action_queue.event_queue.events[-1])
53+
54+ # assert internal deferred wasn't fired
55+ self.assertFalse(self.action_queue.deferred.called)
56+
57+ @defer.inlineCallbacks
58+ def test_server_rescan_when_get_root_fails(self):
59+ """Test error handling after server_rescan when get_root fails."""
60+
61+ msg = protocol_pb2.Message()
62+ msg.type = protocol_pb2.Message.ERROR
63+ msg.error.type = protocol_pb2.Error.PROTOCOL_ERROR
64+ msg.error.comment = 'get_root failed'
65+ exc = errors.StorageRequestError(request=None, message=msg)
66+ self.patch(self.action_queue, 'get_root', self.fail_please(exc))
67+
68+ self.action_queue.client.query = self.fail_please(NotImplementedError())
69+
70+ yield self.action_queue.server_rescan(root_mdid=object(), data_gen=list)
71+
72+ event = ('SYS_SERVER_RESCAN_DONE', (), {})
73+ self.assertNotIn(event, self.action_queue.event_queue.events)
74+
75+ event = ('SYS_SERVER_ERROR', (), {'error': str(exc)})
76+ self.assertEqual(event, self.action_queue.event_queue.events[-1])
77+
78+ # assert internal deferred wasn't fired
79+ self.assertFalse(self.action_queue.deferred.called)
80+
81+ @defer.inlineCallbacks
82+ def test_server_rescan_when_query_fails(self):
83+ """Test error handling after server_rescan when query fails."""
84+
85+ self.patch(self.action_queue, 'get_root',
86+ self.succeed_please(result=object()))
87+
88+ msg = protocol_pb2.Message()
89+ msg.type = protocol_pb2.Message.ERROR
90+ msg.error.type = protocol_pb2.Error.PROTOCOL_ERROR
91+ msg.error.comment = 'query failed'
92+ exc = errors.StorageRequestError(request=None, message=msg)
93+ self.action_queue.client.query = self.fail_please(exc)
94+
95+ yield self.action_queue.server_rescan(root_mdid=object(), data_gen=list)
96+
97+ event = ('SYS_SERVER_RESCAN_DONE', (), {})
98+ self.assertNotIn(event, self.action_queue.event_queue.events)
99+
100+ event = ('SYS_SERVER_ERROR', (), {'error': str(exc)})
101+ self.assertEqual(event, self.action_queue.event_queue.events[-1])
102+
103+ # assert internal deferred wasn't fired
104+ self.assertFalse(self.action_queue.deferred.called)
105
106=== modified file 'ubuntuone/syncdaemon/action_queue.py'
107--- ubuntuone/syncdaemon/action_queue.py 2010-04-12 15:55:43 +0000
108+++ ubuntuone/syncdaemon/action_queue.py 2010-04-12 19:44:26 +0000
109@@ -886,6 +886,7 @@
110 @defer.inlineCallbacks
111 def _send_request_and_handle_errors(self, request, request_error,
112 event_error, event_ok,
113+ fire_deferred=True,
114 args=(), kwargs={}):
115 """Send 'request' to the server, using params 'args' and 'kwargs'.
116
117@@ -907,7 +908,7 @@
118 finally:
119 # common handling for all cases
120 if client is not self.client:
121- client_mismatch_msg = "Client mismatch while processing "\
122+ client_mismatch_msg = "Client mismatch while processing " \
123 "the request '%s', " \
124 "client (%r) is not self.client (%r)."
125 logger.warning(client_mismatch_msg, req_name,
126@@ -932,9 +933,10 @@
127 if failure is not None:
128 logger.error("The request '%s' failed with the error:\n\n%s\n",
129 req_name, failure)
130- # it looks like we won't be authenticating, so hook up the
131- # for-testing deferred now
132- self.deferred.callback(Failure(failure))
133+ if fire_deferred:
134+ # it looks like we won't be authenticating, so hook up the
135+ # for-testing deferred now
136+ self.deferred.callback(Failure(failure))
137 else:
138 defer.returnValue(result)
139
140@@ -998,31 +1000,37 @@
141 # callback the deferred if everything went ok
142 self.deferred.callback(self.client)
143
144- @defer.inlineCallbacks
145 def server_rescan(self, root_mdid, data_gen):
146 """Do the server rescan."""
147- client = self.client
148- yield self.get_root(root_mdid)
149- if client is not self.client:
150- return
151- data = data_gen()
152- logger.info("Server rescan: will query %d objects", len(data))
153- # we check we're going to actually log, because this could be expensive
154- if logger.isEnabledFor(TRACE):
155- for share, node, hash in data:
156- logger.trace("Server rescan: share: %r, node: %r, hash: %s",
157- share or '/root/', node, hash)
158- logger.trace("Server rescan: all data shown")
159- yield client.query(data)
160- if client is not self.client:
161- return
162- logger.info("Server rescan: done")
163- self.event_queue.push('SYS_SERVER_RESCAN_DONE')
164+
165+ @defer.inlineCallbacks
166+ def _get_root_and_query(root_mdid, data_gen):
167+ """Get user's root and then query each element in data_gen()."""
168+ yield self.get_root(root_mdid)
169+ data = data_gen()
170+ logger.info("Server rescan: will query %d objects", len(data))
171+ # check we're going to actually log, because this could be expensive
172+ if logger.isEnabledFor(TRACE):
173+ for share, node, hash in data:
174+ logger.trace("Server rescan: share: %r, node: %r, hash: %s",
175+ share or '/root/', node, hash)
176+ logger.trace("Server rescan: all data shown")
177+ yield self.client.query(data)
178+
179+ get_root_and_query_d = self._send_request_and_handle_errors(
180+ request=_get_root_and_query,
181+ request_error=None, event_error=None,
182+ event_ok='SYS_SERVER_RESCAN_DONE', fire_deferred=False,
183+ args=(root_mdid, data_gen)
184+ )
185+ return get_root_and_query_d
186
187 def get_root(self, marker):
188- """
189- Get the user's root uuid. Use the uuid_map, so the caller can
190- use the marker in followup operations.
191+ """Get the user's root uuid.
192+
193+ Use the uuid_map, so the caller can use the marker in followup
194+ operations.
195+
196 """
197 log = mklog(logger, 'get_root', '', marker, marker=marker)
198 log.debug('starting')

Subscribers

People subscribed via source and target branches