Merge lp:~nataliabidart/ubuntuone-client/remove-watches-even-on-rename into lp:ubuntuone-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Guillermo Gonzalez
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~nataliabidart/ubuntuone-client/remove-watches-even-on-rename
Merge into: lp:ubuntuone-client
Prerequisite: lp:~nataliabidart/ubuntuone-client/unsubscribe-udf-if-broken-path
Diff against target: 269 lines (+87/-48)
3 files modified
tests/syncdaemon/test_eq_inotify.py (+71/-47)
tests/syncdaemon/test_vm.py (+15/-0)
ubuntuone/syncdaemon/volume_manager.py (+1/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/remove-watches-even-on-rename
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Facundo Batista (community) Approve
dobey (community) Approve
Review via email: mp+17888@code.launchpad.net

Commit message

Watches are remove after UDF subscription no matter if paths exist on disk or not.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Watches are remove after UDF subscription no matter if paths exist on disk or not.

Fixed test about UDF unsubscription after ancestor path was messed up.

Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
Facundo Batista (facundo) wrote :
Download full text (11.8 KiB)

===============================================================================
[ERROR]: tests.syncdaemon.test_eq_inotify.AncestorsUDFTestCase.test_file_events_are_ignored_on_udf_ancestor

Traceback (most recent call last):
Failure: twisted.python.failure.DefaultException:
===============================================================================
[ERROR]: tests.syncdaemon.test_eq_inotify.AncestorsUDFTestCase.test_file_events_are_ignored_on_udf_ancestor

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 757, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/tests/syncdaemon/test_eq_inotify.py", line 1166, in check
    self.assertEquals([], self.listener.events)
  File "/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/tests/syncdaemon/test_eq_inotify.py", line 1140, in failUnlessEqual
    raise exception
twisted.trial.unittest.FailTest: not equal:
a = []
b = [('VM_UDF_CREATED', (<ubuntuone.syncdaemon.volume_manager.UDF object at 0xa1f8f6c>,), {})]

===============================================================================
[ERROR]: tests.syncdaemon.test_eq_inotify.AncestorsUDFTestCase.test_file_events_are_not_ignored_on_common_prefix_name

Traceback (most recent call last):
Failure: twisted.python.failure.DefaultException:
===============================================================================
[ERROR]: tests.syncdaemon.test_eq_inotify.AncestorsUDFTestCase.test_file_events_are_not_ignored_on_common_prefix_name

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 757, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/tests/syncdaemon/test_eq_inotify.py", line 1245, in check
    self.assertEquals(expected, self.listener.events)
  File "/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/tests/syncdaemon/test_eq_inotify.py", line 1140, in failUnlessEqual
    raise exception
twisted.trial.unittest.FailTest: not equal:
a = [('FS_FILE_CREATE', ('/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/_trial_temp/tmp/tests.syncdaemon.test_eq_inotify/AncestorsUDFTestCase/test_file_events_are_not_ignored/tmpdir/ubuntuonehacker/Documents/Reading/Book/testit',), {}), ('FS_FILE_OPEN', ('/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/_trial_temp/tmp/tests.syncdaemon.test_eq_inotify/AncestorsUDFTestCase/test_file_events_are_not_ignored/tmpdir/ubuntuonehacker/Documents/Reading/Book/testit',), {}), ('FS_FILE_CLOSE_WRITE', ('/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/_trial_temp/tmp/tests.syncdaemon.test_eq_inotify/AncestorsUDFTestCase/test_file_events_are_not_ignored/tmpdir/ubuntuonehacker/Documents/Reading/Book/testit',), {}), ('FS_FILE_OPEN', ('/home/facundo/canonical/u1-client/review_remove-watches-even-on-rename/_trial_temp/tmp/tests.syncdaemon.test_eq_inotify/AncestorsUDFTestCase/test_file_events_are_not_ignored/tmpdir/ubuntuonehacker/Documents/Reading/...

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> FAILED (errors=8, successes=43)

Tests are fixed now. Thanks!

Revision history for this message
Facundo Batista (facundo) wrote :

It's ok!

review: Approve
Revision history for this message
dobey (dobey) wrote :

Attempt to merge lp:~nataliabidart/ubuntuone-client/remove-watches-even-on-rename into lp:ubuntuone-client failed due to merge conflicts:

text conflict in tests/syncdaemon/test_eq_inotify.py

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> Attempt to merge lp:~nataliabidart/ubuntuone-client/remove-watches-even-on-
> rename into lp:ubuntuone-client failed due to merge conflicts:
>
> text conflict in tests/syncdaemon/test_eq_inotify.py

Conflicts resolved.

Revision history for this message
Guillermo Gonzalez (verterok) wrote :

3 approve stamp!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/syncdaemon/test_eq_inotify.py'
2--- tests/syncdaemon/test_eq_inotify.py 2010-01-26 15:57:39 +0000
3+++ tests/syncdaemon/test_eq_inotify.py 2010-01-26 19:17:11 +0000
4@@ -20,6 +20,7 @@
5
6 import functools
7 import os
8+import shutil
9 import unittest
10
11 from twisted.internet import defer, reactor
12@@ -1088,21 +1089,27 @@
13 return self._deferred
14
15
16-class AncestorsUDFTestCase(BaseTwisted):
17+class AncestorsUDFTestCase(testcase.BaseTwistedTestCase):
18 """Events over UDF's ancestor are properly handled."""
19
20+ timeout = 2
21+
22 def setUp(self):
23 """Init."""
24- result = BaseTwisted.setUp(self)
25+ testcase.BaseTwistedTestCase.setUp(self)
26+ self._deferred = defer.Deferred()
27 self.home_dir = self.mktemp('ubuntuonehacker')
28-
29-
30+ self.root_dir = self.mktemp('root_dir')
31 self.data_dir = self.mktemp('data_dir')
32 self.shares_dir = self.mktemp('shares_dir')
33 self.partials_dir = self.mktemp('partials_dir')
34 self.main = testcase.FakeMain(self.root_dir, self.shares_dir,
35 self.data_dir, self.partials_dir)
36- ##self.eq.fs.vm = self.main.vm
37+ self.eq = self.main.event_q
38+ assert self.eq is self.eq.fs.vm.m.event_q
39+
40+ self.listener = testcase.Listener()
41+ self.eq.subscribe(self.listener)
42
43 self.env_var = 'HOME'
44 self.old_value = os.environ.get(self.env_var, None)
45@@ -1116,31 +1123,24 @@
46 suggested_path, path, True)
47 self.ancestors = self.udf.ancestors # this requires a fake HOME
48 os.makedirs(path)
49- self.eq.fs.vm.add_udf(self.udf)
50- assert self.udf.volume_id in self.eq.fs.vm.udfs
51+ d = self.eq.fs.vm.add_udf(self.udf)
52
53 # every ancestor has a watch already, added by LocalRescan. Copy that.
54 self.eq.inotify_add_watch(self.udf.path)
55 for path in self.ancestors:
56 self.eq.inotify_add_watch(path)
57
58- self.listener = testcase.Listener()
59- self.eq.subscribe(self.listener)
60-
61- return result
62+ # reset events up to now
63+ d.addCallback(lambda _: setattr(self.listener, 'events', []))
64+ return d
65
66 def tearDown(self):
67 """Cleanup."""
68 self.eq.unsubscribe(self.listener)
69-
70- ##self.eq.fs.vm._remove_watches(self.home_dir)
71- for path in self.ancestors + [self.udf.path]:
72- if os.path.exists(path):
73- self.eq.inotify_rm_watch(path)
74-
75 self.main.shutdown()
76
77 self.rmtree(self.home_dir)
78+ self.rmtree(self.root_dir)
79 self.rmtree(self.data_dir)
80 self.rmtree(self.shares_dir)
81 self.rmtree(self.partials_dir)
82@@ -1150,7 +1150,27 @@
83 else:
84 os.environ[self.env_var] = self.old_value
85
86- BaseTwisted.tearDown(self)
87+ testcase.BaseTwistedTestCase.tearDown(self)
88+
89+ def failUnlessEqual(self, first, second, msg=''):
90+ """Fail the test if C{first} and C{second} are not equal.
91+
92+ @param msg: A string describing the failure that's included in the
93+ exception.
94+
95+ """
96+ if not first == second:
97+ if msg is None:
98+ msg = ''
99+ if len(msg) > 0:
100+ msg += '\n'
101+ exception = self.failureException(
102+ '%snot equal:\na = %s\nb = %s\n'
103+ % (msg, repr(first), repr(second)))
104+ self._deferred.errback(msg)
105+ raise exception
106+ return first
107+ assertEqual = assertEquals = failUnlessEquals = failUnlessEqual
108
109 def test_file_events_are_ignored_on_udf_ancestor(self):
110 """Events on UDF ancestors are ignored."""
111@@ -1175,7 +1195,7 @@
112 def check():
113 """Check."""
114 self.assertEquals([], self.listener.events)
115- self.finished_ok()
116+ self._deferred.callback(True)
117
118 reactor.callLater(.1, check)
119 return self._deferred
120@@ -1212,7 +1232,7 @@
121 def check():
122 """Check."""
123 self.assertEquals(expected, self.listener.events)
124- self.finished_ok()
125+ self._deferred.callback(True)
126
127 reactor.callLater(.1, check)
128 return self._deferred
129@@ -1230,20 +1250,19 @@
130 assert not self.eq._processor._is_udf_ancestor(path)
131
132 os.makedirs(path)
133- self.eq.fs.vm.add_udf(other_udf)
134-
135 # every ancestor has a watch already, added by LocalRescan. Copy that.
136 self.eq.inotify_add_watch(other_udf.path)
137 for path in other_ancestors:
138 self.eq.inotify_add_watch(path)
139
140 fname = os.path.join(other_udf.path, 'testit')
141- # generate FS_FILE_CREATE, FS_FILE_OPEN, FS_FILE_CLOSE_WRITE
142- open(fname, 'w').close()
143+ def modify(_):
144+ # generate FS_FILE_CREATE, FS_FILE_OPEN, FS_FILE_CLOSE_WRITE
145+ open(fname, 'w').close()
146
147- # generate FS_FILE_CLOSE_NOWRITE
148- with open(fname) as f:
149- f.read()
150+ # generate FS_FILE_CLOSE_NOWRITE
151+ with open(fname) as f:
152+ f.read()
153
154 expected = [('FS_FILE_CREATE', (fname,), {}),
155 ('FS_FILE_OPEN', (fname,), {}),
156@@ -1251,10 +1270,15 @@
157 ('FS_FILE_OPEN', (fname,), {}),
158 ('FS_FILE_CLOSE_NOWRITE', (fname,), {})]
159
160+ d = self.eq.fs.vm.add_udf(other_udf)
161+ # reset events up to now
162+ d.addCallback(lambda _: setattr(self.listener, 'events', []))
163+ d.addCallback(modify)
164+
165 def check():
166 """Check."""
167 self.assertEquals(expected, self.listener.events)
168- self.finished_ok()
169+ self._deferred.callback(True)
170
171 reactor.callLater(.1, check)
172 return self._deferred
173@@ -1263,30 +1287,30 @@
174 """UDF is unsubscribed on ancestor move."""
175 original = self.eq.fs.vm.unsubscribe_udf
176 expected = []
177- # pylint: disable-msg=W0108
178- self.eq.fs.vm.unsubscribe_udf = lambda uid: expected.append(uid)
179-
180- def restore():
181- """Restore original unsubscribe_udf."""
182- self.eq.fs.vm.unsubscribe_udf = original
183- self.addCleanup(restore)
184-
185 path = self.ancestors[-1] # any ancestor
186 # generate IN_MOVED_FROM and IN_MOVED_TO
187 newpath = path + u'.old'
188 os.rename(path, newpath)
189- # generate FS_DIR_DELETE over the former UDFs
190- # those have to be ignored!
191- # HUGE FIXME: this generates event on the new, moved path
192- ##self.rmtree(newpath)
193+ assert os.path.exists(newpath)
194
195- def check():
196+ def check(uid):
197 """Check."""
198- self.assertEquals([], self.listener.events)
199- self.assertEquals(expected, [self.udf.volume_id], 'udf unsubscribed')
200- self.finished_ok()
201-
202- reactor.callLater(.1, check)
203+ original(uid)
204+ self.assertEquals(uid, self.udf.id, 'udf unsubscribed')
205+ self.assertEquals(False, self.eq.inotify_has_watch(self.udf.path),
206+ 'watch removed')
207+ self.assertEquals(False, self.eq.fs.vm.udfs[self.udf.id].subscribed)
208+ self._deferred.callback(True)
209+
210+ # pylint: disable-msg=W0108
211+ self.eq.fs.vm.unsubscribe_udf = check
212+
213+ def restore():
214+ """Restore original unsubscribe_udf."""
215+ self.eq.fs.vm.unsubscribe_udf = original
216+ shutil.rmtree(newpath)
217+ self.addCleanup(restore)
218+
219 return self._deferred
220
221 def test_remove_udf_per_se(self):
222@@ -1309,7 +1333,7 @@
223 """Check."""
224 self.assertEquals([], self.listener.events)
225 self.assertEquals(expected, [uid], 'udf deleted')
226- self.finished_ok()
227+ self._deferred.callback(True)
228
229 reactor.callLater(.1, check)
230 return self._deferred
231
232=== modified file 'tests/syncdaemon/test_vm.py'
233--- tests/syncdaemon/test_vm.py 2010-01-25 23:15:23 +0000
234+++ tests/syncdaemon/test_vm.py 2010-01-26 19:17:10 +0000
235@@ -448,6 +448,21 @@
236 for path in paths:
237 self.assertFalse(self.main.event_q.inotify_has_watch(path), path)
238
239+ def test_remove_watches_after_dir_rename(self):
240+ """Test for VolumeManager._remove_watches after dir rename."""
241+ path = os.path.join(self.root_dir, 'testit')
242+ os.mkdir(path)
243+ self.main.fs.create(path, "", is_dir=True)
244+ self.main.fs.set_node_id(path, 'dir_node_id')
245+ self.main.event_q.inotify_add_watch(path)
246+
247+ os.rename(path, path+'.old')
248+ # remove the watches
249+ self.vm._remove_watches(self.root_dir)
250+
251+ self.assertFalse(self.main.event_q.inotify_has_watch(path),
252+ 'watch should noy be present')
253+
254 def test_delete_fsm_object(self):
255 """Test for VolumeManager._delete_fsm_object"""
256 path = os.path.join(self.root_dir, 'dir')
257
258=== modified file 'ubuntuone/syncdaemon/volume_manager.py'
259--- ubuntuone/syncdaemon/volume_manager.py 2010-01-26 19:11:29 +0000
260+++ ubuntuone/syncdaemon/volume_manager.py 2010-01-26 19:17:11 +0000
261@@ -573,7 +573,7 @@
262 def _remove_watches(self, path):
263 """Remove the inotify watches from path and it subdirs."""
264 for a_path, is_dir in self.m.fs.get_paths_starting_with(path):
265- if is_dir and os.path.exists(a_path):
266+ if is_dir:
267 self._remove_watch(a_path)
268
269 def create_share(self, path, username, name, access_level):

Subscribers

People subscribed via source and target branches