Merge lp:~facundo/ubuntuone-client/unsubscribe-during-lr into lp:ubuntuone-client

Proposed by Facundo Batista
Status: Work in progress
Proposed branch: lp:~facundo/ubuntuone-client/unsubscribe-during-lr
Merge into: lp:ubuntuone-client
Diff against target: 182 lines (+104/-9)
3 files modified
contrib/testing/testcase.py (+6/-0)
tests/syncdaemon/test_localrescan.py (+81/-8)
ubuntuone/syncdaemon/local_rescan.py (+17/-1)
To merge this branch: bzr merge lp:~facundo/ubuntuone-client/unsubscribe-during-lr
Reviewer Review Type Date Requested Status
Ubuntu One hackers Pending
Review via email: mp+72790@code.launchpad.net

Commit message

Support unsubscribing the volume (or removing it) while LocalRescan'ing (LP: #820353).

Description of the change

Support unsubscribing the volume (or removing it) while LocalRescan'ing.

Also renamed the 'ro_share' to 'rw_share', because it's actually a writable one.

Tests included.

To post a comment you must log in.

Unmerged revisions

1111. By Facundo Batista

Support unsubscribing the volume (or removing it) while LocalRescan'ing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'contrib/testing/testcase.py'
2--- contrib/testing/testcase.py 2011-08-15 22:05:02 +0000
3+++ contrib/testing/testcase.py 2011-08-24 21:06:23 +0000
4@@ -439,6 +439,12 @@
5 udf.subscribed = False
6 self.udfs[udf_id] = udf
7
8+ def unsubscribe_share(self, share_id):
9+ """Mark the Share as unsubscribed."""
10+ share = self.shares[share_id]
11+ share.subscribed = False
12+ self.shares[share_id] = share
13+
14 def delete_volume(self, volume_id):
15 """Request the deletion of a volume."""
16
17
18=== modified file 'tests/syncdaemon/test_localrescan.py'
19--- tests/syncdaemon/test_localrescan.py 2011-08-12 15:26:13 +0000
20+++ tests/syncdaemon/test_localrescan.py 2011-08-24 21:06:23 +0000
21@@ -62,18 +62,27 @@
22 """Fake EQ"""
23 def __init__(self):
24 self.pushed = []
25+ self.watching = set()
26
27 def push(self, event, **kwargs):
28 """Store stuff as pushed."""
29 self.pushed.append((event, kwargs))
30
31 def _fake(self, *a, **k):
32- """fake"""
33- add_watch = freeze_rollback = is_frozen = _fake
34- rm_watch = freeze_begin = add_to_mute_filter = _fake
35+ """Fake."""
36+ freeze_rollback = is_frozen = _fake
37+ freeze_begin = add_to_mute_filter = _fake
38+
39+ def add_watch(self, path):
40+ """Fake add watch."""
41+ self.watching.add(path)
42+
43+ def rm_watch(self, path):
44+ """Fake rm watch."""
45+ self.watching.discard(path)
46
47 def freeze_commit(self, events):
48- """just store events"""
49+ """Just store events."""
50 self.pushed.extend(events)
51
52
53@@ -506,7 +515,7 @@
54 self.lr = local_rescan.LocalRescan(self.vm, self.fsm, self.eq, self.aq)
55
56 # create a share
57- self.share = yield self.create_share('share_id', u'ro_share',
58+ self.share = yield self.create_share('share_id', u'rw_share',
59 access_level='Modify')
60 self.fsm.create(self.share.path, "share_id", is_dir=True)
61 self.fsm.set_node_id(self.share.path, "uuidshare")
62@@ -905,9 +914,9 @@
63 def test_one_dir_ro_share(self):
64 """The dir is in a share that's RO, no error but no action."""
65 # create the share
66- share = yield self.create_share('share_id', u'ro_share2',
67+ share = yield self.create_share('new_share_id', u'ro_share2',
68 access_level='View')
69- self.fsm.create(share.path, "share_id", is_dir=True)
70+ self.fsm.create(share.path, "new_share_id", is_dir=True)
71 self.fsm.set_node_id(share.path, "uuidshare")
72
73 lr = local_rescan.LocalRescan(self.vm, self.fsm, self.eq, self.aq)
74@@ -1005,6 +1014,70 @@
75 yield self.lr.start()
76 self.assertEqual(self.eq.pushed, [])
77
78+ @defer.inlineCallbacks
79+ def test_middle_unsubscribe(self):
80+ """Unsubscribe while the LR."""
81+ # make a file, and a dir with a file in it
82+ sh1 = os.path.join(self.share.path, "file")
83+ open_file(sh1, 'w').close()
84+
85+ # create a node that is already there (normally LR would put a
86+ # watch on it), and put a file in it
87+ sh2 = self.create_node("old_dir", is_dir=True)
88+ sh3 = os.path.join(sh2, "inside")
89+ open_file(sh3, 'w').close()
90+
91+ # do some magic to unsubscribe in the middle of the LR
92+ original_compare = self.lr._compare
93+
94+ def middle(dirpath, dnames, fnames, share):
95+ """Unsubscribe, and call the original."""
96+ if share == self.share:
97+ self.vm.unsubscribe_share(share.id)
98+ self.lr._compare = original_compare
99+ return original_compare(dirpath, dnames, fnames, share)
100+
101+ self.lr._compare = middle
102+
103+ # make LR spin and check
104+ yield self.lr.start()
105+ self.assertEqual(self.eq.pushed, [])
106+ self.assertNotIn(sh2, self.eq.watching)
107+ self.assertTrue(self.handler.check_debug(
108+ "Discarded scan", "volume unsubscribed or removed"))
109+
110+ @defer.inlineCallbacks
111+ def test_middle_remove(self):
112+ """Remove the share while the LR."""
113+ # make a file, and a dir with a file in it
114+ sh1 = os.path.join(self.share.path, "file")
115+ open_file(sh1, 'w').close()
116+
117+ # create a node that is already there (normally LR would put a
118+ # watch on it), and put a file in it
119+ sh2 = self.create_node("old_dir", is_dir=True)
120+ sh3 = os.path.join(sh2, "inside")
121+ open_file(sh3, 'w').close()
122+
123+ # do some magic to unsubscribe in the middle of the LR
124+ original_compare = self.lr._compare
125+
126+ def middle(dirpath, dnames, fnames, share):
127+ """Unsubscribe, and call the original."""
128+ if share == self.share:
129+ del self.vm.shares[share.id]
130+ self.lr._compare = original_compare
131+ return original_compare(dirpath, dnames, fnames, share)
132+
133+ self.lr._compare = middle
134+
135+ # make LR spin and check
136+ yield self.lr.start()
137+ self.assertEqual(self.eq.pushed, [])
138+ self.assertNotIn(sh2, self.eq.watching)
139+ self.assertTrue(self.handler.check_debug(
140+ "Discarded scan", "volume unsubscribed or removed"))
141+
142
143 class InotifyTests(TwistedBase):
144 """Test LocalRescan pushing events to the EventQueue."""
145@@ -2015,7 +2088,7 @@
146 def test_SERVER_share(self):
147 """We were downloading the share root dir but it was interrupted."""
148 # create a share
149- share = yield self.create_share('share_id_1', u'rw_share',
150+ share = yield self.create_share('share_id_1', u'new_share',
151 access_level='Modify')
152 self.fsm.create(share.path, "share_id_1", is_dir=True)
153 self.fsm.set_node_id(share.path, "uuid_share_1")
154
155=== modified file 'ubuntuone/syncdaemon/local_rescan.py'
156--- ubuntuone/syncdaemon/local_rescan.py 2011-08-10 15:03:17 +0000
157+++ ubuntuone/syncdaemon/local_rescan.py 2011-08-24 21:06:23 +0000
158@@ -660,7 +660,23 @@
159
160 events, to_scan_later = self._compare(dirpath, dnames, fnames,
161 share)
162- to_later.extend(to_scan_later)
163+
164+ # if the volume is no longer suscribed or was remvoed, discard
165+ # these events, remove the just added watch and avoid going deeper
166+ # FIXME: soportar que no este
167+ try:
168+ still_useful = self.vm.get_volume(share.id).subscribed
169+ except volume_manager.VolumeDoesNotExist:
170+ still_useful = False
171+
172+ if still_useful:
173+ to_later.extend(to_scan_later)
174+ else:
175+ m = "Discarded scan, volume unsubscribed or removed; id: %s"
176+ log_debug(m, share.id)
177+ events = []
178+ self.eq.rm_watch(dirpath)
179+
180 return events
181
182 delete_events = []

Subscribers

People subscribed via source and target branches