Merge lp:~dobey/ubuntuone-client/rm-zeitgeist into lp:ubuntuone-client
- rm-zeitgeist
- Merge into trunk
Proposed by
dobey
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | dobey | ||||
Approved revision: | 1384 | ||||
Merged at revision: | 1384 | ||||
Proposed branch: | lp:~dobey/ubuntuone-client/rm-zeitgeist | ||||
Merge into: | lp:ubuntuone-client | ||||
Diff against target: |
2477 lines (+0/-2349) 15 files modified
contrib/testing/testcase.py (+0/-1) tests/platform/event_logging/__init__.py (+0/-27) tests/platform/event_logging/test_linux.py (+0/-92) tests/platform/event_logging/test_windows.py (+0/-43) tests/platform/linux/eventlog/__init__.py (+0/-27) tests/platform/linux/eventlog/test_zg_listener.py (+0/-1216) tests/platform/linux/eventlog/test_zglog.py (+0/-174) tests/syncdaemon/test_main.py (+0/-14) tests/syncdaemon/test_status_listener.py (+0/-6) ubuntuone/eventlog/__init__.py (+0/-29) ubuntuone/eventlog/zg_listener.py (+0/-556) ubuntuone/eventlog/zglog.py (+0/-61) ubuntuone/platform/event_logging/__init__.py (+0/-39) ubuntuone/platform/event_logging/linux.py (+0/-51) ubuntuone/syncdaemon/main.py (+0/-13) |
||||
To merge this branch: | bzr merge lp:~dobey/ubuntuone-client/rm-zeitgeist | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mike McCracken (community) | Approve | ||
Alejandro J. Cura (community) | Approve | ||
Review via email: mp+146454@code.launchpad.net |
Commit message
Remove usage of zg to reduce complexity, as we aren't using the feature.
Description of the change
To post a comment you must log in.
Revision history for this message
Mike McCracken (mikemc) : | # |
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 2013-01-22 20:03:12 +0000 | |||
3 | +++ contrib/testing/testcase.py 2013-02-04 16:10:53 +0000 | |||
4 | @@ -293,7 +293,6 @@ | |||
5 | 293 | self.lr = local_rescan.LocalRescan(self.vm, self.fs, | 293 | self.lr = local_rescan.LocalRescan(self.vm, self.fs, |
6 | 294 | self.event_q, self.action_q) | 294 | self.event_q, self.action_q) |
7 | 295 | 295 | ||
8 | 296 | self.eventlog_listener = None | ||
9 | 297 | self.status_listener = FakeStatusListener() | 296 | self.status_listener = FakeStatusListener() |
10 | 298 | 297 | ||
11 | 299 | def _connect_aq(self, _): | 298 | def _connect_aq(self, _): |
12 | 300 | 299 | ||
13 | === removed directory 'tests/platform/event_logging' | |||
14 | === removed file 'tests/platform/event_logging/__init__.py' | |||
15 | --- tests/platform/event_logging/__init__.py 2012-05-02 22:09:13 +0000 | |||
16 | +++ tests/platform/event_logging/__init__.py 1970-01-01 00:00:00 +0000 | |||
17 | @@ -1,27 +0,0 @@ | |||
18 | 1 | # Copyright 2012 Canonical Ltd. | ||
19 | 2 | # | ||
20 | 3 | # This program is free software: you can redistribute it and/or modify it | ||
21 | 4 | # under the terms of the GNU General Public License version 3, as published | ||
22 | 5 | # by the Free Software Foundation. | ||
23 | 6 | # | ||
24 | 7 | # This program is distributed in the hope that it will be useful, but | ||
25 | 8 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
26 | 9 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
27 | 10 | # PURPOSE. See the GNU General Public License for more details. | ||
28 | 11 | # | ||
29 | 12 | # You should have received a copy of the GNU General Public License along | ||
30 | 13 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
31 | 14 | # | ||
32 | 15 | # In addition, as a special exception, the copyright holders give | ||
33 | 16 | # permission to link the code of portions of this program with the | ||
34 | 17 | # OpenSSL library under certain conditions as described in each | ||
35 | 18 | # individual source file, and distribute linked combinations | ||
36 | 19 | # including the two. | ||
37 | 20 | # You must obey the GNU General Public License in all respects | ||
38 | 21 | # for all of the code used other than OpenSSL. If you modify | ||
39 | 22 | # file(s) with this exception, you may extend this exception to your | ||
40 | 23 | # version of the file(s), but you are not obligated to do so. If you | ||
41 | 24 | # do not wish to do so, delete this exception statement from your | ||
42 | 25 | # version. If you delete this exception statement from all source | ||
43 | 26 | # files in the program, then also delete it here. | ||
44 | 27 | """Platform/event_logging test code.""" | ||
45 | 28 | 0 | ||
46 | === removed file 'tests/platform/event_logging/test_linux.py' | |||
47 | --- tests/platform/event_logging/test_linux.py 2012-05-02 22:09:13 +0000 | |||
48 | +++ tests/platform/event_logging/test_linux.py 1970-01-01 00:00:00 +0000 | |||
49 | @@ -1,92 +0,0 @@ | |||
50 | 1 | # tests.platform.event_logging.test_linux | ||
51 | 2 | # | ||
52 | 3 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
53 | 4 | # | ||
54 | 5 | # Copyright 2010-2012 Canonical Ltd. | ||
55 | 6 | # | ||
56 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
57 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
58 | 9 | # by the Free Software Foundation. | ||
59 | 10 | # | ||
60 | 11 | # This program is distributed in the hope that it will be useful, but | ||
61 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
62 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
63 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
64 | 15 | # | ||
65 | 16 | # You should have received a copy of the GNU General Public License along | ||
66 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
67 | 18 | # | ||
68 | 19 | # In addition, as a special exception, the copyright holders give | ||
69 | 20 | # permission to link the code of portions of this program with the | ||
70 | 21 | # OpenSSL library under certain conditions as described in each | ||
71 | 22 | # individual source file, and distribute linked combinations | ||
72 | 23 | # including the two. | ||
73 | 24 | # You must obey the GNU General Public License in all respects | ||
74 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
75 | 26 | # file(s) with this exception, you may extend this exception to your | ||
76 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
77 | 28 | # do not wish to do so, delete this exception statement from your | ||
78 | 29 | # version. If you delete this exception statement from all source | ||
79 | 30 | # files in the program, then also delete it here. | ||
80 | 31 | """Test the event logging on linux.""" | ||
81 | 32 | |||
82 | 33 | import sys | ||
83 | 34 | |||
84 | 35 | from twisted.trial.unittest import TestCase | ||
85 | 36 | |||
86 | 37 | import ubuntuone.platform.event_logging.linux as event_logging | ||
87 | 38 | |||
88 | 39 | |||
89 | 40 | class ZeitgeistDetectionTestCase(TestCase): | ||
90 | 41 | """Test the is_zeitgeist_installed function.""" | ||
91 | 42 | |||
92 | 43 | def patch_module(self, module_name, fake_module): | ||
93 | 44 | """Monkey patch a module for the duration of the test.""" | ||
94 | 45 | UNDEFINED = object() | ||
95 | 46 | real_module = sys.modules.get(module_name, UNDEFINED) | ||
96 | 47 | |||
97 | 48 | def restore(): | ||
98 | 49 | """Restore the real_module.""" | ||
99 | 50 | if real_module is UNDEFINED: | ||
100 | 51 | del(sys.modules[module_name]) | ||
101 | 52 | else: | ||
102 | 53 | sys.modules[module_name] = real_module | ||
103 | 54 | |||
104 | 55 | self.addCleanup(restore) | ||
105 | 56 | sys.modules[module_name] = fake_module | ||
106 | 57 | |||
107 | 58 | def test_zg_installed_returns_true(self): | ||
108 | 59 | """When zg is installed, it returns true.""" | ||
109 | 60 | self.patch_module("zeitgeist", object()) | ||
110 | 61 | self.patch_module("zeitgeist.mimetypes", object()) | ||
111 | 62 | result = event_logging.is_zeitgeist_installed() | ||
112 | 63 | self.assertEqual(result, True) | ||
113 | 64 | |||
114 | 65 | def test_zg_not_installed_returns_false(self): | ||
115 | 66 | """When zg is not installed, it returns false.""" | ||
116 | 67 | self.patch_module("zeitgeist", None) | ||
117 | 68 | result = event_logging.is_zeitgeist_installed() | ||
118 | 69 | self.assertEqual(result, False) | ||
119 | 70 | |||
120 | 71 | def test_old_zg_installed_returns_false(self): | ||
121 | 72 | """When an old zg is installed, it returns false.""" | ||
122 | 73 | self.patch_module("zeitgeist", object()) | ||
123 | 74 | self.patch_module("zeitgeist.mimetypes", None) | ||
124 | 75 | result = event_logging.is_zeitgeist_installed() | ||
125 | 76 | self.assertEqual(result, False) | ||
126 | 77 | |||
127 | 78 | |||
128 | 79 | class GetListenerTestCase(TestCase): | ||
129 | 80 | """The zg listener is created.""" | ||
130 | 81 | |||
131 | 82 | def test_zeitgeist_installed_returns_listener(self): | ||
132 | 83 | """get_listener returns a listener if ZG installed.""" | ||
133 | 84 | self.patch(event_logging, "is_zeitgeist_installed", lambda: True) | ||
134 | 85 | listener = event_logging.get_listener(None, None) | ||
135 | 86 | self.assertNotEqual(listener, None) | ||
136 | 87 | |||
137 | 88 | def test_zeitgeist_not_installed_returns_none(self): | ||
138 | 89 | """get_listener returns None if ZG not installed.""" | ||
139 | 90 | self.patch(event_logging, "is_zeitgeist_installed", lambda: False) | ||
140 | 91 | listener = event_logging.get_listener(None, None) | ||
141 | 92 | self.assertEqual(listener, None) | ||
142 | 93 | 0 | ||
143 | === removed file 'tests/platform/event_logging/test_windows.py' | |||
144 | --- tests/platform/event_logging/test_windows.py 2012-05-02 22:09:13 +0000 | |||
145 | +++ tests/platform/event_logging/test_windows.py 1970-01-01 00:00:00 +0000 | |||
146 | @@ -1,43 +0,0 @@ | |||
147 | 1 | # tests.platform.windows.test_event_logging | ||
148 | 2 | # | ||
149 | 3 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
150 | 4 | # | ||
151 | 5 | # Copyright 2010-2012 Canonical Ltd. | ||
152 | 6 | # | ||
153 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
154 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
155 | 9 | # by the Free Software Foundation. | ||
156 | 10 | # | ||
157 | 11 | # This program is distributed in the hope that it will be useful, but | ||
158 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
159 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
160 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
161 | 15 | # | ||
162 | 16 | # You should have received a copy of the GNU General Public License along | ||
163 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
164 | 18 | # | ||
165 | 19 | # In addition, as a special exception, the copyright holders give | ||
166 | 20 | # permission to link the code of portions of this program with the | ||
167 | 21 | # OpenSSL library under certain conditions as described in each | ||
168 | 22 | # individual source file, and distribute linked combinations | ||
169 | 23 | # including the two. | ||
170 | 24 | # You must obey the GNU General Public License in all respects | ||
171 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
172 | 26 | # file(s) with this exception, you may extend this exception to your | ||
173 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
174 | 28 | # do not wish to do so, delete this exception statement from your | ||
175 | 29 | # version. If you delete this exception statement from all source | ||
176 | 30 | # files in the program, then also delete it here. | ||
177 | 31 | """Test the event logging on windows.""" | ||
178 | 32 | |||
179 | 33 | from twisted.trial import unittest | ||
180 | 34 | |||
181 | 35 | class GetListenerTestCase(unittest.TestCase): | ||
182 | 36 | """Listener creation tests.""" | ||
183 | 37 | |||
184 | 38 | def test_never_creates_a_listener(self): | ||
185 | 39 | """The listener is never created on windows.""" | ||
186 | 40 | from ubuntuone.platform import event_logging | ||
187 | 41 | listener = event_logging.get_listener(None, None) | ||
188 | 42 | self.assertEqual(listener, None) | ||
189 | 43 | |||
190 | 44 | 0 | ||
191 | === removed directory 'tests/platform/linux/eventlog' | |||
192 | === removed file 'tests/platform/linux/eventlog/__init__.py' | |||
193 | --- tests/platform/linux/eventlog/__init__.py 2012-04-09 20:07:05 +0000 | |||
194 | +++ tests/platform/linux/eventlog/__init__.py 1970-01-01 00:00:00 +0000 | |||
195 | @@ -1,27 +0,0 @@ | |||
196 | 1 | # Copyright 2010-2012 Canonical Ltd. | ||
197 | 2 | # | ||
198 | 3 | # This program is free software: you can redistribute it and/or modify it | ||
199 | 4 | # under the terms of the GNU General Public License version 3, as published | ||
200 | 5 | # by the Free Software Foundation. | ||
201 | 6 | # | ||
202 | 7 | # This program is distributed in the hope that it will be useful, but | ||
203 | 8 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
204 | 9 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
205 | 10 | # PURPOSE. See the GNU General Public License for more details. | ||
206 | 11 | # | ||
207 | 12 | # You should have received a copy of the GNU General Public License along | ||
208 | 13 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
209 | 14 | # | ||
210 | 15 | # In addition, as a special exception, the copyright holders give | ||
211 | 16 | # permission to link the code of portions of this program with the | ||
212 | 17 | # OpenSSL library under certain conditions as described in each | ||
213 | 18 | # individual source file, and distribute linked combinations | ||
214 | 19 | # including the two. | ||
215 | 20 | # You must obey the GNU General Public License in all respects | ||
216 | 21 | # for all of the code used other than OpenSSL. If you modify | ||
217 | 22 | # file(s) with this exception, you may extend this exception to your | ||
218 | 23 | # version of the file(s), but you are not obligated to do so. If you | ||
219 | 24 | # do not wish to do so, delete this exception statement from your | ||
220 | 25 | # version. If you delete this exception statement from all source | ||
221 | 26 | # files in the program, then also delete it here. | ||
222 | 27 | """Tests module.""" | ||
223 | 28 | 0 | ||
224 | === removed file 'tests/platform/linux/eventlog/test_zg_listener.py' | |||
225 | --- tests/platform/linux/eventlog/test_zg_listener.py 2012-10-16 15:13:24 +0000 | |||
226 | +++ tests/platform/linux/eventlog/test_zg_listener.py 1970-01-01 00:00:00 +0000 | |||
227 | @@ -1,1216 +0,0 @@ | |||
228 | 1 | # -*- coding: utf-8 -*- | ||
229 | 2 | # | ||
230 | 3 | # Copyright 2010-2012 Canonical Ltd. | ||
231 | 4 | # | ||
232 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
233 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
234 | 7 | # by the Free Software Foundation. | ||
235 | 8 | # | ||
236 | 9 | # This program is distributed in the hope that it will be useful, but | ||
237 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
238 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
239 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
240 | 13 | # | ||
241 | 14 | # You should have received a copy of the GNU General Public License along | ||
242 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
243 | 16 | # | ||
244 | 17 | # In addition, as a special exception, the copyright holders give | ||
245 | 18 | # permission to link the code of portions of this program with the | ||
246 | 19 | # OpenSSL library under certain conditions as described in each | ||
247 | 20 | # individual source file, and distribute linked combinations | ||
248 | 21 | # including the two. | ||
249 | 22 | # You must obey the GNU General Public License in all respects | ||
250 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
251 | 24 | # file(s) with this exception, you may extend this exception to your | ||
252 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
253 | 26 | # do not wish to do so, delete this exception statement from your | ||
254 | 27 | # version. If you delete this exception statement from all source | ||
255 | 28 | # files in the program, then also delete it here. | ||
256 | 29 | """Test the event logging from SyncDaemon into Zeitgeist.""" | ||
257 | 30 | |||
258 | 31 | import logging | ||
259 | 32 | import os | ||
260 | 33 | import sys | ||
261 | 34 | import uuid | ||
262 | 35 | |||
263 | 36 | from os.path import basename | ||
264 | 37 | from twisted.internet import defer | ||
265 | 38 | from zeitgeist.datamodel import Interpretation, Manifestation | ||
266 | 39 | |||
267 | 40 | # python-zeitgeist on lucid has no mimetypes module, and it's usually | ||
268 | 41 | # disabled, but fake it for running tests on lucid | ||
269 | 42 | try: | ||
270 | 43 | import zeitgeist.mimetypes | ||
271 | 44 | assert(zeitgeist.mimetypes is not None) # make pyflakes happy | ||
272 | 45 | except ImportError: | ||
273 | 46 | |||
274 | 47 | class FakeMimetypes(object): | ||
275 | 48 | """A fake zg.mimetypes module.""" | ||
276 | 49 | |||
277 | 50 | def get_interpretation_for_mimetype(self, mimetype): | ||
278 | 51 | """This fake always returns AUDIO.""" | ||
279 | 52 | return Interpretation.AUDIO | ||
280 | 53 | |||
281 | 54 | sys.modules["zeitgeist.mimetypes"] = FakeMimetypes() | ||
282 | 55 | |||
283 | 56 | from contrib.testing.testcase import ( | ||
284 | 57 | FakeMain, FakeMainTestCase, BaseTwistedTestCase) | ||
285 | 58 | from ubuntuone.devtools.handlers import MementoHandler | ||
286 | 59 | from ubuntuone.platform import expand_user | ||
287 | 60 | from ubuntuone.storageprotocol import client, delta | ||
288 | 61 | from ubuntuone.storageprotocol.request import ROOT | ||
289 | 62 | from ubuntuone.storageprotocol.sharersp import NotifyShareHolder | ||
290 | 63 | from ubuntuone.syncdaemon.action_queue import ( | ||
291 | 64 | RequestQueue, Upload, MakeFile, MakeDir) | ||
292 | 65 | from ubuntuone.eventlog.zg_listener import ( | ||
293 | 66 | zglog, ZeitgeistListener, ACTOR_UBUNTUONE, | ||
294 | 67 | EVENT_INTERPRETATION_U1_FOLDER_SHARED, | ||
295 | 68 | EVENT_INTERPRETATION_U1_FOLDER_UNSHARED, | ||
296 | 69 | EVENT_INTERPRETATION_U1_SHARE_ACCEPTED, | ||
297 | 70 | EVENT_INTERPRETATION_U1_SHARE_UNACCEPTED, | ||
298 | 71 | EVENT_INTERPRETATION_U1_CONFLICT_RENAME, | ||
299 | 72 | EVENT_INTERPRETATION_U1_UDF_CREATED, | ||
300 | 73 | EVENT_INTERPRETATION_U1_UDF_DELETED, | ||
301 | 74 | EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED, | ||
302 | 75 | EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED, | ||
303 | 76 | MANIFESTATION_U1_CONTACT_DATA_OBJECT, DIRECTORY_MIMETYPE, | ||
304 | 77 | INTERPRETATION_U1_CONTACT, URI_PROTOCOL_U1, | ||
305 | 78 | STORAGE_DELETED, STORAGE_NETWORK, STORAGE_LOCAL) | ||
306 | 79 | from ubuntuone.syncdaemon.sync import Sync | ||
307 | 80 | from ubuntuone.syncdaemon.volume_manager import ( | ||
308 | 81 | ACCESS_LEVEL_RO, | ||
309 | 82 | get_udf_path, Share, Shared, UDF, | ||
310 | 83 | ) | ||
311 | 84 | from tests.syncdaemon.test_action_queue import ( | ||
312 | 85 | ConnectedBaseTestCase, | ||
313 | 86 | FakeSemaphore, | ||
314 | 87 | FakeTempFile, | ||
315 | 88 | TestingProtocol, | ||
316 | 89 | ) | ||
317 | 90 | |||
318 | 91 | VOLUME = uuid.UUID('12345678-1234-1234-1234-123456789abc') | ||
319 | 92 | |||
320 | 93 | |||
321 | 94 | class MockLogger(object): | ||
322 | 95 | """A mock logger that stores whatever is logged into it.""" | ||
323 | 96 | |||
324 | 97 | def __init__(self): | ||
325 | 98 | """Initialize this instance.""" | ||
326 | 99 | self.events = [] | ||
327 | 100 | self.deferreds = [] | ||
328 | 101 | |||
329 | 102 | def log(self, event): | ||
330 | 103 | """Log the event.""" | ||
331 | 104 | self.events.append(event) | ||
332 | 105 | if self.deferreds: | ||
333 | 106 | self.callback_next_deferred(event) | ||
334 | 107 | |||
335 | 108 | def callback_next_deferred(self, event): | ||
336 | 109 | """Pop the next deferred and callback it.""" | ||
337 | 110 | d = self.deferreds.pop() | ||
338 | 111 | if d: | ||
339 | 112 | d.callback(event) | ||
340 | 113 | |||
341 | 114 | |||
342 | 115 | def listen_for(event_q, event, callback, count=1, collect=False): | ||
343 | 116 | """Setup a EQ listener for the specified event.""" | ||
344 | 117 | class Listener(object): | ||
345 | 118 | """A basic listener to handle the pushed event.""" | ||
346 | 119 | |||
347 | 120 | def __init__(self): | ||
348 | 121 | self.hits = 0 | ||
349 | 122 | self.events = [] | ||
350 | 123 | |||
351 | 124 | def _handle_event(self, *args, **kwargs): | ||
352 | 125 | self.hits += 1 | ||
353 | 126 | if collect: | ||
354 | 127 | self.events.append((args, kwargs)) | ||
355 | 128 | if self.hits == count: | ||
356 | 129 | event_q.unsubscribe(self) | ||
357 | 130 | if collect: | ||
358 | 131 | callback(self.events) | ||
359 | 132 | elif kwargs: | ||
360 | 133 | callback((args, kwargs)) | ||
361 | 134 | else: | ||
362 | 135 | callback(args) | ||
363 | 136 | |||
364 | 137 | listener = Listener() | ||
365 | 138 | setattr(listener, 'handle_' + event, listener._handle_event) | ||
366 | 139 | event_q.subscribe(listener) | ||
367 | 140 | return listener | ||
368 | 141 | |||
369 | 142 | |||
370 | 143 | class ZeitgeistListenerTestCase(FakeMainTestCase): | ||
371 | 144 | """Tests for ZeitgeistListener.""" | ||
372 | 145 | |||
373 | 146 | @defer.inlineCallbacks | ||
374 | 147 | def setUp(self): | ||
375 | 148 | """Initialize this instance.""" | ||
376 | 149 | yield super(ZeitgeistListenerTestCase, self).setUp() | ||
377 | 150 | self.patch(zglog, "ZeitgeistLogger", MockLogger) | ||
378 | 151 | self.listener = ZeitgeistListener(self.fs, self.vm) | ||
379 | 152 | self.event_q.subscribe(self.listener) | ||
380 | 153 | self.patch(self.event_q, "ignored_base_exception", RuntimeError) | ||
381 | 154 | |||
382 | 155 | def _listen_for(self, *args, **kwargs): | ||
383 | 156 | return listen_for(self.main.event_q, *args, **kwargs) | ||
384 | 157 | |||
385 | 158 | |||
386 | 159 | class ZeitgeistSharesTestCase(ZeitgeistListenerTestCase): | ||
387 | 160 | """Tests for all Share-related zeitgeist events.""" | ||
388 | 161 | |||
389 | 162 | @defer.inlineCallbacks | ||
390 | 163 | def test_share_created_with_username_is_logged(self): | ||
391 | 164 | """A ShareCreated event is logged.""" | ||
392 | 165 | fake_username = "fake user" | ||
393 | 166 | path = os.path.join(self.vm.root.path, 'shared_path') | ||
394 | 167 | sample_node_id = "node id" | ||
395 | 168 | self.main.fs.create(path, "") | ||
396 | 169 | self.main.fs.set_node_id(path, sample_node_id) | ||
397 | 170 | |||
398 | 171 | def fake_create_share(node_id, user, name, access_level, marker, path): | ||
399 | 172 | """Fake the creation of the share on the server.""" | ||
400 | 173 | self.assertIn(marker, self.vm.marker_share_map) | ||
401 | 174 | share_id = self.fs.get_by_mdid(marker).share_id | ||
402 | 175 | self.main.event_q.push('AQ_CREATE_SHARE_OK', | ||
403 | 176 | share_id=share_id, | ||
404 | 177 | marker=marker) | ||
405 | 178 | |||
406 | 179 | d = defer.Deferred() | ||
407 | 180 | self._listen_for('AQ_CREATE_SHARE_OK', d.callback, 1, collect=True) | ||
408 | 181 | self.patch(self.main.action_q, "create_share", fake_create_share) | ||
409 | 182 | self.vm.create_share(path, fake_username, 'shared_name', | ||
410 | 183 | ACCESS_LEVEL_RO) | ||
411 | 184 | |||
412 | 185 | yield d | ||
413 | 186 | |||
414 | 187 | self.assert_folder_shared_is_logged(path, fake_username) | ||
415 | 188 | |||
416 | 189 | def test_share_created_with_email_is_logged(self): | ||
417 | 190 | """A ShareCreated event is logged.""" | ||
418 | 191 | fake_username = "fakeuser@somewhere.com" | ||
419 | 192 | path = os.path.join(self.vm.root.path, 'shared_path') | ||
420 | 193 | sample_node_id = "node id" | ||
421 | 194 | self.main.fs.create(path, "") | ||
422 | 195 | self.main.fs.set_node_id(path, sample_node_id) | ||
423 | 196 | |||
424 | 197 | def fake_create_share(node_id, user, name, access_level, marker, path): | ||
425 | 198 | """Fake the creation of the share on the server.""" | ||
426 | 199 | self.assertIn(marker, self.vm.marker_share_map) | ||
427 | 200 | self.main.event_q.push('AQ_SHARE_INVITATION_SENT', | ||
428 | 201 | marker=marker) | ||
429 | 202 | |||
430 | 203 | self.patch(self.main.action_q, "create_share", fake_create_share) | ||
431 | 204 | self.vm.create_share(path, fake_username, 'shared_name', | ||
432 | 205 | ACCESS_LEVEL_RO) | ||
433 | 206 | |||
434 | 207 | self.assert_folder_shared_is_logged(path, fake_username) | ||
435 | 208 | |||
436 | 209 | def assert_folder_shared_is_logged(self, path, fake_username): | ||
437 | 210 | """Assert that the FolderShared event was logged.""" | ||
438 | 211 | |||
439 | 212 | self.assertEqual(len(self.listener.zg.events), 1) | ||
440 | 213 | event = self.listener.zg.events[0] | ||
441 | 214 | foldername = basename(path) | ||
442 | 215 | |||
443 | 216 | self.assertEqual(event.interpretation, | ||
444 | 217 | EVENT_INTERPRETATION_U1_FOLDER_SHARED) | ||
445 | 218 | self.assertEqual(event.manifestation, | ||
446 | 219 | Manifestation.USER_ACTIVITY) | ||
447 | 220 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
448 | 221 | |||
449 | 222 | folder = event.subjects[0] | ||
450 | 223 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
451 | 224 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
452 | 225 | self.assertEqual(folder.manifestation, | ||
453 | 226 | Manifestation.REMOTE_DATA_OBJECT) | ||
454 | 227 | self.assertTrue(folder.origin.endswith(path)) | ||
455 | 228 | self.assertEqual(folder.text, foldername) | ||
456 | 229 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
457 | 230 | self.assertEqual(folder.storage, STORAGE_NETWORK) | ||
458 | 231 | |||
459 | 232 | other_user = event.subjects[1] | ||
460 | 233 | self.assertEqual(other_user.uri, "mailto:" + fake_username) | ||
461 | 234 | self.assertEqual(other_user.interpretation, INTERPRETATION_U1_CONTACT) | ||
462 | 235 | self.assertEqual(other_user.manifestation, | ||
463 | 236 | MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
464 | 237 | self.assertEqual(other_user.text, fake_username) | ||
465 | 238 | |||
466 | 239 | @defer.inlineCallbacks | ||
467 | 240 | def test_share_deleted_is_logged(self): | ||
468 | 241 | """Test VolumeManager.delete_share.""" | ||
469 | 242 | sample_share_id = "share id" | ||
470 | 243 | sample_node_id = "node id" | ||
471 | 244 | fake_username = "fake user" | ||
472 | 245 | folder_name = "shared_path" | ||
473 | 246 | path = os.path.join(self.vm.root.path, folder_name) | ||
474 | 247 | self.main.fs.create(path, "") | ||
475 | 248 | self.main.fs.set_node_id(path, sample_node_id) | ||
476 | 249 | share = Shared(path=path, volume_id=sample_share_id, | ||
477 | 250 | node_id=sample_node_id, other_username=fake_username) | ||
478 | 251 | yield self.vm.add_shared(share) | ||
479 | 252 | |||
480 | 253 | def fake_delete_share(share_id): | ||
481 | 254 | """Fake delete_share.""" | ||
482 | 255 | self.assertEqual(share_id, share.volume_id) | ||
483 | 256 | self.main.event_q.push('AQ_DELETE_SHARE_OK', share_id=share_id) | ||
484 | 257 | |||
485 | 258 | self.patch(self.main.action_q, 'delete_share', fake_delete_share) | ||
486 | 259 | d = defer.Deferred() | ||
487 | 260 | self._listen_for('VM_SHARE_DELETED', d.callback, 1, collect=True) | ||
488 | 261 | self.vm.delete_share(share.volume_id) | ||
489 | 262 | yield d | ||
490 | 263 | |||
491 | 264 | self.assertEqual(len(self.listener.zg.events), 1) | ||
492 | 265 | event = self.listener.zg.events[0] | ||
493 | 266 | |||
494 | 267 | self.assertEqual(event.interpretation, | ||
495 | 268 | EVENT_INTERPRETATION_U1_FOLDER_UNSHARED) | ||
496 | 269 | self.assertEqual(event.manifestation, | ||
497 | 270 | Manifestation.USER_ACTIVITY) | ||
498 | 271 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
499 | 272 | |||
500 | 273 | folder = event.subjects[0] | ||
501 | 274 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
502 | 275 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
503 | 276 | self.assertEqual(folder.manifestation, | ||
504 | 277 | Manifestation.REMOTE_DATA_OBJECT) | ||
505 | 278 | self.assertTrue(folder.origin.endswith(path)) | ||
506 | 279 | self.assertEqual(folder.text, folder_name) | ||
507 | 280 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
508 | 281 | self.assertEqual(folder.storage, STORAGE_NETWORK) | ||
509 | 282 | |||
510 | 283 | other_user = event.subjects[1] | ||
511 | 284 | self.assertEqual(other_user.uri, "mailto:" + fake_username) | ||
512 | 285 | self.assertEqual(other_user.interpretation, INTERPRETATION_U1_CONTACT) | ||
513 | 286 | self.assertEqual(other_user.manifestation, | ||
514 | 287 | MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
515 | 288 | self.assertEqual(other_user.text, fake_username) | ||
516 | 289 | |||
517 | 290 | @defer.inlineCallbacks | ||
518 | 291 | def test_share_accepted_is_logged(self): | ||
519 | 292 | """Test that an accepted share event is logged.""" | ||
520 | 293 | # initialize the the root | ||
521 | 294 | self.vm._got_root('root_uuid') | ||
522 | 295 | fake_username = "fake user" | ||
523 | 296 | folder_name = "shared_path" | ||
524 | 297 | path = os.path.join(self.vm.root.path, folder_name) | ||
525 | 298 | self.main.fs.create(path, "") | ||
526 | 299 | share_path = os.path.join(self.shares_dir, folder_name) | ||
527 | 300 | share = Share(path=share_path, volume_id='volume_id', node_id="node_id", | ||
528 | 301 | other_username=fake_username) | ||
529 | 302 | yield self.vm.add_share(share) | ||
530 | 303 | |||
531 | 304 | self.assertEqual(len(self.listener.zg.events), 1) | ||
532 | 305 | event = self.listener.zg.events[0] | ||
533 | 306 | |||
534 | 307 | self.assertEqual(event.interpretation, | ||
535 | 308 | EVENT_INTERPRETATION_U1_SHARE_ACCEPTED) | ||
536 | 309 | self.assertEqual(event.manifestation, | ||
537 | 310 | Manifestation.USER_ACTIVITY) | ||
538 | 311 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
539 | 312 | |||
540 | 313 | folder = event.subjects[0] | ||
541 | 314 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
542 | 315 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
543 | 316 | self.assertEqual(folder.manifestation, | ||
544 | 317 | Manifestation.REMOTE_DATA_OBJECT) | ||
545 | 318 | self.assertTrue(folder.origin.endswith(share_path)) | ||
546 | 319 | self.assertEqual(folder.text, folder_name) | ||
547 | 320 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
548 | 321 | self.assertEqual(folder.storage, STORAGE_NETWORK) | ||
549 | 322 | |||
550 | 323 | other_user = event.subjects[1] | ||
551 | 324 | self.assertEqual(other_user.uri, "mailto:" + fake_username) | ||
552 | 325 | self.assertEqual(other_user.interpretation, INTERPRETATION_U1_CONTACT) | ||
553 | 326 | self.assertEqual(other_user.manifestation, | ||
554 | 327 | MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
555 | 328 | self.assertEqual(other_user.text, fake_username) | ||
556 | 329 | |||
557 | 330 | @defer.inlineCallbacks | ||
558 | 331 | def test_share_unaccepted_is_logged(self): | ||
559 | 332 | """Test that an unaccepted share event is logged.""" | ||
560 | 333 | fake_username = "fake user" | ||
561 | 334 | folder_name = u"share" | ||
562 | 335 | d = defer.Deferred() | ||
563 | 336 | |||
564 | 337 | share_path = os.path.join(self.main.shares_dir, folder_name) | ||
565 | 338 | holder = NotifyShareHolder.from_params(uuid.uuid4(), | ||
566 | 339 | uuid.uuid4(), | ||
567 | 340 | u'fake_share', | ||
568 | 341 | fake_username, | ||
569 | 342 | u'visible_name', 'Read') | ||
570 | 343 | |||
571 | 344 | share = Share.from_notify_holder(holder, share_path) | ||
572 | 345 | yield self.main.vm.add_share(share) | ||
573 | 346 | self._listen_for('VM_VOLUME_DELETED', d.callback, 1, collect=True) | ||
574 | 347 | self.main.event_q.push('SV_SHARE_DELETED', share_id=holder.share_id) | ||
575 | 348 | yield d | ||
576 | 349 | |||
577 | 350 | self.assertEqual(len(self.listener.zg.events), 2) | ||
578 | 351 | event = self.listener.zg.events[1] | ||
579 | 352 | |||
580 | 353 | self.assertEqual(event.interpretation, | ||
581 | 354 | EVENT_INTERPRETATION_U1_SHARE_UNACCEPTED) | ||
582 | 355 | self.assertEqual(event.manifestation, | ||
583 | 356 | Manifestation.USER_ACTIVITY) | ||
584 | 357 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
585 | 358 | |||
586 | 359 | folder = event.subjects[0] | ||
587 | 360 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
588 | 361 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
589 | 362 | self.assertEqual(folder.manifestation, | ||
590 | 363 | Manifestation.REMOTE_DATA_OBJECT) | ||
591 | 364 | self.assertTrue(folder.origin.endswith(share_path)) | ||
592 | 365 | self.assertEqual(folder.text, folder_name) | ||
593 | 366 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
594 | 367 | self.assertEqual(folder.storage, STORAGE_NETWORK) | ||
595 | 368 | |||
596 | 369 | other_user = event.subjects[1] | ||
597 | 370 | self.assertEqual(other_user.uri, "mailto:" + fake_username) | ||
598 | 371 | self.assertEqual(other_user.interpretation, INTERPRETATION_U1_CONTACT) | ||
599 | 372 | self.assertEqual(other_user.manifestation, | ||
600 | 373 | MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
601 | 374 | self.assertEqual(other_user.text, fake_username) | ||
602 | 375 | |||
603 | 376 | |||
604 | 377 | class ZeitgeistUDFsTestCase(ZeitgeistListenerTestCase): | ||
605 | 378 | """Tests for all UDFs-related zeitgeist events.""" | ||
606 | 379 | |||
607 | 380 | def _create_udf(self, id, node_id, suggested_path, subscribed=True): | ||
608 | 381 | """Create an UDF and returns it and the volume.""" | ||
609 | 382 | path = get_udf_path(suggested_path) | ||
610 | 383 | # make sure suggested_path is unicode | ||
611 | 384 | if isinstance(suggested_path, str): | ||
612 | 385 | suggested_path = suggested_path.decode('utf-8') | ||
613 | 386 | udf = UDF(str(id), str(node_id), suggested_path, path, subscribed) | ||
614 | 387 | return udf | ||
615 | 388 | |||
616 | 389 | @defer.inlineCallbacks | ||
617 | 390 | def test_udf_create_is_logged(self): | ||
618 | 391 | """Test for Folders.create.""" | ||
619 | 392 | folder_name = u'ñoño'.encode('utf-8') | ||
620 | 393 | path = os.path.join(self.home_dir, folder_name) | ||
621 | 394 | id = uuid.uuid4() | ||
622 | 395 | node_id = uuid.uuid4() | ||
623 | 396 | |||
624 | 397 | def create_udf(path, name, marker): | ||
625 | 398 | """Fake create_udf.""" | ||
626 | 399 | # check that the marker is the full path to the udf | ||
627 | 400 | expanded_path = expand_user(path.encode('utf-8')) | ||
628 | 401 | udf_path = os.path.join(expanded_path, name.encode('utf-8')) | ||
629 | 402 | if str(marker) != udf_path: | ||
630 | 403 | d.errback(ValueError("marker != path - " | ||
631 | 404 | "marker: %r path: %r" % (marker, udf_path))) | ||
632 | 405 | self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=id, | ||
633 | 406 | node_id=node_id, | ||
634 | 407 | marker=marker)) | ||
635 | 408 | |||
636 | 409 | self.patch(self.main.action_q, "create_udf", create_udf) | ||
637 | 410 | |||
638 | 411 | d = defer.Deferred() | ||
639 | 412 | self.listener.zg.deferreds.append(d) | ||
640 | 413 | self.vm.create_udf(path) | ||
641 | 414 | yield d | ||
642 | 415 | |||
643 | 416 | self.assertEqual(len(self.listener.zg.events), 1) | ||
644 | 417 | event = self.listener.zg.events[0] | ||
645 | 418 | |||
646 | 419 | self.assertEqual(event.interpretation, | ||
647 | 420 | EVENT_INTERPRETATION_U1_UDF_CREATED) | ||
648 | 421 | self.assertEqual(event.manifestation, | ||
649 | 422 | Manifestation.USER_ACTIVITY) | ||
650 | 423 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
651 | 424 | |||
652 | 425 | folder = event.subjects[0] | ||
653 | 426 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
654 | 427 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
655 | 428 | self.assertEqual(folder.manifestation, | ||
656 | 429 | Manifestation.REMOTE_DATA_OBJECT) | ||
657 | 430 | self.assertTrue(folder.origin.endswith(path)) | ||
658 | 431 | self.assertEqual(folder.text, folder_name) | ||
659 | 432 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
660 | 433 | self.assertEqual(folder.storage, STORAGE_NETWORK) | ||
661 | 434 | |||
662 | 435 | @defer.inlineCallbacks | ||
663 | 436 | def test_udf_delete_is_logged(self): | ||
664 | 437 | """Test for Folders.delete.""" | ||
665 | 438 | id = uuid.uuid4() | ||
666 | 439 | node_id = uuid.uuid4() | ||
667 | 440 | folder_name = u'ñoño'.encode('utf-8') | ||
668 | 441 | path = os.path.join(self.home_dir, folder_name) | ||
669 | 442 | |||
670 | 443 | d = defer.Deferred() | ||
671 | 444 | self.listener.zg.deferreds.append(d) | ||
672 | 445 | |||
673 | 446 | def create_udf(path, name, marker): | ||
674 | 447 | """Fake create_udf.""" | ||
675 | 448 | # check that the marker is the full path to the udf | ||
676 | 449 | expanded_path = expand_user(path.encode('utf-8')) | ||
677 | 450 | udf_path = os.path.join(expanded_path, name.encode('utf-8')) | ||
678 | 451 | if str(marker) != udf_path: | ||
679 | 452 | d.errback(ValueError("marker != path - " | ||
680 | 453 | "marker: %r path: %r" % (marker, udf_path))) | ||
681 | 454 | self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=id, | ||
682 | 455 | node_id=node_id, | ||
683 | 456 | marker=marker)) | ||
684 | 457 | |||
685 | 458 | self.patch(self.main.action_q, "create_udf", create_udf) | ||
686 | 459 | |||
687 | 460 | self.vm.create_udf(path) | ||
688 | 461 | yield d | ||
689 | 462 | |||
690 | 463 | def delete_volume(volume_id, path): | ||
691 | 464 | """Fake delete_volume.""" | ||
692 | 465 | self.main.event_q.push("AQ_DELETE_VOLUME_OK", volume_id=id) | ||
693 | 466 | |||
694 | 467 | self.patch(self.main.action_q, "delete_volume", delete_volume) | ||
695 | 468 | |||
696 | 469 | self.assertEqual(len(self.listener.zg.events), 1) | ||
697 | 470 | event = self.listener.zg.events[0] | ||
698 | 471 | |||
699 | 472 | d2 = defer.Deferred() | ||
700 | 473 | self.listener.zg.deferreds.append(d2) | ||
701 | 474 | self.vm.delete_volume(str(id)) | ||
702 | 475 | yield d2 | ||
703 | 476 | |||
704 | 477 | self.assertEqual(len(self.listener.zg.events), 2) | ||
705 | 478 | event = self.listener.zg.events[1] | ||
706 | 479 | |||
707 | 480 | self.assertEqual(event.interpretation, | ||
708 | 481 | EVENT_INTERPRETATION_U1_UDF_DELETED) | ||
709 | 482 | self.assertEqual(event.manifestation, | ||
710 | 483 | Manifestation.USER_ACTIVITY) | ||
711 | 484 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
712 | 485 | |||
713 | 486 | folder = event.subjects[0] | ||
714 | 487 | self.assertTrue(folder.uri.startswith(URI_PROTOCOL_U1)) | ||
715 | 488 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
716 | 489 | self.assertEqual(folder.manifestation, | ||
717 | 490 | Manifestation.DELETED_RESOURCE) | ||
718 | 491 | self.assertTrue(folder.origin.endswith(path)) | ||
719 | 492 | self.assertEqual(folder.text, folder_name) | ||
720 | 493 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
721 | 494 | self.assertEqual(folder.storage, STORAGE_DELETED) | ||
722 | 495 | |||
723 | 496 | @defer.inlineCallbacks | ||
724 | 497 | def test_udf_subscribe_is_logged(self): | ||
725 | 498 | """Test for Folders.subscribe.""" | ||
726 | 499 | folder_name = u"ñoño" | ||
727 | 500 | suggested_path = u'~/' + folder_name | ||
728 | 501 | udf = self._create_udf(uuid.uuid4(), 'node_id', suggested_path, | ||
729 | 502 | subscribed=False) | ||
730 | 503 | yield self.main.vm.add_udf(udf) | ||
731 | 504 | d = defer.Deferred() | ||
732 | 505 | self.listener.zg.deferreds.append(d) | ||
733 | 506 | self.vm.subscribe_udf(udf.volume_id) | ||
734 | 507 | yield d | ||
735 | 508 | |||
736 | 509 | self.assertEqual(len(self.listener.zg.events), 2) | ||
737 | 510 | event = self.listener.zg.events[1] | ||
738 | 511 | |||
739 | 512 | self.assertEqual(event.interpretation, | ||
740 | 513 | EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED) | ||
741 | 514 | self.assertEqual(event.manifestation, | ||
742 | 515 | Manifestation.USER_ACTIVITY) | ||
743 | 516 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
744 | 517 | |||
745 | 518 | folder = event.subjects[0] | ||
746 | 519 | self.assertTrue(folder.uri.endswith(udf.path)) | ||
747 | 520 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
748 | 521 | self.assertEqual(folder.manifestation, | ||
749 | 522 | Manifestation.FILE_DATA_OBJECT) | ||
750 | 523 | self.assertTrue(folder.origin.startswith(URI_PROTOCOL_U1)) | ||
751 | 524 | self.assertEqual(folder.text.decode('utf-8'), folder_name) | ||
752 | 525 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
753 | 526 | self.assertEqual(folder.storage, STORAGE_LOCAL) | ||
754 | 527 | |||
755 | 528 | @defer.inlineCallbacks | ||
756 | 529 | def test_udf_unsubscribe_is_logged(self): | ||
757 | 530 | """Test for Folders.unsubscribe.""" | ||
758 | 531 | suggested_path = u'~/ñoño' | ||
759 | 532 | udf = self._create_udf(uuid.uuid4(), 'node_id', suggested_path, | ||
760 | 533 | subscribed=True) | ||
761 | 534 | folder_name = basename(udf.path) | ||
762 | 535 | yield self.main.vm.add_udf(udf) | ||
763 | 536 | d = defer.Deferred() | ||
764 | 537 | self._listen_for('VM_UDF_UNSUBSCRIBED', d.callback, 1, collect=True) | ||
765 | 538 | self.vm.unsubscribe_udf(udf.volume_id) | ||
766 | 539 | yield d | ||
767 | 540 | |||
768 | 541 | self.assertEqual(len(self.listener.zg.events), 2) | ||
769 | 542 | event = self.listener.zg.events[1] | ||
770 | 543 | |||
771 | 544 | self.assertEqual(event.interpretation, | ||
772 | 545 | EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED) | ||
773 | 546 | self.assertEqual(event.manifestation, | ||
774 | 547 | Manifestation.USER_ACTIVITY) | ||
775 | 548 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
776 | 549 | |||
777 | 550 | folder = event.subjects[0] | ||
778 | 551 | self.assertTrue(folder.uri.endswith(udf.path)) | ||
779 | 552 | self.assertEqual(folder.interpretation, Interpretation.FOLDER) | ||
780 | 553 | self.assertEqual(folder.manifestation, | ||
781 | 554 | Manifestation.DELETED_RESOURCE) | ||
782 | 555 | self.assertTrue(folder.origin.startswith(URI_PROTOCOL_U1)) | ||
783 | 556 | self.assertEqual(folder.text, folder_name) | ||
784 | 557 | self.assertEqual(folder.mimetype, DIRECTORY_MIMETYPE) | ||
785 | 558 | self.assertEqual(folder.storage, STORAGE_DELETED) | ||
786 | 559 | |||
787 | 560 | |||
788 | 561 | class ZeitgeistRemoteFileSyncTestCase(ConnectedBaseTestCase): | ||
789 | 562 | """File sync events are logged into Zeitgeist.""" | ||
790 | 563 | |||
791 | 564 | @defer.inlineCallbacks | ||
792 | 565 | def setUp(self): | ||
793 | 566 | """Initialize this test instance.""" | ||
794 | 567 | yield super(ZeitgeistRemoteFileSyncTestCase, self).setUp() | ||
795 | 568 | self.rq = request_queue = RequestQueue(action_queue=self.action_queue) | ||
796 | 569 | self.rq.transfers_semaphore = FakeSemaphore() | ||
797 | 570 | |||
798 | 571 | class MyUpload(Upload): | ||
799 | 572 | """Just to allow monkeypatching.""" | ||
800 | 573 | |||
801 | 574 | self.share_id = "" | ||
802 | 575 | self.mdid = self.main.fs.create(os.path.join(self.root, 'file'), '') | ||
803 | 576 | self.command = MyUpload(request_queue, share_id=self.share_id, | ||
804 | 577 | node_id='a_node_id', previous_hash='prev_hash', | ||
805 | 578 | hash='yadda', crc32=0, size=0, mdid=self.mdid) | ||
806 | 579 | self.command.make_logger() | ||
807 | 580 | self.command.tempfile = FakeTempFile(self.mktemp('tmpdir')) | ||
808 | 581 | self.fsm = self.action_queue.main.fs | ||
809 | 582 | self.vm = self.action_queue.main.vm | ||
810 | 583 | self.patch(zglog, "ZeitgeistLogger", MockLogger) | ||
811 | 584 | self.listener = ZeitgeistListener(self.fsm, self.vm) | ||
812 | 585 | self.action_queue.event_queue.subscribe(self.listener) | ||
813 | 586 | self.root_id = "roootid" | ||
814 | 587 | self.sync = Sync(main=self.main) | ||
815 | 588 | |||
816 | 589 | def test_syncdaemon_creates_file_on_server_is_logged(self): | ||
817 | 590 | """Files created by SyncDaemon on the server are logged.""" | ||
818 | 591 | filename = "filename.mp3" | ||
819 | 592 | path = os.path.join(self.vm.root.path, filename) | ||
820 | 593 | self.fsm.create(path, "") | ||
821 | 594 | self.fsm.set_node_id(path, "a_node_id") | ||
822 | 595 | |||
823 | 596 | request = client.MakeFile(self.action_queue.client, self.share_id, | ||
824 | 597 | 'parent', filename) | ||
825 | 598 | request.new_id = 'a_node_id' | ||
826 | 599 | request.new_generation = 13 | ||
827 | 600 | |||
828 | 601 | # create a command and trigger it success | ||
829 | 602 | cmd = MakeFile(self.rq, self.share_id, 'parent', filename, | ||
830 | 603 | 'marker', self.mdid) | ||
831 | 604 | cmd.handle_success(request) | ||
832 | 605 | |||
833 | 606 | # create a request and fill it with succesful information | ||
834 | 607 | aq_client = TestingProtocol() | ||
835 | 608 | request = client.PutContent(aq_client, self.share_id, | ||
836 | 609 | 'node', 'prvhash', 'newhash', 'crc32', | ||
837 | 610 | 'size', 'deflated', 'fd') | ||
838 | 611 | request.new_generation = 13 | ||
839 | 612 | |||
840 | 613 | # trigger success in the command | ||
841 | 614 | self.command.handle_success(request) | ||
842 | 615 | |||
843 | 616 | # check for successful event | ||
844 | 617 | kwargs = dict(share_id=self.command.share_id, node_id='a_node_id', | ||
845 | 618 | hash='yadda', new_generation=13) | ||
846 | 619 | |||
847 | 620 | info = dict(marker='marker', new_id='a_node_id', new_generation=13, | ||
848 | 621 | volume_id=self.share_id) | ||
849 | 622 | events = [ | ||
850 | 623 | ('AQ_FILE_NEW_OK', info), | ||
851 | 624 | ('AQ_UPLOAD_FINISHED', kwargs), | ||
852 | 625 | ] | ||
853 | 626 | self.assertEqual(events, self.command.action_queue.event_queue.events) | ||
854 | 627 | |||
855 | 628 | self.assertEqual(len(self.listener.zg.events), 1) | ||
856 | 629 | event = self.listener.zg.events[0] | ||
857 | 630 | |||
858 | 631 | self.assertEqual(event.interpretation, | ||
859 | 632 | Interpretation.CREATE_EVENT) | ||
860 | 633 | self.assertEqual(event.manifestation, | ||
861 | 634 | Manifestation.SCHEDULED_ACTIVITY) | ||
862 | 635 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
863 | 636 | |||
864 | 637 | remote_file = event.subjects[0] | ||
865 | 638 | self.assertTrue(remote_file.uri.startswith(URI_PROTOCOL_U1)) | ||
866 | 639 | self.assertEqual(remote_file.interpretation, Interpretation.AUDIO) | ||
867 | 640 | self.assertEqual(remote_file.manifestation, | ||
868 | 641 | Manifestation.REMOTE_DATA_OBJECT) | ||
869 | 642 | self.assertTrue(remote_file.origin.endswith(filename)) | ||
870 | 643 | self.assertEqual(remote_file.text, filename) | ||
871 | 644 | self.assertEqual(remote_file.mimetype, "audio/mpeg") | ||
872 | 645 | self.assertEqual(remote_file.storage, STORAGE_NETWORK) | ||
873 | 646 | |||
874 | 647 | def test_syncdaemon_creates_dir_on_server_is_logged(self): | ||
875 | 648 | """Dirs created by SyncDaemon on the server are logged.""" | ||
876 | 649 | dirname = "dirname" | ||
877 | 650 | path = os.path.join(self.vm.root.path, dirname) | ||
878 | 651 | self.fsm.create(path, "") | ||
879 | 652 | self.fsm.set_node_id(path, "a_node_id") | ||
880 | 653 | |||
881 | 654 | request = client.MakeDir(self.action_queue.client, self.share_id, | ||
882 | 655 | 'parent', dirname) | ||
883 | 656 | request.new_id = 'a_node_id' | ||
884 | 657 | request.new_generation = 13 | ||
885 | 658 | |||
886 | 659 | # create a command and trigger it success | ||
887 | 660 | cmd = MakeDir(self.rq, self.share_id, 'parent', | ||
888 | 661 | dirname, 'marker', self.mdid) | ||
889 | 662 | cmd.handle_success(request) | ||
890 | 663 | |||
891 | 664 | # check for successful event | ||
892 | 665 | info = dict(marker='marker', new_id='a_node_id', new_generation=13, | ||
893 | 666 | volume_id=self.share_id) | ||
894 | 667 | events = [('AQ_DIR_NEW_OK', info)] | ||
895 | 668 | self.assertEqual(events, self.command.action_queue.event_queue.events) | ||
896 | 669 | |||
897 | 670 | self.assertEqual(len(self.listener.zg.events), 1) | ||
898 | 671 | event = self.listener.zg.events[0] | ||
899 | 672 | |||
900 | 673 | self.assertEqual(event.interpretation, | ||
901 | 674 | Interpretation.CREATE_EVENT) | ||
902 | 675 | self.assertEqual(event.manifestation, | ||
903 | 676 | Manifestation.SCHEDULED_ACTIVITY) | ||
904 | 677 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
905 | 678 | |||
906 | 679 | remote_folder = event.subjects[0] | ||
907 | 680 | self.assertTrue(remote_folder.uri.startswith(URI_PROTOCOL_U1)) | ||
908 | 681 | self.assertEqual(remote_folder.interpretation, Interpretation.FOLDER) | ||
909 | 682 | self.assertEqual(remote_folder.manifestation, | ||
910 | 683 | Manifestation.REMOTE_DATA_OBJECT) | ||
911 | 684 | self.assertTrue(remote_folder.origin.endswith(dirname)) | ||
912 | 685 | self.assertEqual(remote_folder.text, dirname) | ||
913 | 686 | self.assertEqual(remote_folder.mimetype, DIRECTORY_MIMETYPE) | ||
914 | 687 | self.assertEqual(remote_folder.storage, STORAGE_NETWORK) | ||
915 | 688 | |||
916 | 689 | def test_syncdaemon_modifies_on_server_is_logged(self): | ||
917 | 690 | """Files modified by SyncDaemon on the server are logged.""" | ||
918 | 691 | filename = "filename.mp3" | ||
919 | 692 | path = os.path.join(self.vm.root.path, filename) | ||
920 | 693 | self.fsm.create(path, "") | ||
921 | 694 | self.fsm.set_node_id(path, "a_node_id") | ||
922 | 695 | |||
923 | 696 | # create a request and fill it with succesful information | ||
924 | 697 | aq_client = TestingProtocol() | ||
925 | 698 | request = client.PutContent(aq_client, self.share_id, | ||
926 | 699 | 'node', 'prvhash', 'newhash', 'crc32', | ||
927 | 700 | 'size', 'deflated', 'fd') | ||
928 | 701 | request.new_generation = 13 | ||
929 | 702 | |||
930 | 703 | # trigger success in the command | ||
931 | 704 | self.command.handle_success(request) | ||
932 | 705 | |||
933 | 706 | # check for successful event | ||
934 | 707 | kwargs = dict(share_id=self.command.share_id, node_id='a_node_id', | ||
935 | 708 | hash='yadda', new_generation=13) | ||
936 | 709 | |||
937 | 710 | events = [('AQ_UPLOAD_FINISHED', kwargs)] | ||
938 | 711 | self.assertEqual(events, self.command.action_queue.event_queue.events) | ||
939 | 712 | |||
940 | 713 | self.assertEqual(len(self.listener.zg.events), 1) | ||
941 | 714 | event = self.listener.zg.events[0] | ||
942 | 715 | |||
943 | 716 | self.assertEqual(event.interpretation, | ||
944 | 717 | Interpretation.MODIFY_EVENT) | ||
945 | 718 | self.assertEqual(event.manifestation, | ||
946 | 719 | Manifestation.SCHEDULED_ACTIVITY) | ||
947 | 720 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
948 | 721 | |||
949 | 722 | remote_file = event.subjects[0] | ||
950 | 723 | self.assertTrue(remote_file.uri.startswith(URI_PROTOCOL_U1)) | ||
951 | 724 | self.assertEqual(remote_file.interpretation, Interpretation.AUDIO) | ||
952 | 725 | self.assertEqual(remote_file.manifestation, | ||
953 | 726 | Manifestation.REMOTE_DATA_OBJECT) | ||
954 | 727 | self.assertTrue(remote_file.origin.endswith(filename)) | ||
955 | 728 | self.assertEqual(remote_file.text, filename) | ||
956 | 729 | self.assertEqual(remote_file.mimetype, "audio/mpeg") | ||
957 | 730 | self.assertEqual(remote_file.storage, STORAGE_NETWORK) | ||
958 | 731 | |||
959 | 732 | @defer.inlineCallbacks | ||
960 | 733 | def test_syncdaemon_deletes_file_on_server_is_logged(self): | ||
961 | 734 | """Files deleted by SD on the server are logged.""" | ||
962 | 735 | file_name = "filename.mp3" | ||
963 | 736 | d = defer.Deferred() | ||
964 | 737 | listen_for(self.main.event_q, 'AQ_UNLINK_OK', d.callback) | ||
965 | 738 | |||
966 | 739 | path = os.path.join(self.main.vm.root.path, "filename.mp3") | ||
967 | 740 | self.main.event_q.push("AQ_UNLINK_OK", share_id="", | ||
968 | 741 | parent_id="parent_id", | ||
969 | 742 | node_id="node_id", new_generation=13, | ||
970 | 743 | was_dir=False, old_path=path) | ||
971 | 744 | yield d | ||
972 | 745 | |||
973 | 746 | self.assertEqual(len(self.listener.zg.events), 1) | ||
974 | 747 | event = self.listener.zg.events[0] | ||
975 | 748 | |||
976 | 749 | self.assertEqual(event.interpretation, | ||
977 | 750 | Interpretation.DELETE_EVENT) | ||
978 | 751 | self.assertEqual(event.manifestation, | ||
979 | 752 | Manifestation.SCHEDULED_ACTIVITY) | ||
980 | 753 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
981 | 754 | |||
982 | 755 | remote_file = event.subjects[0] | ||
983 | 756 | self.assertTrue(remote_file.uri.startswith(URI_PROTOCOL_U1)) | ||
984 | 757 | self.assertEqual(remote_file.interpretation, Interpretation.AUDIO) | ||
985 | 758 | self.assertEqual(remote_file.manifestation, | ||
986 | 759 | Manifestation.DELETED_RESOURCE) | ||
987 | 760 | self.assertTrue(remote_file.origin.endswith(file_name)) | ||
988 | 761 | self.assertEqual(remote_file.text, file_name) | ||
989 | 762 | self.assertEqual(remote_file.mimetype, "audio/mpeg") | ||
990 | 763 | self.assertEqual(remote_file.storage, STORAGE_DELETED) | ||
991 | 764 | |||
992 | 765 | @defer.inlineCallbacks | ||
993 | 766 | def test_syncdaemon_deletes_dir_on_server_is_logged(self): | ||
994 | 767 | """Directories deleted by SD on the server are logged.""" | ||
995 | 768 | folder_name = "folder name" | ||
996 | 769 | d = defer.Deferred() | ||
997 | 770 | listen_for(self.main.event_q, 'AQ_UNLINK_OK', d.callback) | ||
998 | 771 | |||
999 | 772 | path = os.path.join(self.main.vm.root.path, "folder name") | ||
1000 | 773 | self.main.event_q.push("AQ_UNLINK_OK", share_id="", | ||
1001 | 774 | parent_id="parent_id", | ||
1002 | 775 | node_id="node_id", new_generation=13, | ||
1003 | 776 | was_dir=True, old_path=path) | ||
1004 | 777 | yield d | ||
1005 | 778 | |||
1006 | 779 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1007 | 780 | event = self.listener.zg.events[0] | ||
1008 | 781 | |||
1009 | 782 | self.assertEqual(event.interpretation, | ||
1010 | 783 | Interpretation.DELETE_EVENT) | ||
1011 | 784 | self.assertEqual(event.manifestation, | ||
1012 | 785 | Manifestation.SCHEDULED_ACTIVITY) | ||
1013 | 786 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1014 | 787 | |||
1015 | 788 | remote_folder = event.subjects[0] | ||
1016 | 789 | self.assertTrue(remote_folder.uri.startswith(URI_PROTOCOL_U1)) | ||
1017 | 790 | self.assertEqual(remote_folder.interpretation, Interpretation.FOLDER) | ||
1018 | 791 | self.assertEqual(remote_folder.manifestation, | ||
1019 | 792 | Manifestation.DELETED_RESOURCE) | ||
1020 | 793 | self.assertTrue(remote_folder.origin.endswith(folder_name)) | ||
1021 | 794 | self.assertEqual(remote_folder.text, folder_name) | ||
1022 | 795 | self.assertEqual(remote_folder.mimetype, DIRECTORY_MIMETYPE) | ||
1023 | 796 | self.assertEqual(remote_folder.storage, STORAGE_DELETED) | ||
1024 | 797 | |||
1025 | 798 | |||
1026 | 799 | class ZeitgeistLocalFileSyncTestCase(BaseTwistedTestCase): | ||
1027 | 800 | """Zeitgeist events coming from the server.""" | ||
1028 | 801 | timeout = 5 | ||
1029 | 802 | |||
1030 | 803 | @defer.inlineCallbacks | ||
1031 | 804 | def setUp(self): | ||
1032 | 805 | """Initialize this instance.""" | ||
1033 | 806 | yield super(ZeitgeistLocalFileSyncTestCase, self).setUp() | ||
1034 | 807 | self.root = self.mktemp('root') | ||
1035 | 808 | self.shares = self.mktemp('shares') | ||
1036 | 809 | self.data = self.mktemp('data') | ||
1037 | 810 | self.partials_dir = self.mktemp('partials_dir') | ||
1038 | 811 | self.handler = MementoHandler() | ||
1039 | 812 | self.handler.setLevel(logging.ERROR) | ||
1040 | 813 | FakeMain._sync_class = Sync | ||
1041 | 814 | self.main = FakeMain(root_dir=self.root, shares_dir=self.shares, | ||
1042 | 815 | data_dir=self.data, | ||
1043 | 816 | partials_dir=self.partials_dir) | ||
1044 | 817 | self._logger = logging.getLogger('ubuntuone.SyncDaemon') | ||
1045 | 818 | self._logger.addHandler(self.handler) | ||
1046 | 819 | |||
1047 | 820 | self.root_id = root_id = "roootid" | ||
1048 | 821 | self.main.vm._got_root(root_id) | ||
1049 | 822 | self.filemp3delta = delta.FileInfoDelta( | ||
1050 | 823 | generation=5, is_live=True, file_type=delta.FILE, | ||
1051 | 824 | parent_id=self.root_id, share_id=ROOT, node_id=uuid.uuid4(), | ||
1052 | 825 | name=u"fileñ.mp3", is_public=False, content_hash="hash", | ||
1053 | 826 | crc32=1, size=10, last_modified=0) | ||
1054 | 827 | |||
1055 | 828 | self.dirdelta = delta.FileInfoDelta( | ||
1056 | 829 | generation=6, is_live=True, file_type=delta.DIRECTORY, | ||
1057 | 830 | parent_id=root_id, share_id=ROOT, node_id=uuid.uuid4(), | ||
1058 | 831 | name=u"directory_ñ", is_public=False, content_hash="hash", | ||
1059 | 832 | crc32=1, size=10, last_modified=0) | ||
1060 | 833 | |||
1061 | 834 | self.patch(zglog, "ZeitgeistLogger", MockLogger) | ||
1062 | 835 | self.listener = ZeitgeistListener(self.main.fs, self.main.vm) | ||
1063 | 836 | self.main.event_q.subscribe(self.listener) | ||
1064 | 837 | |||
1065 | 838 | @defer.inlineCallbacks | ||
1066 | 839 | def tearDown(self): | ||
1067 | 840 | """Clean up this instance.""" | ||
1068 | 841 | self._logger.removeHandler(self.handler) | ||
1069 | 842 | self.main.shutdown() | ||
1070 | 843 | FakeMain._sync_class = None | ||
1071 | 844 | for record in self.handler.records: | ||
1072 | 845 | exc_info = getattr(record, 'exc_info', None) | ||
1073 | 846 | if exc_info is not None: | ||
1074 | 847 | raise exc_info[0], exc_info[1], exc_info[2] | ||
1075 | 848 | yield super(ZeitgeistLocalFileSyncTestCase, self).tearDown() | ||
1076 | 849 | |||
1077 | 850 | @defer.inlineCallbacks | ||
1078 | 851 | def test_syncdaemon_creates_file_locally_is_logged(self): | ||
1079 | 852 | """Files created locally by SyncDaemon are logged.""" | ||
1080 | 853 | file_name = self.filemp3delta.name.encode('utf8') | ||
1081 | 854 | d = defer.Deferred() | ||
1082 | 855 | d2 = defer.Deferred() | ||
1083 | 856 | listen_for(self.main.event_q, 'SV_FILE_NEW', d.callback) | ||
1084 | 857 | listen_for(self.main.event_q, 'AQ_DOWNLOAD_FINISHED', d2.callback) | ||
1085 | 858 | |||
1086 | 859 | deltas = [self.filemp3delta] | ||
1087 | 860 | kwargs = dict(volume_id=ROOT, delta_content=deltas, end_generation=11, | ||
1088 | 861 | full=True, free_bytes=10) | ||
1089 | 862 | self.main.sync.handle_AQ_DELTA_OK(**kwargs) | ||
1090 | 863 | |||
1091 | 864 | # check that the file is created | ||
1092 | 865 | node = self.main.fs.get_by_node_id(ROOT, self.filemp3delta.node_id) | ||
1093 | 866 | self.assertEqual(node.path, file_name) | ||
1094 | 867 | self.assertEqual(node.is_dir, False) | ||
1095 | 868 | self.assertEqual(node.generation, self.filemp3delta.generation) | ||
1096 | 869 | |||
1097 | 870 | yield d # wait for SV_FILE_NEW | ||
1098 | 871 | |||
1099 | 872 | dlargs = dict( | ||
1100 | 873 | share_id=self.filemp3delta.share_id, | ||
1101 | 874 | node_id=self.filemp3delta.node_id, | ||
1102 | 875 | server_hash="server hash") | ||
1103 | 876 | self.main.event_q.push("AQ_DOWNLOAD_FINISHED", **dlargs) | ||
1104 | 877 | |||
1105 | 878 | yield d2 # wait for AQ_DOWNLOAD_FINISHED | ||
1106 | 879 | |||
1107 | 880 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1108 | 881 | event = self.listener.zg.events[0] | ||
1109 | 882 | |||
1110 | 883 | self.assertEqual(event.interpretation, | ||
1111 | 884 | Interpretation.CREATE_EVENT) | ||
1112 | 885 | self.assertEqual(event.manifestation, | ||
1113 | 886 | Manifestation.WORLD_ACTIVITY) | ||
1114 | 887 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1115 | 888 | |||
1116 | 889 | local_file = event.subjects[0] | ||
1117 | 890 | self.assertTrue(local_file.uri.endswith(file_name)) | ||
1118 | 891 | self.assertEqual(local_file.interpretation, Interpretation.AUDIO) | ||
1119 | 892 | self.assertEqual(local_file.manifestation, | ||
1120 | 893 | Manifestation.FILE_DATA_OBJECT) | ||
1121 | 894 | self.assertTrue(local_file.origin.startswith(URI_PROTOCOL_U1)) | ||
1122 | 895 | self.assertEqual(local_file.text, file_name) | ||
1123 | 896 | self.assertEqual(local_file.mimetype, "audio/mpeg") | ||
1124 | 897 | self.assertEqual(local_file.storage, STORAGE_LOCAL) | ||
1125 | 898 | |||
1126 | 899 | @defer.inlineCallbacks | ||
1127 | 900 | def test_syncdaemon_creates_dir_locally_is_logged(self): | ||
1128 | 901 | """Dirs created locally by SyncDaemon are logged.""" | ||
1129 | 902 | folder_name = self.dirdelta.name.encode('utf8') | ||
1130 | 903 | d = defer.Deferred() | ||
1131 | 904 | listen_for(self.main.event_q, 'SV_DIR_NEW', d.callback) | ||
1132 | 905 | |||
1133 | 906 | deltas = [self.dirdelta] | ||
1134 | 907 | kwargs = dict(volume_id=ROOT, delta_content=deltas, end_generation=11, | ||
1135 | 908 | full=True, free_bytes=10) | ||
1136 | 909 | self.main.sync.handle_AQ_DELTA_OK(**kwargs) | ||
1137 | 910 | |||
1138 | 911 | # check that the dir is created | ||
1139 | 912 | node = self.main.fs.get_by_node_id(ROOT, self.dirdelta.node_id) | ||
1140 | 913 | self.assertEqual(node.path, folder_name) | ||
1141 | 914 | self.assertEqual(node.is_dir, True) | ||
1142 | 915 | self.assertEqual(node.generation, self.dirdelta.generation) | ||
1143 | 916 | |||
1144 | 917 | yield d # wait for SV_DIR_NEW | ||
1145 | 918 | |||
1146 | 919 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1147 | 920 | event = self.listener.zg.events[0] | ||
1148 | 921 | |||
1149 | 922 | self.assertEqual(event.interpretation, | ||
1150 | 923 | Interpretation.CREATE_EVENT) | ||
1151 | 924 | self.assertEqual(event.manifestation, | ||
1152 | 925 | Manifestation.WORLD_ACTIVITY) | ||
1153 | 926 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1154 | 927 | |||
1155 | 928 | local_folder = event.subjects[0] | ||
1156 | 929 | self.assertTrue(local_folder.uri.endswith(folder_name)) | ||
1157 | 930 | self.assertEqual(local_folder.interpretation, Interpretation.FOLDER) | ||
1158 | 931 | self.assertEqual(local_folder.manifestation, | ||
1159 | 932 | Manifestation.FILE_DATA_OBJECT) | ||
1160 | 933 | self.assertTrue(local_folder.origin.startswith(URI_PROTOCOL_U1)) | ||
1161 | 934 | self.assertEqual(local_folder.text, folder_name) | ||
1162 | 935 | self.assertEqual(local_folder.mimetype, DIRECTORY_MIMETYPE) | ||
1163 | 936 | self.assertEqual(local_folder.storage, STORAGE_LOCAL) | ||
1164 | 937 | |||
1165 | 938 | @defer.inlineCallbacks | ||
1166 | 939 | def test_syncdaemon_modifies_locally_is_logged(self): | ||
1167 | 940 | """Files modified locally by SyncDaemon are logged.""" | ||
1168 | 941 | file_name = self.filemp3delta.name.encode('utf8') | ||
1169 | 942 | d = defer.Deferred() | ||
1170 | 943 | d2 = defer.Deferred() | ||
1171 | 944 | listen_for(self.main.event_q, 'SV_FILE_NEW', d.callback) | ||
1172 | 945 | listen_for(self.main.event_q, 'AQ_DOWNLOAD_FINISHED', d2.callback) | ||
1173 | 946 | |||
1174 | 947 | deltas = [self.filemp3delta] | ||
1175 | 948 | kwargs = dict(volume_id=ROOT, delta_content=deltas, end_generation=11, | ||
1176 | 949 | full=True, free_bytes=10) | ||
1177 | 950 | self.main.sync.handle_AQ_DELTA_OK(**kwargs) | ||
1178 | 951 | |||
1179 | 952 | # check that the file is modified | ||
1180 | 953 | node = self.main.fs.get_by_node_id(ROOT, self.filemp3delta.node_id) | ||
1181 | 954 | self.assertEqual(node.path, file_name) | ||
1182 | 955 | self.assertEqual(node.is_dir, False) | ||
1183 | 956 | self.assertEqual(node.generation, self.filemp3delta.generation) | ||
1184 | 957 | |||
1185 | 958 | yield d # wait for SV_FILE_NEW | ||
1186 | 959 | |||
1187 | 960 | # remove from the recent list | ||
1188 | 961 | local_file_id = (self.filemp3delta.share_id, self.filemp3delta.node_id) | ||
1189 | 962 | self.listener.newly_created_local_files.remove(local_file_id) | ||
1190 | 963 | |||
1191 | 964 | dlargs = dict( | ||
1192 | 965 | share_id=self.filemp3delta.share_id, | ||
1193 | 966 | node_id=self.filemp3delta.node_id, | ||
1194 | 967 | server_hash="server hash") | ||
1195 | 968 | self.main.event_q.push("AQ_DOWNLOAD_FINISHED", **dlargs) | ||
1196 | 969 | |||
1197 | 970 | yield d2 # wait for AQ_DOWNLOAD_FINISHED | ||
1198 | 971 | |||
1199 | 972 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1200 | 973 | event = self.listener.zg.events[0] | ||
1201 | 974 | |||
1202 | 975 | self.assertEqual(event.interpretation, | ||
1203 | 976 | Interpretation.MODIFY_EVENT) | ||
1204 | 977 | self.assertEqual(event.manifestation, | ||
1205 | 978 | Manifestation.WORLD_ACTIVITY) | ||
1206 | 979 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1207 | 980 | |||
1208 | 981 | local_file = event.subjects[0] | ||
1209 | 982 | self.assertTrue(local_file.uri.endswith(file_name)) | ||
1210 | 983 | self.assertEqual(local_file.interpretation, Interpretation.AUDIO) | ||
1211 | 984 | self.assertEqual(local_file.manifestation, | ||
1212 | 985 | Manifestation.FILE_DATA_OBJECT) | ||
1213 | 986 | self.assertTrue(local_file.origin.startswith(URI_PROTOCOL_U1)) | ||
1214 | 987 | self.assertEqual(local_file.text, file_name) | ||
1215 | 988 | self.assertEqual(local_file.mimetype, "audio/mpeg") | ||
1216 | 989 | self.assertEqual(local_file.storage, STORAGE_LOCAL) | ||
1217 | 990 | |||
1218 | 991 | @defer.inlineCallbacks | ||
1219 | 992 | def test_syncdaemon_deletes_file_locally_is_logged(self): | ||
1220 | 993 | """Files deleted locally by SyncDaemon are logged.""" | ||
1221 | 994 | file_name = self.filemp3delta.name.encode("utf-8") | ||
1222 | 995 | d = defer.Deferred() | ||
1223 | 996 | listen_for(self.main.event_q, 'SV_FILE_DELETED', d.callback) | ||
1224 | 997 | |||
1225 | 998 | filename = self.filemp3delta.name.encode("utf-8") | ||
1226 | 999 | path = os.path.join(self.main.vm.root.path, filename) | ||
1227 | 1000 | self.main.event_q.push("SV_FILE_DELETED", volume_id="", | ||
1228 | 1001 | node_id="node_id", was_dir=False, | ||
1229 | 1002 | old_path=path) | ||
1230 | 1003 | yield d | ||
1231 | 1004 | |||
1232 | 1005 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1233 | 1006 | event = self.listener.zg.events[0] | ||
1234 | 1007 | |||
1235 | 1008 | self.assertEqual(event.interpretation, | ||
1236 | 1009 | Interpretation.DELETE_EVENT) | ||
1237 | 1010 | self.assertEqual(event.manifestation, | ||
1238 | 1011 | Manifestation.WORLD_ACTIVITY) | ||
1239 | 1012 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1240 | 1013 | |||
1241 | 1014 | local_file = event.subjects[0] | ||
1242 | 1015 | self.assertTrue(local_file.uri.endswith(file_name)) | ||
1243 | 1016 | self.assertEqual(local_file.interpretation, Interpretation.AUDIO) | ||
1244 | 1017 | self.assertEqual(local_file.manifestation, | ||
1245 | 1018 | Manifestation.DELETED_RESOURCE) | ||
1246 | 1019 | self.assertTrue(local_file.origin.startswith(URI_PROTOCOL_U1)) | ||
1247 | 1020 | self.assertEqual(local_file.text, file_name) | ||
1248 | 1021 | self.assertEqual(local_file.mimetype, "audio/mpeg") | ||
1249 | 1022 | self.assertEqual(local_file.storage, STORAGE_DELETED) | ||
1250 | 1023 | |||
1251 | 1024 | @defer.inlineCallbacks | ||
1252 | 1025 | def test_syncdaemon_deletes_dir_locally_is_logged(self): | ||
1253 | 1026 | """Dirs deleted locally by SyncDaemon are logged.""" | ||
1254 | 1027 | folder_name = "folder name" | ||
1255 | 1028 | d = defer.Deferred() | ||
1256 | 1029 | listen_for(self.main.event_q, 'SV_FILE_DELETED', d.callback) | ||
1257 | 1030 | |||
1258 | 1031 | path = os.path.join(self.main.vm.root.path, "folder name") | ||
1259 | 1032 | self.main.event_q.push("SV_FILE_DELETED", volume_id="", | ||
1260 | 1033 | node_id="node_id", was_dir=True, | ||
1261 | 1034 | old_path=path) | ||
1262 | 1035 | |||
1263 | 1036 | yield d | ||
1264 | 1037 | |||
1265 | 1038 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1266 | 1039 | event = self.listener.zg.events[0] | ||
1267 | 1040 | |||
1268 | 1041 | self.assertEqual(event.interpretation, | ||
1269 | 1042 | Interpretation.DELETE_EVENT) | ||
1270 | 1043 | self.assertEqual(event.manifestation, | ||
1271 | 1044 | Manifestation.WORLD_ACTIVITY) | ||
1272 | 1045 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1273 | 1046 | |||
1274 | 1047 | local_folder = event.subjects[0] | ||
1275 | 1048 | self.assertTrue(local_folder.uri.endswith(folder_name)) | ||
1276 | 1049 | self.assertEqual(local_folder.interpretation, Interpretation.FOLDER) | ||
1277 | 1050 | self.assertEqual(local_folder.manifestation, | ||
1278 | 1051 | Manifestation.DELETED_RESOURCE) | ||
1279 | 1052 | self.assertTrue(local_folder.origin.startswith(URI_PROTOCOL_U1)) | ||
1280 | 1053 | self.assertEqual(local_folder.text, folder_name) | ||
1281 | 1054 | self.assertEqual(local_folder.mimetype, DIRECTORY_MIMETYPE) | ||
1282 | 1055 | self.assertEqual(local_folder.storage, STORAGE_DELETED) | ||
1283 | 1056 | |||
1284 | 1057 | @defer.inlineCallbacks | ||
1285 | 1058 | def test_file_sync_conflict_is_logged(self): | ||
1286 | 1059 | """Files renamed because of conflict are logged.""" | ||
1287 | 1060 | file_name = "sample.mp3" | ||
1288 | 1061 | d = defer.Deferred() | ||
1289 | 1062 | listen_for(self.main.event_q, 'FSM_FILE_CONFLICT', d.callback) | ||
1290 | 1063 | |||
1291 | 1064 | testfile = os.path.join(self.main.vm.root.path, file_name) | ||
1292 | 1065 | mdid = self.main.fs.create(testfile, "") | ||
1293 | 1066 | self.main.fs.set_node_id(testfile, "uuid") | ||
1294 | 1067 | with open(testfile, "w") as fh: | ||
1295 | 1068 | fh.write("this is music!") | ||
1296 | 1069 | |||
1297 | 1070 | self.main.fs.move_to_conflict(mdid) | ||
1298 | 1071 | |||
1299 | 1072 | yield d | ||
1300 | 1073 | |||
1301 | 1074 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1302 | 1075 | event = self.listener.zg.events[0] | ||
1303 | 1076 | |||
1304 | 1077 | self.assertEqual(event.interpretation, | ||
1305 | 1078 | EVENT_INTERPRETATION_U1_CONFLICT_RENAME) | ||
1306 | 1079 | self.assertEqual(event.manifestation, | ||
1307 | 1080 | Manifestation.WORLD_ACTIVITY) | ||
1308 | 1081 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1309 | 1082 | |||
1310 | 1083 | local_file = event.subjects[0] | ||
1311 | 1084 | new_name = testfile + self.main.fs.CONFLICT_SUFFIX | ||
1312 | 1085 | self.assertTrue(local_file.uri.endswith(new_name)) | ||
1313 | 1086 | self.assertEqual(local_file.interpretation, Interpretation.AUDIO) | ||
1314 | 1087 | self.assertEqual(local_file.manifestation, | ||
1315 | 1088 | Manifestation.FILE_DATA_OBJECT) | ||
1316 | 1089 | self.assertTrue(local_file.origin.endswith(testfile)) | ||
1317 | 1090 | self.assertEqual(local_file.text, | ||
1318 | 1091 | file_name + self.main.fs.CONFLICT_SUFFIX) | ||
1319 | 1092 | self.assertEqual(local_file.mimetype, "audio/mpeg") | ||
1320 | 1093 | self.assertEqual(local_file.storage, STORAGE_LOCAL) | ||
1321 | 1094 | |||
1322 | 1095 | @defer.inlineCallbacks | ||
1323 | 1096 | def test_dir_sync_conflict_is_logged(self): | ||
1324 | 1097 | """Dirs renamed because of conflict are logged.""" | ||
1325 | 1098 | folder_name = "sampledir" | ||
1326 | 1099 | d = defer.Deferred() | ||
1327 | 1100 | listen_for(self.main.event_q, 'FSM_DIR_CONFLICT', d.callback) | ||
1328 | 1101 | |||
1329 | 1102 | testdir = os.path.join(self.main.vm.root.path, folder_name) | ||
1330 | 1103 | mdid = self.main.fs.create(testdir, "", is_dir=True) | ||
1331 | 1104 | self.main.fs.set_node_id(testdir, "uuid") | ||
1332 | 1105 | os.mkdir(testdir) | ||
1333 | 1106 | |||
1334 | 1107 | self.main.fs.move_to_conflict(mdid) | ||
1335 | 1108 | |||
1336 | 1109 | yield d | ||
1337 | 1110 | |||
1338 | 1111 | self.assertEqual(len(self.listener.zg.events), 1) | ||
1339 | 1112 | event = self.listener.zg.events[0] | ||
1340 | 1113 | |||
1341 | 1114 | self.assertEqual(event.interpretation, | ||
1342 | 1115 | EVENT_INTERPRETATION_U1_CONFLICT_RENAME) | ||
1343 | 1116 | self.assertEqual(event.manifestation, | ||
1344 | 1117 | Manifestation.WORLD_ACTIVITY) | ||
1345 | 1118 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1346 | 1119 | |||
1347 | 1120 | local_folder = event.subjects[0] | ||
1348 | 1121 | new_name = testdir + self.main.fs.CONFLICT_SUFFIX | ||
1349 | 1122 | self.assertTrue(local_folder.uri.endswith(new_name)) | ||
1350 | 1123 | self.assertEqual(local_folder.interpretation, Interpretation.FOLDER) | ||
1351 | 1124 | self.assertEqual(local_folder.manifestation, | ||
1352 | 1125 | Manifestation.FILE_DATA_OBJECT) | ||
1353 | 1126 | self.assertTrue(local_folder.origin.endswith(testdir)) | ||
1354 | 1127 | self.assertEqual(local_folder.text, | ||
1355 | 1128 | folder_name + self.main.fs.CONFLICT_SUFFIX) | ||
1356 | 1129 | self.assertEqual(local_folder.mimetype, DIRECTORY_MIMETYPE) | ||
1357 | 1130 | self.assertEqual(local_folder.storage, STORAGE_LOCAL) | ||
1358 | 1131 | |||
1359 | 1132 | |||
1360 | 1133 | class ZeitgeistPublicFilesTestCase(ZeitgeistListenerTestCase): | ||
1361 | 1134 | """Public files events are logged into Zeitgeist.""" | ||
1362 | 1135 | |||
1363 | 1136 | @defer.inlineCallbacks | ||
1364 | 1137 | def test_publish_url_is_logged(self): | ||
1365 | 1138 | """Publishing a file with a url is logged.""" | ||
1366 | 1139 | share_id = "share" | ||
1367 | 1140 | node_id = "node_id" | ||
1368 | 1141 | is_public = True | ||
1369 | 1142 | public_url = 'http://example.com/foo.mp3' | ||
1370 | 1143 | |||
1371 | 1144 | share_path = os.path.join(self.shares_dir, 'share') | ||
1372 | 1145 | yield self.main.vm.add_share(Share(path=share_path, volume_id='share', | ||
1373 | 1146 | other_username='other username')) | ||
1374 | 1147 | path = os.path.join(share_path, "foo.mp3") | ||
1375 | 1148 | self.main.fs.create(path, str(share_id)) | ||
1376 | 1149 | self.main.fs.set_node_id(path, str(node_id)) | ||
1377 | 1150 | |||
1378 | 1151 | d = defer.Deferred() | ||
1379 | 1152 | self._listen_for('AQ_CHANGE_PUBLIC_ACCESS_OK', d.callback) | ||
1380 | 1153 | self.main.event_q.push('AQ_CHANGE_PUBLIC_ACCESS_OK', | ||
1381 | 1154 | share_id=share_id, node_id=node_id, | ||
1382 | 1155 | is_public=is_public, public_url=public_url) | ||
1383 | 1156 | yield d | ||
1384 | 1157 | |||
1385 | 1158 | self.assertEqual(len(self.listener.zg.events), 2) | ||
1386 | 1159 | event = self.listener.zg.events[1] | ||
1387 | 1160 | |||
1388 | 1161 | self.assertEqual(event.interpretation, | ||
1389 | 1162 | Interpretation.CREATE_EVENT) | ||
1390 | 1163 | self.assertEqual(event.manifestation, | ||
1391 | 1164 | Manifestation.USER_ACTIVITY) | ||
1392 | 1165 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1393 | 1166 | |||
1394 | 1167 | public_file = event.subjects[0] | ||
1395 | 1168 | self.assertEqual(public_file.uri, public_url) | ||
1396 | 1169 | self.assertEqual(public_file.interpretation, Interpretation.AUDIO) | ||
1397 | 1170 | self.assertEqual(public_file.manifestation, | ||
1398 | 1171 | Manifestation.REMOTE_DATA_OBJECT) | ||
1399 | 1172 | self.assertTrue(public_file.origin.endswith(node_id)) | ||
1400 | 1173 | self.assertEqual(public_file.text, public_url) | ||
1401 | 1174 | self.assertEqual(public_file.mimetype, "audio/mpeg") | ||
1402 | 1175 | self.assertEqual(public_file.storage, STORAGE_NETWORK) | ||
1403 | 1176 | |||
1404 | 1177 | @defer.inlineCallbacks | ||
1405 | 1178 | def test_unpublish_url_is_logged(self): | ||
1406 | 1179 | """Unpublishing a file with a url is logged.""" | ||
1407 | 1180 | share_id = "share" | ||
1408 | 1181 | node_id = "node_id" | ||
1409 | 1182 | is_public = False | ||
1410 | 1183 | public_url = 'http://example.com/foo.mp3' | ||
1411 | 1184 | |||
1412 | 1185 | share_path = os.path.join(self.shares_dir, 'share') | ||
1413 | 1186 | yield self.main.vm.add_share(Share(path=share_path, volume_id='share', | ||
1414 | 1187 | other_username='other username')) | ||
1415 | 1188 | path = os.path.join(share_path, "foo.mp3") | ||
1416 | 1189 | self.main.fs.create(path, str(share_id)) | ||
1417 | 1190 | self.main.fs.set_node_id(path, str(node_id)) | ||
1418 | 1191 | |||
1419 | 1192 | d = defer.Deferred() | ||
1420 | 1193 | self._listen_for('AQ_CHANGE_PUBLIC_ACCESS_OK', d.callback) | ||
1421 | 1194 | self.main.event_q.push('AQ_CHANGE_PUBLIC_ACCESS_OK', | ||
1422 | 1195 | share_id=share_id, node_id=node_id, | ||
1423 | 1196 | is_public=is_public, public_url=public_url) | ||
1424 | 1197 | yield d | ||
1425 | 1198 | |||
1426 | 1199 | self.assertEqual(len(self.listener.zg.events), 2) | ||
1427 | 1200 | event = self.listener.zg.events[1] | ||
1428 | 1201 | |||
1429 | 1202 | self.assertEqual(event.interpretation, | ||
1430 | 1203 | Interpretation.DELETE_EVENT) | ||
1431 | 1204 | self.assertEqual(event.manifestation, | ||
1432 | 1205 | Manifestation.USER_ACTIVITY) | ||
1433 | 1206 | self.assertEqual(event.actor, ACTOR_UBUNTUONE) | ||
1434 | 1207 | |||
1435 | 1208 | public_file = event.subjects[0] | ||
1436 | 1209 | self.assertEqual(public_file.uri, public_url) | ||
1437 | 1210 | self.assertEqual(public_file.interpretation, Interpretation.AUDIO) | ||
1438 | 1211 | self.assertEqual(public_file.manifestation, | ||
1439 | 1212 | Manifestation.DELETED_RESOURCE) | ||
1440 | 1213 | self.assertTrue(public_file.origin.endswith(node_id)) | ||
1441 | 1214 | self.assertEqual(public_file.text, public_url) | ||
1442 | 1215 | self.assertEqual(public_file.mimetype, "audio/mpeg") | ||
1443 | 1216 | self.assertEqual(public_file.storage, STORAGE_DELETED) | ||
1444 | 1217 | 0 | ||
1445 | === removed file 'tests/platform/linux/eventlog/test_zglog.py' | |||
1446 | --- tests/platform/linux/eventlog/test_zglog.py 2012-04-30 14:24:55 +0000 | |||
1447 | +++ tests/platform/linux/eventlog/test_zglog.py 1970-01-01 00:00:00 +0000 | |||
1448 | @@ -1,174 +0,0 @@ | |||
1449 | 1 | # -*- coding: utf-8 -*- | ||
1450 | 2 | # | ||
1451 | 3 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
1452 | 4 | # | ||
1453 | 5 | # Copyright 2010-2012 Canonical Ltd. | ||
1454 | 6 | # | ||
1455 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
1456 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
1457 | 9 | # by the Free Software Foundation. | ||
1458 | 10 | # | ||
1459 | 11 | # This program is distributed in the hope that it will be useful, but | ||
1460 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1461 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1462 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
1463 | 15 | # | ||
1464 | 16 | # You should have received a copy of the GNU General Public License along | ||
1465 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1466 | 18 | # | ||
1467 | 19 | # In addition, as a special exception, the copyright holders give | ||
1468 | 20 | # permission to link the code of portions of this program with the | ||
1469 | 21 | # OpenSSL library under certain conditions as described in each | ||
1470 | 22 | # individual source file, and distribute linked combinations | ||
1471 | 23 | # including the two. | ||
1472 | 24 | # You must obey the GNU General Public License in all respects | ||
1473 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
1474 | 26 | # file(s) with this exception, you may extend this exception to your | ||
1475 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
1476 | 28 | # do not wish to do so, delete this exception statement from your | ||
1477 | 29 | # version. If you delete this exception statement from all source | ||
1478 | 30 | # files in the program, then also delete it here. | ||
1479 | 31 | """Tests for the Zeitgeist logging.""" | ||
1480 | 32 | |||
1481 | 33 | import os | ||
1482 | 34 | import shutil | ||
1483 | 35 | import subprocess | ||
1484 | 36 | import tempfile | ||
1485 | 37 | import time | ||
1486 | 38 | |||
1487 | 39 | from distutils.spawn import find_executable | ||
1488 | 40 | |||
1489 | 41 | from twisted.internet import defer | ||
1490 | 42 | from zeitgeist.client import ZeitgeistClient | ||
1491 | 43 | from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation | ||
1492 | 44 | |||
1493 | 45 | from tests.platform.ipc.test_linux import DBusTwistedTestCase | ||
1494 | 46 | from ubuntuone.eventlog.zglog import ZeitgeistLogger | ||
1495 | 47 | |||
1496 | 48 | SRCDIR = os.environ.get('SRCDIR', os.getcwd()) | ||
1497 | 49 | |||
1498 | 50 | |||
1499 | 51 | class NotFoundError(Exception): | ||
1500 | 52 | """Not found error.""" | ||
1501 | 53 | |||
1502 | 54 | |||
1503 | 55 | class ZeitgeistNotStartedTests(DBusTwistedTestCase): | ||
1504 | 56 | """Tests for the zeitgeist logging module.""" | ||
1505 | 57 | |||
1506 | 58 | def test_log_does_not_err_when_daemon_not_started(self): | ||
1507 | 59 | """zeitgeist-daemon was not started.""" | ||
1508 | 60 | timestamp = int(time.time() * 1000) | ||
1509 | 61 | subject = Subject.new_for_values( | ||
1510 | 62 | uri="file:///tmp/folder1", | ||
1511 | 63 | interpretation=Interpretation.FOLDER, | ||
1512 | 64 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
1513 | 65 | origin="ubuntuone:uuid", | ||
1514 | 66 | mimetype="inode/directory", | ||
1515 | 67 | text="sample folder" | ||
1516 | 68 | ) | ||
1517 | 69 | sample_event = Event.new_for_values( | ||
1518 | 70 | timestamp=timestamp, | ||
1519 | 71 | interpretation=Interpretation.ACCESS_EVENT, | ||
1520 | 72 | manifestation=Manifestation.USER_ACTIVITY, | ||
1521 | 73 | actor="mailto:sample_subject", | ||
1522 | 74 | subjects=[subject] | ||
1523 | 75 | ) | ||
1524 | 76 | |||
1525 | 77 | zg = ZeitgeistLogger() | ||
1526 | 78 | d = zg.log(sample_event) | ||
1527 | 79 | self.assertEqual(zg.client, None) | ||
1528 | 80 | |||
1529 | 81 | def verify(result): | ||
1530 | 82 | """Stored result is the empty list, because zg not available.""" | ||
1531 | 83 | self.assertEqual(result, []) | ||
1532 | 84 | return result | ||
1533 | 85 | |||
1534 | 86 | d.addCallback(verify) | ||
1535 | 87 | return d | ||
1536 | 88 | |||
1537 | 89 | |||
1538 | 90 | def wait_zeitgeist_started(seconds=10): | ||
1539 | 91 | """Wait a few seconds until zg is started, or fail if it can't.""" | ||
1540 | 92 | client = None | ||
1541 | 93 | count = 0 | ||
1542 | 94 | while client is None: | ||
1543 | 95 | count += 1 | ||
1544 | 96 | try: | ||
1545 | 97 | client = ZeitgeistClient() | ||
1546 | 98 | break | ||
1547 | 99 | except RuntimeError: | ||
1548 | 100 | if count > seconds * 10: | ||
1549 | 101 | raise | ||
1550 | 102 | time.sleep(0.1) | ||
1551 | 103 | |||
1552 | 104 | |||
1553 | 105 | class ZeitgeistTestCase(DBusTwistedTestCase): | ||
1554 | 106 | """Tests for the zeitgeist logging module.""" | ||
1555 | 107 | |||
1556 | 108 | @defer.inlineCallbacks | ||
1557 | 109 | def setUp(self): | ||
1558 | 110 | yield super(ZeitgeistTestCase, self).setUp() | ||
1559 | 111 | zgdaemon = find_executable("zeitgeist-daemon") | ||
1560 | 112 | if not zgdaemon: | ||
1561 | 113 | raise NotFoundError("zeitgeist-daemon was not found.") | ||
1562 | 114 | |||
1563 | 115 | tempfolder = tempfile.mkdtemp(prefix="test-u1-zeitgeist-") | ||
1564 | 116 | tempstdout = tempfile.TemporaryFile(prefix="test-u1-stdout-") | ||
1565 | 117 | tempstderr = tempfile.TemporaryFile(prefix="test-u1-stderr-") | ||
1566 | 118 | os.environ["ZEITGEIST_DATA_PATH"] = tempfolder | ||
1567 | 119 | p = subprocess.Popen([zgdaemon], bufsize=4096, stdout=tempstdout, | ||
1568 | 120 | stderr=tempstderr) | ||
1569 | 121 | |||
1570 | 122 | def cleanup(): | ||
1571 | 123 | """Wait for the process to finish.""" | ||
1572 | 124 | p.terminate() | ||
1573 | 125 | p.wait() | ||
1574 | 126 | del(os.environ["ZEITGEIST_DATA_PATH"]) | ||
1575 | 127 | shutil.rmtree(tempfolder) | ||
1576 | 128 | |||
1577 | 129 | wait_zeitgeist_started() | ||
1578 | 130 | self.addCleanup(cleanup) | ||
1579 | 131 | |||
1580 | 132 | def test_log_records_the_event(self): | ||
1581 | 133 | """The log method records the event in zg.""" | ||
1582 | 134 | timestamp = int(time.time() * 1000) | ||
1583 | 135 | subject = Subject.new_for_values( | ||
1584 | 136 | uri="file:///tmp/folder1", | ||
1585 | 137 | interpretation=Interpretation.FOLDER, | ||
1586 | 138 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
1587 | 139 | origin="ubuntuone:uuid", | ||
1588 | 140 | mimetype="inode/directory", | ||
1589 | 141 | text="sample folder" | ||
1590 | 142 | ) | ||
1591 | 143 | sample_event = Event.new_for_values( | ||
1592 | 144 | timestamp=timestamp, | ||
1593 | 145 | interpretation=Interpretation.ACCESS_EVENT, | ||
1594 | 146 | manifestation=Manifestation.USER_ACTIVITY, | ||
1595 | 147 | actor="mailto:sample_subject", | ||
1596 | 148 | subjects=[subject] | ||
1597 | 149 | ) | ||
1598 | 150 | |||
1599 | 151 | sample_template = Event.new_for_values() | ||
1600 | 152 | |||
1601 | 153 | zg = ZeitgeistLogger() | ||
1602 | 154 | self.assertNotEqual(zg.client, None) | ||
1603 | 155 | |||
1604 | 156 | d2 = defer.Deferred() | ||
1605 | 157 | |||
1606 | 158 | def logged(id_list): | ||
1607 | 159 | """The event was logged to zeitgeist.""" | ||
1608 | 160 | |||
1609 | 161 | def events_found(event_list): | ||
1610 | 162 | """zg returned the list of events.""" | ||
1611 | 163 | self.assertEqual(event_list[0].id, id_list[0]) | ||
1612 | 164 | d2.callback("ok") | ||
1613 | 165 | |||
1614 | 166 | zg.client.find_events_for_template(sample_template, events_found) | ||
1615 | 167 | |||
1616 | 168 | d = zg.log(sample_event) | ||
1617 | 169 | d.addCallbacks(logged, d2.errback) | ||
1618 | 170 | |||
1619 | 171 | return d2 | ||
1620 | 172 | |||
1621 | 173 | |||
1622 | 174 | ZeitgeistTestCase.skip = 'Suite is hanging in nightlies build (LP: #929812).' | ||
1623 | 175 | 0 | ||
1624 | === modified file 'tests/syncdaemon/test_main.py' | |||
1625 | --- tests/syncdaemon/test_main.py 2013-01-16 23:57:30 +0000 | |||
1626 | +++ tests/syncdaemon/test_main.py 2013-02-04 16:10:53 +0000 | |||
1627 | @@ -83,8 +83,6 @@ | |||
1628 | 83 | self.partials_dir = self.mktemp('partials_dir') | 83 | self.partials_dir = self.mktemp('partials_dir') |
1629 | 84 | 84 | ||
1630 | 85 | self.patch(main_mod, 'SyncdaemonService', FakedExternalInterface) | 85 | self.patch(main_mod, 'SyncdaemonService', FakedExternalInterface) |
1631 | 86 | # no event logger by default | ||
1632 | 87 | self.patch(main_mod.event_logging, "get_listener", lambda *a: None) | ||
1633 | 88 | # no status listener by default | 86 | # no status listener by default |
1634 | 89 | self.patch(main_mod.status_listener, "get_listener", lambda *a: None) | 87 | self.patch(main_mod.status_listener, "get_listener", lambda *a: None) |
1635 | 90 | 88 | ||
1636 | @@ -257,18 +255,6 @@ | |||
1637 | 257 | s.add(x) | 255 | s.add(x) |
1638 | 258 | return s | 256 | return s |
1639 | 259 | 257 | ||
1640 | 260 | def test_event_logger_starts_if_available(self): | ||
1641 | 261 | """The event logger is started if available.""" | ||
1642 | 262 | self.patch(main_mod.event_logging, | ||
1643 | 263 | "get_listener", lambda *a: FakeListener()) | ||
1644 | 264 | main = self.build_main() | ||
1645 | 265 | self.assertIn(main.eventlog_listener, self._get_listeners(main)) | ||
1646 | 266 | |||
1647 | 267 | def test_event_logger_not_started_if_not_available(self): | ||
1648 | 268 | """The event logger is not started if it's not available.""" | ||
1649 | 269 | main = self.build_main() | ||
1650 | 270 | self.assertNotIn(main.eventlog_listener, self._get_listeners(main)) | ||
1651 | 271 | |||
1652 | 272 | def test_status_listener_is_installed(self): | 258 | def test_status_listener_is_installed(self): |
1653 | 273 | """The status listener is installed if needed.""" | 259 | """The status listener is installed if needed.""" |
1654 | 274 | self.patch(main_mod.status_listener, | 260 | self.patch(main_mod.status_listener, |
1655 | 275 | 261 | ||
1656 | === modified file 'tests/syncdaemon/test_status_listener.py' | |||
1657 | --- tests/syncdaemon/test_status_listener.py 2012-09-20 18:04:58 +0000 | |||
1658 | +++ tests/syncdaemon/test_status_listener.py 2013-02-04 16:10:53 +0000 | |||
1659 | @@ -54,12 +54,6 @@ | |||
1660 | 54 | self.assertEqual(listener.vm, vm) | 54 | self.assertEqual(listener.vm, vm) |
1661 | 55 | self.assertNotEqual(listener.status_frontend, None) | 55 | self.assertNotEqual(listener.status_frontend, None) |
1662 | 56 | 56 | ||
1663 | 57 | def test_zeitgeist_not_installed_returns_none(self): | ||
1664 | 58 | """get_listener returns None if status reporting is disabled.""" | ||
1665 | 59 | self.patch(status_listener, "should_start_listener", lambda: False) | ||
1666 | 60 | listener = status_listener.get_listener(None, None) | ||
1667 | 61 | self.assertEqual(listener, None) | ||
1668 | 62 | |||
1669 | 63 | 57 | ||
1670 | 64 | def listen_for(event_q, event, callback, count=1, collect=False): | 58 | def listen_for(event_q, event, callback, count=1, collect=False): |
1671 | 65 | """Setup a EQ listener for the specified event.""" | 59 | """Setup a EQ listener for the specified event.""" |
1672 | 66 | 60 | ||
1673 | === removed directory 'ubuntuone/eventlog' | |||
1674 | === removed file 'ubuntuone/eventlog/__init__.py' | |||
1675 | --- ubuntuone/eventlog/__init__.py 2012-04-09 20:07:05 +0000 | |||
1676 | +++ ubuntuone/eventlog/__init__.py 1970-01-01 00:00:00 +0000 | |||
1677 | @@ -1,29 +0,0 @@ | |||
1678 | 1 | # ubuntuone.eventlog - Ubuntu One event logging modules | ||
1679 | 2 | # | ||
1680 | 3 | # Copyright 2010-2012 Canonical Ltd. | ||
1681 | 4 | # | ||
1682 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
1683 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
1684 | 7 | # by the Free Software Foundation. | ||
1685 | 8 | # | ||
1686 | 9 | # This program is distributed in the hope that it will be useful, but | ||
1687 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1688 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1689 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
1690 | 13 | # | ||
1691 | 14 | # You should have received a copy of the GNU General Public License along | ||
1692 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1693 | 16 | # | ||
1694 | 17 | # In addition, as a special exception, the copyright holders give | ||
1695 | 18 | # permission to link the code of portions of this program with the | ||
1696 | 19 | # OpenSSL library under certain conditions as described in each | ||
1697 | 20 | # individual source file, and distribute linked combinations | ||
1698 | 21 | # including the two. | ||
1699 | 22 | # You must obey the GNU General Public License in all respects | ||
1700 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
1701 | 24 | # file(s) with this exception, you may extend this exception to your | ||
1702 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
1703 | 26 | # do not wish to do so, delete this exception statement from your | ||
1704 | 27 | # version. If you delete this exception statement from all source | ||
1705 | 28 | # files in the program, then also delete it here. | ||
1706 | 29 | """Event logging module.""" | ||
1707 | 30 | 0 | ||
1708 | === removed file 'ubuntuone/eventlog/zg_listener.py' | |||
1709 | --- ubuntuone/eventlog/zg_listener.py 2012-04-09 20:07:05 +0000 | |||
1710 | +++ ubuntuone/eventlog/zg_listener.py 1970-01-01 00:00:00 +0000 | |||
1711 | @@ -1,556 +0,0 @@ | |||
1712 | 1 | # ubuntuone.eventlog.zg_listener - listen for SD events, log into ZG | ||
1713 | 2 | # | ||
1714 | 3 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
1715 | 4 | # | ||
1716 | 5 | # Copyright 2010-2012 Canonical Ltd. | ||
1717 | 6 | # | ||
1718 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
1719 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
1720 | 9 | # by the Free Software Foundation. | ||
1721 | 10 | # | ||
1722 | 11 | # This program is distributed in the hope that it will be useful, but | ||
1723 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1724 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1725 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
1726 | 15 | # | ||
1727 | 16 | # You should have received a copy of the GNU General Public License along | ||
1728 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1729 | 18 | # | ||
1730 | 19 | # In addition, as a special exception, the copyright holders give | ||
1731 | 20 | # permission to link the code of portions of this program with the | ||
1732 | 21 | # OpenSSL library under certain conditions as described in each | ||
1733 | 22 | # individual source file, and distribute linked combinations | ||
1734 | 23 | # including the two. | ||
1735 | 24 | # You must obey the GNU General Public License in all respects | ||
1736 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
1737 | 26 | # file(s) with this exception, you may extend this exception to your | ||
1738 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
1739 | 28 | # do not wish to do so, delete this exception statement from your | ||
1740 | 29 | # version. If you delete this exception statement from all source | ||
1741 | 30 | # files in the program, then also delete it here. | ||
1742 | 31 | """Event logging from SyncDaemon into Zeitgeist.""" | ||
1743 | 32 | |||
1744 | 33 | import mimetypes | ||
1745 | 34 | |||
1746 | 35 | from os.path import basename | ||
1747 | 36 | |||
1748 | 37 | from zeitgeist.datamodel import Event, Interpretation, Manifestation, Subject | ||
1749 | 38 | from zeitgeist.mimetypes import get_interpretation_for_mimetype | ||
1750 | 39 | |||
1751 | 40 | from ubuntuone.eventlog import zglog | ||
1752 | 41 | from ubuntuone.syncdaemon.volume_manager import Share, UDF | ||
1753 | 42 | |||
1754 | 43 | ACTOR_UBUNTUONE = "dbus://com.ubuntuone.SyncDaemon.service" | ||
1755 | 44 | DIRECTORY_MIMETYPE = "inode/directory" | ||
1756 | 45 | DEFAULT_MIME = "application/octet-stream" | ||
1757 | 46 | DEFAULT_INTERPRETATION = Interpretation.DOCUMENT | ||
1758 | 47 | EVENT_INTERPRETATION_U1_FOLDER_SHARED = "u1://FolderShared" | ||
1759 | 48 | EVENT_INTERPRETATION_U1_FOLDER_UNSHARED = "u1://FolderUnshared" | ||
1760 | 49 | EVENT_INTERPRETATION_U1_SHARE_ACCEPTED = "u1://ShareAccepted" | ||
1761 | 50 | EVENT_INTERPRETATION_U1_SHARE_UNACCEPTED = "u1://ShareUnaccepted" | ||
1762 | 51 | EVENT_INTERPRETATION_U1_CONFLICT_RENAME = "u1://ConflictRename" | ||
1763 | 52 | EVENT_INTERPRETATION_U1_UDF_CREATED = "u1://UserFolderCreated" | ||
1764 | 53 | EVENT_INTERPRETATION_U1_UDF_DELETED = "u1://UserFolderDeleted" | ||
1765 | 54 | EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED = "u1://UserFolderSubscribed" | ||
1766 | 55 | EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED = "u1://UserFolderUnsubscribed" | ||
1767 | 56 | MANIFESTATION_U1_CONTACT_DATA_OBJECT = "u1://ContactDataObject" | ||
1768 | 57 | INTERPRETATION_U1_CONTACT = "u1://Contact" | ||
1769 | 58 | URI_PROTOCOL_U1 = "ubuntuone:" | ||
1770 | 59 | STORAGE_LOCAL = "" | ||
1771 | 60 | STORAGE_NETWORK = "net" | ||
1772 | 61 | STORAGE_DELETED = "deleted" | ||
1773 | 62 | |||
1774 | 63 | |||
1775 | 64 | class ZeitgeistListener(object): | ||
1776 | 65 | """An Event Queue listener that logs into ZG.""" | ||
1777 | 66 | |||
1778 | 67 | def __init__(self, fsm, vm): | ||
1779 | 68 | """Initialize this instance.""" | ||
1780 | 69 | self.fsm = fsm | ||
1781 | 70 | self.vm = vm | ||
1782 | 71 | self.zg = zglog.ZeitgeistLogger() | ||
1783 | 72 | self.newly_created_server_files = set() | ||
1784 | 73 | self.newly_created_local_files = set() | ||
1785 | 74 | |||
1786 | 75 | def handle_AQ_CREATE_SHARE_OK(self, share_id, marker): | ||
1787 | 76 | """Log the 'directory shared thru the server' event.""" | ||
1788 | 77 | share_id = str(share_id) | ||
1789 | 78 | share = self.vm.shared.get(share_id) | ||
1790 | 79 | if not share: | ||
1791 | 80 | share = self.vm.marker_share_map[marker] | ||
1792 | 81 | share_id = share.node_id | ||
1793 | 82 | self.log_folder_shared(share, share_id) | ||
1794 | 83 | |||
1795 | 84 | def handle_AQ_SHARE_INVITATION_SENT(self, marker): | ||
1796 | 85 | """Log the 'directory shared thru http' event.""" | ||
1797 | 86 | share = self.vm.marker_share_map[marker] | ||
1798 | 87 | mdo = self.fsm.get_by_mdid(marker) | ||
1799 | 88 | self.log_folder_shared(share, mdo.share_id) | ||
1800 | 89 | |||
1801 | 90 | def log_folder_shared(self, share, share_id): | ||
1802 | 91 | """Log the 'directory shared' event.""" | ||
1803 | 92 | fullpath = share.path | ||
1804 | 93 | folder_name = basename(fullpath) | ||
1805 | 94 | |||
1806 | 95 | folder = Subject.new_for_values( | ||
1807 | 96 | uri=URI_PROTOCOL_U1 + str(share.node_id), | ||
1808 | 97 | interpretation=Interpretation.FOLDER, | ||
1809 | 98 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
1810 | 99 | origin="file:///" + fullpath, | ||
1811 | 100 | text=folder_name, | ||
1812 | 101 | mimetype=DIRECTORY_MIMETYPE, | ||
1813 | 102 | storage=STORAGE_NETWORK) | ||
1814 | 103 | |||
1815 | 104 | other_username = share.other_username | ||
1816 | 105 | other_user = Subject.new_for_values( | ||
1817 | 106 | uri="mailto:" + other_username, | ||
1818 | 107 | interpretation=INTERPRETATION_U1_CONTACT, | ||
1819 | 108 | text=other_username, | ||
1820 | 109 | manifestation=MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
1821 | 110 | |||
1822 | 111 | event = Event.new_for_values( | ||
1823 | 112 | interpretation=EVENT_INTERPRETATION_U1_FOLDER_SHARED, | ||
1824 | 113 | manifestation=Manifestation.USER_ACTIVITY, | ||
1825 | 114 | actor=ACTOR_UBUNTUONE, | ||
1826 | 115 | subjects=[folder, other_user]) | ||
1827 | 116 | |||
1828 | 117 | self.zg.log(event) | ||
1829 | 118 | |||
1830 | 119 | def handle_VM_SHARE_DELETED(self, share): | ||
1831 | 120 | """Log the share deleted event.""" | ||
1832 | 121 | folder = Subject.new_for_values( | ||
1833 | 122 | uri=URI_PROTOCOL_U1 + str(share.node_id), | ||
1834 | 123 | interpretation=Interpretation.FOLDER, | ||
1835 | 124 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
1836 | 125 | origin="file:///" + share.path, | ||
1837 | 126 | text=basename(share.path), | ||
1838 | 127 | mimetype=DIRECTORY_MIMETYPE, | ||
1839 | 128 | storage=STORAGE_NETWORK) | ||
1840 | 129 | |||
1841 | 130 | other_username = share.other_username | ||
1842 | 131 | other_user = Subject.new_for_values( | ||
1843 | 132 | uri="mailto:" + other_username, | ||
1844 | 133 | interpretation=INTERPRETATION_U1_CONTACT, | ||
1845 | 134 | text=other_username, | ||
1846 | 135 | manifestation=MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
1847 | 136 | |||
1848 | 137 | event = Event.new_for_values( | ||
1849 | 138 | interpretation=EVENT_INTERPRETATION_U1_FOLDER_UNSHARED, | ||
1850 | 139 | manifestation=Manifestation.USER_ACTIVITY, | ||
1851 | 140 | actor=ACTOR_UBUNTUONE, | ||
1852 | 141 | subjects=[folder, other_user]) | ||
1853 | 142 | |||
1854 | 143 | self.zg.log(event) | ||
1855 | 144 | |||
1856 | 145 | def handle_VM_SHARE_CREATED(self, share_id): | ||
1857 | 146 | """Log the share accepted event.""" | ||
1858 | 147 | share = self.vm.shares[share_id] | ||
1859 | 148 | |||
1860 | 149 | folder = Subject.new_for_values( | ||
1861 | 150 | uri=URI_PROTOCOL_U1 + str(share.node_id), | ||
1862 | 151 | interpretation=Interpretation.FOLDER, | ||
1863 | 152 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
1864 | 153 | origin="file:///" + share.path, | ||
1865 | 154 | text=basename(share.path), | ||
1866 | 155 | mimetype=DIRECTORY_MIMETYPE, | ||
1867 | 156 | storage=STORAGE_NETWORK) | ||
1868 | 157 | |||
1869 | 158 | other_username = share.other_username | ||
1870 | 159 | other_user = Subject.new_for_values( | ||
1871 | 160 | uri="mailto:" + other_username, | ||
1872 | 161 | interpretation=INTERPRETATION_U1_CONTACT, | ||
1873 | 162 | text=other_username, | ||
1874 | 163 | manifestation=MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
1875 | 164 | |||
1876 | 165 | event = Event.new_for_values( | ||
1877 | 166 | interpretation=EVENT_INTERPRETATION_U1_SHARE_ACCEPTED, | ||
1878 | 167 | manifestation=Manifestation.USER_ACTIVITY, | ||
1879 | 168 | actor=ACTOR_UBUNTUONE, | ||
1880 | 169 | subjects=[folder, other_user]) | ||
1881 | 170 | |||
1882 | 171 | self.zg.log(event) | ||
1883 | 172 | |||
1884 | 173 | def log_share_unaccepted(self, share): | ||
1885 | 174 | """Log the share unaccepted event.""" | ||
1886 | 175 | folder = Subject.new_for_values( | ||
1887 | 176 | uri=URI_PROTOCOL_U1 + str(share.node_id), | ||
1888 | 177 | interpretation=Interpretation.FOLDER, | ||
1889 | 178 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
1890 | 179 | origin="file:///" + share.path, | ||
1891 | 180 | text=basename(share.path), | ||
1892 | 181 | mimetype=DIRECTORY_MIMETYPE, | ||
1893 | 182 | storage=STORAGE_NETWORK) | ||
1894 | 183 | |||
1895 | 184 | other_username = share.other_username | ||
1896 | 185 | other_user = Subject.new_for_values( | ||
1897 | 186 | uri="mailto:" + other_username, | ||
1898 | 187 | interpretation=INTERPRETATION_U1_CONTACT, | ||
1899 | 188 | text=other_username, | ||
1900 | 189 | manifestation=MANIFESTATION_U1_CONTACT_DATA_OBJECT) | ||
1901 | 190 | |||
1902 | 191 | event = Event.new_for_values( | ||
1903 | 192 | interpretation=EVENT_INTERPRETATION_U1_SHARE_UNACCEPTED, | ||
1904 | 193 | manifestation=Manifestation.USER_ACTIVITY, | ||
1905 | 194 | actor=ACTOR_UBUNTUONE, | ||
1906 | 195 | subjects=[folder, other_user]) | ||
1907 | 196 | |||
1908 | 197 | self.zg.log(event) | ||
1909 | 198 | |||
1910 | 199 | def log_udf_deleted(self, volume): | ||
1911 | 200 | """Log the udf deleted event.""" | ||
1912 | 201 | folder = Subject.new_for_values( | ||
1913 | 202 | uri=URI_PROTOCOL_U1 + str(volume.node_id), | ||
1914 | 203 | interpretation=Interpretation.FOLDER, | ||
1915 | 204 | manifestation=Manifestation.DELETED_RESOURCE, | ||
1916 | 205 | origin="file:///" + volume.path, | ||
1917 | 206 | text=basename(volume.path), | ||
1918 | 207 | mimetype=DIRECTORY_MIMETYPE, | ||
1919 | 208 | storage=STORAGE_DELETED) | ||
1920 | 209 | |||
1921 | 210 | event = Event.new_for_values( | ||
1922 | 211 | interpretation=EVENT_INTERPRETATION_U1_UDF_DELETED, | ||
1923 | 212 | manifestation=Manifestation.USER_ACTIVITY, | ||
1924 | 213 | actor=ACTOR_UBUNTUONE, | ||
1925 | 214 | subjects=[folder]) | ||
1926 | 215 | |||
1927 | 216 | self.zg.log(event) | ||
1928 | 217 | |||
1929 | 218 | def handle_VM_VOLUME_DELETED(self, volume): | ||
1930 | 219 | """Log the share/UDF unaccepted event.""" | ||
1931 | 220 | if isinstance(volume, Share): | ||
1932 | 221 | self.log_share_unaccepted(volume) | ||
1933 | 222 | if isinstance(volume, UDF): | ||
1934 | 223 | self.log_udf_deleted(volume) | ||
1935 | 224 | |||
1936 | 225 | def handle_VM_UDF_CREATED(self, udf): | ||
1937 | 226 | """An udf was created. Log it into Zeitgeist.""" | ||
1938 | 227 | folder = Subject.new_for_values( | ||
1939 | 228 | uri=URI_PROTOCOL_U1 + str(udf.node_id), | ||
1940 | 229 | interpretation=Interpretation.FOLDER, | ||
1941 | 230 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
1942 | 231 | origin="file:///" + udf.path, | ||
1943 | 232 | text=basename(udf.path), | ||
1944 | 233 | mimetype=DIRECTORY_MIMETYPE, | ||
1945 | 234 | storage=STORAGE_NETWORK) | ||
1946 | 235 | |||
1947 | 236 | event = Event.new_for_values( | ||
1948 | 237 | interpretation=EVENT_INTERPRETATION_U1_UDF_CREATED, | ||
1949 | 238 | manifestation=Manifestation.USER_ACTIVITY, | ||
1950 | 239 | actor=ACTOR_UBUNTUONE, | ||
1951 | 240 | subjects=[folder]) | ||
1952 | 241 | |||
1953 | 242 | self.zg.log(event) | ||
1954 | 243 | |||
1955 | 244 | def handle_VM_UDF_SUBSCRIBED(self, udf): | ||
1956 | 245 | """An udf was subscribed.""" | ||
1957 | 246 | |||
1958 | 247 | folder = Subject.new_for_values( | ||
1959 | 248 | uri="file:///" + udf.path, | ||
1960 | 249 | interpretation=Interpretation.FOLDER, | ||
1961 | 250 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
1962 | 251 | origin=URI_PROTOCOL_U1 + str(udf.node_id), | ||
1963 | 252 | text=basename(udf.path), | ||
1964 | 253 | mimetype=DIRECTORY_MIMETYPE, | ||
1965 | 254 | storage=STORAGE_LOCAL) | ||
1966 | 255 | |||
1967 | 256 | event = Event.new_for_values( | ||
1968 | 257 | interpretation=EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED, | ||
1969 | 258 | manifestation=Manifestation.USER_ACTIVITY, | ||
1970 | 259 | actor=ACTOR_UBUNTUONE, | ||
1971 | 260 | subjects=[folder]) | ||
1972 | 261 | |||
1973 | 262 | self.zg.log(event) | ||
1974 | 263 | |||
1975 | 264 | def handle_VM_UDF_UNSUBSCRIBED(self, udf): | ||
1976 | 265 | """An udf was unsubscribed.""" | ||
1977 | 266 | |||
1978 | 267 | folder = Subject.new_for_values( | ||
1979 | 268 | uri="file:///" + udf.path, | ||
1980 | 269 | interpretation=Interpretation.FOLDER, | ||
1981 | 270 | manifestation=Manifestation.DELETED_RESOURCE, | ||
1982 | 271 | origin=URI_PROTOCOL_U1 + str(udf.node_id), | ||
1983 | 272 | text=basename(udf.path), | ||
1984 | 273 | mimetype=DIRECTORY_MIMETYPE, | ||
1985 | 274 | storage=STORAGE_DELETED) | ||
1986 | 275 | |||
1987 | 276 | event = Event.new_for_values( | ||
1988 | 277 | interpretation=EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED, | ||
1989 | 278 | manifestation=Manifestation.USER_ACTIVITY, | ||
1990 | 279 | actor=ACTOR_UBUNTUONE, | ||
1991 | 280 | subjects=[folder]) | ||
1992 | 281 | |||
1993 | 282 | self.zg.log(event) | ||
1994 | 283 | |||
1995 | 284 | def handle_AQ_FILE_NEW_OK(self, volume_id, marker, new_id, new_generation): | ||
1996 | 285 | """A new file was created on server. Store and wait till it uploads.""" | ||
1997 | 286 | self.newly_created_server_files.add((volume_id, new_id)) | ||
1998 | 287 | |||
1999 | 288 | def get_mime_and_interpretation_for_filepath(self, filepath): | ||
2000 | 289 | """Try to guess the mime and the interpretation from the path.""" | ||
2001 | 290 | mime, encoding = mimetypes.guess_type(filepath) | ||
2002 | 291 | if mime is None: | ||
2003 | 292 | return DEFAULT_MIME, DEFAULT_INTERPRETATION | ||
2004 | 293 | interpret = get_interpretation_for_mimetype(mime) | ||
2005 | 294 | if interpret is None: | ||
2006 | 295 | return DEFAULT_MIME, Interpretation.DOCUMENT | ||
2007 | 296 | return mime, interpret | ||
2008 | 297 | |||
2009 | 298 | def handle_AQ_UPLOAD_FINISHED(self, share_id, node_id, hash, | ||
2010 | 299 | new_generation): | ||
2011 | 300 | """A file finished uploading to the server.""" | ||
2012 | 301 | |||
2013 | 302 | mdo = self.fsm.get_by_node_id(share_id, node_id) | ||
2014 | 303 | path = self.fsm.get_abspath(share_id, mdo.path) | ||
2015 | 304 | |||
2016 | 305 | if (share_id, node_id) in self.newly_created_server_files: | ||
2017 | 306 | self.newly_created_server_files.remove((share_id, node_id)) | ||
2018 | 307 | event_interpretation = Interpretation.CREATE_EVENT | ||
2019 | 308 | else: | ||
2020 | 309 | event_interpretation = Interpretation.MODIFY_EVENT | ||
2021 | 310 | |||
2022 | 311 | mime, interp = self.get_mime_and_interpretation_for_filepath(path) | ||
2023 | 312 | |||
2024 | 313 | file_subject = Subject.new_for_values( | ||
2025 | 314 | uri=URI_PROTOCOL_U1 + str(node_id), | ||
2026 | 315 | interpretation=interp, | ||
2027 | 316 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
2028 | 317 | origin="file:///" + path, | ||
2029 | 318 | text=basename(path), | ||
2030 | 319 | mimetype=mime, | ||
2031 | 320 | storage=STORAGE_NETWORK) | ||
2032 | 321 | |||
2033 | 322 | event = Event.new_for_values( | ||
2034 | 323 | interpretation=event_interpretation, | ||
2035 | 324 | manifestation=Manifestation.SCHEDULED_ACTIVITY, | ||
2036 | 325 | actor=ACTOR_UBUNTUONE, | ||
2037 | 326 | subjects=[file_subject]) | ||
2038 | 327 | |||
2039 | 328 | self.zg.log(event) | ||
2040 | 329 | |||
2041 | 330 | def handle_AQ_DIR_NEW_OK(self, volume_id, marker, new_id, new_generation): | ||
2042 | 331 | """A dir was created on the server.""" | ||
2043 | 332 | |||
2044 | 333 | mdo = self.fsm.get_by_node_id(volume_id, new_id) | ||
2045 | 334 | path = self.fsm.get_abspath(volume_id, mdo.path) | ||
2046 | 335 | |||
2047 | 336 | file_subject = Subject.new_for_values( | ||
2048 | 337 | uri=URI_PROTOCOL_U1 + str(new_id), | ||
2049 | 338 | interpretation=Interpretation.FOLDER, | ||
2050 | 339 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
2051 | 340 | origin="file:///" + path, | ||
2052 | 341 | text=basename(path), | ||
2053 | 342 | mimetype=DIRECTORY_MIMETYPE, | ||
2054 | 343 | storage=STORAGE_NETWORK) | ||
2055 | 344 | |||
2056 | 345 | event = Event.new_for_values( | ||
2057 | 346 | interpretation=Interpretation.CREATE_EVENT, | ||
2058 | 347 | manifestation=Manifestation.SCHEDULED_ACTIVITY, | ||
2059 | 348 | actor=ACTOR_UBUNTUONE, | ||
2060 | 349 | subjects=[file_subject]) | ||
2061 | 350 | |||
2062 | 351 | self.zg.log(event) | ||
2063 | 352 | |||
2064 | 353 | def handle_SV_FILE_NEW(self, volume_id, node_id, parent_id, name): | ||
2065 | 354 | """A file was created locally by Syncdaemon.""" | ||
2066 | 355 | self.newly_created_local_files.add((volume_id, node_id)) | ||
2067 | 356 | |||
2068 | 357 | def handle_AQ_DOWNLOAD_FINISHED(self, share_id, node_id, server_hash): | ||
2069 | 358 | """A file finished downloading from the server.""" | ||
2070 | 359 | |||
2071 | 360 | mdo = self.fsm.get_by_node_id(share_id, node_id) | ||
2072 | 361 | path = self.fsm.get_abspath(share_id, mdo.path) | ||
2073 | 362 | |||
2074 | 363 | if (share_id, node_id) in self.newly_created_local_files: | ||
2075 | 364 | self.newly_created_local_files.remove((share_id, node_id)) | ||
2076 | 365 | event_interpretation = Interpretation.CREATE_EVENT | ||
2077 | 366 | else: | ||
2078 | 367 | event_interpretation = Interpretation.MODIFY_EVENT | ||
2079 | 368 | |||
2080 | 369 | mime, interp = self.get_mime_and_interpretation_for_filepath(path) | ||
2081 | 370 | |||
2082 | 371 | file_subject = Subject.new_for_values( | ||
2083 | 372 | uri="file:///" + path, | ||
2084 | 373 | interpretation=interp, | ||
2085 | 374 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
2086 | 375 | origin=URI_PROTOCOL_U1 + str(node_id), | ||
2087 | 376 | text=basename(path), | ||
2088 | 377 | mimetype=mime, | ||
2089 | 378 | storage=STORAGE_LOCAL) | ||
2090 | 379 | |||
2091 | 380 | event = Event.new_for_values( | ||
2092 | 381 | interpretation=event_interpretation, | ||
2093 | 382 | manifestation=Manifestation.WORLD_ACTIVITY, | ||
2094 | 383 | actor=ACTOR_UBUNTUONE, | ||
2095 | 384 | subjects=[file_subject]) | ||
2096 | 385 | |||
2097 | 386 | self.zg.log(event) | ||
2098 | 387 | |||
2099 | 388 | def handle_SV_DIR_NEW(self, volume_id, node_id, parent_id, name): | ||
2100 | 389 | """A file finished downloading from the server.""" | ||
2101 | 390 | |||
2102 | 391 | mdo = self.fsm.get_by_node_id(volume_id, node_id) | ||
2103 | 392 | path = self.fsm.get_abspath(volume_id, mdo.path) | ||
2104 | 393 | |||
2105 | 394 | file_subject = Subject.new_for_values( | ||
2106 | 395 | uri="file:///" + path, | ||
2107 | 396 | interpretation=Interpretation.FOLDER, | ||
2108 | 397 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
2109 | 398 | origin=URI_PROTOCOL_U1 + str(node_id), | ||
2110 | 399 | text=basename(path), | ||
2111 | 400 | mimetype=DIRECTORY_MIMETYPE, | ||
2112 | 401 | storage=STORAGE_LOCAL) | ||
2113 | 402 | |||
2114 | 403 | event = Event.new_for_values( | ||
2115 | 404 | interpretation=Interpretation.CREATE_EVENT, | ||
2116 | 405 | manifestation=Manifestation.WORLD_ACTIVITY, | ||
2117 | 406 | actor=ACTOR_UBUNTUONE, | ||
2118 | 407 | subjects=[file_subject]) | ||
2119 | 408 | |||
2120 | 409 | self.zg.log(event) | ||
2121 | 410 | |||
2122 | 411 | def handle_SV_FILE_DELETED(self, volume_id, node_id, was_dir, old_path): | ||
2123 | 412 | """A file or folder was deleted locally by Syncdaemon.""" | ||
2124 | 413 | if was_dir: | ||
2125 | 414 | mime, interp = DIRECTORY_MIMETYPE, Interpretation.FOLDER | ||
2126 | 415 | else: | ||
2127 | 416 | mime, interp = self.get_mime_and_interpretation_for_filepath( | ||
2128 | 417 | old_path) | ||
2129 | 418 | |||
2130 | 419 | file_subject = Subject.new_for_values( | ||
2131 | 420 | uri="file:///" + old_path, | ||
2132 | 421 | interpretation=interp, | ||
2133 | 422 | manifestation=Manifestation.DELETED_RESOURCE, | ||
2134 | 423 | origin=URI_PROTOCOL_U1 + str(node_id), | ||
2135 | 424 | text=basename(old_path), | ||
2136 | 425 | mimetype=mime, | ||
2137 | 426 | storage=STORAGE_DELETED) | ||
2138 | 427 | |||
2139 | 428 | event = Event.new_for_values( | ||
2140 | 429 | interpretation=Interpretation.DELETE_EVENT, | ||
2141 | 430 | manifestation=Manifestation.WORLD_ACTIVITY, | ||
2142 | 431 | actor=ACTOR_UBUNTUONE, | ||
2143 | 432 | subjects=[file_subject]) | ||
2144 | 433 | |||
2145 | 434 | self.zg.log(event) | ||
2146 | 435 | |||
2147 | 436 | def handle_AQ_UNLINK_OK(self, share_id, parent_id, node_id, | ||
2148 | 437 | new_generation, was_dir, old_path): | ||
2149 | 438 | """A file or folder was deleted on the server by Syncdaemon,""" | ||
2150 | 439 | if was_dir: | ||
2151 | 440 | mime, interp = DIRECTORY_MIMETYPE, Interpretation.FOLDER | ||
2152 | 441 | else: | ||
2153 | 442 | mime, interp = self.get_mime_and_interpretation_for_filepath( | ||
2154 | 443 | old_path) | ||
2155 | 444 | |||
2156 | 445 | file_subject = Subject.new_for_values( | ||
2157 | 446 | uri=URI_PROTOCOL_U1 + str(node_id), | ||
2158 | 447 | interpretation=interp, | ||
2159 | 448 | manifestation=Manifestation.DELETED_RESOURCE, | ||
2160 | 449 | origin="file:///" + old_path, | ||
2161 | 450 | text=basename(old_path), | ||
2162 | 451 | mimetype=mime, | ||
2163 | 452 | storage=STORAGE_DELETED) | ||
2164 | 453 | |||
2165 | 454 | event = Event.new_for_values( | ||
2166 | 455 | interpretation=Interpretation.DELETE_EVENT, | ||
2167 | 456 | manifestation=Manifestation.SCHEDULED_ACTIVITY, | ||
2168 | 457 | actor=ACTOR_UBUNTUONE, | ||
2169 | 458 | subjects=[file_subject]) | ||
2170 | 459 | |||
2171 | 460 | self.zg.log(event) | ||
2172 | 461 | |||
2173 | 462 | def handle_FSM_FILE_CONFLICT(self, old_name, new_name): | ||
2174 | 463 | """A file was renamed because of conflict.""" | ||
2175 | 464 | mime, interp = self.get_mime_and_interpretation_for_filepath(old_name) | ||
2176 | 465 | |||
2177 | 466 | file_subject = Subject.new_for_values( | ||
2178 | 467 | uri="file:///" + new_name, | ||
2179 | 468 | interpretation=interp, | ||
2180 | 469 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
2181 | 470 | origin="file:///" + old_name, | ||
2182 | 471 | text=basename(new_name), | ||
2183 | 472 | mimetype=mime, | ||
2184 | 473 | storage=STORAGE_LOCAL) | ||
2185 | 474 | |||
2186 | 475 | event = Event.new_for_values( | ||
2187 | 476 | interpretation=EVENT_INTERPRETATION_U1_CONFLICT_RENAME, | ||
2188 | 477 | manifestation=Manifestation.WORLD_ACTIVITY, | ||
2189 | 478 | actor=ACTOR_UBUNTUONE, | ||
2190 | 479 | subjects=[file_subject]) | ||
2191 | 480 | |||
2192 | 481 | self.zg.log(event) | ||
2193 | 482 | |||
2194 | 483 | def handle_FSM_DIR_CONFLICT(self, old_name, new_name): | ||
2195 | 484 | """A dir was renamed because of conflict.""" | ||
2196 | 485 | folder_subject = Subject.new_for_values( | ||
2197 | 486 | uri="file:///" + new_name, | ||
2198 | 487 | interpretation=Interpretation.FOLDER, | ||
2199 | 488 | manifestation=Manifestation.FILE_DATA_OBJECT, | ||
2200 | 489 | origin="file:///" + old_name, | ||
2201 | 490 | text=basename(new_name), | ||
2202 | 491 | mimetype=DIRECTORY_MIMETYPE, | ||
2203 | 492 | storage=STORAGE_LOCAL) | ||
2204 | 493 | |||
2205 | 494 | event = Event.new_for_values( | ||
2206 | 495 | interpretation=EVENT_INTERPRETATION_U1_CONFLICT_RENAME, | ||
2207 | 496 | manifestation=Manifestation.WORLD_ACTIVITY, | ||
2208 | 497 | actor=ACTOR_UBUNTUONE, | ||
2209 | 498 | subjects=[folder_subject]) | ||
2210 | 499 | |||
2211 | 500 | self.zg.log(event) | ||
2212 | 501 | |||
2213 | 502 | def handle_AQ_CHANGE_PUBLIC_ACCESS_OK(self, share_id, node_id, is_public, | ||
2214 | 503 | public_url): | ||
2215 | 504 | """The status of a published resource changed. Log it!""" | ||
2216 | 505 | if is_public: | ||
2217 | 506 | self.log_publishing(share_id, node_id, is_public, public_url) | ||
2218 | 507 | else: | ||
2219 | 508 | self.log_unpublishing(share_id, node_id, is_public, public_url) | ||
2220 | 509 | |||
2221 | 510 | def log_publishing(self, share_id, node_id, is_public, public_url): | ||
2222 | 511 | """Log the publishing of a resource.""" | ||
2223 | 512 | mime, interp = self.get_mime_and_interpretation_for_filepath( | ||
2224 | 513 | public_url) | ||
2225 | 514 | |||
2226 | 515 | origin = "" if node_id is None else URI_PROTOCOL_U1 + str(node_id) | ||
2227 | 516 | |||
2228 | 517 | public_file = Subject.new_for_values( | ||
2229 | 518 | uri=public_url, | ||
2230 | 519 | interpretation=interp, | ||
2231 | 520 | manifestation=Manifestation.REMOTE_DATA_OBJECT, | ||
2232 | 521 | origin=origin, | ||
2233 | 522 | text=public_url, | ||
2234 | 523 | mimetype=mime, | ||
2235 | 524 | storage=STORAGE_NETWORK) | ||
2236 | 525 | |||
2237 | 526 | event = Event.new_for_values( | ||
2238 | 527 | interpretation=Interpretation.CREATE_EVENT, | ||
2239 | 528 | manifestation=Manifestation.USER_ACTIVITY, | ||
2240 | 529 | actor=ACTOR_UBUNTUONE, | ||
2241 | 530 | subjects=[public_file]) | ||
2242 | 531 | |||
2243 | 532 | self.zg.log(event) | ||
2244 | 533 | |||
2245 | 534 | def log_unpublishing(self, share_id, node_id, is_public, public_url): | ||
2246 | 535 | """Log the unpublishing of a resource.""" | ||
2247 | 536 | mime, interp = self.get_mime_and_interpretation_for_filepath( | ||
2248 | 537 | public_url) | ||
2249 | 538 | |||
2250 | 539 | origin = "" if node_id is None else URI_PROTOCOL_U1 + str(node_id) | ||
2251 | 540 | |||
2252 | 541 | public_file = Subject.new_for_values( | ||
2253 | 542 | uri=public_url, | ||
2254 | 543 | interpretation=interp, | ||
2255 | 544 | manifestation=Manifestation.DELETED_RESOURCE, | ||
2256 | 545 | text=public_url, | ||
2257 | 546 | origin=origin, | ||
2258 | 547 | mimetype=mime, | ||
2259 | 548 | storage=STORAGE_DELETED) | ||
2260 | 549 | |||
2261 | 550 | event = Event.new_for_values( | ||
2262 | 551 | interpretation=Interpretation.DELETE_EVENT, | ||
2263 | 552 | manifestation=Manifestation.USER_ACTIVITY, | ||
2264 | 553 | actor=ACTOR_UBUNTUONE, | ||
2265 | 554 | subjects=[public_file]) | ||
2266 | 555 | |||
2267 | 556 | self.zg.log(event) | ||
2268 | 557 | 0 | ||
2269 | === removed file 'ubuntuone/eventlog/zglog.py' | |||
2270 | --- ubuntuone/eventlog/zglog.py 2012-04-09 20:07:05 +0000 | |||
2271 | +++ ubuntuone/eventlog/zglog.py 1970-01-01 00:00:00 +0000 | |||
2272 | @@ -1,61 +0,0 @@ | |||
2273 | 1 | # -*- coding: utf-8 -*- | ||
2274 | 2 | # | ||
2275 | 3 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
2276 | 4 | # | ||
2277 | 5 | # Copyright 2010-2012 Canonical Ltd. | ||
2278 | 6 | # | ||
2279 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
2280 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
2281 | 9 | # by the Free Software Foundation. | ||
2282 | 10 | # | ||
2283 | 11 | # This program is distributed in the hope that it will be useful, but | ||
2284 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2285 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2286 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
2287 | 15 | # | ||
2288 | 16 | # You should have received a copy of the GNU General Public License along | ||
2289 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2290 | 18 | # | ||
2291 | 19 | # In addition, as a special exception, the copyright holders give | ||
2292 | 20 | # permission to link the code of portions of this program with the | ||
2293 | 21 | # OpenSSL library under certain conditions as described in each | ||
2294 | 22 | # individual source file, and distribute linked combinations | ||
2295 | 23 | # including the two. | ||
2296 | 24 | # You must obey the GNU General Public License in all respects | ||
2297 | 25 | # for all of the code used other than OpenSSL. If you modify | ||
2298 | 26 | # file(s) with this exception, you may extend this exception to your | ||
2299 | 27 | # version of the file(s), but you are not obligated to do so. If you | ||
2300 | 28 | # do not wish to do so, delete this exception statement from your | ||
2301 | 29 | # version. If you delete this exception statement from all source | ||
2302 | 30 | # files in the program, then also delete it here. | ||
2303 | 31 | """Log into the Zeitgeist daemon.""" | ||
2304 | 32 | |||
2305 | 33 | from twisted.internet.defer import Deferred | ||
2306 | 34 | |||
2307 | 35 | from ubuntuone.logger import logging | ||
2308 | 36 | |||
2309 | 37 | logger = logging.getLogger('ubuntuone.eventlog.zglog') | ||
2310 | 38 | |||
2311 | 39 | |||
2312 | 40 | class ZeitgeistLogger(object): | ||
2313 | 41 | """A class that logs zeitgeist events.""" | ||
2314 | 42 | client = None | ||
2315 | 43 | |||
2316 | 44 | def __init__(self): | ||
2317 | 45 | """Initialize this instance.""" | ||
2318 | 46 | try: | ||
2319 | 47 | from zeitgeist.client import ZeitgeistClient | ||
2320 | 48 | self.client = ZeitgeistClient() | ||
2321 | 49 | logger.info("Zeitgeist support initialized.") | ||
2322 | 50 | except Exception: | ||
2323 | 51 | logger.exception("Zeitgeist support not started:") | ||
2324 | 52 | |||
2325 | 53 | def log(self, event): | ||
2326 | 54 | """Log a zeitgeist event.""" | ||
2327 | 55 | d = Deferred() | ||
2328 | 56 | if self.client: | ||
2329 | 57 | logger.info("Logging Zeitgeist event: %r", event) | ||
2330 | 58 | self.client.insert_event(event, d.callback, d.errback) | ||
2331 | 59 | else: | ||
2332 | 60 | d.callback([]) | ||
2333 | 61 | return d | ||
2334 | 62 | 0 | ||
2335 | === removed directory 'ubuntuone/platform/event_logging' | |||
2336 | === removed file 'ubuntuone/platform/event_logging/__init__.py' | |||
2337 | --- ubuntuone/platform/event_logging/__init__.py 2012-05-01 17:43:39 +0000 | |||
2338 | +++ ubuntuone/platform/event_logging/__init__.py 1970-01-01 00:00:00 +0000 | |||
2339 | @@ -1,39 +0,0 @@ | |||
2340 | 1 | # -*- coding: utf-8 *-* | ||
2341 | 2 | # | ||
2342 | 3 | # Copyright 2011-2012 Canonical Ltd. | ||
2343 | 4 | # | ||
2344 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
2345 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
2346 | 7 | # by the Free Software Foundation. | ||
2347 | 8 | # | ||
2348 | 9 | # This program is distributed in the hope that it will be useful, but | ||
2349 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2350 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2351 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
2352 | 13 | # | ||
2353 | 14 | # You should have received a copy of the GNU General Public License along | ||
2354 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2355 | 16 | # | ||
2356 | 17 | # In addition, as a special exception, the copyright holders give | ||
2357 | 18 | # permission to link the code of portions of this program with the | ||
2358 | 19 | # OpenSSL library under certain conditions as described in each | ||
2359 | 20 | # individual source file, and distribute linked combinations | ||
2360 | 21 | # including the two. | ||
2361 | 22 | # You must obey the GNU General Public License in all respects | ||
2362 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
2363 | 24 | # file(s) with this exception, you may extend this exception to your | ||
2364 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
2365 | 26 | # do not wish to do so, delete this exception statement from your | ||
2366 | 27 | # version. If you delete this exception statement from all source | ||
2367 | 28 | # files in the program, then also delete it here. | ||
2368 | 29 | """Builds a syncdaemon listener that logs events if ZG is installed.""" | ||
2369 | 30 | |||
2370 | 31 | import sys | ||
2371 | 32 | |||
2372 | 33 | if sys.platform in ["win32", "darwin"]: | ||
2373 | 34 | # Zeitgeist is not installed on these platforms | ||
2374 | 35 | get_listener = lambda x, y: None | ||
2375 | 36 | else: | ||
2376 | 37 | from ubuntuone.platform.event_logging import linux as source | ||
2377 | 38 | get_listener = source.get_listener | ||
2378 | 39 | |||
2379 | 40 | 0 | ||
2380 | === removed file 'ubuntuone/platform/event_logging/linux.py' | |||
2381 | --- ubuntuone/platform/event_logging/linux.py 2012-04-27 22:55:12 +0000 | |||
2382 | +++ ubuntuone/platform/event_logging/linux.py 1970-01-01 00:00:00 +0000 | |||
2383 | @@ -1,51 +0,0 @@ | |||
2384 | 1 | # | ||
2385 | 2 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
2386 | 3 | # | ||
2387 | 4 | # Copyright 2010-2012 Canonical Ltd. | ||
2388 | 5 | # | ||
2389 | 6 | # This program is free software: you can redistribute it and/or modify it | ||
2390 | 7 | # under the terms of the GNU General Public License version 3, as published | ||
2391 | 8 | # by the Free Software Foundation. | ||
2392 | 9 | # | ||
2393 | 10 | # This program is distributed in the hope that it will be useful, but | ||
2394 | 11 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2395 | 12 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2396 | 13 | # PURPOSE. See the GNU General Public License for more details. | ||
2397 | 14 | # | ||
2398 | 15 | # You should have received a copy of the GNU General Public License along | ||
2399 | 16 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2400 | 17 | # | ||
2401 | 18 | # In addition, as a special exception, the copyright holders give | ||
2402 | 19 | # permission to link the code of portions of this program with the | ||
2403 | 20 | # OpenSSL library under certain conditions as described in each | ||
2404 | 21 | # individual source file, and distribute linked combinations | ||
2405 | 22 | # including the two. | ||
2406 | 23 | # You must obey the GNU General Public License in all respects | ||
2407 | 24 | # for all of the code used other than OpenSSL. If you modify | ||
2408 | 25 | # file(s) with this exception, you may extend this exception to your | ||
2409 | 26 | # version of the file(s), but you are not obligated to do so. If you | ||
2410 | 27 | # do not wish to do so, delete this exception statement from your | ||
2411 | 28 | # version. If you delete this exception statement from all source | ||
2412 | 29 | # files in the program, then also delete it here. | ||
2413 | 30 | """Builds a syncdaemon listener that logs events if ZG is installed.""" | ||
2414 | 31 | |||
2415 | 32 | |||
2416 | 33 | def is_zeitgeist_installed(): | ||
2417 | 34 | """Return true if zeitgeist is installed.""" | ||
2418 | 35 | try: | ||
2419 | 36 | import zeitgeist | ||
2420 | 37 | import zeitgeist.mimetypes | ||
2421 | 38 | # use the above module in some way so pylint does not complain | ||
2422 | 39 | assert(zeitgeist is not None) | ||
2423 | 40 | return True | ||
2424 | 41 | except (ImportError, AttributeError): | ||
2425 | 42 | return False | ||
2426 | 43 | |||
2427 | 44 | |||
2428 | 45 | def get_listener(fsm, vm): | ||
2429 | 46 | """Build a listener if zg is installed.""" | ||
2430 | 47 | if is_zeitgeist_installed(): | ||
2431 | 48 | from ubuntuone.eventlog import zg_listener | ||
2432 | 49 | return zg_listener.ZeitgeistListener(fsm, vm) | ||
2433 | 50 | else: | ||
2434 | 51 | return None | ||
2435 | 52 | 0 | ||
2436 | === modified file 'ubuntuone/syncdaemon/main.py' | |||
2437 | --- ubuntuone/syncdaemon/main.py 2013-01-22 20:03:12 +0000 | |||
2438 | +++ ubuntuone/syncdaemon/main.py 2013-02-04 16:10:53 +0000 | |||
2439 | @@ -48,7 +48,6 @@ | |||
2440 | 48 | volume_manager, | 48 | volume_manager, |
2441 | 49 | ) | 49 | ) |
2442 | 50 | from ubuntuone import syncdaemon, clientdefs | 50 | from ubuntuone import syncdaemon, clientdefs |
2443 | 51 | from ubuntuone.platform import event_logging | ||
2444 | 52 | from ubuntuone.syncdaemon import status_listener | 51 | from ubuntuone.syncdaemon import status_listener |
2445 | 53 | from ubuntuone.syncdaemon.interaction_interfaces import SyncdaemonService | 52 | from ubuntuone.syncdaemon.interaction_interfaces import SyncdaemonService |
2446 | 54 | from ubuntuone.syncdaemon.states import StateManager, QueueManager | 53 | from ubuntuone.syncdaemon.states import StateManager, QueueManager |
2447 | @@ -147,22 +146,12 @@ | |||
2448 | 147 | if user_config.get_autoconnect(): | 146 | if user_config.get_autoconnect(): |
2449 | 148 | self.external.connect(autoconnecting=True) | 147 | self.external.connect(autoconnecting=True) |
2450 | 149 | 148 | ||
2451 | 150 | self.eventlog_listener = None | ||
2452 | 151 | self.start_event_logger() | ||
2453 | 152 | |||
2454 | 153 | self.status_listener = None | 149 | self.status_listener = None |
2455 | 154 | self.start_status_listener() | 150 | self.start_status_listener() |
2456 | 155 | 151 | ||
2457 | 156 | self.mark = task.LoopingCall(self.log_mark) | 152 | self.mark = task.LoopingCall(self.log_mark) |
2458 | 157 | self.mark.start(mark_interval) | 153 | self.mark.start(mark_interval) |
2459 | 158 | 154 | ||
2460 | 159 | def start_event_logger(self): | ||
2461 | 160 | """Start the event logger if it's available for this platform.""" | ||
2462 | 161 | self.eventlog_listener = event_logging.get_listener(self.fs, self.vm) | ||
2463 | 162 | # subscribe to EQ, to be unsubscribed in shutdown | ||
2464 | 163 | if self.eventlog_listener: | ||
2465 | 164 | self.event_q.subscribe(self.eventlog_listener) | ||
2466 | 165 | |||
2467 | 166 | def start_status_listener(self): | 155 | def start_status_listener(self): |
2468 | 167 | """Start the status listener if it is configured to start.""" | 156 | """Start the status listener if it is configured to start.""" |
2469 | 168 | self.status_listener = status_listener.get_listener(self.fs, self.vm, | 157 | self.status_listener = status_listener.get_listener(self.fs, self.vm, |
2470 | @@ -228,8 +217,6 @@ | |||
2471 | 228 | self.event_q.push('SYS_QUIT') | 217 | self.event_q.push('SYS_QUIT') |
2472 | 229 | 218 | ||
2473 | 230 | self.event_q.unsubscribe(self.vm) | 219 | self.event_q.unsubscribe(self.vm) |
2474 | 231 | if getattr(self, 'eventlog_listener', None) is not None: | ||
2475 | 232 | self.event_q.unsubscribe(self.eventlog_listener) | ||
2476 | 233 | if getattr(self, 'status_listener', None) is not None: | 220 | if getattr(self, 'status_listener', None) is not None: |
2477 | 234 | self.event_q.unsubscribe(self.status_listener) | 221 | self.event_q.unsubscribe(self.status_listener) |
2478 | 235 | 222 |
The code removal looks good. +1
We never ended up giving this any real usage, since we found better ways to do the status reporting. So I'm happy that all of this is finally gone.