Merge lp:~dobey/ubuntuone-client/rm-zeitgeist into lp:ubuntuone-client

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
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.

To post a comment you must log in.
Revision history for this message
Alejandro J. Cura (alecu) wrote :

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.

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

Subscribers

People subscribed via source and target branches