Merge lp:~verterok/ubuntuone-client/fix-571548 into lp:ubuntuone-client/stable-1-2

Proposed by Guillermo Gonzalez
Status: Merged
Approved by: Rodrigo Moya
Approved revision: 509
Merged at revision: 511
Proposed branch: lp:~verterok/ubuntuone-client/fix-571548
Merge into: lp:ubuntuone-client/stable-1-2
Diff against target: 207 lines (+104/-13)
3 files modified
contrib/testing/testcase.py (+7/-8)
tests/syncdaemon/test_localrescan.py (+78/-5)
ubuntuone/syncdaemon/local_rescan.py (+19/-0)
To merge this branch: bzr merge lp:~verterok/ubuntuone-client/fix-571548
Reviewer Review Type Date Requested Status
Rodrigo Moya (community) Approve
Tim Cole (community) Approve
Natalia Bidart (community) Approve
Review via email: mp+24468@code.launchpad.net

Commit message

Check volume root metadata state in local rescan, fix it if it's in SERVER and log a warning of it's != NONE and != SERVER.

Description of the change

Check volume root metadata state in local rescan, fix it if it's in SERVER and log a warning of it's != NONE and != SERVER.
From the user POV fix syncdaemon not downloading new folders in a UDF e.g: a new artist album form the purchased music UDF.

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

nice!

review: Approve
Revision history for this message
Tim Cole (tcole) :
review: Approve
509. By Guillermo Gonzalez

fix test to work on tarmac

Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

Looks good

review: Approve

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 2010-04-09 16:14:12 +0000
3+++ contrib/testing/testcase.py 2010-05-05 02:44:27 +0000
4@@ -23,6 +23,7 @@
5 import logging
6 import os
7 import shutil
8+import itertools
9
10 from ubuntuone.oauthdesktop.main import Login, LoginProcessor
11 from ubuntuone.syncdaemon import (
12@@ -508,7 +509,7 @@
13
14 def __init__(self, root_path):
15 """ Creates the instance"""
16- self.root = volume_manager.Share(path=root_path, access_level='Modify')
17+ self.root = volume_manager.Root(node_id="root_node_id", path=root_path)
18 self.shares = {'':self.root}
19 self.udfs = {}
20 self.log = logging.getLogger('ubuntuone.SyncDaemon.VM-test')
21@@ -540,14 +541,12 @@
22 except KeyError:
23 return self.udfs[id]
24
25- def get_volumes(self, access_level='Modify', all_volumes=False):
26+ def get_volumes(self, all_volumes=False):
27 """Simple get_volumes for FakeVolumeManager."""
28- for share in self.shares.values():
29- if all_volumes or share.access_level == access_level:
30- yield share
31- for udf in self.udfs.values():
32- if all_volumes or udf.subscribed:
33- yield udf
34+ volumes = itertools.chain(self.shares.values(), self.udfs.values())
35+ for volume in volumes:
36+ if all_volumes or volume.active:
37+ yield volume
38
39 def unsubscribe_udf(self, udf_id):
40 """Mark the UDF with udf_id as unsubscribed."""
41
42=== modified file 'tests/syncdaemon/test_localrescan.py'
43--- tests/syncdaemon/test_localrescan.py 2010-04-16 16:23:58 +0000
44+++ tests/syncdaemon/test_localrescan.py 2010-05-05 02:44:27 +0000
45@@ -1,4 +1,3 @@
46-#
47 # Author: Facundo Batista <facundo@canonical.com>
48 # Author: Natalia Bidart <natalia.bidart@canonical.com>
49 #
50@@ -71,6 +70,7 @@
51 def setUp(self):
52 """ Setup the test """
53 testcase.BaseTwistedTestCase.setUp(self)
54+
55 self.home_dir = self.mktemp('ubuntuonehacker')
56 self.shares_dir = self.mktemp('shares')
57 usrdir = self.mktemp("usrdir")
58@@ -80,7 +80,7 @@
59 self.fsm = filesystem_manager.FileSystemManager(self.fsmdir,
60 self.partials_dir,
61 self.vm)
62- self.fsm.create(usrdir, "")
63+ self.fsm.create(usrdir, "", is_dir=True)
64 self.eq = FakeEQ()
65 self.fsm.register_eq(self.eq)
66 self.aq = FakeAQ()
67@@ -91,12 +91,13 @@
68
69 @staticmethod
70 def create_share(share_id, share_name, fsm, shares_dir,
71- access_level='Modify'):
72+ access_level='Modify', accepted=True):
73 """ creates a share """
74 share_path = os.path.join(shares_dir, share_name)
75 os.makedirs(share_path)
76 share = volume_manager.Share(path=share_path, volume_id=share_id,
77- access_level=access_level)
78+ access_level=access_level,
79+ accepted=accepted)
80 fsm.vm.add_share(share)
81 return share
82
83@@ -158,7 +159,7 @@
84 def test_empty_rw(self):
85 """Test with one empty Modify share."""
86 # create the share
87- share = self.create_share('share_id', 'ro_share', self.fsm,
88+ share = self.create_share('share_id', 'rw_share', self.fsm,
89 self.shares_dir, access_level='Modify')
90 self.fsm.create(share.path, "share_id", is_dir=True)
91 self.fsm.set_node_id(share.path, "uuid")
92@@ -374,6 +375,8 @@
93 self.shares_dir, access_level='Modify')
94 self.fsm.create(self.share.path, "share_id", is_dir=True)
95 self.fsm.set_node_id(self.share.path, "uuidshare")
96+ self.share.node_id = "uuidshare"
97+ self.vm.shares['share_id'] = self.share
98
99 def startTest(self, check_function):
100 """Start the test using lr.start()."""
101@@ -1850,6 +1853,76 @@
102 return self.deferred
103
104
105+class RootBadStateTests(TwistedBase):
106+ """Test what happens with volume roots left in a bad state last time."""
107+
108+ @defer.inlineCallbacks
109+ def setUp(self):
110+ yield TwistedBase.setUp(self)
111+ self.env_var = 'HOME'
112+ self.old_value = os.environ.get(self.env_var, None)
113+ os.environ[self.env_var] = self.home_dir
114+
115+
116+ def tearDown(self):
117+ if self.old_value is None:
118+ os.environ.pop(self.env_var)
119+ else:
120+ os.environ[self.env_var] = self.old_value
121+ return TwistedBase.tearDown(self)
122+
123+ def _test_it(self, volume):
124+ """Run the bad state test for a specific volume."""
125+ path = volume.path
126+ mdid = self.fsm.get_by_path(path).mdid
127+ partial_path = os.path.join(self.fsm.partials_dir,
128+ mdid + ".u1partial." + os.path.basename(path))
129+
130+ # start the download, never complete it
131+ self.fsm.set_by_mdid(mdid, server_hash="blah-hash-blah")
132+ self.fsm.create_partial(volume.node_id, volume.volume_id)
133+ fh = self.fsm.get_partial_for_writing(volume.node_id, volume.volume_id)
134+ fh.write("foobar")
135+ self.assertTrue(os.path.exists(partial_path))
136+
137+ def check(_):
138+ """arrange the metadata so later server_rescan will do ok"""
139+ mdobj = self.fsm.get_by_mdid(mdid)
140+ self.assertFalse(mdobj.info.is_partial)
141+ self.assertEqual(mdobj.server_hash, mdobj.local_hash)
142+ self.assertFalse(os.path.exists(partial_path))
143+
144+ self.startTest(check)
145+ return self.deferred
146+
147+ def test_SERVER_root(self):
148+ """We were downloading the root dir, but it was interrupted."""
149+ # create the root
150+ self.fsm.set_node_id(self.vm.root.path, self.vm.root.node_id)
151+ return self._test_it(self.vm.root)
152+
153+ def test_SERVER_share(self):
154+ """We were downloading the share root dir but it was interrupted."""
155+ # create a share
156+ share = self.create_share('share_id_1', 'rw_share', self.fsm,
157+ self.shares_dir, access_level='Modify')
158+ self.fsm.create(share.path, "share_id_1", is_dir=True)
159+ self.fsm.set_node_id(share.path, "uuid_share_1")
160+ share.node_id = "uuid_share_1"
161+ self.vm.shares['share_id_1'] = share
162+ return self._test_it(share)
163+
164+ def test_SERVER_udf(self):
165+ """We were downloading the udf root dir, but it was interrupted."""
166+ udf_path = os.path.join(self.home_dir, "myudf")
167+ os.mkdir(udf_path)
168+ udf = self.create_udf('udf_id', 'udf_root_node_id', "~/myudf",
169+ udf_path, True)
170+ self.fsm.create(udf.path, 'udf_id', is_dir=True)
171+ self.fsm.set_node_id(udf.path, 'udf_root_node_id')
172+ return self._test_it(udf)
173+
174+
175 class TrashTests(TwistedBase):
176 """Test handling trash."""
177
178
179=== modified file 'ubuntuone/syncdaemon/local_rescan.py'
180--- ubuntuone/syncdaemon/local_rescan.py 2010-04-16 16:23:58 +0000
181+++ ubuntuone/syncdaemon/local_rescan.py 2010-05-05 02:44:27 +0000
182@@ -302,6 +302,25 @@
183 # check all directories
184 to_scan_later = []
185 events = []
186+
187+ # check if dirpath is the share root
188+ if dirpath == share.path:
189+ fullname = share.path
190+ mdobj = self.fsm.get_by_path(fullname)
191+ changed = self.fsm.changed(mdid=mdobj.mdid)
192+ if changed == "SERVER":
193+ # download interrupted
194+ log_debug("checking root: %r in SERVER, fixing hash and "
195+ "removing partial.", fullname)
196+ self.fsm.set_by_mdid(mdobj.mdid,
197+ server_hash=mdobj.local_hash)
198+ self.fsm.remove_partial(mdobj.node_id, mdobj.share_id)
199+ elif changed == "NONE":
200+ log_debug("checking root: %r in NONE, ok!", fullname)
201+ else:
202+ log_warning("checking root: %r in wrong changed "
203+ "value '%s'", fullname, changed)
204+
205 for dname in dirnames:
206 fullname = os.path.join(dirpath, dname)
207 if dname in shouldbe:

Subscribers

People subscribed via source and target branches