diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-07-13 17:17:25 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-07-13 17:17:25 (GMT) |
commit | 35f7c5a2f2510e4be81fa936cc89248d896e16d1 (patch) | |
tree | 7941e72a6002ab1090cd37885ce21e03b3356e27 | |
parent | 8229a0806945e998cb537ed94c27162ea6258839 (diff) |
There is no sync event anyumore, only commit
-rw-r--r-- | sugar_network/node/__init__.py | 4 | ||||
-rw-r--r-- | sugar_network/node/subscribe_socket.py | 5 | ||||
-rw-r--r-- | tests/__init__.py | 35 | ||||
-rw-r--r-- | tests/units/__main__.py | 8 | ||||
-rwxr-xr-x | tests/units/bus.py | 2 | ||||
-rwxr-xr-x | tests/units/home_mount.py | 272 | ||||
-rwxr-xr-x | tests/units/mounts.py | 631 | ||||
-rwxr-xr-x | tests/units/mountset.py | 2 | ||||
-rwxr-xr-x | tests/units/node_mount.py | 6 | ||||
-rwxr-xr-x | tests/units/remote_mount.py | 380 | ||||
-rwxr-xr-x | tests/units/subscribe_socket.py | 17 |
11 files changed, 689 insertions, 673 deletions
diff --git a/sugar_network/node/__init__.py b/sugar_network/node/__init__.py index 834e6f5..c31399a 100644 --- a/sugar_network/node/__init__.py +++ b/sugar_network/node/__init__.py @@ -47,8 +47,8 @@ data_root = Option( 'data and indexes', default='/var/lib/sugar-network/db', name='data_root') -only_sync_notification = Option( - 'subscribers can be notified only with "sync" events; ' \ +only_commit_events = Option( + 'subscribers can be notified only with "commit" events; ' \ 'that is useful to minimize interactions between ' \ 'server and clients', default=False, type_cast=Option.bool_cast, action='store_true') diff --git a/sugar_network/node/subscribe_socket.py b/sugar_network/node/subscribe_socket.py index f4ace12..d7e84a7 100644 --- a/sugar_network/node/subscribe_socket.py +++ b/sugar_network/node/subscribe_socket.py @@ -85,12 +85,9 @@ class SubscribeSocket(object): self._subscribers.remove(conn) def __signal_cb(self, event): - if node.only_sync_notification.value: + if node.only_commit_events.value: if event['event'] != 'commit': - # Even "sync" event can be ignored, - # passing only "commit" is enough return - event['event'] = 'sync' else: if event['event'] == 'commit': # Subscribers already got update notifications enough diff --git a/tests/__init__.py b/tests/__init__.py index 82175a0..834f766 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -69,6 +69,7 @@ class Test(unittest.TestCase): ad.index_flush_threshold.value = 1 node.find_limit.value = 1024 node.tmpdir.value = tmpdir + '/tmp' + node.only_commit_events.value = False ad.index_write_queue.value = 10 local.local_root.value = tmpdir local.activity_dirs.value = [tmpdir + '/Activities'] @@ -112,20 +113,18 @@ class Test(unittest.TestCase): while self._overriden: mod, name, old_handler = self._overriden.pop() setattr(mod, name, old_handler) - coroutine.shutdown() sys.stdout.flush() def stop_servers(self): if self.mounts is not None: self.mounts.close() - if bus.Client.connection is not None: - bus.Client.connection.close() bus.Client.close() if self.server is not None: self.server.stop() while self.forks: pid = self.forks.pop() self.assertEqual(0, self.waitpid(pid)) + coroutine.shutdown() def waitpid(self, pid, sig=signal.SIGTERM): if pid in self.forks: @@ -202,11 +201,7 @@ class Test(unittest.TestCase): coroutine.sleep(1) return child.pid - def start_server(self, classes=None, open=True): - - def server(): - self.server.serve_forever() - + def start_server(self, classes=None): if classes is None: classes = [User, Context] volume = Volume('local', classes) @@ -214,24 +209,24 @@ class Test(unittest.TestCase): self.mounts['~'] = HomeMount(volume) self.mounts['/'] = RemoteMount(volume) self.server = IPCServer(self.mounts) - coroutine.spawn(server) - if open: - self.mounts.open() + coroutine.spawn(self.server.serve_forever) + self.mounts.open() + self.mounts.opened.wait() coroutine.dispatch() def start_ipc_and_restful_server(self, classes=None, **kwargs): pid = self.fork(self.restful_server, classes) - self.start_server(classes, open=False) + self.start_server(classes) - def wait_connect(event): - if event['event'] == 'mount': - connected.set() + if not self.mounts['/'].mounted: - connected = coroutine.Event() - bus.Client.connect(wait_connect) - coroutine.sleep(.1) - self.mounts.open() - connected.wait() + def wait_connect(event): + if event.get('mountpoint') == '/' and event['event'] == 'mount': + connected.set() + + connected = coroutine.Event() + self.mounts.connect(wait_connect) + connected.wait() return pid diff --git a/tests/units/__main__.py b/tests/units/__main__.py index 8ccc7b0..ed42c14 100644 --- a/tests/units/__main__.py +++ b/tests/units/__main__.py @@ -5,20 +5,20 @@ from __init__ import tests from collection import * from sneakernet import * from bus import * -from mounts import * from activities_crawler import * from activities import * from ipc_client import * from glib_client import * from injector import * from sync import * -from mountset import * -from node_mount import * from subscribe_socket import * from router import * from volume import * from local import * from node import * - +from mountset import * +from home_mount import * +from remote_mount import * +from node_mount import * tests.main() diff --git a/tests/units/bus.py b/tests/units/bus.py index eb536a5..c38a69a 100755 --- a/tests/units/bus.py +++ b/tests/units/bus.py @@ -16,7 +16,7 @@ from sugar_network.local.mountset import Mountset from sugar_network.resources.volume import Volume -class IPCTest(tests.Test): +class BusTest(tests.Test): def test_Rendezvous(self): diff --git a/tests/units/home_mount.py b/tests/units/home_mount.py new file mode 100755 index 0000000..b0fef20 --- /dev/null +++ b/tests/units/home_mount.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python +# sugar-lint: disable + +import os +import socket +from os.path import exists + +from __init__ import tests + +from active_toolkit import sockets, coroutine +from sugar_network import Client + + +class HomeMountTest(tests.Test): + + def test_create(self): + self.start_server() + local = Client('~') + + guid = local.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + self.assertNotEqual(None, guid) + + res = local.Context(guid, ['title', 'keep', 'keep_impl', 'position']) + self.assertEqual(guid, res['guid']) + self.assertEqual('title', res['title']) + self.assertEqual(False, res['keep']) + self.assertEqual(0, res['keep_impl']) + self.assertEqual([-1, -1], res['position']) + + def test_update(self): + self.start_server() + local = Client('~') + + guid = local.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + context = local.Context(guid) + context['title'] = 'title_2' + context['keep'] = True + context['position'] = (2, 3) + context.post() + + context = local.Context(guid, ['title', 'keep', 'position']) + self.assertEqual('title_2', context['title']) + self.assertEqual(True, context['keep']) + self.assertEqual([2, 3], context['position']) + + def test_get(self): + self.start_server() + local = Client('~') + + guid = local.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + context = local.Context(guid, ['title', 'keep', 'keep_impl', 'position']) + self.assertEqual(guid, context['guid']) + self.assertEqual('title', context['title']) + self.assertEqual(False, context['keep']) + self.assertEqual(0, context['keep_impl']) + self.assertEqual([-1, -1], context['position']) + + def test_find(self): + self.start_server() + local = Client('~') + + guid_1 = local.Context( + type='activity', + title='title_1', + summary='summary', + description='description').post() + guid_2 = local.Context( + type='activity', + title='title_2', + summary='summary', + description='description').post() + guid_3 = local.Context( + type='activity', + title='title_3', + summary='summary', + description='description').post() + + cursor = local.Context.cursor(reply=['guid', 'title', 'keep', 'keep_impl', 'position']) + self.assertEqual(3, cursor.total) + self.assertEqual( + sorted([ + (guid_1, 'title_1', False, 0, [-1, -1]), + (guid_2, 'title_2', False, 0, [-1, -1]), + (guid_3, 'title_3', False, 0, [-1, -1]), + ]), + sorted([(i['guid'], i['title'], i['keep'], i['keep_impl'], i['position']) for i in cursor])) + + def test_upload_blob(self): + self.start_server() + local = Client('~') + + guid = local.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + self.touch(('file', 'blob')) + local.Context(guid).upload_blob('preview', 'file') + self.assertEqual('blob', local.Context(guid).get_blob('preview').read()) + + self.touch(('file2', 'blob2')) + local.Context(guid).upload_blob('preview', 'file2', pass_ownership=True) + self.assertEqual('blob2', local.Context(guid).get_blob('preview').read()) + assert not exists('file2') + + def test_GetAbsetnBLOB(self): + self.start_server() + client = Client('~') + + guid = client.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + path, mime_type = client.Context(guid).get_blob_path('icon') + self.assertEqual(None, path) + self.assertEqual(True, client.Context(guid).get_blob('icon').closed) + + def test_Subscription(self): + self.start_server() + client = Client('~') + + subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) + subscription.connect('run/subscribe') + coroutine.sleep() + + guid = client.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('props') + self.assertEqual( + {'mountpoint': '*', 'document': 'context', 'event': 'create', 'guid': guid, 'seqno': 1}, + event) + self.assertEqual( + {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 1}, + subscription.read_message()) + + client.Context(guid, title='new-title').post() + + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('props') + self.assertEqual( + {'mountpoint': '~', 'document': 'context', 'event': 'update', 'guid': guid, 'seqno': 2}, + event) + self.assertEqual( + {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 2}, + subscription.read_message()) + + client.Context.delete(guid) + + coroutine.select([subscription.fileno()], [], []) + self.assertEqual( + {'mountpoint': '~', 'document': 'context', 'event': 'delete', 'guid': guid}, + subscription.read_message()) + self.assertEqual( + {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 2}, + subscription.read_message()) + + def test_Subscription_NotifyOnline(self): + self.start_ipc_and_restful_server() + + local = Client('~') + remote = Client('/') + + guid = remote.Context( + type='activity', + title={'en': 'title'}, + summary={'en': 'summary'}, + description={'en': 'description'}, + keep=True).post() + + subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) + subscription.connect('run/subscribe') + coroutine.sleep(1) + + local.Context(guid, keep=False).post() + coroutine.sleep(1) + + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('props') + self.assertEqual( + {'mountpoint': '*', 'document': 'context', 'event': 'update', 'guid': guid, 'seqno': 2}, + event) + + def test_Connect(self): + self.start_server() + client = Client('~') + + self.assertEqual(True, client.connected) + + def test_Localize(self): + os.environ['LANG'] = 'en_US' + self.start_server() + client = Client('~') + + guid = client.Context( + type='activity', + title='title_en', + summary='summary_en', + description='description_en').post() + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'ru_RU' + self.start_server() + client = Client('~') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + res['title'] = 'title_ru' + res['summary'] = 'summary_ru' + res['description'] = 'description_ru' + res.post() + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_ru', res['title']) + self.assertEqual('summary_ru', res['summary']) + self.assertEqual('description_ru', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'es_ES' + self.start_server() + client = Client('~') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'ru_RU' + self.start_server() + client = Client('~') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_ru', res['title']) + self.assertEqual('summary_ru', res['summary']) + self.assertEqual('description_ru', res['description']) + + +if __name__ == '__main__': + tests.main() diff --git a/tests/units/mounts.py b/tests/units/mounts.py deleted file mode 100755 index 7ae1b29..0000000 --- a/tests/units/mounts.py +++ /dev/null @@ -1,631 +0,0 @@ -#!/usr/bin/env python -# sugar-lint: disable - -import os -import cgi -import time -import json -import socket -import hashlib -import subprocess -from email.message import Message -from cStringIO import StringIO -from os.path import join, exists - -from __init__ import tests - -import active_document as ad -from active_toolkit import sockets, coroutine -from sugar_network import Client, ServerError, local, node -from sugar_network.local import mounts as mounts_, activities -from sugar_network.local.mounts import RemoteMount -from sugar_network.local.mountset import Mountset -from sugar_network.local.bus import IPCServer -from sugar_network.toolkit import sugar, http, inotify -from sugar_network.resources.user import User -from sugar_network.resources.context import Context -from sugar_network.resources.volume import Volume - - -class MountsTest(tests.Test): - - def setUp(self): - tests.Test.setUp(self) - node.only_sync_notification.value = False - mounts_._RECONNECTION_TIMEOUT = 1 - - def test_OfflineMount_create(self): - self.start_server() - local = Client('~') - - guid = local.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - self.assertNotEqual(None, guid) - - res = local.Context(guid, ['title', 'keep', 'keep_impl', 'position']) - self.assertEqual(guid, res['guid']) - self.assertEqual('title', res['title']) - self.assertEqual(False, res['keep']) - self.assertEqual(0, res['keep_impl']) - self.assertEqual([-1, -1], res['position']) - - def test_OfflineMount_update(self): - self.start_server() - local = Client('~') - - guid = local.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - context = local.Context(guid) - context['title'] = 'title_2' - context['keep'] = True - context['position'] = (2, 3) - context.post() - - context = local.Context(guid, ['title', 'keep', 'position']) - self.assertEqual('title_2', context['title']) - self.assertEqual(True, context['keep']) - self.assertEqual([2, 3], context['position']) - - def test_OfflineMount_get(self): - self.start_server() - local = Client('~') - - guid = local.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - context = local.Context(guid, ['title', 'keep', 'keep_impl', 'position']) - self.assertEqual(guid, context['guid']) - self.assertEqual('title', context['title']) - self.assertEqual(False, context['keep']) - self.assertEqual(0, context['keep_impl']) - self.assertEqual([-1, -1], context['position']) - - def test_OfflineMount_find(self): - self.start_server() - local = Client('~') - - guid_1 = local.Context( - type='activity', - title='title_1', - summary='summary', - description='description').post() - guid_2 = local.Context( - type='activity', - title='title_2', - summary='summary', - description='description').post() - guid_3 = local.Context( - type='activity', - title='title_3', - summary='summary', - description='description').post() - - cursor = local.Context.cursor(reply=['guid', 'title', 'keep', 'keep_impl', 'position']) - self.assertEqual(3, cursor.total) - self.assertEqual( - sorted([ - (guid_1, 'title_1', False, 0, [-1, -1]), - (guid_2, 'title_2', False, 0, [-1, -1]), - (guid_3, 'title_3', False, 0, [-1, -1]), - ]), - sorted([(i['guid'], i['title'], i['keep'], i['keep_impl'], i['position']) for i in cursor])) - - def test_OfflineMount_upload_blob(self): - self.start_server() - local = Client('~') - - guid = local.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - self.touch(('file', 'blob')) - local.Context(guid).upload_blob('preview', 'file') - self.assertEqual('blob', local.Context(guid).get_blob('preview').read()) - - self.touch(('file2', 'blob2')) - local.Context(guid).upload_blob('preview', 'file2', pass_ownership=True) - self.assertEqual('blob2', local.Context(guid).get_blob('preview').read()) - assert not exists('file2') - - def test_OfflineMount_GetAbsetnBLOB(self): - self.start_server() - client = Client('~') - - guid = client.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - path, mime_type = client.Context(guid).get_blob_path('icon') - self.assertEqual(None, path) - self.assertEqual(True, client.Context(guid).get_blob('icon').closed) - - def test_OnlineMount_GetKeep(self): - self.start_ipc_and_restful_server() - - remote = Client('/') - - guid = remote.Context( - type='activity', - title='remote', - summary='summary', - description='description').post() - - context = remote.Context(guid, ['keep', 'keep_impl']) - self.assertEqual(False, context['keep']) - self.assertEqual(0, context['keep_impl']) - self.assertEqual( - [(guid, False, False)], - [(i['guid'], i['keep'], i['keep_impl']) for i in remote.Context.cursor(reply=['keep', 'keep_impl'])]) - - self.mounts.home_volume['context'].create(guid=guid, type='activity', - title={'en': 'local'}, summary={'en': 'summary'}, - description={'en': 'description'}, keep=True, keep_impl=2, - user=[sugar.uid()]) - - context = remote.Context(guid, ['keep', 'keep_impl']) - self.assertEqual(True, context['keep']) - self.assertEqual(2, context['keep_impl']) - self.assertEqual( - [(guid, True, 2)], - [(i['guid'], i['keep'], i['keep_impl']) for i in remote.Context.cursor(reply=['keep', 'keep_impl'])]) - - def test_OnlineMount_SetKeep(self): - self.start_ipc_and_restful_server() - - remote = Client('/') - local = Client('~') - - guid_1 = remote.Context( - type=['activity'], - title='remote', - summary='summary', - description='description').post() - guid_2 = remote.Context( - type=['activity'], - title='remote-2', - summary='summary', - description='description').post() - - self.assertRaises(ServerError, lambda: local.Context(guid_1, reply=['title'])['title']) - self.assertRaises(ServerError, lambda: local.Context(guid_2, reply=['title'])['title']) - - remote.Context(guid_1, keep=True).post() - - cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'remote', True, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'remote', True, 0), - (guid_2, 'remote-2', False, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - - remote.Context(guid_1, keep=False).post() - - cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'remote', False, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'remote', False, 0), - (guid_2, 'remote-2', False, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - - context = local.Context(guid_1) - context['title'] = 'local' - context.post() - context = local.Context(guid_1, reply=['keep', 'keep_impl', 'title']) - self.assertEqual('local', context['title']) - - remote.Context(guid_1, keep=True).post() - - cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'local', True, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) - self.assertEqual( - sorted([ - (guid_1, 'remote', True, 0), - (guid_2, 'remote-2', False, 0), - ]), - sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) - - def test_OfflineSubscription(self): - self.start_server() - client = Client('~') - - subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) - subscription.connect('run/subscribe') - coroutine.sleep() - - guid = client.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - coroutine.select([subscription.fileno()], [], []) - event = subscription.read_message() - event.pop('props') - self.assertEqual( - {'mountpoint': '*', 'document': 'context', 'event': 'create', 'guid': guid}, - event) - self.assertEqual( - {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 1}, - subscription.read_message()) - - client.Context(guid, title='new-title').post() - - coroutine.select([subscription.fileno()], [], []) - event = subscription.read_message() - event.pop('props') - self.assertEqual( - {'mountpoint': '~', 'document': 'context', 'event': 'update', 'guid': guid}, - event) - self.assertEqual( - {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 2}, - subscription.read_message()) - - client.Context.delete(guid) - - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '~', 'document': 'context', 'event': 'delete', 'guid': guid}, - subscription.read_message()) - self.assertEqual( - {'mountpoint': '~', 'document': 'context', 'event': 'commit', 'seqno': 2}, - subscription.read_message()) - - def test_OnlineSubscription(self): - self.fork(self.restful_server) - coroutine.sleep(1) - - self.start_server() - client = Client('/') - - subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) - subscription.connect('run/subscribe') - coroutine.sleep(1) - - guid = client.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - self.assertEqual( - {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, - subscription.read_message()) - coroutine.select([subscription.fileno()], [], []) - event = subscription.read_message() - event.pop('props') - self.assertEqual( - {'mountpoint': '/', 'document': 'context', 'event': 'create', 'guid': guid}, - event) - - client.Context(guid, title='new-title').post() - - coroutine.select([subscription.fileno()], [], []) - event = subscription.read_message() - event.pop('props') - self.assertEqual( - {'mountpoint': '/', 'document': 'context', 'event': 'update', 'guid': guid}, - event) - - client.Context.delete(guid) - - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '/', 'document': 'context', 'event': 'delete', 'guid': guid}, - subscription.read_message()) - - def test_OfflineSubscription_NotifyOnline(self): - self.start_ipc_and_restful_server() - - local = Client('~') - remote = Client('/') - - guid = remote.Context( - type='activity', - title={'en': 'title'}, - summary={'en': 'summary'}, - description={'en': 'description'}, - keep=True).post() - - subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) - subscription.connect('run/subscribe') - coroutine.sleep(1) - - local.Context(guid, keep=False).post() - coroutine.sleep(1) - - coroutine.select([subscription.fileno()], [], []) - event = subscription.read_message() - event.pop('props') - self.assertEqual( - {'mountpoint': '*', 'document': 'context', 'event': 'update', 'guid': guid}, - event) - - def test_OfflineConnect(self): - self.start_server() - client = Client('~') - - self.assertEqual(True, client.connected) - - def test_OfflineMount_Localize(self): - os.environ['LANG'] = 'en_US' - self.start_server() - client = Client('~') - - guid = client.Context( - type='activity', - title='title_en', - summary='summary_en', - description='description_en').post() - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'ru_RU' - self.start_server() - client = Client('~') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - res['title'] = 'title_ru' - res['summary'] = 'summary_ru' - res['description'] = 'description_ru' - res.post() - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_ru', res['title']) - self.assertEqual('summary_ru', res['summary']) - self.assertEqual('description_ru', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'es_ES' - self.start_server() - client = Client('~') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'ru_RU' - self.start_server() - client = Client('~') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_ru', res['title']) - self.assertEqual('summary_ru', res['summary']) - self.assertEqual('description_ru', res['description']) - - def test_OnlineConnect(self): - pid = self.fork(self.restful_server) - volume = Volume('local', [User, Context]) - mounts = Mountset(volume) - mounts['/'] = RemoteMount(volume) - ipc_server = IPCServer(mounts) - coroutine.spawn(ipc_server.serve_forever) - - client = Client('/') - subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) - subscription.connect('run/subscribe') - - mounts.open() - coroutine.dispatch() - - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, - subscription.read_message()) - self.assertEqual(True, client.connected) - - self.waitpid(pid) - - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '/', 'event': 'unmount', 'document': '*', 'name': 'Network', 'private': False}, - subscription.read_message()) - self.assertEqual(False, client.connected) - - pid = self.fork(self.restful_server) - coroutine.sleep(1) - - self.assertEqual(False, client.connected) - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, - subscription.read_message()) - self.assertEqual(True, client.connected) - - self.waitpid(pid) - - coroutine.select([subscription.fileno()], [], []) - self.assertEqual( - {'mountpoint': '/', 'event': 'unmount', 'document': '*', 'name': 'Network', 'private': False}, - subscription.read_message()) - self.assertEqual(False, client.connected) - - def test_OnlineMount_upload_blob(self): - self.start_ipc_and_restful_server() - remote = Client('/') - - guid = remote.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - self.touch(('file', 'blob')) - remote.Context(guid).upload_blob('preview', 'file') - self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) - - self.touch(('file2', 'blob2')) - remote.Context(guid).upload_blob('preview', 'file2', pass_ownership=True) - self.assertEqual('blob2', remote.Context(guid).get_blob('preview').read()) - assert not exists('file2') - - def test_OnlineMount_StaleBLOBs(self): - self.start_ipc_and_restful_server() - remote = Client('/') - - guid = remote.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - self.touch(('file', 'blob-1')) - remote.Context(guid).upload_blob('preview', 'file') - self.assertEqual('blob-1', remote.Context(guid).get_blob('preview').read()) - - cache_path = 'cache/context/%s/%s/preview' % (guid[:2], guid) - self.touch((cache_path, 'blob-2')) - self.assertEqual('blob-2', remote.Context(guid).get_blob('preview').read()) - self.assertEqual(3, json.load(file(cache_path + '.meta'))['seqno']) - - self.touch(('file', 'blob-3')) - remote.Context(guid).upload_blob('preview', 'file') - self.assertEqual('blob-3', remote.Context(guid).get_blob('preview').read()) - self.assertEqual(4, json.load(file(cache_path + '.meta'))['seqno']) - - def test_OnlineMount_DoNotStaleBLOBs(self): - self.start_ipc_and_restful_server() - remote = Client('/') - - guid = remote.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - self.touch(('file', 'blob')) - remote.Context(guid).upload_blob('preview', 'file') - self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) - - cache_path = 'cache/context/%s/%s/preview' % (guid[:2], guid) - self.assertEqual(3, json.load(file(cache_path + '.meta'))['seqno']) - - # Shift seqno - remote.Context(guid, title='title-1').post() - remote.Context(guid, title='title-2').post() - remote.Context(guid, title='title-3').post() - coroutine.sleep(1) - - remote.close() - self.stop_servers() - self.start_ipc_and_restful_server() - remote = Client('/') - - self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) - self.assertEqual(6, json.load(file(cache_path + '.meta'))['seqno']) - - def test_OnlineMount_GetAbsetnBLOB(self): - self.start_ipc_and_restful_server() - client = Client('/') - - guid = client.Context( - type='activity', - title='title', - summary='summary', - description='description').post() - - path, mime_type = client.Context(guid).get_blob_path('icon') - self.assertEqual(None, path) - self.assertEqual(True, client.Context(guid).get_blob('icon').closed) - - def test_OnlineMount_Localize(self): - os.environ['LANG'] = 'en_US' - self.start_ipc_and_restful_server() - client = Client('/') - - guid = client.Context( - type='activity', - title='title_en', - summary='summary_en', - description='description_en').post() - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'ru_RU' - self.start_ipc_and_restful_server() - client = Client('/') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - res['title'] = 'title_ru' - res['summary'] = 'summary_ru' - res['description'] = 'description_ru' - res.post() - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_ru', res['title']) - self.assertEqual('summary_ru', res['summary']) - self.assertEqual('description_ru', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'es_ES' - self.start_ipc_and_restful_server() - client = Client('/') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_en', res['title']) - self.assertEqual('summary_en', res['summary']) - self.assertEqual('description_en', res['description']) - - self.stop_servers() - os.environ['LANG'] = 'ru_RU' - self.start_ipc_and_restful_server() - client = Client('/') - - res = client.Context(guid, ['title', 'summary', 'description']) - self.assertEqual('title_ru', res['title']) - self.assertEqual('summary_ru', res['summary']) - self.assertEqual('description_ru', res['description']) - - -if __name__ == '__main__': - tests.main() diff --git a/tests/units/mountset.py b/tests/units/mountset.py index 2edb090..c58728e 100755 --- a/tests/units/mountset.py +++ b/tests/units/mountset.py @@ -34,7 +34,7 @@ class MountsetTest(tests.Test): volume = Volume('local', [User, Context]) mounts = Mountset(volume) - Client.connection = mounts + Client._connection = mounts self.mounted = coroutine.Event() def events_cb(event): diff --git a/tests/units/node_mount.py b/tests/units/node_mount.py index cb8cfe7..f5826c4 100755 --- a/tests/units/node_mount.py +++ b/tests/units/node_mount.py @@ -32,7 +32,7 @@ class NodeMountTest(tests.Test): volume = Volume('local', [User, Context]) mounts = Mountset(volume) - Client.connection = mounts + Client._connection = mounts self.got_event = coroutine.Event() def events_cb(event): @@ -184,7 +184,7 @@ class NodeMountTest(tests.Test): description='description').post() got_commit.wait() self.assertEqual([ - {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'create', 'guid': guid}, + {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'create', 'guid': guid, 'seqno': 1}, {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'commit', 'seqno': 1}, ], events) @@ -193,7 +193,7 @@ class NodeMountTest(tests.Test): client.Context(guid, title='new-title').post() got_commit.wait() self.assertEqual([ - {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'update', 'guid': guid}, + {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'update', 'guid': guid, 'seqno': 2}, {'mountpoint': tests.tmpdir + '/mnt', 'document': 'context', 'event': 'commit', 'seqno': 2}, ], events) diff --git a/tests/units/remote_mount.py b/tests/units/remote_mount.py new file mode 100755 index 0000000..62a81ac --- /dev/null +++ b/tests/units/remote_mount.py @@ -0,0 +1,380 @@ +#!/usr/bin/env python +# sugar-lint: disable + +import os +import json +import socket +from cStringIO import StringIO +from os.path import exists + +from __init__ import tests + +from active_toolkit import sockets, coroutine +from sugar_network import Client, ServerError +from sugar_network.local.mounts import RemoteMount +from sugar_network.local.mountset import Mountset +from sugar_network.local.bus import IPCServer +from sugar_network.toolkit import sugar, http +from sugar_network.resources.user import User +from sugar_network.resources.context import Context +from sugar_network.resources.volume import Volume + + +class RemoteMountTest(tests.Test): + + def test_GetKeep(self): + self.start_ipc_and_restful_server() + + remote = Client('/') + + guid = remote.Context( + type='activity', + title='remote', + summary='summary', + description='description').post() + + context = remote.Context(guid, ['keep', 'keep_impl']) + self.assertEqual(False, context['keep']) + self.assertEqual(0, context['keep_impl']) + self.assertEqual( + [(guid, False, False)], + [(i['guid'], i['keep'], i['keep_impl']) for i in remote.Context.cursor(reply=['keep', 'keep_impl'])]) + + self.mounts.home_volume['context'].create(guid=guid, type='activity', + title={'en': 'local'}, summary={'en': 'summary'}, + description={'en': 'description'}, keep=True, keep_impl=2, + user=[sugar.uid()]) + + context = remote.Context(guid, ['keep', 'keep_impl']) + self.assertEqual(True, context['keep']) + self.assertEqual(2, context['keep_impl']) + self.assertEqual( + [(guid, True, 2)], + [(i['guid'], i['keep'], i['keep_impl']) for i in remote.Context.cursor(reply=['keep', 'keep_impl'])]) + + def test_SetKeep(self): + self.start_ipc_and_restful_server() + + remote = Client('/') + local = Client('~') + + guid_1 = remote.Context( + type=['activity'], + title='remote', + summary='summary', + description='description').post() + guid_2 = remote.Context( + type=['activity'], + title='remote-2', + summary='summary', + description='description').post() + + self.assertRaises(ServerError, lambda: local.Context(guid_1, reply=['title'])['title']) + self.assertRaises(ServerError, lambda: local.Context(guid_2, reply=['title'])['title']) + + remote.Context(guid_1, keep=True).post() + + cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'remote', True, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'remote', True, 0), + (guid_2, 'remote-2', False, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + + remote.Context(guid_1, keep=False).post() + + cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'remote', False, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'remote', False, 0), + (guid_2, 'remote-2', False, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + + context = local.Context(guid_1) + context['title'] = 'local' + context.post() + context = local.Context(guid_1, reply=['keep', 'keep_impl', 'title']) + self.assertEqual('local', context['title']) + + remote.Context(guid_1, keep=True).post() + + cursor = local.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'local', True, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + cursor = remote.Context.cursor(reply=['keep', 'keep_impl', 'title']) + self.assertEqual( + sorted([ + (guid_1, 'remote', True, 0), + (guid_2, 'remote-2', False, 0), + ]), + sorted([(i.guid, i['title'], i['keep'], i['keep_impl']) for i in cursor])) + + def test_Subscription(self): + self.fork(self.restful_server) + coroutine.sleep(1) + + self.start_server() + client = Client('/') + + subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) + subscription.connect('run/subscribe') + coroutine.sleep(1) + + guid = client.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + self.assertEqual( + {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, + subscription.read_message()) + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('props') + event.pop('seqno') + self.assertEqual( + {'mountpoint': '/', 'document': 'context', 'event': 'create', 'guid': guid}, + event) + + client.Context(guid, title='new-title').post() + + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('props') + event.pop('seqno') + self.assertEqual( + {'mountpoint': '/', 'document': 'context', 'event': 'update', 'guid': guid}, + event) + + client.Context.delete(guid) + + coroutine.select([subscription.fileno()], [], []) + event = subscription.read_message() + event.pop('seqno') + self.assertEqual( + {'mountpoint': '/', 'document': 'context', 'event': 'delete', 'guid': guid}, + event) + + def test_Connect(self): + pid = self.fork(self.restful_server) + volume = Volume('local', [User, Context]) + mounts = Mountset(volume) + mounts['/'] = RemoteMount(volume) + ipc_server = IPCServer(mounts) + coroutine.spawn(ipc_server.serve_forever) + + client = Client('/') + subscription = sockets.SocketFile(coroutine.socket(socket.AF_UNIX)) + subscription.connect('run/subscribe') + + mounts.open() + coroutine.dispatch() + + coroutine.select([subscription.fileno()], [], []) + self.assertEqual( + {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, + subscription.read_message()) + self.assertEqual(True, client.connected) + + self.waitpid(pid) + + coroutine.select([subscription.fileno()], [], []) + self.assertEqual( + {'mountpoint': '/', 'event': 'unmount', 'document': '*', 'name': 'Network', 'private': False}, + subscription.read_message()) + self.assertEqual(False, client.connected) + + pid = self.fork(self.restful_server) + coroutine.sleep(1) + + self.assertEqual(False, client.connected) + coroutine.select([subscription.fileno()], [], []) + self.assertEqual( + {'mountpoint': '/', 'event': 'mount', 'document': '*', 'name': 'Network', 'private': False}, + subscription.read_message()) + self.assertEqual(True, client.connected) + + self.waitpid(pid) + + coroutine.select([subscription.fileno()], [], []) + self.assertEqual( + {'mountpoint': '/', 'event': 'unmount', 'document': '*', 'name': 'Network', 'private': False}, + subscription.read_message()) + self.assertEqual(False, client.connected) + + def test_upload_blob(self): + self.start_ipc_and_restful_server() + remote = Client('/') + + guid = remote.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + self.touch(('file', 'blob')) + remote.Context(guid).upload_blob('preview', 'file') + self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) + + self.touch(('file2', 'blob2')) + remote.Context(guid).upload_blob('preview', 'file2', pass_ownership=True) + self.assertEqual('blob2', remote.Context(guid).get_blob('preview').read()) + assert not exists('file2') + + def test_StaleBLOBs(self): + self.start_ipc_and_restful_server() + remote = Client('/') + + guid = remote.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + http.request('PUT', ['context', guid, 'preview'], files={'file': StringIO('blob-1')}) + self.assertEqual('blob-1', remote.Context(guid).get_blob('preview').read()) + + cache_path = 'cache/context/%s/%s/preview' % (guid[:2], guid) + self.touch((cache_path, 'blob-2')) + self.assertEqual('blob-2', remote.Context(guid).get_blob('preview').read()) + self.assertEqual(3, json.load(file(cache_path + '.meta'))['seqno']) + + http.request('PUT', ['context', guid, 'preview'], files={'file': StringIO('blob-3')}) + self.assertEqual('blob-3', remote.Context(guid).get_blob('preview').read()) + self.assertEqual(4, json.load(file(cache_path + '.meta'))['seqno']) + + def test_DoNotStaleBLOBs(self): + self.start_ipc_and_restful_server() + remote = Client('/') + + guid = http.request('POST', ['context'], + headers={'Content-Type': 'application/json'}, + data={ + 'type': 'activity', + 'title': 'title', + 'summary': 'summary', + 'description': 'description', + }) + + http.request('PUT', ['context', guid, 'preview'], files={'file': StringIO('blob')}) + self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) + + cache_path = 'cache/context/%s/%s/preview' % (guid[:2], guid) + self.assertEqual(3, json.load(file(cache_path + '.meta'))['seqno']) + + # Shift seqno + http.request('POST', ['context'], + headers={'Content-Type': 'application/json'}, + data={ + 'type': 'activity', + 'title': 'title2', + 'summary': 'summary2', + 'description': 'description2', + }) + coroutine.sleep(1) + + remote.close() + self.stop_servers() + self.start_ipc_and_restful_server() + remote = Client('/') + + self.assertEqual('blob', remote.Context(guid).get_blob('preview').read()) + self.assertEqual(4, json.load(file(cache_path + '.meta'))['seqno']) + + + + + + + + def test_GetAbsentBLOB(self): + self.start_ipc_and_restful_server() + client = Client('/') + + guid = client.Context( + type='activity', + title='title', + summary='summary', + description='description').post() + + path, mime_type = client.Context(guid).get_blob_path('icon') + self.assertEqual(None, path) + self.assertEqual(True, client.Context(guid).get_blob('icon').closed) + + def test_Localize(self): + os.environ['LANG'] = 'en_US' + self.start_ipc_and_restful_server() + client = Client('/') + + guid = client.Context( + type='activity', + title='title_en', + summary='summary_en', + description='description_en').post() + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'ru_RU' + self.start_ipc_and_restful_server() + client = Client('/') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + res['title'] = 'title_ru' + res['summary'] = 'summary_ru' + res['description'] = 'description_ru' + res.post() + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_ru', res['title']) + self.assertEqual('summary_ru', res['summary']) + self.assertEqual('description_ru', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'es_ES' + self.start_ipc_and_restful_server() + client = Client('/') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_en', res['title']) + self.assertEqual('summary_en', res['summary']) + self.assertEqual('description_en', res['description']) + + self.stop_servers() + os.environ['LANG'] = 'ru_RU' + self.start_ipc_and_restful_server() + client = Client('/') + + res = client.Context(guid, ['title', 'summary', 'description']) + self.assertEqual('title_ru', res['title']) + self.assertEqual('summary_ru', res['summary']) + self.assertEqual('description_ru', res['description']) + + +if __name__ == '__main__': + tests.main() diff --git a/tests/units/subscribe_socket.py b/tests/units/subscribe_socket.py index 4e8c6c2..f63329b 100755 --- a/tests/units/subscribe_socket.py +++ b/tests/units/subscribe_socket.py @@ -25,7 +25,7 @@ class SubscribeSocketTest(tests.Test): return result def test_Subscribe(self): - node.only_sync_notification.value = False + node.only_commit_events.value = False self.fork(self.restful_server, [User, Document]) rest = tests.Request('http://localhost:8800') @@ -38,6 +38,7 @@ class SubscribeSocketTest(tests.Test): event = subscription.read_message() event.pop('props') + event.pop('seqno') self.assertEqual({ 'guid': guid, 'document': 'document', @@ -52,6 +53,7 @@ class SubscribeSocketTest(tests.Test): event = subscription.read_message() event.pop('props') + event.pop('seqno') self.assertEqual({ 'event': 'update', 'document': 'document', @@ -61,18 +63,19 @@ class SubscribeSocketTest(tests.Test): rest.delete('/document/' + guid) self.assertRaises(RuntimeError, rest.get, '/document/' + guid) - + event = subscription.read_message() + event.pop('seqno') self.assertEqual({ 'event': 'delete', 'document': 'document', 'guid': guid, }, - subscription.read_message()) + event) self.assertRaises(socket.timeout, socket.wait_read, subscription.fileno(), 1) def test_OnlySyncEvents(self): - node.only_sync_notification.value = True + node.only_commit_events.value = True self.fork(self.restful_server, [User, Document]) rest = tests.Request('http://localhost:8800') @@ -82,7 +85,7 @@ class SubscribeSocketTest(tests.Test): self.assertEqual({ 'document': 'document', - 'event': 'sync', + 'event': 'commit', 'seqno': 2, }, subscription.read_message()) @@ -91,7 +94,7 @@ class SubscribeSocketTest(tests.Test): self.assertEqual({ 'document': 'document', - 'event': 'sync', + 'event': 'commit', 'seqno': 3, }, subscription.read_message()) @@ -100,7 +103,7 @@ class SubscribeSocketTest(tests.Test): self.assertEqual({ 'document': 'document', - 'event': 'sync', + 'event': 'commit', 'seqno': 4, }, subscription.read_message()) |