diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-09-18 22:36:10 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-09-18 22:36:10 (GMT) |
commit | 59d3250fc511bd75ff722872b914fd0e4633c8e2 (patch) | |
tree | 46798c411ba665c36b61f55789108c481ad2a35c | |
parent | 595bcf11f40b09d8bc6e9e27335e927f56d224cc (diff) |
Switch to pre/post commands code; return local BLOB urls for IPC requests
-rwxr-xr-x | sugar-network-service | 8 | ||||
-rw-r--r-- | sugar_network/local/mounts.py | 22 | ||||
-rw-r--r-- | sugar_network/local/mountset.py | 86 | ||||
-rw-r--r-- | sugar_network/node/commands.py | 149 | ||||
-rw-r--r-- | sugar_network/resources/volume.py | 19 | ||||
-rw-r--r-- | sugar_network/toolkit/dbus_thread.py | 3 | ||||
-rw-r--r-- | sugar_network/toolkit/http.py | 11 | ||||
-rw-r--r-- | sugar_network/toolkit/router.py | 12 | ||||
-rwxr-xr-x | tests/units/activities.py | 36 | ||||
-rwxr-xr-x | tests/units/datastore.py | 4 | ||||
-rwxr-xr-x | tests/units/injector.py | 2 | ||||
-rwxr-xr-x | tests/units/node_mount.py | 8 | ||||
-rwxr-xr-x | tests/units/remote_mount.py | 2 | ||||
-rwxr-xr-x | tests/units/volume.py | 4 |
14 files changed, 204 insertions, 162 deletions
diff --git a/sugar-network-service b/sugar-network-service index d461457..37cb2f2 100755 --- a/sugar-network-service +++ b/sugar-network-service @@ -166,9 +166,9 @@ class Application(application.Application): logging.info('Proceed delayed start') mountset.disconnect(delayed_start) - mountset.home_volume.populate() - datastore.populate(mountset.home_volume['artifact']) - self._sync(mountset.home_volume) + mountset.volume.populate() + datastore.populate(mountset.volume['artifact']) + self._sync(mountset.volume) logging.info('Listening for IPC requests on %s port', local.ipc_port.value) @@ -176,7 +176,7 @@ class Application(application.Application): Router(mountset)) jobs.spawn(server.serve_forever) - jobs.spawn(activities.monitor, mountset.home_volume['context'], + jobs.spawn(activities.monitor, mountset.volume['context'], local.activity_dirs.value) if webui.webui.value: diff --git a/sugar_network/local/mounts.py b/sugar_network/local/mounts.py index d0297b5..a526840 100644 --- a/sugar_network/local/mounts.py +++ b/sugar_network/local/mounts.py @@ -25,6 +25,7 @@ import active_document as ad from sweets_recipe import Bundle from sugar_network.toolkit import sugar, http from sugar_network.local import activities, cache +from sugar_network.resources.volume import Request from sugar_network import local, checkin, sugar from active_toolkit import util, coroutine, enforce @@ -135,7 +136,6 @@ class HomeMount(LocalMount): util.exception(_logger, 'Failed to read %r spec file', path) continue - print '>', request.access_level == ad.ACCESS_LOCAL if request.access_level == ad.ACCESS_LOCAL: impl_id = spec.root else: @@ -245,10 +245,9 @@ class _ProxyCommands(object): if home.exists(guid): home.update(guid, patch) elif [True for prop, value in patch.items() if value]: - clone = ad.Request(method='GET', document='context', - guid=guid) - clone.accept_language = request.accept_language - props = super_call(clone, ad.Response()) + copy = Request(method='GET', document='context', guid=guid) + copy.accept_language = request.accept_language + props = super_call(copy, ad.Response()) props.update(patch) props['guid'] = guid props['user'] = [sugar.uid()] @@ -341,6 +340,19 @@ class RemoteMount(ad.CommandsProcessor, _Mount, _ProxyCommands): if pass_ownership and exists(path): os.unlink(path) + @ad.property_command(method='GET') + def get_prop(self, document, guid, prop, response): + directory = self._home_volume[document] + prop = directory.metadata[prop] + + if not isinstance(prop, ad.BlobProperty): + raise ad.CommandNotFound() + + meta = self.get_blob(document, guid, prop.name) + enforce(meta is not None, ad.NotFound) + response.content_type = meta['mime_type'] + return file(meta['path'], 'rb') + def mount(self, url=None): if url and url not in self._api_urls: self._api_urls.append(url) diff --git a/sugar_network/local/mountset.py b/sugar_network/local/mountset.py index 8fd63a1..7cba34b 100644 --- a/sugar_network/local/mountset.py +++ b/sugar_network/local/mountset.py @@ -25,7 +25,7 @@ from sugar_network.toolkit.router import Router from sugar_network.local.mounts import LocalMount, NodeMount from sugar_network.node.commands import NodeCommands from sugar_network.node.sync_node import SyncCommands -from sugar_network.resources.volume import Volume, Commands +from sugar_network.resources.volume import Volume, Commands, Request from active_toolkit import util, coroutine, enforce @@ -38,14 +38,13 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): def __init__(self, home_volume): self.opened = coroutine.Event() - self.home_volume = home_volume self._subscriptions = {} self._lang = ad.default_lang() self._jobs = coroutine.Pool() self._servers = coroutine.Pool() dict.__init__(self) - ad.CommandsProcessor.__init__(self) + ad.CommandsProcessor.__init__(self, home_volume) SyncCommands.__init__(self, local.path('sync')) Commands.__init__(self) @@ -94,7 +93,7 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): for guid in (request.content or '').split(): _logger.info('Checkin %r context', guid) mount.call( - ad.Request(method='PUT', document='context', guid=guid, + Request(method='PUT', document='context', guid=guid, accept_language=[self._lang], content={'keep_impl': 2, 'keep': False}), ad.Response()) @@ -108,7 +107,7 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): for guid in (request.content or '').split(): _logger.info('Keep %r context', guid) mount.call( - ad.Request(method='PUT', document='context', guid=guid, + Request(method='PUT', document='context', guid=guid, accept_language=[self._lang], content={'keep': True}), ad.Response()) @@ -123,7 +122,7 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): for guid in [context] if isinstance(context, basestring) else context: feed = mount.call( - ad.Request(method='GET', document='context', guid=guid, + Request(method='GET', document='context', guid=guid, prop='feed', accept_language=[self._lang]), ad.Response()) for impls in feed.values(): @@ -133,31 +132,25 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): return list(requires) + def super_call(self, request, response): + if 'mountpoint' in request: + mountpoint = request.pop('mountpoint') + else: + mountpoint = '/' + mount = self[mountpoint] + if mountpoint == '/': + mount.set_mounted(True) + enforce(mount.mounted.is_set(), '%r is not mounted', mountpoint) + return mount.call(request, response) + def call(self, request, response=None): if response is None: response = ad.Response() request.accept_language = [self._lang] - mountpoint = request.get('mountpoint') or '/' - try: - try: - result = ad.CommandsProcessor.call(self, request, response) - except ad.CommandNotFound: - if 'mountpoint' in request: - request.pop('mountpoint') - mount = self[mountpoint] - if mountpoint == '/': - mount.set_mounted(True) - enforce(mount.mounted.is_set(), - '%r is not mounted', mountpoint) - result = mount.call(request, response) - except Exception: - util.exception(_logger, 'Failed to call %s on %r', - request, mountpoint) - raise - - _logger.debug('Called %s on %r: %r', request, mountpoint, result) - return result + return ad.CommandsProcessor.call(self, request, response) + except ad.CommandNotFound: + return self.super_call(request, response) def connect(self, callback, condition=None, **kwargs): self._subscriptions[callback] = condition or kwargs @@ -196,8 +189,43 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): self._jobs.kill() for mountpoint in self.keys(): del self[mountpoint] - if self.home_volume is not None: - self.home_volume.close() + if self.volume is not None: + self.volume.close() + + @ad.directory_command_pre(method='GET', arguments={'reply': ad.to_list}) + def _Mountset_find_pre(self, request): + self._exclude_blobs(request) + + @ad.directory_command_post(method='GET') + def _Mountset_find_post(self, request, response, result): + self._include_blobs(request, result['result']) + return result + + @ad.document_command_pre(method='GET', arguments={'reply': ad.to_list}) + def _Mountset_get_pre(self, request): + self._exclude_blobs(request) + + @ad.document_command_post(method='GET') + def _Mountset_get_post(self, request, response, result): + self._include_blobs(request, [result]) + return result + + def _exclude_blobs(self, request): + reply = request.get('reply') + if reply: + reply_set = set(reply) + request.blobs = reply_set & self.get_blobs(request['document']) + if request.blobs: + reply[:] = list(reply_set - request.blobs) + + def _include_blobs(self, request, result): + if not request.blobs: + return + for props in result: + guid = props.get('guid') or request['guid'] + for name in request.blobs: + props[name] = 'http://localhost:%s/%s/%s/%s' % \ + (local.ipc_port.value, request['document'], guid, name) def _discover_masters(self): for host in zeroconf.browse_workstations(): @@ -220,7 +248,7 @@ class Mountset(dict, ad.CommandsProcessor, Commands, SyncCommands): volume, server_mode = self._mount_volume(path) if server_mode: _logger.debug('Mount %r in node mode', path) - self[path] = self.node_mount = NodeMount(volume, self.home_volume) + self[path] = self.node_mount = NodeMount(volume, self.volume) else: _logger.debug('Mount %r in node-less mode', path) self[path] = LocalMount(volume) diff --git a/sugar_network/node/commands.py b/sugar_network/node/commands.py index e8f2e03..6bceb68 100644 --- a/sugar_network/node/commands.py +++ b/sugar_network/node/commands.py @@ -57,13 +57,6 @@ class NodeCommands(ad.VolumeCommands, Commands): with file(master_path, 'w') as f: f.write(_DEFAULT_MASTER_GUID) - self._blobs = {} - for document, directory in self.volume.items(): - self._blobs.setdefault(document, set()) - for prop in directory.metadata.values(): - if isinstance(prop, ad.BlobProperty): - self._blobs[document].add(prop.name) - def connect(self, callback, condition=None, **kwargs): self.volume.connect(callback, condition) @@ -87,64 +80,6 @@ class NodeCommands(ad.VolumeCommands, Commands): directory = self.volume[document] directory.update(guid, {'layer': ['deleted']}) - @ad.directory_command(method='GET', - arguments={'offset': ad.to_int, 'limit': ad.to_int, - 'reply': ad.to_list}) - def find(self, document, request, offset=None, limit=None, query=None, - reply=None, order_by=None, group_by=None, **kwargs): - if limit is None: - limit = node.find_limit.value - elif limit > node.find_limit.value: - _logger.warning('The find limit is restricted to %s', - node.find_limit.value) - limit = node.find_limit.value - - blobs = None - if reply: - reply = set(reply) - blobs = reply & self._blobs[document] - reply = list(reply - blobs) - - layer = kwargs.get('layer', ['public']) - if isinstance(layer, basestring): - layer = [layer] - if 'deleted' in layer: - _logger.warning('Requesting "deleted" layer') - layer.remove('deleted') - kwargs['layer'] = layer - - result = ad.VolumeCommands.find(self, document, request, offset, limit, - query, reply, order_by, group_by, **kwargs) - - if blobs: - for props in result['result']: - self._mixin_blob(document, blobs, props) - - return result - - @ad.document_command(method='GET', arguments={'reply': ad.to_list}) - def get(self, document, guid, request, reply=None): - blobs = None - if reply: - reply = set(reply) - blobs = reply & self._blobs[document] - reply = list(reply - blobs) - - if reply: - if 'layer' not in reply: - reply.append('layer') - if 'guid' not in reply: - reply.append('guid') - - result = ad.VolumeCommands.get(self, document, guid, request, reply) - enforce('deleted' not in result['layer'], ad.NotFound, - 'Document is not found') - - if blobs: - self._mixin_blob(document, blobs, result) - - return result - def resolve(self, request): cmd = ad.VolumeCommands.resolve(self, request) if cmd is None: @@ -174,6 +109,68 @@ class NodeCommands(ad.VolumeCommands, Commands): self._set_author(props) ad.VolumeCommands.before_update(self, request, props) + @ad.directory_command_pre(method='GET') + def _NodeCommands_find_pre(self, request): + if 'limit' not in request: + request['limit'] = node.find_limit.value + elif request['limit'] > node.find_limit.value: + _logger.warning('The find limit is restricted to %s', + node.find_limit.value) + request['limit'] = node.find_limit.value + + layer = request.get('layer', ['public']) + if 'deleted' in layer: + _logger.warning('Requesting "deleted" layer') + layer.remove('deleted') + request['layer'] = layer + + @ad.directory_command_post(method='GET') + def _NodeCommands_find_post(self, request, response, result): + self._mixin_blobs(request, result['result']) + return result + + @ad.document_command_post(method='GET') + def _NodeCommands_get_post(self, request, response, result): + directory = self.volume[request['document']] + doc = directory.get(request['guid']) + enforce('deleted' not in doc['layer'], ad.NotFound, + 'Document deleted') + self._mixin_blobs(request, [result]) + return result + + def _mixin_blobs(self, request, result): + reply = request.get('reply') + if not reply: + return + + document = request['document'] + blobs = set(reply) & self.get_blobs(document) + if not blobs: + return + + for props in result: + guid = props.get('guid') or request['guid'] + doc = self.volume[document].get(guid) + for name in blobs: + + def compose_url(value): + if value is None: + value = '/'.join(['', document, guid, name]) + if value.startswith('/'): + value = 'http://%s:%s%s' % \ + (node.host.value, node.port.value, value) + return value + + url = None + meta = doc.meta(name) + if meta is not None: + url = meta.url() + + if type(url) is list: + props[name] = [compose_url(i.get('url')) for i in url] + else: + props[name] = compose_url(url) + def _set_author(self, props): users = self.volume['user'] authors = [] @@ -187,28 +184,6 @@ class NodeCommands(ad.VolumeCommands, Commands): authors.append(user['name']) props['author'] = authors - def _mixin_blob(self, document, blobs, props): - doc = self.volume[document].get(props['guid']) - for name in blobs: - - def compose_url(value): - if value is None: - value = '/'.join(['', document, props['guid'], name]) - if value.startswith('/'): - value = 'http://%s:%s%s' % \ - (node.host.value, node.port.value, value) - return value - - url = None - meta = doc.meta(name) - if meta is not None: - url = meta.url() - - if type(url) is list: - props[name] = [compose_url(i.get('url')) for i in url] - else: - props[name] = compose_url(url) - class MasterCommands(NodeCommands, SyncCommands): diff --git a/sugar_network/resources/volume.py b/sugar_network/resources/volume.py index ac9c7ef..975330e 100644 --- a/sugar_network/resources/volume.py +++ b/sugar_network/resources/volume.py @@ -18,16 +18,23 @@ import logging from os.path import join import active_document as ad +from active_document import directory as ad_directory from active_toolkit import coroutine from sugar_network.toolkit.sneakernet import DiskFull from sugar_network.toolkit.collection import Sequence +ad_directory._LAYOUT_VERSION = 2 _DIFF_CHUNK = 1024 _logger = logging.getLogger('resources.volume') +class Request(ad.Request): + + blobs = None + + class Resource(ad.Document): @ad.active_property(prefix='RU', typecast=[], default=[], @@ -136,8 +143,11 @@ class Volume(ad.SingleVolume): class Commands(object): + volume = None + def __init__(self): self._notifier = coroutine.AsyncResult() + self._blobs = {} self.connect(lambda event: self._notify(event)) def connect(self, callback, condition=None, **kwargs): @@ -156,6 +166,15 @@ class Commands(object): response['Cache-Control'] = 'no-cache' return self._pull_events(only_commits) + def get_blobs(self, document): + blobs = self._blobs.get(document) + if blobs is None: + blobs = self._blobs[document] = set() + for prop in self.volume[document].metadata.values(): + if isinstance(prop, ad.BlobProperty): + blobs.add(prop.name) + return blobs + def _pull_events(self, only_commits): # Otherwise, gevent's WSGI server doesn't sent HTTP status yield '\n' diff --git a/sugar_network/toolkit/dbus_thread.py b/sugar_network/toolkit/dbus_thread.py index 1cf2380..1d87c67 100644 --- a/sugar_network/toolkit/dbus_thread.py +++ b/sugar_network/toolkit/dbus_thread.py @@ -24,6 +24,7 @@ from dbus.mainloop.glib import threads_init, DBusGMainLoop import active_document as ad from active_toolkit import util, coroutine from sugar_network.toolkit import sugar +from sugar_network.resources.volume import Request _logger = logging.getLogger('dbus_thread') @@ -90,7 +91,7 @@ class Service(Object): def call(self, reply_cb, error_cb, content=None, content_stream=None, content_length=None, args=None, **kwargs): """Call a command in parent thread.""" - request = ad.Request(kwargs) + request = Request(kwargs) request.principal = sugar.uid() request.access_level = ad.ACCESS_LOCAL request.content = content diff --git a/sugar_network/toolkit/http.py b/sugar_network/toolkit/http.py index 627103d..36b1bfb 100644 --- a/sugar_network/toolkit/http.py +++ b/sugar_network/toolkit/http.py @@ -93,10 +93,11 @@ class Client(object): return response def call(self, request): - method = request.pop('method') - document = request.pop('document') - guid = request.pop('guid') if 'guid' in request else None - prop = request.pop('prop') if 'prop' in request else None + params = request.copy() + method = params.pop('method') + document = params.pop('document') + guid = params.pop('guid') if 'guid' in params else None + prop = params.pop('prop') if 'prop' in params else None path = [document] if guid: @@ -104,7 +105,7 @@ class Client(object): if prop: path.append(prop) - return self.request(method, path, data=request.content, params=request, + return self.request(method, path, data=request.content, params=params, headers={'Content-Type': 'application/json'}) def download(self, url_path, out_path, seqno=None, extract=False): diff --git a/sugar_network/toolkit/router.py b/sugar_network/toolkit/router.py index d02dd28..08f70a3 100644 --- a/sugar_network/toolkit/router.py +++ b/sugar_network/toolkit/router.py @@ -24,6 +24,7 @@ from os.path import join, isfile import active_document as ad from sugar_network import static +from sugar_network.resources.volume import Request from active_toolkit.sockets import BUFFER_SIZE from active_toolkit import util, enforce @@ -67,7 +68,7 @@ class Router(object): if user not in self._authenticated and \ (request.path != ['user'] or request['method'] != 'POST'): _logger.debug('Logging %r user', user) - request = ad.Request(method='GET', cmd='exists', + request = Request(method='GET', cmd='exists', document='user', guid=user) enforce(self._cp.call(request, ad.Response()), Unauthorized, 'Principal user does not exist') @@ -116,6 +117,7 @@ class Router(object): def __call__(self, environ, start_response): request = _Request(environ) + request_repr = str(request) if _logger.level <= logging.DEBUG else None response = _Response() js_callback = None @@ -128,7 +130,7 @@ class Router(object): except ad.Redirect, error: response.status = '303 See Other' response['Location'] = error.location - result = '' + response.content_type = None except Exception, error: util.exception('Error while processing %r request', environ['PATH_INFO'] or '/') @@ -164,7 +166,7 @@ class Router(object): response.content_length = len(result) _logger.debug('Called %s: response=%r result=%r streamed=%r', - request, response, result, result_streamed) + request_repr, response, result, result_streamed) start_response(response.status, response.items()) @@ -175,10 +177,10 @@ class Router(object): yield result -class _Request(ad.Request): +class _Request(Request): def __init__(self, environ): - ad.Request.__init__(self) + Request.__init__(self) self.access_level = ad.ACCESS_REMOTE self.environ = environ diff --git a/tests/units/activities.py b/tests/units/activities.py index 077e6dc..9636d93 100755 --- a/tests/units/activities.py +++ b/tests/units/activities.py @@ -37,7 +37,7 @@ class ActivitiesTest(tests.Test): def test_Inotify_NoPermissions(self): assert not exists('/foo/bar') - inotify = activities._Inotify(self.mounts.home_volume['context']) + inotify = activities._Inotify(self.mounts.volume['context']) inotify.setup(['/foo/bar']) assert not exists('/foo/bar') @@ -52,7 +52,7 @@ class ActivitiesTest(tests.Test): found = [] lost = [] - inotify = activities._Inotify(self.mounts.home_volume['context']) + inotify = activities._Inotify(self.mounts.volume['context']) inotify.found = found.append inotify.lost = lost.append inotify.setup(['.']) @@ -118,7 +118,7 @@ class ActivitiesTest(tests.Test): found = [] lost = [] - inotify = activities._Inotify(self.mounts.home_volume['context']) + inotify = activities._Inotify(self.mounts.volume['context']) inotify.found = found.append inotify.lost = lost.append inotify.setup(['Activities']) @@ -166,10 +166,10 @@ class ActivitiesTest(tests.Test): def test_Checkin_Create(self): self.job = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) coroutine.sleep() - self.mounts.home_volume['context'].create( + self.mounts.volume['context'].create( guid='org.sugarlabs.HelloWorld', type='activity', title={'en': 'title'}, summary={'en': 'summary'}, description={'en': 'description'}, user=[sugar.uid()]) @@ -207,7 +207,7 @@ class ActivitiesTest(tests.Test): os.readlink('activities/context/org.sugarlabs.HelloWorld/' + hashed_path)) self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'title'}, 'keep': False, 'keep_impl': 2}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) assert exists('share/icons/sugar/scalable/mimetypes/foo-bar.svg') self.assertEqual( tests.tmpdir + '/Activities/activity/activity/icon.svg', @@ -220,10 +220,10 @@ class ActivitiesTest(tests.Test): def test_Checkin_Copy(self): self.job = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) coroutine.sleep() - self.mounts.home_volume['context'].create( + self.mounts.volume['context'].create( guid='org.sugarlabs.HelloWorld', type='activity', title={'en': 'title'}, summary={'en': 'summary'}, description={'en': 'description'}, user=[sugar.uid()]) @@ -247,14 +247,14 @@ class ActivitiesTest(tests.Test): os.readlink('activities/context/org.sugarlabs.HelloWorld/' + hashed_path)) self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'title'}, 'keep': False, 'keep_impl': 2}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) def test_Checkin_Hardlink(self): self.job = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) coroutine.sleep() - self.mounts.home_volume['context'].create( + self.mounts.volume['context'].create( guid='org.sugarlabs.HelloWorld', type='activity', title={'en': 'title'}, summary={'en': 'summary'}, description={'en': 'description'}, user=[sugar.uid()]) @@ -280,11 +280,11 @@ class ActivitiesTest(tests.Test): os.readlink('activities/context/org.sugarlabs.HelloWorld/' + hashed_path)) self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'title'}, 'keep': False, 'keep_impl': 2}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) def test_OfflineCheckin(self): self.job = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) coroutine.sleep() self.touch(('Activities/activity/activity/activity.info', [ @@ -306,13 +306,13 @@ class ActivitiesTest(tests.Test): self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'HelloWorld'}, 'keep': False, 'keep_impl': 2}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) def test_Checkout(self): self.job = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) - self.mounts.home_volume['context'].create( + self.mounts.volume['context'].create( guid='org.sugarlabs.HelloWorld', type='activity', title={'en': 'title'}, summary={'en': 'summary'}, description={'en': 'description'}, user=[sugar.uid()]) @@ -344,7 +344,7 @@ class ActivitiesTest(tests.Test): assert exists('activities/context/org.sugarlabs.HelloWorld/' + hashed_path) self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'title'}, 'keep': False, 'keep_impl': 2}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) assert exists('share/icons/sugar/scalable/mimetypes/foo-bar.svg') assert exists('share/mime/packages/%s.xml' % hashed_path) assert exists('share/mime/application/x-foo-bar.xml') @@ -356,7 +356,7 @@ class ActivitiesTest(tests.Test): assert not exists('activities/context/org.sugarlabs.HelloWorld/' + hashed_path) self.assertEqual( {'guid': 'org.sugarlabs.HelloWorld', 'title': {'en': 'title'}, 'keep': False, 'keep_impl': 0}, - self.mounts.home_volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) + self.mounts.volume['context'].get('org.sugarlabs.HelloWorld').properties(['guid', 'title', 'keep', 'keep_impl'])) assert not lexists('share/icons/sugar/scalable/mimetypes/foo-bar.svg') assert not lexists('share/mime/packages/%s.xml' % hashed_path) assert not lexists('share/mime/application/x-foo-bar.xml') diff --git a/tests/units/datastore.py b/tests/units/datastore.py index 339e073..6f12f2e 100755 --- a/tests/units/datastore.py +++ b/tests/units/datastore.py @@ -18,7 +18,7 @@ class DatastoreTest(tests.Test): def test_populate_NothingToImport(self): self.create_mountset([Artifact]) - artifacts = self.mounts.home_volume['artifact'] + artifacts = self.mounts.volume['artifact'] ds_create('1', uid='1') datastore.populate(artifacts) @@ -41,7 +41,7 @@ class DatastoreTest(tests.Test): def test_populate(self): self.create_mountset([Artifact]) - artifacts = self.mounts.home_volume['artifact'] + artifacts = self.mounts.volume['artifact'] ds_create('1', data='data-1', diff --git a/tests/units/injector.py b/tests/units/injector.py index a69a2cf..ffc39be 100755 --- a/tests/units/injector.py +++ b/tests/units/injector.py @@ -266,7 +266,7 @@ class InjectorTest(tests.Test): client = IPCClient(mountpoint='~') monitor = coroutine.spawn(activities.monitor, - self.mounts.home_volume['context'], ['Activities']) + self.mounts.volume['context'], ['Activities']) coroutine.sleep() blob = client.get(['context', 'bundle_id', 'feed'], cmd='get_blob') diff --git a/tests/units/node_mount.py b/tests/units/node_mount.py index 6e864a3..0a67bc2 100755 --- a/tests/units/node_mount.py +++ b/tests/units/node_mount.py @@ -72,7 +72,7 @@ class NodeMountTest(tests.Test): ], remote.get(['context'], reply=['guid', 'keep', 'keep_impl'])['result']) - mounts.home_volume['context'].create(guid=guid, type='activity', + mounts.volume['context'].create(guid=guid, type='activity', title='local', summary='summary', description='description', keep=True, keep_impl=2, user=[sugar.uid()]) @@ -89,7 +89,7 @@ class NodeMountTest(tests.Test): def test_SetKeep(self): mounts = self.start_server() mounts[tests.tmpdir + '/mnt'].mounted.wait() - mounts['~'] = HomeMount(mounts.home_volume) + mounts['~'] = HomeMount(mounts.volume) local = IPCClient(mountpoint='~') remote = IPCClient(mountpoint=tests.tmpdir + '/mnt') @@ -166,10 +166,10 @@ class NodeMountTest(tests.Test): mounts = self.start_server() mounts[tests.tmpdir + '/mnt'].mounted.wait() - mounts['~'] = HomeMount(mounts.home_volume) + mounts['~'] = HomeMount(mounts.volume) local = IPCClient(mountpoint='~') remote = IPCClient(mountpoint=tests.tmpdir + '/mnt') - coroutine.spawn(activities.monitor, mounts.home_volume['context'], ['Activities']) + coroutine.spawn(activities.monitor, mounts.volume['context'], ['Activities']) context = remote.post(['context'], { 'type': 'activity', diff --git a/tests/units/remote_mount.py b/tests/units/remote_mount.py index 7ac5610..40e7cfb 100755 --- a/tests/units/remote_mount.py +++ b/tests/units/remote_mount.py @@ -43,7 +43,7 @@ class RemoteMountTest(tests.Test): [(guid, False, False)], [(i['guid'], i['keep'], i['keep_impl']) for i in cursor]) - self.mounts.home_volume['context'].create(guid=guid, type='activity', + self.mounts.volume['context'].create(guid=guid, type='activity', title={'en': 'local'}, summary={'en': 'summary'}, description={'en': 'description'}, keep=True, keep_impl=2, user=[sugar.uid()]) diff --git a/tests/units/volume.py b/tests/units/volume.py index 1642fb9..0c43b67 100755 --- a/tests/units/volume.py +++ b/tests/units/volume.py @@ -177,6 +177,8 @@ class VolumeTest(tests.Test): def read_events(): for event in cp.subscribe(ad.Response()): + if not event.strip(): + continue assert event.startswith('data: ') assert event.endswith('\n\n') event = json.loads(event[6:]) @@ -217,6 +219,8 @@ class VolumeTest(tests.Test): def read_events(): for event in cp.subscribe(ad.Response(), only_commits=True): + if not event.strip(): + continue assert event.startswith('data: ') assert event.endswith('\n\n') event = json.loads(event[6:]) |