Merge lp:~facundo/ubuntuone-client/lr-this-was-not-deleted-you-fool into lp:ubuntuone-client

Proposed by Facundo Batista
Status: Merged
Approved by: Guillermo Gonzalez
Approved revision: 273
Merged at revision: not available
Proposed branch: lp:~facundo/ubuntuone-client/lr-this-was-not-deleted-you-fool
Merge into: lp:ubuntuone-client
Diff against target: 180 lines
4 files modified
tests/syncdaemon/test_localrescan.py (+26/-3)
ubuntuone/syncdaemon/__init__.py (+5/-1)
ubuntuone/syncdaemon/local_rescan.py (+29/-16)
ubuntuone/u1sync/client.py (+1/-1)
To merge this branch: bzr merge lp:~facundo/ubuntuone-client/lr-this-was-not-deleted-you-fool
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Lucio Torre (community) Approve
Review via email: mp+14130@code.launchpad.net

Commit message

Support a non-content file in LR.

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

Support a non-content file in LR.

If there's MD in non-content state, converge to safe removing the MD.

Note that the hashed of the parent noded need to be dirtied, otherwise it never will be updated with server stuff by comparison (well, not never, until another change happens).

Tests included. Also needed to fix previous tests that left files in non-content while testing something else.

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

Oh, also I added a new capability!

Revision history for this message
Lucio Torre (lucio.torre) wrote :

clear and tested

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

worked like a charm

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_localrescan.py'
2--- tests/syncdaemon/test_localrescan.py 2009-10-14 18:38:59 +0000
3+++ tests/syncdaemon/test_localrescan.py 2009-10-29 02:10:22 +0000
4@@ -120,6 +120,10 @@
5
6 self.fsm.create(filepath, which_share.id, is_dir=is_dir)
7 self.fsm.set_node_id(filepath, "uuid"+path)
8+
9+ # for files we put hashes to signal them not non-content
10+ if not is_dir:
11+ self.fsm.set_by_path(filepath, local_hash="h", server_hash="h")
12 return filepath
13
14
15@@ -892,6 +896,7 @@
16 filepath = os.path.join(self.share.path, "a")
17 self.fsm.create(filepath, self.share.id, is_dir=False)
18 self.fsm.set_node_id(filepath, "uuid1")
19+ self.fsm.set_by_path(filepath, local_hash="hash", server_hash="hash")
20
21 def check(_):
22 """ asserts that GoodListener was called. """
23@@ -1404,17 +1409,35 @@
24 # this is a case when a file is written with content, the make_file
25 # to the server was ok (we have the file uuid), but before
26 # HQ finishes everything is stopped; when started again, it needs
27- # to generate the FILE_CLOSE_WRITE, to start the hash&upload process
28- # again
29+ # to generate the corresponding events, to start the hash&upload
30+ # process again
31 path = os.path.join(self.share.path, "a")
32 self.fsm.create(path, self.share.id, is_dir=False)
33 self.fsm.set_node_id(path, "uuid")
34+ self.fsm.set_by_path(path, local_hash="", server_hash="")
35 with open(path, "w") as fh:
36 fh.write("foo")
37
38 def check(_):
39 '''check'''
40- self.assertEqual(self.eq.pushed, [('FS_FILE_CLOSE_WRITE', path)])
41+ self.assertEqual(self.eq.pushed, [('FS_FILE_CREATE', path),
42+ ('FS_FILE_CLOSE_WRITE', path)
43+ ])
44+
45+ self.startTest(check)
46+ return self.deferred
47+
48+ def test_notcontent_file(self):
49+ '''The file is created but never started to download.'''
50+ # create the file in metadata
51+ path = os.path.join(self.share.path, "a")
52+# open(path, "w").close()
53+ mdid = self.fsm.create(path, self.share.id, is_dir=False, node_id="1")
54+
55+ def check(_):
56+ '''No event, and no MD'''
57+ self.assertEqual(self.eq.pushed, [])
58+ self.assertFalse(self.fsm.has_metadata(path=path))
59
60 self.startTest(check)
61 return self.deferred
62
63=== modified file 'ubuntuone/syncdaemon/__init__.py'
64--- ubuntuone/syncdaemon/__init__.py 2009-08-26 13:53:20 +0000
65+++ ubuntuone/syncdaemon/__init__.py 2009-10-29 02:10:22 +0000
66@@ -16,4 +16,8 @@
67 """ client module """
68
69 # required capabilities
70-REQUIRED_CAPS = frozenset(["no-content", "account-info", "resumable-uploads"])
71+REQUIRED_CAPS = frozenset(["no-content",
72+ "account-info",
73+ "resumable-uploads",
74+ "fix462230",
75+ ])
76
77=== modified file 'ubuntuone/syncdaemon/local_rescan.py'
78--- ubuntuone/syncdaemon/local_rescan.py 2009-09-28 17:34:38 +0000
79+++ ubuntuone/syncdaemon/local_rescan.py 2009-10-29 02:10:22 +0000
80@@ -153,14 +153,14 @@
81
82 reactor.callLater(0, safe_scan)
83
84- def _get_share_dirs(self, share_id, path):
85- '''Get all the directories in a share.'''
86- all_share_dirs = []
87+ def _get_share_info(self, share_id, path):
88+ '''Get all the objects information for a share.'''
89+ share_info = []
90 for obj in self.fsm.get_mdobjs_by_share_id(share_id, path):
91 changd = self.fsm.changed(mdid=obj.mdid)
92- all_share_dirs.append(
93- (obj.path, obj.is_dir, obj.stat, changd, obj.node_id))
94- return all_share_dirs
95+ share_info.append((obj.path, obj.is_dir, obj.stat, changd,
96+ obj.node_id, obj.local_hash, obj.server_hash))
97+ return share_info
98
99 def _scan_tree(self, share, path, scan_partials, mdid):
100 '''Scans a whole tree, using the received path as root.'''
101@@ -205,8 +205,8 @@
102 log_debug("comparing directory %r", dirpath)
103
104 # get the share info
105- all_share_dirs = self._get_share_dirs(share.id, dirpath)
106- shouldbe = self._paths_filter(all_share_dirs, dirpath, len(share.path))
107+ share_info = self._get_share_info(share.id, dirpath)
108+ shouldbe = self._paths_filter(share_info, dirpath, len(share.path))
109
110 def despair(message, fullname, also_children=False, also_remove=None):
111 '''Something went very bad with this node, converge!'''
112@@ -429,7 +429,7 @@
113 to_inform = []
114
115 # get all the info inside that dir
116- for shrpath, is_dir, statinfo, _, _ in all_share_dirs:
117+ for shrpath, is_dir, statinfo, _, _, _, _ in share_info:
118 if shrpath.startswith(base_path):
119 qparts = len(shrpath.split(os.path.sep))
120 to_inform.append((qparts, shrpath, is_dir))
121@@ -457,7 +457,7 @@
122 events.append(('FS_FILE_DELETE', fullname))
123 return events, to_scan_later
124
125- def _paths_filter(self, all_share_dirs, dirpath, len_shr_path):
126+ def _paths_filter(self, shrinfo, dirpath, len_shr_path):
127 '''Returns the paths that belong to this dir.'''
128 # paths in shares are relative, remove the first slash
129 direct = dirpath[len_shr_path + 1:]
130@@ -465,18 +465,31 @@
131
132 # build the dict
133 filesdirs = {}
134- for shrpath, is_dir, statinfo, changed, node_id in all_share_dirs:
135- base, fname = os.path.split(shrpath)
136+ for fpath, is_dir, statinfo, changed, node_id, lhash, shash in shrinfo:
137+ base, fname = os.path.split(fpath)
138 if base == direct:
139 # if without node_id, remove the metadata, and take it as new
140 if node_id is None:
141- fullname = os.path.join(basedir, shrpath)
142+ fullname = os.path.join(basedir, fpath)
143 m = "Deleting metadata, because of node_id=None, of %r"
144 log_debug(m, fullname)
145 self.fsm.delete_metadata(fullname)
146- continue
147-
148- filesdirs[fname] = is_dir, statinfo, changed
149+
150+ # if both hashes aren't set in a file, it's a non-content
151+ # situation, remove the metadata
152+ elif not is_dir and not lhash and not shash:
153+ fullname = os.path.join(basedir, fpath)
154+ m = "Deleting metadata, both hashes empty, of %r"
155+ log_debug(m, fullname)
156+ self.fsm.delete_metadata(fullname)
157+
158+ # also set the parent hashes to "", to force a new scan
159+ parent = os.path.dirname(fullname)
160+ log_debug("Dirtying the parent hashes, path: %r", parent)
161+ self.fsm.set_by_path(parent, server_hash="", local_hash="")
162+
163+ else:
164+ filesdirs[fname] = is_dir, statinfo, changed
165 return filesdirs
166
167 def _scan_one_dir(self, scan_info):
168
169=== modified file 'ubuntuone/u1sync/client.py'
170--- ubuntuone/u1sync/client.py 2009-09-08 20:14:06 +0000
171+++ ubuntuone/u1sync/client.py 2009-10-29 02:10:22 +0000
172@@ -178,7 +178,7 @@
173
174 class Client(object):
175 """U1 storage client facade."""
176- required_caps = frozenset(["no-content"])
177+ required_caps = frozenset(["no-content", "fix462230"])
178
179 def __init__(self, realm, reactor=reactor):
180 """Create the instance."""

Subscribers

People subscribed via source and target branches