diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2013-08-01 18:42:36 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2013-08-01 18:42:36 (GMT) |
commit | c5fb6a110e1fdf99b192e7029f29d73157c21d22 (patch) | |
tree | d153001a6f98e32548a74211142746c07db97519 | |
parent | edbccdb9861c291f6b26574ff3d54aec2733be79 (diff) |
Get rid of redundant "public" lauer
All objects without "deleted" layers are public.
-rw-r--r-- | sugar_network/db/directory.py | 68 | ||||
-rw-r--r-- | sugar_network/db/index.py | 116 | ||||
-rw-r--r-- | sugar_network/db/resource.py | 2 | ||||
-rw-r--r-- | sugar_network/node/routes.py | 21 | ||||
-rw-r--r-- | sugar_network/node/slave.py | 7 | ||||
-rw-r--r-- | sugar_network/toolkit/router.py | 11 | ||||
-rwxr-xr-x | tests/units/db/index.py | 60 | ||||
-rwxr-xr-x | tests/units/db/resource.py | 58 | ||||
-rwxr-xr-x | tests/units/db/routes.py | 28 | ||||
-rwxr-xr-x | tests/units/node/node.py | 16 | ||||
-rwxr-xr-x | tests/units/node/sync_offline.py | 6 | ||||
-rwxr-xr-x | tests/units/node/sync_online.py | 16 | ||||
-rwxr-xr-x | tests/units/node/volume.py | 22 |
13 files changed, 182 insertions, 249 deletions
diff --git a/sugar_network/db/directory.py b/sugar_network/db/directory.py index 08f1c35..b8d9176 100644 --- a/sugar_network/db/directory.py +++ b/sugar_network/db/directory.py @@ -152,42 +152,8 @@ class Directory(object): guid, self.metadata.name) return self.document_class(guid, record, cached_props) - def find(self, *args, **kwargs): - """Search documents. - - The result will be an array of dictionaries with found documents' - properties. - - :param offset: - the resulting list should start with this offset; - 0 by default - :param limit: - the resulting list will be at least `limit` size; - the `--find-limit` will be used by default - :param query: - a string in Xapian serach format, empty to avoid text search - :param reply: - an array of property names to use only in the resulting list; - only GUID property will be used by default - :param order_by: - property name to sort resulting list; might be prefixed with ``+`` - (or without any prefixes) for ascending order, and ``-`` for - descending order - :param group_by: - property name to group resulting list by; no groupping by default - :param kwargs: - a dictionary with property values to restrict the search - :returns: - a tuple of (`documents`, `total_count`); where the `total_count` is - the total number of documents conforming the search parameters, - i.e., not only documents that are included to the resulting list - - """ - # XXX Hardcode SN layers switch; Remove in 0.9 - if kwargs.get('layer') in ('peruvian-pilot', ['peruvian-pilot']): - kwargs['layer'] = 'pilot' - - mset = self._index.find(_Query(*args, **kwargs)) + def find(self, **kwargs): + mset = self._index.find(**kwargs) def iterate(): for hit in mset: @@ -403,33 +369,3 @@ class _SessionSeqno(object): def commit(self): pass - - -class _Query(object): - - def __init__(self, offset=None, limit=None, query='', reply=None, - order_by=None, no_cache=False, group_by=None, **kwargs): - self.query = query - self.no_cache = no_cache - self.group_by = group_by - - if offset is None: - offset = 0 - self.offset = offset - - self.limit = limit or 16 - - if reply is None: - reply = ['guid'] - self.reply = reply - - if order_by is None: - order_by = 'ctime' - self.order_by = order_by - - self.request = kwargs - - def __repr__(self): - return 'offset=%s limit=%s request=%r query=%r order_by=%s ' \ - 'group_by=%s' % (self.offset, self.limit, self.request, - self.query, self.order_by, self.group_by) diff --git a/sugar_network/db/index.py b/sugar_network/db/index.py index 3c8579f..156ff76 100644 --- a/sugar_network/db/index.py +++ b/sugar_network/db/index.py @@ -82,6 +82,9 @@ class IndexReader(object): pass os.utime(self._mtime_path, (value, value)) + def ensure_open(self): + pass + def get_cached(self, guid): """Return cached document. @@ -125,20 +128,46 @@ class IndexReader(object): """ raise NotImplementedError() - def find(self, query): - """Search documents within the index. - - Function interface is the same as for `db.Resource.find`. + def find(self, offset=0, limit=64, query='', reply=('guid',), + order_by=None, no_cache=False, group_by=None, **request): + """Search resources within the index. + + The result will be an array of dictionaries with found documents' + properties. + + :param offset: + the resulting list should start with this offset; + 0 by default + :param limit: + the resulting list will be at least `limit` size; + the `--find-limit` will be used by default + :param query: + a string in Xapian serach format, empty to avoid text search + :param reply: + an array of property names to use only in the resulting list; + only GUID property will be used by default + :param order_by: + property name to sort resulting list; might be prefixed with ``+`` + (or without any prefixes) for ascending order, and ``-`` for + descending order + :param group_by: + property name to group resulting list by; no groupping by default + :param request: + a dictionary with property values to restrict the search + :returns: + a tuple of (`documents`, `total_count`); where the `total_count` is + the total number of documents conforming the search parameters, + i.e., not only documents that are included to the resulting list """ + self.ensure_open() + start_timestamp = time.time() # This will assure that the results count is exact. - check_at_least = query.offset + query.limit + 1 + check_at_least = offset + limit + 1 - enquire = self._enquire(query.request, query.query, query.order_by, - query.group_by) - mset = self._call_db(enquire.get_mset, query.offset, query.limit, - check_at_least) + enquire = self._enquire(request, query, order_by, group_by) + mset = self._call_db(enquire.get_mset, offset, limit, check_at_least) _logger.debug('Found in %s: %s time=%s total=%s parsed=%s', self.metadata.name, query, time.time() - start_timestamp, @@ -152,7 +181,7 @@ class IndexReader(object): def _enquire(self, request, query, order_by, group_by): enquire = xapian.Enquire(self._db) - queries = [] + all_queries = [] and_not_queries = [] boolean_queries = [] @@ -184,50 +213,37 @@ class IndexReader(object): xapian.QueryParser.FLAG_WILDCARD | xapian.QueryParser.FLAG_PURE_NOT, '') - queries.append(query) + all_queries.append(query) for name, value in request.items(): + queries = sub_queries = [] + if name.startswith('!'): + queries = and_not_queries + name = name[1:] + elif name.startswith('not_'): + queries = and_not_queries + name = name[4:] prop = self._props.get(name) if prop is None or not prop.prefix: continue - - sub_queries = [] - not_queries = [] for needle in value if type(value) in (tuple, list) else [value]: if needle is None: continue if prop.parse is not None: needle = prop.parse(needle) needle = next(_fmt_prop_value(prop, needle)) - if needle.startswith('!'): - term = _term(prop.prefix, needle[1:]) - not_queries.append(xapian.Query(term)) - elif needle.startswith('-'): - term = _term(prop.prefix, needle[1:]) - and_not_queries.append(xapian.Query(term)) - else: - term = _term(prop.prefix, needle) - sub_queries.append(xapian.Query(term)) - - if not_queries: - not_query = xapian.Query(xapian.Query.OP_AND_NOT, - [xapian.Query(''), - xapian.Query(xapian.Query.OP_OR, not_queries)]) - sub_queries.append(not_query) - - if sub_queries: - if len(sub_queries) == 1: - query = sub_queries[0] - else: - query = xapian.Query(xapian.Query.OP_OR, sub_queries) - if prop.boolean: - boolean_queries.append(query) - else: - queries.append(query) + queries.append(xapian.Query(_term(prop.prefix, needle))) + if len(sub_queries) == 1: + all_queries.append(sub_queries[0]) + elif sub_queries: + all_queries.append( + xapian.Query(xapian.Query.OP_OR, sub_queries)) final = None - if queries: - final = xapian.Query(xapian.Query.OP_AND, queries) + if len(all_queries) == 1: + final = all_queries[0] + elif all_queries: + final = xapian.Query(xapian.Query.OP_AND, all_queries) if boolean_queries: query = xapian.Query(xapian.Query.OP_AND, boolean_queries) if final is None: @@ -313,8 +329,7 @@ class IndexWriter(IndexReader): # Let `_commit_handler()` call `wait()` to not miss immediate commit coroutine.dispatch() - - self._do_open() + self.ensure_open() def close(self): """Flush index write pending queue and close the index.""" @@ -325,14 +340,8 @@ class IndexWriter(IndexReader): self._commit_job = None self._db = None - def find(self, query): - if self._db is None: - self._do_open() - return IndexReader.find(self, query) - def store(self, guid, properties, pre_cb=None, post_cb=None, *args): - if self._db is None: - self._do_open() + self.ensure_open() if pre_cb is not None: pre_cb(guid, properties, *args) @@ -377,8 +386,7 @@ class IndexWriter(IndexReader): self._check_for_commit() def delete(self, guid, post_cb=None, *args): - if self._db is None: - self._do_open() + self.ensure_open() _logger.debug('Delete %r document from %r', guid, self.metadata.name) @@ -402,7 +410,9 @@ class IndexWriter(IndexReader): with file(self._mtime_path, 'w'): pass - def _do_open(self): + def ensure_open(self): + if self._db is not None: + return try: self._db = xapian.WritableDatabase(self._path, xapian.DB_CREATE_OR_OPEN) diff --git a/sugar_network/db/resource.py b/sugar_network/db/resource.py index 7484a89..fe071dc 100644 --- a/sugar_network/db/resource.py +++ b/sugar_network/db/resource.py @@ -73,7 +73,7 @@ class Resource(object): }) return result - @indexed_property(prefix='RL', typecast=[], default=['public']) + @indexed_property(prefix='RL', typecast=[], default=[]) def layer(self, value): return value diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py index f2db4ca..41cebc3 100644 --- a/sugar_network/node/routes.py +++ b/sugar_network/node/routes.py @@ -23,6 +23,7 @@ from os.path import join, isdir, exists from sugar_network import db, node, toolkit, model from sugar_network.node import stats_node, stats_user +# pylint: disable-msg=W0611 from sugar_network.toolkit.router import route, preroute, postroute from sugar_network.toolkit.router import ACL, fallbackroute from sugar_network.toolkit.spec import EMPTY_LICENSE @@ -223,7 +224,7 @@ class NodeRoutes(db.Routes, model.Routes): versions = [] impls, __ = implementations.find(limit=db.MAX_LIMIT, - context=context.guid, layer=layer) + context=context.guid, layer=layer, not_layer='deleted') for impl in impls: for arch, spec in impl.meta('data')['spec'].items(): spec['guid'] = impl.guid @@ -334,11 +335,11 @@ class NodeRoutes(db.Routes, model.Routes): _logger.warning('The find limit is restricted to %s', node.find_limit.value) request['limit'] = node.find_limit.value - layer = request.get('layer', ['public']) + layer = request.setdefault('layer', []) if 'deleted' in layer: _logger.warning('Requesting "deleted" layer') layer.remove('deleted') - request['layer'] = layer + request.add('not_layer', 'deleted') return db.Routes.find(self, request, reply) def get(self, request, reply): @@ -385,11 +386,10 @@ class NodeRoutes(db.Routes, model.Routes): if 'stability' not in request: request['stability'] = 'stable' - if 'layer' not in request: - request['layer'] = 'public' impls, __ = self.volume['implementation'].find( - context=request.guid, order_by='-version', **request) + context=request.guid, order_by='-version', not_layer='deleted', + **request) impl = None for impl in impls: if requires: @@ -445,16 +445,19 @@ def load_bundle(volume, bundle_path, impl=None): http.BadRequest, 'Inappropriate bundle type') if impl.get('license') in (None, EMPTY_LICENSE): existing, total = volume['implementation'].find( - context=impl['context'], order_by='-version') + context=impl['context'], order_by='-version', + not_layer='deleted') enforce(total, 'License is not specified') impl['license'] = next(existing)['license'] yield impl existing, __ = volume['implementation'].find( - context=impl['context'], version=impl['version']) + context=impl['context'], version=impl['version'], + not_layer='deleted') for i in existing: - volume['implementation'].update(i.guid, {'layer': ['deleted']}) + layer = i['layer'] + ['deleted'] + volume['implementation'].update(i.guid, {'layer': layer}) impl['guid'] = volume['implementation'].create(impl) diff --git a/sugar_network/node/slave.py b/sugar_network/node/slave.py index bbf9e00..2ad1d5a 100644 --- a/sugar_network/node/slave.py +++ b/sugar_network/node/slave.py @@ -83,10 +83,9 @@ class SlaveRoutes(NodeRoutes): @route('POST', cmd='offline-sync', acl=ACL.LOCAL) def offline_sync(self, path): - enforce(node.sync_layers.value and - 'public' not in node.sync_layers.value, - '--layers is not specified, the full master dump might be ' - 'too big and should be limited') + enforce(node.sync_layers.value, + '--sync-layers is not specified, the full master dump ' + 'might be too big and should be limited') enforce(isabs(path), 'Argument \'path\' should be an absolute path') _logger.debug('Start %r synchronization session in %r', diff --git a/sugar_network/toolkit/router.py b/sugar_network/toolkit/router.py index 9ecf556..5c19729 100644 --- a/sugar_network/toolkit/router.py +++ b/sugar_network/toolkit/router.py @@ -229,6 +229,15 @@ class Request(dict): self._pos += len(result) return result + def add(self, key, value): + existing_value = self.get(key) + if existing_value is None: + self[key] = value + elif type(existing_value) is list: + existing_value.append(value) + else: + self[key] = [existing_value, value] + def __repr__(self): return '<Request method=%s path=%r cmd=%s query=%r>' % \ (self.method, self.path, self.cmd, dict(self)) @@ -336,7 +345,7 @@ class Router(object): fallback, method, path, cmd, kwargs = attr.route routes = self._routes for i, part in enumerate(path): - enforce(i == 0 or not routes.fallback_ops or \ + enforce(i == 0 or not routes.fallback_ops or (fallback and i == len(path) - 1), 'Fallback route should not have sub-routes') if part is None: diff --git a/tests/units/db/index.py b/tests/units/db/index.py index 9b7d130..45dcbb8 100755 --- a/tests/units/db/index.py +++ b/tests/units/db/index.py @@ -14,7 +14,6 @@ from sugar_network import toolkit from sugar_network.db import index from sugar_network.db.index import _fmt_prop_value from sugar_network.db.metadata import Metadata, IndexedProperty, GUID_PREFIX, Property -from sugar_network.db.directory import _Query from sugar_network.toolkit.router import ACL from sugar_network.toolkit import coroutine @@ -673,7 +672,7 @@ class IndexTest(tests.Test): ]), db._find(prop=['b', 'foo', 'bar'], reply=['guid'])[0]) - def test_find_NotFilter(self): + def test_find_AndNotFilter(self): db = Index({'prop': IndexedProperty('prop', 1, 'A')}) db.store('1', {'prop': 'a'}) @@ -685,70 +684,38 @@ class IndexTest(tests.Test): {'guid': '2'}, {'guid': '3'}, ]), - db._find(prop='!a', reply=['guid'])[0]) - - self.assertEqual( - sorted([ - {'guid': '3'}, - ]), - db._find(prop=['!a', '!b'], reply=['guid'])[0]) - - self.assertEqual( - sorted([ - ]), - db._find(prop=['!a', '!b', '!c'], reply=['guid'])[0]) - - self.assertEqual( - sorted([ - {'guid': '1'}, - {'guid': '3'}, - ]), - db._find(prop=['!b', 'c'], reply=['guid'])[0]) - - self.assertEqual( - sorted([ - {'guid': '1'}, - {'guid': '3'}, - ]), - db._find(prop=['a', '!b', 'c'], reply=['guid'])[0]) - - def test_find_AndNotFilter(self): - db = Index({'prop': IndexedProperty('prop', 1, 'A')}) - - db.store('1', {'prop': 'a'}) - db.store('2', {'prop': 'b'}) - db.store('3', {'prop': 'c'}) + sorted(db._find(reply=['guid'], not_prop='a')[0])) self.assertEqual( sorted([ {'guid': '2'}, {'guid': '3'}, ]), - db._find(prop='-a', reply=['guid'])[0]) + sorted(db._find(reply=['guid'], **{'!prop': 'a'})[0])) self.assertEqual( sorted([ {'guid': '3'}, ]), - db._find(prop=['-a', '-b'], reply=['guid'])[0]) + sorted(db._find(reply=['guid'], **{'!prop': ['a', 'b']})[0])) self.assertEqual( sorted([ ]), - db._find(prop=['-a', '-b', '-c'], reply=['guid'])[0]) + sorted(db._find(reply=['guid'], **{'!prop': ['a', 'b', 'c']})[0])) self.assertEqual( sorted([ {'guid': '3'}, ]), - db._find(prop=['-b', 'c'], reply=['guid'])[0]) + sorted(db._find(prop='c', reply=['guid'], **{'!prop': 'b'})[0])) self.assertEqual( sorted([ {'guid': '1'}, {'guid': '3'}, ]), - db._find(prop=['a', '-b', 'c'], reply=['guid'])[0]) + sorted(db._find(prop=['a', 'c'], reply=['guid'], **{'!prop': 'b'})[0])) def test_fmt_prop_value(self): prop = Property('prop') @@ -785,18 +752,13 @@ class Index(index.IndexWriter): index.IndexWriter.__init__(self, tests.tmpdir + '/index', metadata, *args) - def _find(self, *args, **kwargs): - if 'reply' not in kwargs: - kwargs['reply'] = {} - if 'order_by' not in kwargs: - kwargs['order_by'] = 'guid' - - mset = self.find(_Query(*args, **kwargs)) + def _find(self, reply=None, **kwargs): + mset = self.find(**kwargs) result = [] - for hit in self.find(_Query(*args, **kwargs)): + for hit in mset: props = {} - for name in kwargs['reply']: + for name in (reply or []): prop = self.metadata[name] if prop.slot is not None: props[name] = hit.document.get_value(prop.slot).decode('utf8') diff --git a/tests/units/db/resource.py b/tests/units/db/resource.py index ed37664..f8a56b1 100755 --- a/tests/units/db/resource.py +++ b/tests/units/db/resource.py @@ -45,13 +45,13 @@ class ResourceTest(tests.Test): directory.create({'slotted': 'slotted', 'not_slotted': 'not_slotted'}) - docs, total = directory.find(0, 100, order_by='slotted') + docs, total = directory.find(order_by='slotted') self.assertEqual(1, total) self.assertEqual( [('slotted', 'not_slotted')], [(i.slotted, i.not_slotted) for i in docs]) - self.assertRaises(RuntimeError, directory.find, 0, 100, order_by='not_slotted') + self.assertRaises(RuntimeError, directory.find, order_by='not_slotted') def test_ActiveProperty_SlottedIUnique(self): @@ -84,14 +84,14 @@ class ResourceTest(tests.Test): guid = directory.create({'term': 'term', 'not_term': 'not_term'}) - docs, total = directory.find(0, 100, term='term') + docs, total = directory.find(term='term') self.assertEqual(1, total) self.assertEqual( [('term', 'not_term')], [(i.term, i.not_term) for i in docs]) - self.assertEqual(0, directory.find(0, 100, query='not_term:not_term')[-1]) - self.assertEqual(1, directory.find(0, 100, query='not_term:=not_term')[-1]) + self.assertEqual(0, directory.find(query='not_term:not_term')[-1]) + self.assertEqual(1, directory.find(query='not_term:=not_term')[-1]) def test_ActiveProperty_TermsUnique(self): @@ -125,8 +125,8 @@ class ResourceTest(tests.Test): guid = directory.create({'no': 'foo', 'yes': 'bar'}) - self.assertEqual(0, directory.find(0, 100, query='foo')[-1]) - self.assertEqual(1, directory.find(0, 100, query='bar')[-1]) + self.assertEqual(0, directory.find(query='foo')[-1]) + self.assertEqual(1, directory.find(query='bar')[-1]) def test_update(self): @@ -145,12 +145,12 @@ class ResourceTest(tests.Test): guid = directory.create({'prop_1': '1', 'prop_2': '2'}) self.assertEqual( [('1', '2')], - [(i.prop_1, i.prop_2) for i in directory.find(0, 1024)[0]]) + [(i.prop_1, i.prop_2) for i in directory.find()[0]]) directory.update(guid, {'prop_1': '3', 'prop_2': '4'}) self.assertEqual( [('3', '4')], - [(i.prop_1, i.prop_2) for i in directory.find(0, 1024)[0]]) + [(i.prop_1, i.prop_2) for i in directory.find()[0]]) def test_delete(self): @@ -168,22 +168,22 @@ class ResourceTest(tests.Test): self.assertEqual( ['1', '2', '3'], - [i.prop for i in directory.find(0, 1024)[0]]) + [i.prop for i in directory.find()[0]]) directory.delete(guid_2) self.assertEqual( ['1', '3'], - [i.prop for i in directory.find(0, 1024)[0]]) + [i.prop for i in directory.find()[0]]) directory.delete(guid_3) self.assertEqual( ['1'], - [i.prop for i in directory.find(0, 1024)[0]]) + [i.prop for i in directory.find()[0]]) directory.delete(guid_1) self.assertEqual( [], - [i.prop for i in directory.find(0, 1024)[0]]) + [i.prop for i in directory.find()[0]]) def test_populate(self): @@ -229,7 +229,7 @@ class ResourceTest(tests.Test): (1, 1, 'prop-1'), (2, 2, 'prop-2'), ], - [(i.ctime, i.mtime, i.prop) for i in directory.find(0, 10)[0]]) + [(i.ctime, i.mtime, i.prop) for i in directory.find()[0]]) def test_populate_IgnoreBadDocuments(self): @@ -267,7 +267,7 @@ class ResourceTest(tests.Test): self.assertEqual(1, populated) self.assertEqual( sorted(['1']), - sorted([i.guid for i in directory.find(0, 10)[0]])) + sorted([i.guid for i in directory.find()[0]])) assert exists('1/1/guid') assert not exists('2/2/guid') assert not exists('3/3/guid') @@ -285,12 +285,12 @@ class ResourceTest(tests.Test): guid = directory.create({'guid': 'guid', 'prop': 'foo'}) self.assertEqual( [('guid', 'foo')], - [(i.guid, i.prop) for i in directory.find(0, 1024)[0]]) + [(i.guid, i.prop) for i in directory.find()[0]]) directory.update(guid, {'prop': 'probe'}) self.assertEqual( [('guid', 'probe')], - [(i.guid, i.prop) for i in directory.find(0, 1024)[0]]) + [(i.guid, i.prop) for i in directory.find()[0]]) def test_seqno(self): @@ -623,7 +623,7 @@ class ResourceTest(tests.Test): (2, '2', 2, '2'), (3, '3', 3, '3'), ]), - sorted([(i['ctime'], i['prop'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]])) + sorted([(i['ctime'], i['prop'], i['mtime'], i['guid']) for i in directory2.find()[0]])) doc = directory2.get('1') self.assertEqual(1, doc.get('seqno')) @@ -675,7 +675,7 @@ class ResourceTest(tests.Test): self.assertEqual( [(2, 2, 'guid')], - [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]]) doc = directory2.get('guid') self.assertEqual(2, doc.get('seqno')) self.assertEqual(2, doc.meta('guid')['mtime']) @@ -689,7 +689,7 @@ class ResourceTest(tests.Test): self.assertEqual( [(2, 2, 'guid')], - [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]]) doc = directory2.get('guid') self.assertEqual(2, doc.get('seqno')) self.assertEqual(2, doc.meta('guid')['mtime']) @@ -704,7 +704,7 @@ class ResourceTest(tests.Test): self.assertEqual( [(2, 1, 'guid')], - [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]]) doc = directory2.get('guid') self.assertEqual(3, doc.get('seqno')) self.assertEqual(2, doc.meta('guid')['mtime']) @@ -719,7 +719,7 @@ class ResourceTest(tests.Test): self.assertEqual( [(2, 1, 'guid')], - [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]]) doc = directory2.get('guid') self.assertEqual(4, doc.get('seqno')) self.assertEqual(2, doc.meta('guid')['mtime']) @@ -744,7 +744,7 @@ class ResourceTest(tests.Test): directory2.merge(shift_seqno=False, **patch) self.assertEqual( [(1, 1, '1', '1')], - [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory2.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory2.find()[0]]) doc = directory2.get('1') self.assertEqual(0, doc.get('seqno')) self.assertEqual(0, doc.meta('guid')['seqno']) @@ -755,7 +755,7 @@ class ResourceTest(tests.Test): directory3.merge(**patch) self.assertEqual( [(1, 1, '1', '1')], - [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]]) doc = directory3.get('1') self.assertEqual(1, doc.get('seqno')) self.assertEqual(1, doc.meta('guid')['seqno']) @@ -768,7 +768,7 @@ class ResourceTest(tests.Test): directory3.merge(shift_seqno=False, **patch) self.assertEqual( [(2, 2, '1', '2')], - [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]]) doc = directory3.get('1') self.assertEqual(1, doc.get('seqno')) self.assertEqual(1, doc.meta('guid')['seqno']) @@ -781,7 +781,7 @@ class ResourceTest(tests.Test): directory3.merge(**patch) self.assertEqual( [(3, 3, '1', '3')], - [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]]) doc = directory3.get('1') self.assertEqual(2, doc.get('seqno')) self.assertEqual(1, doc.meta('guid')['seqno']) @@ -828,7 +828,7 @@ class ResourceTest(tests.Test): self.assertEqual( [(2, 3, '1')], - [(i['ctime'], i['mtime'], i['guid']) for i in directory.find(0, 1024)[0]]) + [(i['ctime'], i['mtime'], i['guid']) for i in directory.find()[0]]) doc = directory.get('1') self.assertEqual(1, doc.get('seqno')) @@ -853,12 +853,12 @@ class ResourceTest(tests.Test): directory = Directory(tests.tmpdir, Document, IndexWriter) guid = directory.create({'prop': '1'}) - self.assertEqual([guid], [i.guid for i in directory.find(0, 1024)[0]]) + self.assertEqual([guid], [i.guid for i in directory.find()[0]]) directory.commit() assert directory.mtime != 0 directory.wipe() - self.assertEqual([], [i.guid for i in directory.find(0, 1024)[0]]) + self.assertEqual([], [i.guid for i in directory.find()[0]]) assert directory.mtime == 0 diff --git a/tests/units/db/routes.py b/tests/units/db/routes.py index 3d2d7f1..f5d44db 100755 --- a/tests/units/db/routes.py +++ b/tests/units/db/routes.py @@ -409,28 +409,28 @@ class RoutesTest(tests.Test): self.assertEqual({'en': 'value_raw'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], - [i.guid for i in directory.find(0, 100, localized_prop='value_raw')[0]]) + [i.guid for i in directory.find(localized_prop='value_raw')[0]]) directory.update(guid, {'localized_prop': 'value_raw2'}) self.assertEqual({'en': 'value_raw2'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], - [i.guid for i in directory.find(0, 100, localized_prop='value_raw2')[0]]) + [i.guid for i in directory.find(localized_prop='value_raw2')[0]]) guid = self.call('POST', path=['testdocument'], accept_language=['ru'], content={'localized_prop': 'value_ru'}) self.assertEqual({'ru': 'value_ru'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], - [i.guid for i in directory.find(0, 100, localized_prop='value_ru')[0]]) + [i.guid for i in directory.find(localized_prop='value_ru')[0]]) self.call('PUT', path=['testdocument', guid], accept_language=['en'], content={'localized_prop': 'value_en'}) self.assertEqual({'ru': 'value_ru', 'en': 'value_en'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], - [i.guid for i in directory.find(0, 100, localized_prop='value_ru')[0]]) + [i.guid for i in directory.find(localized_prop='value_ru')[0]]) self.assertEqual( [guid], - [i.guid for i in directory.find(0, 100, localized_prop='value_en')[0]]) + [i.guid for i in directory.find(localized_prop='value_en')[0]]) def test_LocalizedGet(self): @@ -1572,6 +1572,24 @@ class RoutesTest(tests.Test): prop = Property('prop', typecast=lambda x: x + 1) self.assertEqual(1, _typecast_prop_value(prop.typecast, 0)) + def test_DefaultOrder(self): + + class Document(db.Resource): + pass + + self.volume = db.Volume('db', [Document]) + + self.volume['document'].create({'guid': '3', 'ctime': 3}) + self.volume['document'].create({'guid': '2', 'ctime': 2}) + self.volume['document'].create({'guid': '1', 'ctime': 1}) + + self.assertEqual([ + {'guid': '1'}, + {'guid': '2'}, + {'guid': '3'}, + ], + self.call('GET', ['document'])['result']) + def call(self, method=None, path=None, accept_language=None, content=None, content_stream=None, cmd=None, content_type=None, host=None, request=None, routes=db.Routes, principal=None, diff --git a/tests/units/node/node.py b/tests/units/node/node.py index cf9523b..8a9ce5f 100755 --- a/tests/units/node/node.py +++ b/tests/units/node/node.py @@ -150,10 +150,10 @@ class NodeTest(tests.Test): self.assertEqual({ 'guid': guid, 'title': 'title', - 'layer': ['public'], + 'layer': [], }, call(cp, method='GET', document='context', guid=guid, reply=['guid', 'title', 'layer'])) - self.assertEqual(['public'], volume['context'].get(guid)['layer']) + self.assertEqual([], volume['context'].get(guid)['layer']) def subscribe(): for event in cp.subscribe(): @@ -700,9 +700,9 @@ class NodeTest(tests.Test): guid2 = json.load(conn.request('POST', ['implementation'], bundle2, params={'cmd': 'release'}).raw) self.assertEqual('1', volume['implementation'].get(guid1)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid1)['layer']) + self.assertEqual([], volume['implementation'].get(guid1)['layer']) self.assertEqual('2', volume['implementation'].get(guid2)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid2)['layer']) + self.assertEqual([], volume['implementation'].get(guid2)['layer']) self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone')) activity_info = '\n'.join([ @@ -721,9 +721,9 @@ class NodeTest(tests.Test): self.assertEqual('1', volume['implementation'].get(guid1)['version']) self.assertEqual(['deleted'], volume['implementation'].get(guid1)['layer']) self.assertEqual('2', volume['implementation'].get(guid2)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid2)['layer']) + self.assertEqual([], volume['implementation'].get(guid2)['layer']) self.assertEqual('1', volume['implementation'].get(guid3)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid3)['layer']) + self.assertEqual([], volume['implementation'].get(guid3)['layer']) self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone')) activity_info = '\n'.join([ @@ -744,9 +744,9 @@ class NodeTest(tests.Test): self.assertEqual('2', volume['implementation'].get(guid2)['version']) self.assertEqual(['deleted'], volume['implementation'].get(guid2)['layer']) self.assertEqual('1', volume['implementation'].get(guid3)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid3)['layer']) + self.assertEqual([], volume['implementation'].get(guid3)['layer']) self.assertEqual('2', volume['implementation'].get(guid4)['version']) - self.assertEqual(['public'], volume['implementation'].get(guid4)['layer']) + self.assertEqual([], volume['implementation'].get(guid4)['layer']) self.assertEqual(bundle3, conn.get(['context', 'bundle_id'], cmd='clone')) diff --git a/tests/units/node/sync_offline.py b/tests/units/node/sync_offline.py index f3b7111..0353e58 100755 --- a/tests/units/node/sync_offline.py +++ b/tests/units/node/sync_offline.py @@ -54,11 +54,7 @@ class SyncOfflineTest(tests.Test): node.sync_layers.value = None self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt') node.sync_layers.value = 'public' - self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt') - node.sync_layers.value = ['public'] - self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt') - node.sync_layers.value = ['public', 'foo'] - self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt') + cp.offline_sync(tests.tmpdir + '/mnt') def test_Export(self): diff --git a/tests/units/node/sync_online.py b/tests/units/node/sync_online.py index 4b46306..6a88875 100755 --- a/tests/units/node/sync_online.py +++ b/tests/units/node/sync_online.py @@ -103,8 +103,8 @@ class SyncOnlineTest(tests.Test): client.post(cmd='online-sync') self.assertEqual([ {'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': '22'}, 'layer': ['public']}, - {'guid': guid3, 'content': {'en-us': '3'}, 'layer': ['public']}, + {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []}, + {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []}, ], [i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[8, None]], json.load(file('slave/pull.sequence'))) @@ -120,8 +120,8 @@ class SyncOnlineTest(tests.Test): self.assertEqual([ {'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']}, {'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']}, - {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': ['public']}, - {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': ['public']}, + {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []}, + {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []}, ], [i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[12, None]], json.load(file('slave/pull.sequence'))) @@ -180,8 +180,8 @@ class SyncOnlineTest(tests.Test): slave_client.post(cmd='online-sync') self.assertEqual([ {'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': '22'}, 'layer': ['public']}, - {'guid': guid3, 'content': {'en-us': '3'}, 'layer': ['public']}, + {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []}, + {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []}, ], [i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[8, None]], json.load(file('slave/pull.sequence'))) @@ -197,8 +197,8 @@ class SyncOnlineTest(tests.Test): self.assertEqual([ {'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']}, {'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']}, - {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': ['public']}, - {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': ['public']}, + {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []}, + {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []}, ], [i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[13, None]], json.load(file('slave/pull.sequence'))) diff --git a/tests/units/node/volume.py b/tests/units/node/volume.py index 9a3a113..f6b2105 100755 --- a/tests/units/node/volume.py +++ b/tests/units/node/volume.py @@ -49,7 +49,7 @@ class VolumeTest(tests.Test): 'ctime': {'value': 0, 'mtime': 1}, 'prop': {'value': 'a', 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, }, }, @@ -60,7 +60,7 @@ class VolumeTest(tests.Test): 'ctime': {'value': 0, 'mtime': 2}, 'prop': {'value': 'b', 'mtime': 2}, 'author': {'mtime': 2, 'value': {}}, - 'layer': {'mtime': 2, 'value': ['public']}, + 'layer': {'mtime': 2, 'value': []}, 'tags': {'mtime': 2, 'value': []}, }, }, @@ -375,7 +375,7 @@ class VolumeTest(tests.Test): 'artifact': {'value': artifact, 'mtime': 4.0}, 'rating': {'value': 1, 'mtime': 1.0}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, }}, {'guid': '2', 'diff': { @@ -385,7 +385,7 @@ class VolumeTest(tests.Test): 'context': {'value': context, 'mtime': 2.0}, 'rating': {'value': 2, 'mtime': 2.0}, 'author': {'mtime': 2, 'value': {}}, - 'layer': {'mtime': 2, 'value': ['public']}, + 'layer': {'mtime': 2, 'value': []}, 'tags': {'mtime': 2, 'value': []}, }}, {'commit': [[1, 2]]}, @@ -433,7 +433,7 @@ class VolumeTest(tests.Test): {'guid': guid, 'diff': { 'guid': {'value': guid, 'mtime': 0}, 'author': {'mtime': 0, 'value': {}}, - 'layer': {'mtime': 0, 'value': ['public']}, + 'layer': {'mtime': 0, 'value': []}, 'tags': {'mtime': 0, 'value': []}, 'mtime': {'value': 0, 'mtime': 0}, 'ctime': {'value': 0, 'mtime': 0}, @@ -467,7 +467,7 @@ class VolumeTest(tests.Test): 'diff': { 'guid': {'value': guid, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, @@ -491,7 +491,7 @@ class VolumeTest(tests.Test): {'guid': guid, 'diff': { 'guid': {'value': guid, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, @@ -524,7 +524,7 @@ class VolumeTest(tests.Test): 'diff': { 'guid': {'value': guid1, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, @@ -535,7 +535,7 @@ class VolumeTest(tests.Test): 'diff': { 'guid': {'value': guid2, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, @@ -551,7 +551,7 @@ class VolumeTest(tests.Test): 'diff': { 'guid': {'value': guid1, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, @@ -561,7 +561,7 @@ class VolumeTest(tests.Test): 'diff': { 'guid': {'value': guid2, 'mtime': 1}, 'author': {'mtime': 1, 'value': {}}, - 'layer': {'mtime': 1, 'value': ['public']}, + 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, 'mtime': {'value': 0, 'mtime': 1}, 'ctime': {'value': 0, 'mtime': 1}, |