Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tests/units/node
diff options
context:
space:
mode:
Diffstat (limited to 'tests/units/node')
-rw-r--r--tests/units/node/__main__.py4
-rwxr-xr-xtests/units/node/master.py214
-rwxr-xr-xtests/units/node/model.py660
-rwxr-xr-xtests/units/node/node.py1058
-rwxr-xr-xtests/units/node/obs.py22
-rwxr-xr-xtests/units/node/stats_node.py338
-rwxr-xr-xtests/units/node/sync_online.py22
-rwxr-xr-xtests/units/node/volume.py826
8 files changed, 874 insertions, 2270 deletions
diff --git a/tests/units/node/__main__.py b/tests/units/node/__main__.py
index ac37315..dfadaf3 100644
--- a/tests/units/node/__main__.py
+++ b/tests/units/node/__main__.py
@@ -4,16 +4,14 @@ from __init__ import tests
from downloads import *
from files import *
-from master import *
from node import *
from obs import *
-from stats_node import *
from stats_user import *
from sync import *
from sync_master import *
from sync_offline import *
from sync_online import *
-from volume import *
+from model import *
if __name__ == '__main__':
tests.main()
diff --git a/tests/units/node/master.py b/tests/units/node/master.py
deleted file mode 100755
index b3eaa75..0000000
--- a/tests/units/node/master.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/usr/bin/env python
-# sugar-lint: disable
-
-import os
-
-from __init__ import tests
-
-from sugar_network.node import obs
-from sugar_network.client import IPCConnection
-from sugar_network.toolkit import coroutine, enforce
-
-
-class MasterTest(tests.Test):
-
- def test_Aliases(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
- {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
-
- self.start_online_client()
- ipc = IPCConnection()
-
- guid = ipc.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['pkg1.bin', 'pkg2.bin']],
- 'devel': [['pkg3.devel']],
- },
- 'Debian': {
- 'binary': [['pkg4.bin']],
- 'devel': [['pkg5.devel', 'pkg6.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
- 'Debian-6.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
- 'Debian-7.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
- },
- ipc.get(['context', guid, 'packages']))
-
- def test_WrongAliases(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
- {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, 'resolve failed'))
-
- self.start_online_client()
- ipc = IPCConnection()
-
- guid = ipc.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['pkg1.bin', 'pkg2.bin']],
- 'devel': [['pkg3.devel']],
- },
- 'Debian': {
- 'binary': [['pkg4.bin']],
- 'devel': [['pkg5.devel', 'pkg6.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed'},
- 'Debian-6.0': {'status': 'resolve failed'},
- 'Debian-7.0': {'status': 'resolve failed'},
- },
- ipc.get(['context', guid, 'packages']))
-
- def test_MultipleAliases(self):
-
- def resolve(repo, arch, names):
- enforce(not [i for i in names if 'fake' in i], 'resolve failed')
- return ['fake']
-
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- ])
- self.override(obs, 'resolve', resolve)
-
- self.start_online_client()
- ipc = IPCConnection()
-
- guid = ipc.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['fake.bin'], ['proper.bin'], ['not-reach.bin']],
- 'devel': [['fake.devel'], ['proper.devel'], ['not-reach.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['proper.bin'], 'devel': ['proper.devel']},
- },
- ipc.get(['context', guid, 'packages']))
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['proper.bin']],
- 'devel': [['fake.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed', 'binary': ['proper.bin']},
- },
- ipc.get(['context', guid, 'packages']))
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['fake.bin']],
- 'devel': [['proper.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed'},
- },
- ipc.get(['context', guid, 'packages']))
-
- def test_InvalidateSolutions(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
-
- self.start_online_client()
- ipc = IPCConnection()
-
- events = []
- def read_events():
- for event in ipc.subscribe():
- if event.get('resource') == 'release':
- events.append(event)
- job = coroutine.spawn(read_events)
-
- guid = ipc.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
- coroutine.sleep(.5)
- self.assertEqual([], events)
-
- ipc.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['bin']],
- 'devel': [['devel']],
- },
- })
- coroutine.sleep(.5)
- self.assertEqual([
- {'event': 'populate', 'resource': 'release', 'mtime': int(os.stat('master/release/index/mtime').st_mtime)},
- ],
- events)
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['bin'], 'devel': ['devel']},
- },
- ipc.get(['context', guid, 'packages']))
-
- def test_InvalidateSolutionsOnDependenciesChanges(self):
- self.start_online_client()
- ipc = IPCConnection()
-
- events = []
- def read_events():
- for event in ipc.subscribe():
- if event.get('resource') == 'release':
- events.append(event)
- job = coroutine.spawn(read_events)
-
- guid = ipc.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- 'dependencies': [],
- })
- self.assertEqual(0, len(events))
-
- ipc.put(['context', guid, 'dependencies'], ['foo'])
- coroutine.sleep(.1)
- self.assertEqual([
- {'event': 'populate', 'resource': 'release', 'mtime': int(os.stat('master/release/index/mtime').st_mtime)},
- ],
- events)
-
-
-if __name__ == '__main__':
- tests.main()
diff --git a/tests/units/node/model.py b/tests/units/node/model.py
new file mode 100755
index 0000000..68215c1
--- /dev/null
+++ b/tests/units/node/model.py
@@ -0,0 +1,660 @@
+#!/usr/bin/env python
+# sugar-lint: disable
+
+import os
+import time
+
+from __init__ import tests
+
+from sugar_network import db, toolkit
+from sugar_network.db import files
+from sugar_network.client import Connection, keyfile, api_url
+from sugar_network.model.user import User
+from sugar_network.model.post import Post
+from sugar_network.node import model, obs
+from sugar_network.node.routes import NodeRoutes
+from sugar_network.toolkit.coroutine import this
+from sugar_network.toolkit.router import Request, Router
+from sugar_network.toolkit import i18n, http, coroutine, enforce
+
+
+class ModelTest(tests.Test):
+
+ def test_IncrementReleasesSeqno(self):
+ events = []
+ volume = self.start_master([User, model.Context, Post])
+ this.broadcast = lambda x: events.append(x)
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ context = conn.post(['context'], {
+ 'type': 'group',
+ 'title': 'Activity',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ self.assertEqual([
+ ], [i for i in events if i['event'] == 'release'])
+ self.assertEqual(0, volume.releases_seqno.value)
+
+ aggid = conn.post(['context', context, 'releases'], -1)
+ self.assertEqual([
+ {'event': 'release', 'seqno': 1},
+ ], [i for i in events if i['event'] == 'release'])
+ self.assertEqual(1, volume.releases_seqno.value)
+
+ def test_diff(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ volume = self.start_master([User, Document])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid1 = conn.post(['document'], {'prop': 'a'})
+ self.utime('master/document/%s/%s' % (guid1[:2], guid1), 1)
+ guid2 = conn.post(['document'], {'prop': 'b'})
+ self.utime('master/document/%s/%s' % (guid2[:2], guid2), 2)
+
+ in_seq = toolkit.Sequence([[1, None]])
+ self.assertEqual([
+ {'resource': 'document'},
+ {'guid': guid1,
+ 'diff': {
+ 'guid': {'value': guid1, 'mtime': 1},
+ 'mtime': {'value': 0, 'mtime': 1},
+ 'ctime': {'value': 0, 'mtime': 1},
+ 'prop': {'value': 'a', 'mtime': 1},
+ 'author': {'mtime': 1, 'value': {}},
+ 'layer': {'mtime': 1, 'value': []},
+ 'tags': {'mtime': 1, 'value': []},
+ },
+ },
+ {'guid': guid2,
+ 'diff': {
+ 'guid': {'value': guid2, 'mtime': 2},
+ 'mtime': {'value': 0, 'mtime': 2},
+ 'ctime': {'value': 0, 'mtime': 2},
+ 'prop': {'value': 'b', 'mtime': 2},
+ 'author': {'mtime': 2, 'value': {}},
+ 'layer': {'mtime': 2, 'value': []},
+ 'tags': {'mtime': 2, 'value': []},
+ },
+ },
+ {'commit': [[1, 2]]},
+ ],
+ [i for i in model.diff(volume, in_seq)])
+ self.assertEqual([[1, None]], in_seq)
+
+ def test_diff_Partial(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ volume = self.start_master([User, Document])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid1 = conn.post(['document'], {'prop': 'a'})
+ self.utime('master/document/%s/%s' % (guid1[:2], guid1), 1)
+ guid2 = conn.post(['document'], {'prop': 'b'})
+ self.utime('master/document/%s/%s' % (guid2[:2], guid2), 2)
+
+ in_seq = toolkit.Sequence([[1, None]])
+ patch = model.diff(volume, in_seq)
+ self.assertEqual({'resource': 'document'}, next(patch))
+ self.assertEqual(guid1, next(patch)['guid'])
+ self.assertEqual({'commit': []}, patch.throw(StopIteration()))
+ try:
+ next(patch)
+ assert False
+ except StopIteration:
+ pass
+
+ patch = model.diff(volume, in_seq)
+ self.assertEqual({'resource': 'document'}, next(patch))
+ self.assertEqual(guid1, next(patch)['guid'])
+ self.assertEqual(guid2, next(patch)['guid'])
+ self.assertEqual({'commit': [[1, 1]]}, patch.throw(StopIteration()))
+ try:
+ next(patch)
+ assert False
+ except StopIteration:
+ pass
+
+ def test_diff_Stretch(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ volume = self.start_master([User, Document])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid1 = conn.post(['document'], {'prop': 'a'})
+ self.utime('master/document/%s/%s' % (guid1[:2], guid1), 1)
+ guid2 = conn.post(['document'], {'prop': 'b'})
+ volume['document'].delete(guid2)
+ guid3 = conn.post(['document'], {'prop': 'c'})
+ self.utime('master/document/%s/%s' % (guid3[:2], guid3), 2)
+ guid4 = conn.post(['document'], {'prop': 'd'})
+ volume['document'].delete(guid4)
+ guid5 = conn.post(['document'], {'prop': 'f'})
+ self.utime('master/document/%s/%s' % (guid5[:2], guid5), 2)
+
+ in_seq = toolkit.Sequence([[1, None]])
+ patch = model.diff(volume, in_seq)
+ self.assertEqual({'resource': 'document'}, patch.send(None))
+ self.assertEqual(guid1, patch.send(None)['guid'])
+ self.assertEqual(guid3, patch.send(None)['guid'])
+ self.assertEqual(guid5, patch.send(None)['guid'])
+ self.assertEqual({'commit': [[1, 1], [3, 3]]}, patch.throw(StopIteration()))
+ try:
+ patch.send(None)
+ assert False
+ except StopIteration:
+ pass
+
+ patch = model.diff(volume, in_seq)
+ self.assertEqual({'resource': 'document'}, patch.send(None))
+ self.assertEqual(guid1, patch.send(None)['guid'])
+ self.assertEqual(guid3, patch.send(None)['guid'])
+ self.assertEqual(guid5, patch.send(None)['guid'])
+ self.assertEqual({'commit': [[1, 5]]}, patch.send(None))
+ try:
+ patch.send(None)
+ assert False
+ except StopIteration:
+ pass
+
+ def test_diff_DoNotStretchContinuesPacket(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ volume = self.start_master([User, Document])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid1 = conn.post(['document'], {'prop': 'a'})
+ volume['document'].delete(guid1)
+ guid2 = conn.post(['document'], {'prop': 'b'})
+ volume['document'].delete(guid2)
+ guid3 = conn.post(['document'], {'prop': 'c'})
+ self.utime('master/document/%s/%s' % (guid3[:2], guid3), 2)
+ guid4 = conn.post(['document'], {'prop': 'd'})
+ volume['document'].delete(guid4)
+ guid5 = conn.post(['document'], {'prop': 'f'})
+ self.utime('master/document/%s/%s' % (guid5[:2], guid5), 2)
+
+ in_seq = toolkit.Sequence([[1, None]])
+ patch = model.diff(volume, in_seq, toolkit.Sequence([[1, 1]]))
+ self.assertEqual({'resource': 'document'}, patch.send(None))
+ self.assertEqual(guid3, patch.send(None)['guid'])
+ self.assertEqual(guid5, patch.send(None)['guid'])
+ self.assertEqual({'commit': [[1, 1], [3, 3], [5, 5]]}, patch.send(None))
+ try:
+ patch.send(None)
+ assert False
+ except StopIteration:
+ pass
+
+ def test_diff_TheSameInSeqForAllDocuments(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document1(db.Resource):
+ pass
+
+ class Document2(db.Resource):
+ pass
+
+ class Document3(db.Resource):
+ pass
+
+ volume = self.start_master([User, Document1, Document2, Document3])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid3 = conn.post(['document1'], {})
+ self.utime('master/document/%s/%s' % (guid3[:2], guid3), 3)
+ guid2 = conn.post(['document2'], {})
+ self.utime('master/document/%s/%s' % (guid2[:2], guid2), 2)
+ guid1 = conn.post(['document3'], {})
+ self.utime('master/document/%s/%s' % (guid1[:2], guid1), 1)
+
+ in_seq = toolkit.Sequence([[1, None]])
+ patch = model.diff(volume, in_seq)
+ self.assertEqual({'resource': 'document1'}, patch.send(None))
+ self.assertEqual(guid3, patch.send(None)['guid'])
+ self.assertEqual({'resource': 'document2'}, patch.send(None))
+ self.assertEqual(guid2, patch.send(None)['guid'])
+ self.assertEqual({'resource': 'document3'}, patch.send(None))
+ self.assertEqual(guid1, patch.send(None)['guid'])
+ self.assertEqual({'commit': [[1, 3]]}, patch.send(None))
+ try:
+ patch.send(None)
+ assert False
+ except StopIteration:
+ pass
+
+ def test_merge_Create(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document1(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ class Document2(db.Resource):
+ pass
+
+ self.touch(('master/db.seqno', '100'))
+ volume = self.start_master([Document1, Document2])
+
+ records = [
+ {'resource': 'document1'},
+ {'guid': '1', 'diff': {
+ 'guid': {'value': '1', 'mtime': 1.0},
+ 'ctime': {'value': 2, 'mtime': 2.0},
+ 'mtime': {'value': 3, 'mtime': 3.0},
+ 'prop': {'value': '4', 'mtime': 4.0},
+ }},
+ {'resource': 'document2'},
+ {'guid': '5', 'diff': {
+ 'guid': {'value': '5', 'mtime': 5.0},
+ 'ctime': {'value': 6, 'mtime': 6.0},
+ 'mtime': {'value': 7, 'mtime': 7.0},
+ }},
+ {'commit': [[1, 2]]},
+ ]
+ self.assertEqual(([[1, 2]], [[101, 102]]), model.merge(volume, records))
+
+ self.assertEqual(
+ {'guid': '1', 'prop': '4', 'ctime': 2, 'mtime': 3},
+ volume['document1'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
+ self.assertEqual(1, os.stat('master/document1/1/1/guid').st_mtime)
+ self.assertEqual(2, os.stat('master/document1/1/1/ctime').st_mtime)
+ self.assertEqual(3, os.stat('master/document1/1/1/mtime').st_mtime)
+ self.assertEqual(4, os.stat('master/document1/1/1/prop').st_mtime)
+
+ self.assertEqual(
+ {'guid': '5', 'ctime': 6, 'mtime': 7},
+ volume['document2'].get('5').properties(['guid', 'ctime', 'mtime']))
+ self.assertEqual(5, os.stat('master/document2/5/5/guid').st_mtime)
+ self.assertEqual(6, os.stat('master/document2/5/5/ctime').st_mtime)
+ self.assertEqual(7, os.stat('master/document2/5/5/mtime').st_mtime)
+
+ def test_merge_Update(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Document(db.Resource):
+
+ @db.indexed_property(slot=1)
+ def prop(self, value):
+ return value
+
+ self.touch(('master/db.seqno', '100'))
+ volume = db.Volume('master', [Document])
+ volume['document'].create({'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1})
+ for i in os.listdir('master/document/1/1'):
+ os.utime('master/document/1/1/%s' % i, (2, 2))
+
+ records = [
+ {'resource': 'document'},
+ {'guid': '1', 'diff': {'prop': {'value': '2', 'mtime': 1.0}}},
+ {'commit': [[1, 1]]},
+ ]
+ self.assertEqual(([[1, 1]], []), model.merge(volume, records))
+ self.assertEqual(
+ {'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1},
+ volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
+ self.assertEqual(2, os.stat('master/document/1/1/prop').st_mtime)
+
+ records = [
+ {'resource': 'document'},
+ {'guid': '1', 'diff': {'prop': {'value': '3', 'mtime': 2.0}}},
+ {'commit': [[2, 2]]},
+ ]
+ self.assertEqual(([[2, 2]], []), model.merge(volume, records))
+ self.assertEqual(
+ {'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1},
+ volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
+ self.assertEqual(2, os.stat('master/document/1/1/prop').st_mtime)
+
+ records = [
+ {'resource': 'document'},
+ {'guid': '1', 'diff': {'prop': {'value': '4', 'mtime': 3.0}}},
+ {'commit': [[3, 3]]},
+ ]
+ self.assertEqual(([[3, 3]], [[102, 102]]), model.merge(volume, records))
+ self.assertEqual(
+ {'guid': '1', 'prop': '4', 'ctime': 1, 'mtime': 1},
+ volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
+ self.assertEqual(3, os.stat('master/document/1/1/prop').st_mtime)
+
+ def test_merge_MultipleCommits(self):
+ self.override(time, 'time', lambda: 0)
+
+ class Document(db.Resource):
+
+ @db.stored_property()
+ def prop(self, value):
+ return value
+
+ self.touch(('master/db.seqno', '100'))
+ volume = db.Volume('master', [Document])
+
+ def generator():
+ for i in [
+ {'resource': 'document'},
+ {'commit': [[1, 1]]},
+ {'guid': '1', 'diff': {
+ 'guid': {'value': '1', 'mtime': 1.0},
+ 'ctime': {'value': 2, 'mtime': 2.0},
+ 'mtime': {'value': 3, 'mtime': 3.0},
+ 'prop': {'value': '4', 'mtime': 4.0},
+ }},
+ {'commit': [[2, 3]]},
+ ]:
+ yield i
+
+ records = generator()
+ self.assertEqual(([[1, 3]], [[101, 101]]), model.merge(volume, records))
+ assert volume['document'].exists('1')
+
+ def test_diff_ByLayers(self):
+ self.override(time, 'time', lambda: 0)
+ self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
+
+ class Context(db.Resource):
+ pass
+
+ class Post(db.Resource):
+ pass
+
+ this.request = Request()
+ volume = db.Volume('db', [Context, Post])
+ volume['context'].create({'guid': '0', 'ctime': 1, 'mtime': 1, 'layer': ['layer0', 'common']})
+ volume['context'].create({'guid': '1', 'ctime': 1, 'mtime': 1, 'layer': ['layer1']})
+ volume['post'].create({'guid': '3', 'ctime': 3, 'mtime': 3, 'layer': 'layer3'})
+
+ volume['context'].update('0', {'tags': '0'})
+ volume['context'].update('1', {'tags': '1'})
+ volume['post'].update('3', {'tags': '3'})
+ self.utime('db', 0)
+
+ self.assertEqual(sorted([
+ {'resource': 'context'},
+ {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
+ {'guid': '1', 'diff': {'tags': {'value': '1', 'mtime': 0}}},
+ {'resource': 'post'},
+ {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
+ {'commit': [[4, 6]]},
+ ]),
+ sorted([i for i in model.diff(volume, toolkit.Sequence([[4, None]]))]))
+
+ self.assertEqual(sorted([
+ {'resource': 'context'},
+ {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
+ {'guid': '1', 'diff': {'tags': {'value': '1', 'mtime': 0}}},
+ {'resource': 'post'},
+ {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
+ {'commit': [[4, 6]]},
+ ]),
+ sorted([i for i in model.diff(volume, toolkit.Sequence([[4, None]]), layer='layer1')]))
+
+ self.assertEqual(sorted([
+ {'resource': 'context'},
+ {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
+ {'resource': 'post'},
+ {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
+ {'commit': [[4, 6]]},
+ ]),
+ sorted([i for i in model.diff(volume, toolkit.Sequence([[4, None]]), layer='layer2')]))
+
+ self.assertEqual(sorted([
+ {'resource': 'context'},
+ {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
+ {'resource': 'post'},
+ {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
+ {'commit': [[4, 6]]},
+ ]),
+ sorted([i for i in model.diff(volume, toolkit.Sequence([[4, None]]), layer='foo')]))
+
+ def test_Packages(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'lsb_id': 'Gentoo', 'lsb_release': '2.1', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ {'lsb_id': 'Debian', 'lsb_release': '6.0', 'name': 'Debian-6.0', 'arches': ['x86']},
+ {'lsb_id': 'Debian', 'lsb_release': '7.0', 'name': 'Debian-7.0', 'arches': ['x86_64']},
+ ])
+ self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
+
+ volume = self.start_master([User, model.Context])
+ conn = http.Connection(api_url.value, http.SugarAuth(keyfile.value))
+
+ guid = conn.post(['context'], {
+ 'type': 'package',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ conn.put(['context', guid, 'releases', '*'], {
+ 'binary': ['pkg1.bin', 'pkg2.bin'],
+ 'devel': 'pkg3.devel',
+ })
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
+ },
+ 'status': {
+ 'Gentoo-2.1': 'success',
+ 'Debian-6.0': 'success',
+ 'Debian-7.0': 'success',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ guid = conn.post(['context'], {
+ 'type': 'package',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ conn.put(['context', guid, 'releases', 'Gentoo'], {
+ 'binary': ['pkg1.bin', 'pkg2.bin'],
+ 'devel': 'pkg3.devel',
+ })
+ self.assertEqual({
+ 'Gentoo': {
+ 'seqno': 5,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
+ },
+ 'status': {
+ 'Gentoo-2.1': 'success',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ guid = conn.post(['context'], {
+ 'type': 'package',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ conn.put(['context', guid, 'releases', 'Debian-6.0'], {
+ 'binary': ['pkg1.bin', 'pkg2.bin'],
+ 'devel': 'pkg3.devel',
+ })
+ self.assertEqual({
+ 'Debian-6.0': {
+ 'seqno': 7,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
+ },
+ 'status': {
+ 'Debian-6.0': 'success',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ def test_UnresolvedPackages(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'lsb_id': 'Gentoo', 'lsb_release': '2.1', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ ])
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, 'resolve failed'))
+
+ volume = self.start_master([User, model.Context])
+ conn = http.Connection(api_url.value, http.SugarAuth(keyfile.value))
+
+ guid = conn.post(['context'], {
+ 'type': 'package',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ conn.put(['context', guid, 'releases', '*'], {
+ 'binary': ['pkg1.bin', 'pkg2.bin'],
+ 'devel': 'pkg3.devel',
+ })
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
+ },
+ 'status': {
+ 'Gentoo-2.1': 'resolve failed',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ def test_PackageOverrides(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'lsb_id': 'Gentoo', 'lsb_release': '2.1', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ {'lsb_id': 'Debian', 'lsb_release': '6.0', 'name': 'Debian-6.0', 'arches': ['x86']},
+ {'lsb_id': 'Debian', 'lsb_release': '7.0', 'name': 'Debian-7.0', 'arches': ['x86_64']},
+ ])
+
+ volume = self.start_master([User, model.Context])
+ conn = http.Connection(api_url.value, http.SugarAuth(keyfile.value))
+ guid = conn.post(['context'], {
+ 'type': 'package',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, '1'))
+ conn.put(['context', guid, 'releases', '*'], {'binary': '1'})
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['1']},
+ },
+ 'status': {
+ 'Gentoo-2.1': '1',
+ 'Debian-6.0': '1',
+ 'Debian-7.0': '1',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, '2'))
+ conn.put(['context', guid, 'releases', 'Debian'], {'binary': '2'})
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['1']},
+ },
+ 'Debian': {
+ 'seqno': 4,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['2']},
+ },
+ 'status': {
+ 'Gentoo-2.1': '1',
+ 'Debian-6.0': '2',
+ 'Debian-7.0': '2',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, '3'))
+ conn.put(['context', guid, 'releases', 'Debian-6.0'], {'binary': '3'})
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['1']},
+ },
+ 'Debian': {
+ 'seqno': 4,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['2']},
+ },
+ 'Debian-6.0': {
+ 'seqno': 5,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['3']},
+ },
+ 'status': {
+ 'Gentoo-2.1': '1',
+ 'Debian-6.0': '3',
+ 'Debian-7.0': '2',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, '4'))
+ conn.put(['context', guid, 'releases', 'Debian'], {'binary': '4'})
+ self.assertEqual({
+ '*': {
+ 'seqno': 3,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['1']},
+ },
+ 'Debian': {
+ 'seqno': 6,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['4']},
+ },
+ 'Debian-6.0': {
+ 'seqno': 5,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {'binary': ['3']},
+ },
+ 'status': {
+ 'Gentoo-2.1': '1',
+ 'Debian-6.0': '3',
+ 'Debian-7.0': '4',
+ },
+ },
+ volume['context'][guid]['releases'])
+
+
+if __name__ == '__main__':
+ tests.main()
diff --git a/tests/units/node/node.py b/tests/units/node/node.py
index d8f00ec..0058918 100755
--- a/tests/units/node/node.py
+++ b/tests/units/node/node.py
@@ -16,17 +16,17 @@ from os.path import exists, join
from __init__ import tests
from sugar_network import db, node, model, client
-from sugar_network.client import Connection, keyfile
+from sugar_network.db import files
+from sugar_network.client import Connection, keyfile, api_url
from sugar_network.toolkit import http, coroutine
from sugar_network.toolkit.rrd import Rrd
-from sugar_network.node import stats_user, stats_node, obs
-from sugar_network.node.routes import NodeRoutes, generate_node_stats
+from sugar_network.node import stats_user
+from sugar_network.node.routes import NodeRoutes
from sugar_network.node.master import MasterRoutes
from sugar_network.model.user import User
from sugar_network.model.context import Context
-from sugar_network.model.release import Release
from sugar_network.model.user import User
-from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, Blob, ACL, route
+from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, ACL, route
from sugar_network.toolkit import http
@@ -40,7 +40,7 @@ class NodeTest(tests.Test):
def test_UserStats(self):
volume = db.Volume('db', model.RESOURCES)
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
call(cp, method='POST', document='user', principal=tests.UID, content={
'name': 'user',
@@ -100,69 +100,10 @@ class NodeTest(tests.Test):
},
call(cp, method='GET', cmd='stats-info', document='user', guid=tests.UID, principal=tests.UID))
- def test_NodeStats(self):
- stats_node.stats_node.value = True
- stats_node.stats_node_rras.value = ['RRA:AVERAGE:0.5:1:60', 'RRA:AVERAGE:0.5:3:60']
- rrd = Rrd('stats/node', stats_node.stats_node_step.value, stats_node.stats_node_rras.value)
-
- ts = int(time.time()) / 3 * 3
- for i in range(10):
- rrd['user'].put({'total': i}, ts + i)
-
- volume = db.Volume('db', model.RESOURCES)
- cp = NodeRoutes('guid', volume)
-
- self.assertEqual({
- 'user': [
- (ts + 0, {'total': 0.0}),
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 2.0}),
- (ts + 3, {'total': 3.0}),
- ],
- },
- call(cp, method='GET', cmd='stats', source='user.total', start=ts, end=ts + 3, records=4))
-
- self.assertEqual({
- 'user': [
- (ts + 0, {'total': 0.0}),
- (ts + 3, {'total': 2.0}),
- (ts + 6, {'total': 5.0}),
- (ts + 9, {'total': 8.0}),
- ],
- },
- call(cp, method='GET', cmd='stats', source='user.total', start=ts, end=ts + 9, records=3))
-
- def test_NodeStatsDefaults(self):
- stats_node.stats_node.value = True
- rrd = Rrd('stats/node', stats_node.stats_node_step.value, stats_node.stats_node_rras.value)
-
- ts = int(time.time())
- for i in range(10):
- rrd['user'].put({'total': i}, ts + i)
-
- volume = db.Volume('db', model.RESOURCES)
- cp = NodeRoutes('guid', volume)
-
- self.assertEqual({
- 'user': [
- (ts + 0, {'total': 0.0}),
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 2.0}),
- (ts + 3, {'total': 3.0}),
- (ts + 4, {'total': 4.0}),
- (ts + 5, {'total': 5.0}),
- (ts + 6, {'total': 6.0}),
- (ts + 7, {'total': 7.0}),
- (ts + 8, {'total': 8.0}),
- (ts + 9, {'total': 9.0}),
- ],
- },
- call(cp, method='GET', cmd='stats', source='user.total'))
-
def test_HandleDeletes(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
guid = call(cp, method='POST', document='context', principal=tests.UID, content={
'type': 'activity',
@@ -192,33 +133,41 @@ class NodeTest(tests.Test):
coroutine.dispatch()
self.assertRaises(http.NotFound, call, cp, method='GET', document='context', guid=guid, reply=['guid', 'title'])
self.assertEqual(['deleted'], volume['context'].get(guid)['layer'])
- self.assertEqual({'event': 'delete', 'resource': 'context', 'guid': guid}, events[0])
- def test_SimulateDeleteEvents(self):
- volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ def test_DeletedRestoredHandlers(self):
+ trigger = []
- guid = call(cp, method='POST', document='context', principal=tests.UID, content={
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
+ class TestDocument(db.Resource):
- def subscribe():
- for event in cp.subscribe():
- events.append(event)
- events = []
- coroutine.spawn(subscribe)
- coroutine.dispatch()
+ def deleted(self):
+ trigger.append(False)
- call(cp, method='PUT', document='context', guid=guid, principal=tests.UID, content={'layer': ['deleted']})
- coroutine.dispatch()
- self.assertEqual({'event': 'delete', 'resource': 'context', 'guid': guid}, events[0])
+ def restored(self):
+ trigger.append(True)
+
+ volume = self.start_master([TestDocument, User])
+ conn = Connection(auth=http.SugarAuth(keyfile.value))
+
+ guid = conn.post(['testdocument'], {})
+ self.assertEqual([], trigger)
+
+ conn.put(['testdocument', guid, 'layer'], ['deleted'])
+ self.assertEqual([False], trigger)
+
+ conn.put(['testdocument', guid, 'layer'], [])
+ self.assertEqual([False, True], trigger)
+
+ conn.put(['testdocument', guid, 'layer'], ['bar'])
+ self.assertEqual([False, True], trigger)
+
+ conn.put(['testdocument', guid, 'layer'], ['deleted'])
+ self.assertEqual([False, True, False], trigger)
+
+ conn.put(['testdocument', guid, 'layer'], ['deleted', 'foo'])
+ self.assertEqual([False, True, False], trigger)
def test_RegisterUser(self):
- cp = NodeRoutes('guid', db.Volume('db', [User]))
+ cp = NodeRoutes('guid', volume=db.Volume('db', [User]))
guid = call(cp, method='POST', document='user', principal=tests.UID2, content={
'name': 'user',
@@ -229,7 +178,7 @@ class NodeTest(tests.Test):
def test_UnauthorizedCommands(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
class Routes(NodeRoutes):
@@ -244,7 +193,7 @@ class NodeTest(tests.Test):
class Document(db.Resource):
pass
- cp = Routes('guid', db.Volume('db', [User, Document]))
+ cp = Routes('guid', volume=db.Volume('db', [User, Document]))
guid = call(cp, method='POST', document='document', principal=tests.UID, content={})
self.assertRaises(http.Unauthorized, call, cp, method='GET', cmd='probe1', document='document', guid=guid)
@@ -267,8 +216,8 @@ class NodeTest(tests.Test):
pass
volume = db.Volume('db', [User, Document])
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = Routes('guid', volume)
+ cp = Routes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
guid = call(cp, method='POST', document='document', principal=tests.UID, content={})
@@ -278,7 +227,7 @@ class NodeTest(tests.Test):
call(cp, method='GET', cmd='probe2', document='document', guid=guid)
def test_ForbiddenCommandsForUserResource(self):
- cp = NodeRoutes('guid', db.Volume('db', [User]))
+ cp = NodeRoutes('guid', volume=db.Volume('db', [User]))
call(cp, method='POST', document='user', principal=tests.UID2, content={
'name': 'user1',
@@ -304,9 +253,9 @@ class NodeTest(tests.Test):
return 'ok'
volume = db.Volume('db', [User])
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- volume['user'].create({'guid': tests.UID2, 'name': 'test', 'pubkey': {'blob': StringIO(tests.PUBKEY2)}})
- cp = Routes('guid', volume)
+ cp = Routes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
+ volume['user'].create({'guid': tests.UID2, 'name': 'test', 'pubkey': tests.PUBKEY2})
self.assertRaises(http.Forbidden, call, cp, method='PROBE')
self.assertRaises(http.Forbidden, call, cp, method='PROBE', principal=tests.UID2)
@@ -321,9 +270,9 @@ class NodeTest(tests.Test):
return value
volume = db.Volume('db', [User, Document])
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- volume['user'].create({'guid': tests.UID2, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY2)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
+ volume['user'].create({'guid': tests.UID2, 'name': 'user', 'pubkey': tests.PUBKEY2})
guid = call(cp, method='POST', document='document', principal=tests.UID, content={'prop': '1'})
self.assertRaises(http.Forbidden, call, cp, 'PUT', document='document', guid=guid, content={'prop': '2'}, principal=tests.UID2)
@@ -342,9 +291,9 @@ class NodeTest(tests.Test):
return value
volume = db.Volume('db', [User, Document])
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- volume['user'].create({'guid': tests.UID2, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY2)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
+ volume['user'].create({'guid': tests.UID2, 'name': 'user', 'pubkey': tests.PUBKEY2})
guid = call(cp, method='POST', document='document', principal=tests.UID, content={'prop': '1'})
@@ -363,8 +312,8 @@ class NodeTest(tests.Test):
pass
volume = db.Volume('db', [User])
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = Routes('guid', volume)
+ cp = Routes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
self.assertRaises(http.Forbidden, call, cp, 'PROBE', principal=tests.UID)
self.touch(('authorization.conf', [
@@ -386,7 +335,7 @@ class NodeTest(tests.Test):
pass
volume = db.Volume('db', [User])
- cp = Routes('guid', volume)
+ cp = Routes('guid', volume=volume)
self.assertRaises(http.Unauthorized, call, cp, 'PROBE1')
self.assertRaises(http.Forbidden, call, cp, 'PROBE2')
@@ -401,8 +350,8 @@ class NodeTest(tests.Test):
def test_SetUser(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
guid = call(cp, method='POST', document='context', principal=tests.UID, content={
'type': 'activity',
@@ -416,8 +365,8 @@ class NodeTest(tests.Test):
def test_find_MaxLimit(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
call(cp, method='POST', document='context', principal=tests.UID, content={
'type': 'activity',
@@ -438,23 +387,26 @@ class NodeTest(tests.Test):
'description': 'description',
})
- node.find_limit.value = 3
+ cp._find_limit = 3
self.assertEqual(3, len(call(cp, method='GET', document='context', limit=1024)['result']))
- node.find_limit.value = 2
+ cp._find_limit = 2
self.assertEqual(2, len(call(cp, method='GET', document='context', limit=1024)['result']))
- node.find_limit.value = 1
+ cp._find_limit = 1
self.assertEqual(1, len(call(cp, method='GET', document='context', limit=1024)['result']))
def test_DeletedDocuments(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
guid = call(cp, method='POST', document='context', principal=tests.UID, content={
'type': 'activity',
'title': 'title1',
'summary': 'summary',
'description': 'description',
+ 'artifact_icon': '',
+ 'icon': '',
+ 'logo': '',
})
call(cp, method='GET', document='context', guid=guid)
@@ -468,8 +420,8 @@ class NodeTest(tests.Test):
def test_CreateGUID(self):
# TODO Temporal security hole, see TODO
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- cp = NodeRoutes('guid', volume)
+ cp = NodeRoutes('guid', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
call(cp, method='POST', document='context', principal=tests.UID, content={
'guid': 'foo',
'type': 'activity',
@@ -483,10 +435,10 @@ class NodeTest(tests.Test):
def test_CreateMalformedGUID(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
cp = MasterRoutes('guid', volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
- self.assertRaises(RuntimeError, call, cp, method='POST', document='context', principal=tests.UID, content={
+ self.assertRaises(http.BadRequest, call, cp, method='POST', document='context', principal=tests.UID, content={
'guid': '!?',
'type': 'activity',
'title': 'title',
@@ -496,8 +448,8 @@ class NodeTest(tests.Test):
def test_FailOnExistedGUID(self):
volume = db.Volume('db', model.RESOURCES)
- volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
cp = MasterRoutes('guid', volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user', 'pubkey': tests.PUBKEY})
guid = call(cp, method='POST', document='context', principal=tests.UID, content={
'type': 'activity',
@@ -506,7 +458,7 @@ class NodeTest(tests.Test):
'description': 'description',
})
- self.assertRaises(RuntimeError, call, cp, method='POST', document='context', principal=tests.UID, content={
+ self.assertRaises(http.BadRequest, call, cp, method='POST', document='context', principal=tests.UID, content={
'guid': guid,
'type': 'activity',
'title': 'title',
@@ -566,139 +518,9 @@ class NodeTest(tests.Test):
def test_Clone(self):
volume = self.start_master()
- client = Connection(auth=http.SugarAuth(keyfile.value))
+ client = http.Connection(api_url.value, http.SugarAuth(keyfile.value))
- context = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
- impl1 = client.post(['release'], {
- 'context': context,
- 'license': 'GPLv3+',
- 'version': '1',
- 'stability': 'stable',
- 'notes': '',
- })
- blob1 = self.zips(('topdir/probe', 'probe1'))
- volume['release'].update(impl1, {'data': {
- 'blob': StringIO(blob1),
- 'spec': {
- '*-*': {
- 'requires': {
- 'dep1': {},
- },
- },
- },
- }})
- impl2 = client.post(['release'], {
- 'context': context,
- 'license': 'GPLv3+',
- 'version': '2',
- 'stability': 'stable',
- 'notes': '',
- })
- blob2 = self.zips(('topdir/probe', 'probe2'))
- volume['release'].update(impl2, {'data': {
- 'blob': StringIO(blob2),
- 'spec': {
- '*-*': {
- 'requires': {
- 'dep2': {'restrictions': [[None, '2']]},
- 'dep3': {},
- },
- },
- },
- }})
- impl3 = client.post(['release'], {
- 'context': context,
- 'license': 'GPLv3+',
- 'version': '3',
- 'stability': 'stable',
- 'notes': '',
- })
- blob3 = self.zips(('topdir/probe', 'probe3'))
- volume['release'].update(impl3, {'data': {
- 'blob': StringIO(blob3),
- 'spec': {
- '*-*': {
- 'requires': {
- 'dep2': {'restrictions': [['2', None]]},
- },
- },
- },
- }})
- impl4 = client.post(['release'], {
- 'context': context,
- 'license': 'GPLv3+',
- 'version': '4',
- 'stability': 'developer',
- 'notes': '',
- })
- blob4 = self.zips(('topdir/probe', 'probe4'))
- volume['release'].update(impl4, {'data': {
- 'blob': StringIO(blob4),
- 'spec': {
- '*-*': {
- 'requires': {},
- },
- },
- }})
-
- self.assertEqual(blob3, client.get(['context', context], cmd='clone'))
- self.assertEqual(blob4, client.get(['context', context], cmd='clone', stability='developer'))
- self.assertEqual(blob1, client.get(['context', context], cmd='clone', version='1'))
-
- self.assertEqual(blob1, client.get(['context', context], cmd='clone', requires='dep1'))
- self.assertEqual(blob3, client.get(['context', context], cmd='clone', requires='dep2'))
- self.assertEqual(blob2, client.get(['context', context], cmd='clone', requires='dep2=1'))
- self.assertEqual(blob3, client.get(['context', context], cmd='clone', requires='dep2=2'))
- self.assertEqual(blob2, client.get(['context', context], cmd='clone', requires='dep3'))
-
- self.assertRaises(http.NotFound, client.get, ['context', context], cmd='clone', requires='dep4')
- self.assertRaises(http.NotFound, client.get, ['context', context], cmd='clone', stability='foo')
-
- response = Response()
- client.call(Request(method='GET', path=['context', context], cmd='clone'), response)
- self.assertEqual({
- 'context': context,
- 'stability': 'stable',
- 'guid': impl3,
- 'version': '3',
- 'license': ['GPLv3+'],
- 'layer': ['origin'],
- 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
- 'ctime': self.node_volume['release'].get(impl3).ctime,
- 'notes': {'en-us': ''},
- 'tags': [],
- 'data': {
- 'blob_size': len(blob3),
- 'spec': {
- '*-*': {
- 'requires': {
- 'dep2': {
- 'restrictions': [['2', None]],
- },
- },
- },
- },
- },
- },
- response.meta)
-
- def test_release(self):
- volume = self.start_master()
- conn = Connection(auth=http.SugarAuth(keyfile.value))
-
- conn.post(['context'], {
- 'guid': 'bundle_id',
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
- activity_info = '\n'.join([
+ blob1 = self.zips(('topdir/activity/activity.info', '\n'.join([
'[Activity]',
'name = TestActivitry',
'bundle_id = bundle_id',
@@ -706,42 +528,12 @@ class NodeTest(tests.Test):
'icon = icon',
'activity_version = 1',
'license = Public Domain',
- 'stability = developer',
- 'requires = sugar>=0.88; dep'
- ])
- changelog = "LOG"
- bundle1 = self.zips(
- ('topdir/activity/activity.info', activity_info),
- ('topdir/CHANGELOG', changelog),
- )
- guid1 = json.load(conn.request('POST', ['release'], bundle1, params={'cmd': 'submit'}).raw)
-
- impl = volume['release'].get(guid1)
- self.assertEqual('bundle_id', impl['context'])
- self.assertEqual('1', impl['version'])
- self.assertEqual('developer', impl['stability'])
- self.assertEqual(['Public Domain'], impl['license'])
- self.assertEqual('developer', impl['stability'])
- self.assertEqual({'en-us': changelog}, impl['notes'])
- assert impl['ctime'] > 0
- assert impl['mtime'] > 0
- self.assertEqual({tests.UID: {'role': 3, 'name': 'f470db873b6a35903aca1f2492188e1c4b9ffc42', 'order': 0}}, impl['author'])
-
- data = impl.meta('data')
- self.assertEqual({
- '*-*': {
- 'commands': {'activity': {'exec': 'true'}},
- 'requires': {'dep': {}, 'sugar': {'restrictions': [['0.88', None]]}},
- },
- },
- data['spec'])
-
- self.assertEqual('application/vnd.olpc-sugar', data['mime_type'])
- self.assertEqual(len(bundle1), data['blob_size'])
- self.assertEqual(len(activity_info) + len(changelog), data.get('unpack_size'))
- self.assertEqual(bundle1, conn.get(['context', 'bundle_id'], cmd='clone', stability='developer'))
+ 'requires = dep1',
+ 'stability = stable',
+ ])))
+ release1 = json.load(client.request('POST', ['context'], blob1, params={'cmd': 'submit', 'initial': True}).raw)
- activity_info = '\n'.join([
+ blob2 = self.zips(('topdir/activity/activity.info', '\n'.join([
'[Activity]',
'name = TestActivitry',
'bundle_id = bundle_id',
@@ -749,606 +541,152 @@ class NodeTest(tests.Test):
'icon = icon',
'activity_version = 2',
'license = Public Domain',
+ 'requires = dep2 < 3; dep3',
'stability = stable',
- ])
- bundle2 = self.zips(('topdir/activity/activity.info', activity_info))
- guid2 = json.load(conn.request('POST', ['release'], bundle2, params={'cmd': 'submit'}).raw)
-
- self.assertEqual('1', volume['release'].get(guid1)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid1)['layer'])
- self.assertEqual('2', volume['release'].get(guid2)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid2)['layer'])
- self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone'))
+ ])))
+ release2 = json.load(client.request('POST', ['context'], blob2, params={'cmd': 'submit'}).raw)
- activity_info = '\n'.join([
+ blob3 = self.zips(('topdir/activity/activity.info', '\n'.join([
'[Activity]',
'name = TestActivitry',
'bundle_id = bundle_id',
'exec = true',
'icon = icon',
- 'activity_version = 1',
+ 'activity_version = 3',
'license = Public Domain',
+ 'requires = dep2 >= 2',
'stability = stable',
- ])
- bundle3 = self.zips(('topdir/activity/activity.info', activity_info))
- guid3 = json.load(conn.request('POST', ['release'], bundle3, params={'cmd': 'submit'}).raw)
-
- self.assertEqual('1', volume['release'].get(guid1)['version'])
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(guid1)['layer']))
- self.assertEqual('2', volume['release'].get(guid2)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid2)['layer'])
- self.assertEqual('1', volume['release'].get(guid3)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid3)['layer'])
- self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone'))
+ ])))
+ release3 = json.load(client.request('POST', ['context'], blob3, params={'cmd': 'submit'}).raw)
- activity_info = '\n'.join([
+ blob4 = self.zips(('topdir/activity/activity.info', '\n'.join([
'[Activity]',
'name = TestActivitry',
'bundle_id = bundle_id',
'exec = true',
'icon = icon',
- 'activity_version = 2',
+ 'activity_version = 4',
'license = Public Domain',
- 'stability = buggy',
- ])
- bundle4 = self.zips(('topdir/activity/activity.info', activity_info))
- guid4 = json.load(conn.request('POST', ['release'], bundle4, params={'cmd': 'submit'}).raw)
-
- self.assertEqual('1', volume['release'].get(guid1)['version'])
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(guid1)['layer']))
- self.assertEqual('2', volume['release'].get(guid2)['version'])
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(guid2)['layer']))
- self.assertEqual('1', volume['release'].get(guid3)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid3)['layer'])
- self.assertEqual('2', volume['release'].get(guid4)['version'])
- self.assertEqual(['origin'], volume['release'].get(guid4)['layer'])
- self.assertEqual(bundle3, conn.get(['context', 'bundle_id'], cmd='clone'))
-
- def test_release_UpdateContext(self):
- volume = self.start_master()
- conn = Connection(auth=http.SugarAuth(keyfile.value))
+ 'stability = developer',
+ ])))
+ release4 = json.load(client.request('POST', ['context'], blob4, params={'cmd': 'submit'}).raw)
- conn.post(['context'], {
- 'guid': 'org.laptop.ImageViewerActivity',
- 'type': 'activity',
- 'title': {'en': ''},
- 'summary': {'en': ''},
- 'description': {'en': ''},
- })
- svg = '\n'.join([
- '<?xml version="1.0" encoding="UTF-8"?>',
- '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [',
- ' <!ENTITY fill_color "#123456">',
- ' <!ENTITY stroke_color "#123456">',
- ']>',
- '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">',
- ' <rect x="3" y="7" width="44" height="36" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3"/>',
- ' <polyline points="15,7 25,1 35,7" style="fill:none;;stroke:&stroke_color;;stroke-width:1.25"/>',
- ' <circle cx="14" cy="19" r="4.5" style="fill:&stroke_color;;stroke:&stroke_color;;stroke-width:1.5"/>',
- ' <polyline points="3,36 16,32 26,35" style="fill:none;;stroke:&stroke_color;;stroke-width:2.5"/>',
- ' <polyline points="15,43 37,28 47,34 47,43" style="fill:&stroke_color;;stroke:&stroke_color;;stroke-width:3"/>',
- ' <polyline points="22,41.5 35,30 27,41.5" style="fill:&fill_color;;stroke:none;;stroke-width:0"/>',
- ' <polyline points="26,23 28,25 30,23" style="fill:none;;stroke:&stroke_color;;stroke-width:.9"/>',
- ' <polyline points="31.2,20 33.5,17.7 35.8,20" style="fill:none;;stroke:&stroke_color;;stroke-width:1"/>',
- ' <polyline points="36,13 38.5,15.5 41,13" style="fill:none;;stroke:&stroke_color;;stroke-width:1"/>',
- '</svg>',
- ])
- bundle = self.zips(
- ('ImageViewer.activity/activity/activity.info', '\n'.join([
- '[Activity]',
- 'bundle_id = org.laptop.ImageViewerActivity',
- 'name = Image Viewer',
- 'summary = The Image Viewer activity is a simple and fast image viewer tool',
- 'description = It has features one would expect of a standard image viewer, like zoom, rotate, etc.',
- 'homepage = http://wiki.sugarlabs.org/go/Activities/Image_Viewer',
- 'activity_version = 22',
- 'license = GPLv2+',
- 'icon = activity-imageviewer',
- 'exec = true',
- 'mime_types = image/bmp;image/gif',
- ])),
- ('ImageViewer.activity/locale/ru/LC_MESSAGES/org.laptop.ImageViewerActivity.mo',
- base64.b64decode('3hIElQAAAAAMAAAAHAAAAHwAAAARAAAA3AAAAAAAAAAgAQAADwAAACEBAAAOAAAAMQEAAA0AAABAAQAACgAAAE4BAAAMAAAAWQEAAA0AAABmAQAAJwAAAHQBAAAUAAAAnAEAABAAAACxAQAABwAAAMIBAAAIAAAAygEAANEBAADTAQAAIQAAAKUDAAATAAAAxwMAABwAAADbAwAAFwAAAPgDAAAhAAAAEAQAAB0AAAAyBAAAQAAAAFAEAAA9AAAAkQQAADUAAADPBAAAFAAAAAUFAAAQAAAAGgUAAAEAAAACAAAABwAAAAAAAAADAAAAAAAAAAwAAAAJAAAAAAAAAAoAAAAEAAAAAAAAAAAAAAALAAAABgAAAAgAAAAFAAAAAENob29zZSBkb2N1bWVudABEb3dubG9hZGluZy4uLgBGaXQgdG8gd2luZG93AEZ1bGxzY3JlZW4ASW1hZ2UgVmlld2VyAE9yaWdpbmFsIHNpemUAUmV0cmlldmluZyBzaGFyZWQgaW1hZ2UsIHBsZWFzZSB3YWl0Li4uAFJvdGF0ZSBhbnRpY2xvY2t3aXNlAFJvdGF0ZSBjbG9ja3dpc2UAWm9vbSBpbgBab29tIG91dABQcm9qZWN0LUlkLVZlcnNpb246IFBBQ0tBR0UgVkVSU0lPTgpSZXBvcnQtTXNnaWQtQnVncy1UbzogClBPVC1DcmVhdGlvbi1EYXRlOiAyMDEyLTA5LTI3IDE0OjU3LTA0MDAKUE8tUmV2aXNpb24tRGF0ZTogMjAxMC0wOS0yMiAxMzo1MCswMjAwCkxhc3QtVHJhbnNsYXRvcjoga3JvbTlyYSA8a3JvbTlyYUBnbWFpbC5jb20+Ckxhbmd1YWdlLVRlYW06IExBTkdVQUdFIDxMTEBsaS5vcmc+Ckxhbmd1YWdlOiAKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IDhiaXQKUGx1cmFsLUZvcm1zOiBucGx1cmFscz0zOyBwbHVyYWw9KG4lMTA9PTEgJiYgbiUxMDAhPTExID8gMCA6IG4lMTA+PTIgJiYgbiUxMDw9NCAmJiAobiUxMDA8MTAgfHwgbiUxMDA+PTIwKSA/IDEgOiAyKTsKWC1HZW5lcmF0b3I6IFBvb3RsZSAyLjAuMwoA0JLRi9Cx0LXRgNC40YLQtSDQtNC+0LrRg9C80LXQvdGCANCX0LDQs9GA0YPQt9C60LAuLi4A0KPQvNC10YHRgtC40YLRjCDQsiDQvtC60L3QtQDQn9C+0LvQvdGL0Lkg0Y3QutGA0LDQvQDQn9GA0L7RgdC80L7RgtGAINC60LDRgNGC0LjQvdC+0LoA0JjRgdGC0LjQvdC90YvQuSDRgNCw0LfQvNC10YAA0J/QvtC70YPRh9C10L3QuNC1INC40LfQvtCx0YDQsNC20LXQvdC40LksINC/0L7QtNC+0LbQtNC40YLQtS4uLgDQn9C+0LLQtdGA0L3Rg9GC0Ywg0L/RgNC+0YLQuNCyINGH0LDRgdC+0LLQvtC5INGB0YLRgNC10LvQutC4ANCf0L7QstC10YDQvdGD0YLRjCDQv9C+INGH0LDRgdC+0LLQvtC5INGB0YLRgNC10LvQutC1ANCf0YDQuNCx0LvQuNC30LjRgtGMANCe0YLQtNCw0LvQuNGC0YwA')),
- ('ImageViewer.activity/activity/activity-imageviewer.svg', svg),
- )
- impl = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit'}).raw)
+ assert blob3 == client.get(['context', 'bundle_id'], cmd='clone')
+ assert blob4 == client.get(['context', 'bundle_id'], cmd='clone', stability='developer')
+ assert blob1 == client.get(['context', 'bundle_id'], cmd='clone', version='1')
- context = volume['context'].get('org.laptop.ImageViewerActivity')
- self.assertEqual({
- 'en': 'Image Viewer',
- 'ru': u'Просмотр картинок',
- },
- context['title'])
- self.assertEqual({
- 'en': 'The Image Viewer activity is a simple and fast image viewer tool',
- },
- context['summary'])
- self.assertEqual({
- 'en': 'It has features one would expect of a standard image viewer, like zoom, rotate, etc.',
- },
- context['description'])
- self.assertEqual(svg, file(context['artifact_icon']['blob']).read())
- assert 'blob' in context['icon']
- assert 'blob' in context['logo']
- self.assertEqual('http://wiki.sugarlabs.org/go/Activities/Image_Viewer', context['homepage'])
- self.assertEqual(['image/bmp', 'image/gif'], context['mime_types'])
-
- def test_release_CreateContext(self):
- volume = self.start_master()
- conn = Connection(auth=http.SugarAuth(keyfile.value))
-
- bundle = self.zips(
- ('ImageViewer.activity/activity/activity.info', '\n'.join([
- '[Activity]',
- 'bundle_id = org.laptop.ImageViewerActivity',
- 'name = Image Viewer',
- 'summary = The Image Viewer activity is a simple and fast image viewer tool',
- 'description = It has features one would expect of a standard image viewer, like zoom, rotate, etc.',
- 'homepage = http://wiki.sugarlabs.org/go/Activities/Image_Viewer',
- 'activity_version = 22',
- 'license = GPLv2+',
- 'icon = activity-imageviewer',
- 'exec = true',
- 'mime_types = image/bmp;image/gif',
- ])),
- ('ImageViewer.activity/activity/activity-imageviewer.svg', ''),
- )
- self.assertRaises(http.NotFound, conn.request, 'POST', ['release'], bundle, params={'cmd': 'submit'})
- impl = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit', 'initial': 1}).raw)
-
- context = volume['context'].get('org.laptop.ImageViewerActivity')
- self.assertEqual({'en': 'Image Viewer'}, context['title'])
- self.assertEqual({'en': 'The Image Viewer activity is a simple and fast image viewer tool'}, context['summary'])
- self.assertEqual({'en': 'It has features one would expect of a standard image viewer, like zoom, rotate, etc.'}, context['description'])
- self.assertEqual('http://wiki.sugarlabs.org/go/Activities/Image_Viewer', context['homepage'])
- self.assertEqual(['image/bmp', 'image/gif'], context['mime_types'])
- assert context['ctime'] > 0
- assert context['mtime'] > 0
- self.assertEqual({tests.UID: {'role': 3, 'name': 'f470db873b6a35903aca1f2492188e1c4b9ffc42', 'order': 0}}, context['author'])
-
- def test_release_ByNonAuthors(self):
- volume = self.start_master()
- bundle = self.zips(
- ('ImageViewer.activity/activity/activity.info', '\n'.join([
- '[Activity]',
- 'bundle_id = org.laptop.ImageViewerActivity',
- 'name = Image Viewer',
- 'activity_version = 1',
- 'license = GPLv2+',
- 'icon = activity-imageviewer',
- 'exec = true',
- ])),
- ('ImageViewer.activity/activity/activity-imageviewer.svg', ''),
- )
+ assert blob1 == client.get(['context', 'bundle_id'], cmd='clone', requires='dep1')
+ assert blob3 == client.get(['context', 'bundle_id'], cmd='clone', requires='dep2')
+ assert blob2 == client.get(['context', 'bundle_id'], cmd='clone', requires='dep2=1')
+ assert blob3 == client.get(['context', 'bundle_id'], cmd='clone', requires='dep2=2')
+ assert blob2 == client.get(['context', 'bundle_id'], cmd='clone', requires='dep3')
- conn = Connection(auth=http.SugarAuth(join(tests.root, 'data', tests.UID)))
- impl1 = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit', 'initial': 1}).raw)
- impl2 = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit'}).raw)
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(impl1)['layer']))
- self.assertEqual(['origin'], volume['release'].get(impl2)['layer'])
+ self.assertRaises(http.NotFound, client.get, ['context', 'bundle_id'], cmd='clone', requires='dep4')
+ self.assertRaises(http.NotFound, client.get, ['context', 'bundle_id'], cmd='clone', stability='foo')
- conn = Connection(auth=http.SugarAuth(join(tests.root, 'data', tests.UID2)))
- conn.get(cmd='whoami')
- impl3 = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit'}).raw)
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(impl1)['layer']))
- self.assertEqual(sorted(['origin', 'deleted']), sorted(volume['release'].get(impl2)['layer']))
- self.assertEqual([], volume['release'].get(impl3)['layer'])
+ response = Response()
+ client.call(Request(method='GET', path=['context', 'bundle_id'], cmd='clone'), response)
+ announce = next(volume['post'].find(query='3', limit=1)[0]).guid
+ self.assertEqual({
+ 'license': ['Public Domain'],
+ 'unpack_size': 162,
+ 'stability': 'stable',
+ 'version': '3',
+ 'release': [[3], 0],
+ 'announce': announce,
+ 'requires': ['dep2-2'],
+ 'spec': {
+ '*-*': {
+ 'commands': {'activity': {'exec': u'true'}},
+ 'requires': {'dep2': {'restrictions': [['2', None]]}},
+ 'bundle': str(hash(blob3)),
+ },
+ },
+ }, response.meta)
- def test_release_PopulateRequires(self):
+ def test_release(self):
volume = self.start_master()
conn = Connection(auth=http.SugarAuth(keyfile.value))
+ activity_info = '\n'.join([
+ '[Activity]',
+ 'name = TestActivitry',
+ 'bundle_id = bundle_id',
+ 'exec = true',
+ 'icon = icon',
+ 'activity_version = 1',
+ 'license = Public Domain',
+ 'stability = developer',
+ ])
+ changelog = "LOG"
bundle = self.zips(
- ('ImageViewer.activity/activity/activity.info', '\n'.join([
- '[Activity]',
- 'bundle_id = org.laptop.ImageViewerActivity',
- 'name = Image Viewer',
- 'activity_version = 22',
- 'license = GPLv2+',
- 'icon = activity-imageviewer',
- 'exec = true',
- 'requires = dep1, dep2<10, dep3<=20, dep4>30, dep5>=40, dep6>5<7, dep7>=1<=3',
- ])),
- ('ImageViewer.activity/activity/activity-imageviewer.svg', ''),
+ ('topdir/activity/activity.info', activity_info),
+ ('topdir/CHANGELOG', changelog),
)
- self.assertRaises(http.NotFound, conn.request, 'POST', ['release'], bundle, params={'cmd': 'submit'})
- impl = json.load(conn.request('POST', ['release'], bundle, params={'cmd': 'submit', 'initial': 1}).raw)
-
- self.assertEqual(
- sorted([
- 'dep1', 'dep2', 'dep3', 'dep4-31', 'dep5-40',
- 'dep6-6',
- 'dep7-1', 'dep7-2', 'dep7-3',
- ]),
- sorted(volume['release'].get(impl)['requires']))
-
- def test_generate_node_stats_Posts(self):
- node.stats_root.value = 'stats'
- stats_node.stats_node.value = True
- stats_node.stats_node_rras.value = ['RRA:AVERAGE:0.5:1:10', 'RRA:AVERAGE:0.5:10:10']
- volume = db.Volume('db', model.RESOURCES)
-
- ts = 1000000000
-
- volume['user'].create({
- 'guid': 'user_1',
- 'ctime': ts + 1,
- 'mtime': ts + 1,
- 'layer': [],
- 'name': '',
- })
- volume['context'].create({
- 'guid': 'context_1',
- 'ctime': ts + 1,
- 'mtime': ts + 1,
- 'layer': [],
- 'type': 'activity',
- 'title': '',
- 'summary': '',
- 'description': '',
- })
- volume['release'].create({
- 'guid': 'impl_1',
- 'ctime': ts + 2,
- 'mtime': ts + 2,
- 'layer': [],
- 'context': 'context_1',
- 'license': ['GPL-3'],
- 'version': '1',
- })
- volume['post'].create({
- 'guid': 'topic_1',
- 'ctime': ts + 3,
- 'mtime': ts + 3,
- 'layer': [],
- 'context': 'context_1',
- 'type': 'object',
- 'title': '',
- 'message': '',
- })
- volume['post'].create({
- 'guid': 'solution_1',
- 'ctime': ts + 5,
- 'mtime': ts + 5,
- 'layer': [],
- 'context': 'context_1',
- 'topic': 'topic_1',
- 'title': '',
- 'message': '',
- 'type': 'answer',
- })
- volume['post'].create({
- 'guid': 'review_1',
- 'ctime': ts + 6,
- 'mtime': ts + 6,
- 'layer': [],
- 'context': 'context_1',
- 'vote': 1,
- 'title': '',
- 'message': '',
- 'type': 'review',
- })
- volume['post'].create({
- 'guid': 'review_2',
- 'ctime': ts + 6,
- 'mtime': ts + 6,
- 'layer': [],
- 'context': 'context_1',
- 'topic': 'topic_1',
- 'vote': 2,
- 'title': '',
- 'message': '',
- 'type': 'feedback',
- })
- volume['report'].create({
- 'guid': 'report_1',
- 'ctime': ts + 8,
- 'mtime': ts + 8,
- 'layer': [],
- 'context': 'context_1',
- 'release': 'impl_1',
- 'error': '',
- })
- volume['user'].create({
- 'guid': 'user_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'name': '',
- })
- volume['context'].create({
- 'guid': 'context_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'type': 'activity',
- 'title': '',
- 'summary': '',
- 'description': '',
- })
- volume['release'].create({
- 'guid': 'impl_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'license': ['GPL-3'],
- 'version': '1',
- })
- volume['release'].create({
- 'guid': 'impl_3',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'license': ['GPL-3'],
- 'version': '1',
- })
- volume['post'].create({
- 'guid': 'review_3',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'vote': 3,
- 'title': '',
- 'message': '',
- 'type': 'review',
- })
- volume['post'].create({
- 'guid': 'review_4',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'vote': 4,
- 'title': '',
- 'message': '',
- 'type': 'review',
- })
- volume['report'].create({
- 'guid': 'report_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'release': 'impl_1',
- 'error': '',
- })
- volume['report'].create({
- 'guid': 'report_3',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'release': 'impl_1',
- 'error': '',
- })
- volume['post'].create({
- 'guid': 'topic_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'type': 'object',
- 'title': '',
- 'message': '',
- })
- volume['post'].create({
- 'guid': 'solution_2',
- 'ctime': ts + 4,
- 'mtime': ts + 4,
- 'layer': [],
- 'context': 'context_2',
- 'topic': 'topic_2',
- 'title': '',
- 'message': '',
- 'type': 'answer',
- })
-
- self.override(time, 'time', lambda: ts + 9)
- old_stats = stats_node.Sniffer(volume, 'stats/node')
- old_stats.log(Request(method='GET', path=['release', 'impl_1', 'data']))
- old_stats.log(Request(method='GET', path=['post', 'topic_1', 'data']))
- old_stats.commit(ts + 1)
- old_stats.commit_objects()
- old_stats.commit(ts + 2)
- old_stats.commit(ts + 3)
- old_stats.log(Request(method='GET', path=['release', 'impl_1', 'data']))
- old_stats.log(Request(method='GET', path=['release', 'impl_2', 'data']))
- old_stats.commit(ts + 4)
- old_stats.commit_objects()
- old_stats.commit(ts + 5)
- old_stats.commit(ts + 6)
- old_stats.log(Request(method='GET', path=['post', 'topic_1', 'data']))
- old_stats.log(Request(method='GET', path=['post', 'topic_2', 'data']))
- old_stats.commit(ts + 7)
- old_stats.commit_objects()
- old_stats.commit(ts + 8)
- old_stats.commit_objects()
-
- generate_node_stats(volume, 'stats/node')
- cp = NodeRoutes('guid', volume)
+ release = json.load(conn.request('POST', ['context'], bundle, params={'cmd': 'submit', 'initial': True}).raw)
+ announce = next(volume['post'].find(query='1', limit=1)[0]).guid
self.assertEqual({
- 'user': [
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 1.0}),
- (ts + 3, {'total': 1.0}),
- (ts + 4, {'total': 2.0}),
- (ts + 5, {'total': 2.0}),
- (ts + 6, {'total': 2.0}),
- (ts + 7, {'total': 2.0}),
- (ts + 8, {'total': 2.0}),
- (ts + 9, {'total': 2.0}),
- ],
- 'context': [
- (ts + 1, {'total': 1.0, 'released': 0.0, 'failed': 0.0, 'downloaded': 1.0}),
- (ts + 2, {'total': 1.0, 'released': 1.0, 'failed': 0.0, 'downloaded': 1.0}),
- (ts + 3, {'total': 1.0, 'released': 1.0, 'failed': 0.0, 'downloaded': 1.0}),
- (ts + 4, {'total': 2.0, 'released': 3.0, 'failed': 2.0, 'downloaded': 3.0}),
- (ts + 5, {'total': 2.0, 'released': 3.0, 'failed': 2.0, 'downloaded': 3.0}),
- (ts + 6, {'total': 2.0, 'released': 3.0, 'failed': 2.0, 'downloaded': 3.0}),
- (ts + 7, {'total': 2.0, 'released': 3.0, 'failed': 2.0, 'downloaded': 3.0}),
- (ts + 8, {'total': 2.0, 'released': 3.0, 'failed': 3.0, 'downloaded': 3.0}),
- (ts + 9, {'total': 2.0, 'released': 3.0, 'failed': 3.0, 'downloaded': 3.0}),
- ],
- 'post': [
- (ts + 1, {'total': 0.0, 'downloaded': 1.0}),
- (ts + 2, {'total': 0.0, 'downloaded': 1.0}),
- (ts + 3, {'total': 1.0, 'downloaded': 1.0}),
- (ts + 4, {'total': 5.0, 'downloaded': 1.0}),
- (ts + 5, {'total': 6.0, 'downloaded': 1.0}),
- (ts + 6, {'total': 8.0, 'downloaded': 1.0}),
- (ts + 7, {'total': 8.0, 'downloaded': 3.0}),
- (ts + 8, {'total': 8.0, 'downloaded': 3.0}),
- (ts + 9, {'total': 8.0, 'downloaded': 3.0}),
- ],
- },
- call(cp, method='GET', cmd='stats', source=[
- 'user.total',
- 'context.total',
- 'context.released',
- 'context.failed',
- 'context.downloaded',
- 'post.total',
- 'post.downloaded',
- ], start=ts + 1, end=ts + 10))
+ release: {
+ 'seqno': 4,
+ 'author': {tests.UID: {'name': tests.UID, 'order': 0, 'role': 3}},
+ 'value': {
+ 'license': ['Public Domain'],
+ 'announce': announce,
+ 'release': [[1], 0],
+ 'requires': [],
+ 'spec': {'*-*': {'bundle': str(hash(bundle)), 'commands': {'activity': {'exec': 'true'}}, 'requires': {}}},
+ 'stability': 'developer',
+ 'unpack_size': len(activity_info) + len(changelog),
+ 'version': '1',
+ },
+ },
+ }, conn.get(['context', 'bundle_id', 'releases']))
+ post = volume['post'][announce]
+ assert tests.UID in post['author']
+ self.assertEqual('notification', post['type'])
self.assertEqual({
- 'downloads': 2,
- 'rating': [1, 1],
- },
- volume['context'].get('context_1').properties(['downloads', 'rating']))
- self.assertEqual({
- 'downloads': 1,
- 'rating': [2, 7],
- },
- volume['context'].get('context_2').properties(['downloads', 'rating']))
- self.assertEqual({
- 'downloads': 2,
- 'rating': [1, 2],
- },
- volume['post'].get('topic_1').properties(['downloads', 'rating']))
- self.assertEqual({
- 'downloads': 1,
- 'rating': [0, 0],
- },
- volume['post'].get('topic_2').properties(['downloads', 'rating']))
-
- def test_generate_node_stats_Deletes(self):
- node.stats_root.value = 'stats'
- stats_node.stats_node.value = True
- stats_node.stats_node_rras.value = ['RRA:AVERAGE:0.5:1:10', 'RRA:AVERAGE:0.5:10:10']
- volume = db.Volume('db', model.RESOURCES)
-
- ts = 1000000000
-
- volume['user'].create({
- 'guid': 'user_1',
- 'ctime': ts + 1,
- 'mtime': ts + 2,
- 'layer': ['deleted'],
- 'name': '',
- })
- volume['context'].create({
- 'guid': 'context_1',
- 'ctime': ts + 1,
- 'mtime': ts + 2,
- 'layer': ['deleted'],
- 'type': 'activity',
- 'title': '',
- 'summary': '',
- 'description': '',
- })
- volume['release'].create({
- 'guid': 'impl_1',
- 'ctime': ts + 1,
- 'mtime': ts + 2,
- 'layer': ['deleted'],
- 'context': 'context_1',
- 'license': ['GPL-3'],
- 'version': '1',
- })
- volume['post'].create({
- 'guid': 'post_1',
- 'ctime': ts + 1,
- 'mtime': ts + 2,
- 'layer': ['deleted'],
- 'context': 'context_1',
- 'type': 'object',
- 'title': '',
- 'message': '',
- })
- volume['report'].create({
- 'guid': 'report_1',
- 'ctime': ts + 1,
- 'mtime': ts + 2,
- 'layer': ['deleted'],
- 'context': 'context_1',
- 'release': 'impl_1',
- 'error': '',
- })
-
- self.override(time, 'time', lambda: ts + 9)
- generate_node_stats(volume, 'stats/node')
- cp = NodeRoutes('guid', volume)
-
+ 'en': 'TestActivitry 1 release',
+ 'es': 'TestActivitry 1 release',
+ 'fr': 'TestActivitry 1 release',
+ }, post['title'])
self.assertEqual({
- 'user': [
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 0.0}),
- (ts + 3, {'total': 0.0}),
- ],
- 'context': [
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 0.0}),
- (ts + 3, {'total': 0.0}),
- ],
- 'post': [
- (ts + 1, {'total': 1.0}),
- (ts + 2, {'total': 0.0}),
- (ts + 3, {'total': 0.0}),
- ],
- },
- call(cp, method='GET', cmd='stats', source=[
- 'user.total',
- 'context.total',
- 'post.total',
- ], start=ts + 1, end=ts + 3))
+ 'en-us': 'LOG',
+ }, post['message'])
def test_AggpropInsertAccess(self):
class Document(db.Resource):
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.READ | ACL.INSERT)
+ @db.stored_property(db.Aggregated, acl=ACL.READ | ACL.INSERT)
def prop1(self, value):
return value
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.READ | ACL.INSERT | ACL.AUTHOR)
+ @db.stored_property(db.Aggregated, acl=ACL.READ | ACL.INSERT | ACL.AUTHOR)
def prop2(self, value):
return value
volume = db.Volume('db', [Document, User])
- volume['user'].create({'guid': tests.UID, 'name': 'user1', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- volume['user'].create({'guid': tests.UID2, 'name': 'user2', 'pubkey': {'blob': StringIO(tests.PUBKEY2)}})
+ cp = NodeRoutes('node', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user1', 'pubkey': tests.PUBKEY})
+ volume['user'].create({'guid': tests.UID2, 'name': 'user2', 'pubkey': tests.PUBKEY2})
- cp = NodeRoutes('node', volume)
guid = call(cp, method='POST', document='document', principal=tests.UID, content={})
self.override(time, 'time', lambda: 0)
- call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID, content={'guid': '1'})
- call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID2, content={'guid': '2'})
+ agg1 = call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID)
+ agg2 = call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID2)
self.assertEqual({
- '1': {'seqno': 4, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
- '2': {'seqno': 5, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 3}}},
+ agg1: {'seqno': 4, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}, 'value': None},
+ agg2: {'seqno': 5, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 1}}, 'value': None},
},
call(cp, method='GET', path=['document', guid, 'prop1']))
- call(cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID, content={'guid': '1'})
- self.assertRaises(http. Forbidden, call, cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID2, content={'guid': '2'})
+ agg3 = call(cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID)
+ self.assertRaises(http. Forbidden, call, cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID2)
self.assertEqual({
- '1': {'seqno': 6, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg3: {'seqno': 6, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}, 'value': None},
},
call(cp, method='GET', path=['document', guid, 'prop2']))
@@ -1356,64 +694,64 @@ class NodeTest(tests.Test):
class Document(db.Resource):
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.READ | ACL.INSERT | ACL.REMOVE)
+ @db.stored_property(db.Aggregated, acl=ACL.READ | ACL.INSERT | ACL.REMOVE)
def prop1(self, value):
return value
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.READ | ACL.INSERT | ACL.REMOVE | ACL.AUTHOR)
+ @db.stored_property(db.Aggregated, acl=ACL.READ | ACL.INSERT | ACL.REMOVE | ACL.AUTHOR)
def prop2(self, value):
return value
volume = db.Volume('db', [Document, User])
- volume['user'].create({'guid': tests.UID, 'name': 'user1', 'pubkey': {'blob': StringIO(tests.PUBKEY)}})
- volume['user'].create({'guid': tests.UID2, 'name': 'user2', 'pubkey': {'blob': StringIO(tests.PUBKEY2)}})
+ cp = NodeRoutes('node', volume=volume)
+ volume['user'].create({'guid': tests.UID, 'name': 'user1', 'pubkey': tests.PUBKEY})
+ volume['user'].create({'guid': tests.UID2, 'name': 'user2', 'pubkey': tests.PUBKEY2})
- cp = NodeRoutes('node', volume)
guid = call(cp, method='POST', document='document', principal=tests.UID, content={})
self.override(time, 'time', lambda: 0)
- call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID, content={'guid': '1', 'probe': True})
- call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID2, content={'guid': '2', 'probe': True})
+ agg1 = call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID, content=True)
+ agg2 = call(cp, method='POST', path=['document', guid, 'prop1'], principal=tests.UID2, content=True)
self.assertEqual({
- '1': {'seqno': 4, 'probe': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
- '2': {'seqno': 5, 'probe': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 3}}},
+ agg1: {'seqno': 4, 'value': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg2: {'seqno': 5, 'value': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 1}}},
},
call(cp, method='GET', path=['document', guid, 'prop1']))
- self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop1', '1'], principal=tests.UID2)
- self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop1', '2'], principal=tests.UID)
+ self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop1', agg1], principal=tests.UID2)
+ self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop1', agg2], principal=tests.UID)
self.assertEqual({
- '1': {'seqno': 4, 'probe': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
- '2': {'seqno': 5, 'probe': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 3}}},
+ agg1: {'seqno': 4, 'value': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg2: {'seqno': 5, 'value': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 1}}},
},
call(cp, method='GET', path=['document', guid, 'prop1']))
- call(cp, method='DELETE', path=['document', guid, 'prop1', '1'], principal=tests.UID)
+ call(cp, method='DELETE', path=['document', guid, 'prop1', agg1], principal=tests.UID)
self.assertEqual({
- '1': {'seqno': 6},
- '2': {'seqno': 5, 'probe': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 3}}},
+ agg1: {'seqno': 6, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg2: {'seqno': 5, 'value': True, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 1}}},
},
call(cp, method='GET', path=['document', guid, 'prop1']))
- call(cp, method='DELETE', path=['document', guid, 'prop1', '2'], principal=tests.UID2)
+ call(cp, method='DELETE', path=['document', guid, 'prop1', agg2], principal=tests.UID2)
self.assertEqual({
- '1': {'seqno': 6},
- '2': {'seqno': 7},
+ agg1: {'seqno': 6, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg2: {'seqno': 7, 'author': {tests.UID2: {'name': 'user2', 'order': 0, 'role': 1}}},
},
call(cp, method='GET', path=['document', guid, 'prop1']))
- call(cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID, content={'guid': '1', 'probe': True})
+ agg3 = call(cp, method='POST', path=['document', guid, 'prop2'], principal=tests.UID, content=True)
self.assertEqual({
- '1': {'seqno': 8, 'probe': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg3: {'seqno': 8, 'value': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
},
call(cp, method='GET', path=['document', guid, 'prop2']))
- self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop2', '1'], principal=tests.UID2)
+ self.assertRaises(http.Forbidden, call, cp, method='DELETE', path=['document', guid, 'prop2', agg3], principal=tests.UID2)
self.assertEqual({
- '1': {'seqno': 8, 'probe': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
+ agg3: {'seqno': 8, 'value': True, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
},
call(cp, method='GET', path=['document', guid, 'prop2']))
- call(cp, method='DELETE', path=['document', guid, 'prop2', '1'], principal=tests.UID)
+ call(cp, method='DELETE', path=['document', guid, 'prop2', agg3], principal=tests.UID)
self.assertEqual({
- '1': {'seqno': 9},
+ agg3: {'seqno': 9, 'author': {tests.UID: {'name': 'user1', 'order': 0, 'role': 3}}},
},
call(cp, method='GET', path=['document', guid, 'prop2']))
diff --git a/tests/units/node/obs.py b/tests/units/node/obs.py
index bf43ed6..21b53a0 100755
--- a/tests/units/node/obs.py
+++ b/tests/units/node/obs.py
@@ -39,8 +39,8 @@ class ObsTest(tests.Test):
]))
self.assertEqual([
- {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['i586', 'x86_64']},
- {'distributor_id': 'Fedora', 'name': 'Fedora-11', 'arches': ['i586']},
+ {'lsb_id': 'Debian', 'lsb_release': '6.0', 'name': 'Debian-6.0', 'arches': ['i586', 'x86_64']},
+ {'lsb_id': 'Fedora', 'lsb_release': '11', 'name': 'Fedora-11', 'arches': ['i586']},
],
obs.get_repos())
@@ -51,21 +51,10 @@ class ObsTest(tests.Test):
'project': 'base',
'repository': 'repo',
'arch': 'arch',
- 'package': 'pkg1',
+ 'package': ['pkg1', 'pkg2'],
}},
[ '<resolve>',
' <binary name="pygame" url="http://pkg1.prm" arch="arch"/>',
- '</resolve>',
- ],
- ),
- (('GET', ['resolve']),
- {'allowed': (400, 404), 'params': {
- 'project': 'base',
- 'repository': 'repo',
- 'arch': 'arch',
- 'package': 'pkg2',
- }},
- [ '<resolve>',
' <binary name="pygame" url="http://pkg2.prm" arch="arch"/>',
'</resolve>',
],
@@ -122,10 +111,7 @@ class ObsTest(tests.Test):
('http://pkg2-2.prm', ['4']),
]))
- obs.presolve({
- 'Debian': {'binary': [['deb']]},
- 'Fedora': {'binary': [['pkg1', 'pkg2']], 'devel': [['pkg3']]},
- }, '.')
+ obs.presolve(None, ['pkg1', 'pkg2'], '.')
self.assertEqual({
'arch': [
diff --git a/tests/units/node/stats_node.py b/tests/units/node/stats_node.py
deleted file mode 100755
index eab7fb8..0000000
--- a/tests/units/node/stats_node.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#!/usr/bin/env python
-# sugar-lint: disable
-
-import time
-
-from __init__ import tests
-
-from sugar_network import db, model
-from sugar_network.node.stats_node import Sniffer, stats_node_step
-from sugar_network.toolkit.rrd import Rrd
-from sugar_network.toolkit.router import Request
-
-
-class StatsTest(tests.Test):
-
- def test_InitializeTotals(self):
- volume = db.Volume('local', model.RESOURCES)
-
- stats = Sniffer(volume, 'stats/node')
- self.assertEqual(0, stats._stats['user']['total'])
- self.assertEqual(0, stats._stats['context']['total'])
- self.assertEqual(0, stats._stats['post']['total'])
-
- volume['user'].create({'guid': 'user', 'name': 'user', 'pubkey': ''})
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['post'].create({'guid': 'post', 'context': 'context', 'title': '', 'message': '', 'type': 'update'})
-
- stats = Sniffer(volume, 'stats/node')
- self.assertEqual(1, stats._stats['user']['total'])
- self.assertEqual(1, stats._stats['context']['total'])
- self.assertEqual(1, stats._stats['post']['total'])
-
- def test_POSTs(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
-
- request = Request(method='POST', path=['context'])
- request.principal = 'user'
- stats.log(request)
- stats.log(request)
- stats.log(request)
- self.assertEqual(3, stats._stats['context']['total'])
-
- def test_DELETEs(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
-
- request = Request(method='DELETE', path=['context'])
- request.principal = 'user'
- stats.log(request)
- stats.log(request)
- stats.log(request)
- self.assertEqual(-3, stats._stats['context']['total'])
-
- def test_Posts(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['post'].create({'guid': 'topic', 'type': 'update', 'context': 'context', 'title': '', 'message': ''})
-
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'context': 'context', 'vote': 1, 'type': 'review', 'title': '', 'message': ''}
- stats.log(request)
- self.assertEqual(1, stats._stats['post']['total'])
-
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'context': 'context', 'vote': 2, 'type': 'review', 'title': '', 'message': ''}
- stats.log(request)
- self.assertEqual(2, stats._stats['post']['total'])
-
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'topic': 'topic', 'vote': 3, 'type': 'feedback', 'title': '', 'message': ''}
- stats.log(request)
- self.assertEqual(3, stats._stats['post']['total'])
-
- stats.commit_objects()
- self.assertEqual([2, 3], volume['context'].get('context')['rating'])
- self.assertEqual([1, 3], volume['post'].get('topic')['rating'])
-
- def test_ContextDownloaded(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['release'].create({'guid': 'release', 'context': 'context', 'license': 'GPLv3', 'version': '1', 'date': 0, 'stability': 'stable', 'notes': ''})
-
- request = Request(method='GET', path=['release', 'release', 'fake'])
- request.principal = 'user'
- stats.log(request)
- self.assertEqual(0, stats._stats['context']['downloaded'])
-
- request = Request(method='GET', path=['release', 'release', 'data'])
- request.principal = 'user'
- stats.log(request)
- self.assertEqual(1, stats._stats['context']['downloaded'])
-
- def test_ContextReleased(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
-
- request = Request(method='POST', path=['release'])
- request.principal = 'user'
- request.content = {'context': 'context'}
- stats.log(request)
- self.assertEqual(1, stats._stats['context']['released'])
-
- def test_ContextFailed(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
-
- request = Request(method='POST', path=['report'])
- request.principal = 'user'
- request.content = {'context': 'context'}
- stats.log(request)
- self.assertEqual(1, stats._stats['context']['failed'])
-
- def test_PostDownloaded(self):
- volume = db.Volume('local', model.RESOURCES)
- stats = Sniffer(volume, 'stats/node')
- volume['post'].create({'guid': 'topic', 'type': 'object', 'context': 'context', 'title': '', 'message': ''})
-
- request = Request(method='GET', path=['post', 'topic', 'fake'])
- request.principal = 'user'
- stats.log(request)
- self.assertEqual(0, stats._stats['post']['downloaded'])
-
- request = Request(method='GET', path=['post', 'topic', 'data'])
- request.principal = 'user'
- stats.log(request)
- self.assertEqual(1, stats._stats['post']['downloaded'])
-
- def test_Commit(self):
- volume = db.Volume('local', model.RESOURCES)
- volume['user'].create({'guid': 'user', 'name': 'user', 'pubkey': ''})
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['post'].create({'guid': 'review', 'context': 'context', 'type': 'review', 'title': '', 'message': '', 'vote': 5})
-
- stats = Sniffer(volume, 'stats/node')
- request = Request(method='GET', path=['user', 'user'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='GET', path=['context', 'context'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='GET', path=['post', 'review'])
- request.principal = 'user'
- stats.log(request)
-
- self.assertEqual(1, stats._stats['user']['total'])
- self.assertEqual(1, stats._stats['context']['total'])
- self.assertEqual(1, stats._stats['post']['total'])
-
- ts = int(time.time())
- stats.commit(ts)
- stats.commit_objects()
-
- self.assertEqual(1, stats._stats['user']['total'])
- self.assertEqual(1, stats._stats['context']['total'])
- self.assertEqual(1, stats._stats['post']['total'])
-
- self.assertEqual([
- [('post', ts, {
- 'downloaded': 0.0,
- 'total': 1.0,
- })],
- [('user', ts, {
- 'total': 1.0,
- })],
- [('context', ts, {
- 'failed': 0.0,
- 'downloaded': 0.0,
- 'total': 1.0,
- 'released': 0.0,
- })],
- ],
- [[(j.name,) + i for i in j.get(j.last, j.last)] for j in Rrd('stats/node', 1)])
-
- def test_CommitContextStats(self):
- volume = db.Volume('local', model.RESOURCES)
-
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['release'].create({'guid': 'release', 'context': 'context', 'license': 'GPLv3', 'version': '1', 'date': 0, 'stability': 'stable', 'notes': ''})
-
- self.assertEqual(0, volume['context'].get('context')['downloads'])
- self.assertEqual([0, 0], volume['context'].get('context')['rating'])
-
- stats = Sniffer(volume, 'stats/node')
- request = Request(method='GET', path=['release', 'release', 'data'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'context': 'context', 'vote': 5, 'type': 'review', 'title': '', 'message': ''}
- stats.log(request)
-
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(1, volume['context'].get('context')['downloads'])
- self.assertEqual([1, 5], volume['context'].get('context')['rating'])
-
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(1, volume['context'].get('context')['downloads'])
- self.assertEqual([1, 5], volume['context'].get('context')['rating'])
-
- stats = Sniffer(volume, 'stats/node')
- request = Request(method='GET', path=['release', 'release', 'data'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'context': 'context', 'vote': 1, 'type': 'review', 'title': '', 'message': ''}
- stats.log(request)
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(2, volume['context'].get('context')['downloads'])
- self.assertEqual([2, 6], volume['context'].get('context')['rating'])
-
- def test_CommitTopicStats(self):
- volume = db.Volume('local', model.RESOURCES)
-
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['post'].create({'guid': 'topic', 'type': 'object', 'context': 'context', 'title': '', 'message': ''})
-
- self.assertEqual(0, volume['post'].get('topic')['downloads'])
- self.assertEqual([0, 0], volume['post'].get('topic')['rating'])
-
- stats = Sniffer(volume, 'stats/node')
- request = Request(method='GET', path=['post', 'topic', 'data'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'topic': 'topic', 'vote': 5, 'type': 'feedback'}
- stats.log(request)
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(1, volume['post'].get('topic')['downloads'])
- self.assertEqual([1, 5], volume['post'].get('topic')['rating'])
-
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(1, volume['post'].get('topic')['downloads'])
- self.assertEqual([1, 5], volume['post'].get('topic')['rating'])
-
- request = Request(method='GET', path=['post', 'topic', 'data'])
- request.principal = 'user'
- stats.log(request)
- request = Request(method='POST', path=['post'])
- request.principal = 'user'
- request.content = {'topic': 'topic', 'vote': 1, 'type': 'feedback'}
- stats.log(request)
- stats.commit()
- stats.commit_objects()
-
- self.assertEqual(2, volume['post'].get('topic')['downloads'])
- self.assertEqual([2, 6], volume['post'].get('topic')['rating'])
-
- def test_Suspend(self):
- stats_node_step.value = 5
- volume = db.Volume('local', model.RESOURCES)
- volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''})
- volume['release'].create({'guid': 'impl', 'context': 'context', 'license': 'GPLv3', 'version': '1', 'date': 0, 'stability': 'stable', 'notes': ''})
-
- ts = self.ts = 1000000000
- self.override(time, 'time', lambda: self.ts)
-
- stats = Sniffer(volume, 'stats')
- request = Request(method='POST', path=['context'])
- stats.log(request)
- request = Request(method='GET', path=['release', 'impl', 'data'], context='context')
- stats.log(request)
- stats.suspend()
-
- rdb = Rrd('stats', 1)['context']
- self.assertEqual([
- ],
- [i for i in rdb.get(ts, ts + 10)])
-
- stats = Sniffer(volume, 'stats')
- stats.suspend()
-
- rdb = Rrd('stats', 1)['context']
- self.assertEqual([
- ],
- [i for i in rdb.get(ts, ts + 10)])
-
- self.ts += 6
- stats = Sniffer(volume, 'stats')
-
- rdb = Rrd('stats', 1)['context']
- self.assertEqual([
- (ts + 0, {'failed': 0.0, 'downloaded': 0.0, 'total': 0.0, 'released': 0.0}),
- (ts + 5, {'failed': 0.0, 'downloaded': 1.0, 'total': 2.0, 'released': 0.0}),
- ],
- [i for i in rdb.get(ts, ts + 20)])
-
- request = Request(method='POST', path=['context'])
- stats.log(request)
- request = Request(method='GET', path=['release', 'impl', 'data'], context='context')
- stats.log(request)
- request = Request(method='GET', path=['release', 'impl', 'data'], context='context')
- stats.log(request)
- stats.suspend()
-
- stats = Sniffer(volume, 'stats')
- stats.suspend()
-
- rdb = Rrd('stats', 1)['context']
- self.assertEqual([
- (ts + 0, {'failed': 0.0, 'downloaded': 0.0, 'total': 0.0, 'released': 0.0}),
- (ts + 5, {'failed': 0.0, 'downloaded': 1.0, 'total': 2.0, 'released': 0.0}),
- ],
- [i for i in rdb.get(ts, ts + 10)])
-
- self.ts += 6
- stats = Sniffer(volume, 'stats')
-
- rdb = Rrd('stats', 1)['context']
- self.assertEqual([
- (ts + 0, {'failed': 0.0, 'downloaded': 0.0, 'total': 0.0, 'released': 0.0}),
- (ts + 5, {'failed': 0.0, 'downloaded': 1.0, 'total': 2.0, 'released': 0.0}),
- (ts + 10, {'failed': 0.0, 'downloaded': 3.0, 'total': 3.0, 'released': 0.0}),
- ],
- [i for i in rdb.get(ts, ts + 20)])
-
-
-if __name__ == '__main__':
- tests.main()
diff --git a/tests/units/node/sync_online.py b/tests/units/node/sync_online.py
index 7ee6dcb..e2c864a 100755
--- a/tests/units/node/sync_online.py
+++ b/tests/units/node/sync_online.py
@@ -44,11 +44,11 @@ class SyncOnlineTest(tests.Test):
def type(self, value):
return value
- @db.indexed_property(slot=1, prefix='N', full_text=True, localized=True)
+ @db.indexed_property(db.Localized, slot=1, prefix='N', full_text=True)
def title(self, value):
return value
- @db.indexed_property(prefix='D', full_text=True, localized=True)
+ @db.indexed_property(db.Localized, prefix='D', full_text=True)
def message(self, value):
return value
@@ -80,8 +80,8 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([[4, None]], json.load(file('slave/pull.sequence')))
self.assertEqual([[2, None]], json.load(file('slave/push.sequence')))
- guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'comment'})
- guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'comment'})
+ guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'post'})
+ guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'post'})
client.post(cmd='online-sync')
self.assertEqual([
@@ -92,7 +92,7 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([[6, None]], json.load(file('slave/pull.sequence')))
self.assertEqual([[4, None]], json.load(file('slave/push.sequence')))
- guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'comment'})
+ guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'post'})
client.post(cmd='online-sync')
self.assertEqual([
{'guid': guid1, 'message': {'en-us': '1'}},
@@ -128,7 +128,7 @@ class SyncOnlineTest(tests.Test):
client.put(['document', guid1], {'message': 'a'})
client.put(['document', guid2], {'message': 'b'})
client.put(['document', guid3], {'message': 'c'})
- guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'comment'})
+ guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'post'})
client.delete(['document', guid2])
client.post(cmd='online-sync')
self.assertEqual([
@@ -158,8 +158,8 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([[4, None]], json.load(file('slave/pull.sequence')))
self.assertEqual([[2, None]], json.load(file('slave/push.sequence')))
- guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'comment'})
- guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'comment'})
+ guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'post'})
+ guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'post'})
slave_client.post(cmd='online-sync')
self.assertEqual([
@@ -170,7 +170,7 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([[6, None]], json.load(file('slave/pull.sequence')))
self.assertEqual([[2, None]], json.load(file('slave/push.sequence')))
- guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'comment'})
+ guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'post'})
slave_client.post(cmd='online-sync')
self.assertEqual([
{'guid': guid1, 'message': {'en-us': '1'}},
@@ -206,7 +206,7 @@ class SyncOnlineTest(tests.Test):
client.put(['document', guid1], {'message': 'a'})
client.put(['document', guid2], {'message': 'b'})
client.put(['document', guid3], {'message': 'c'})
- guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'comment'})
+ guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'post'})
client.delete(['document', guid2])
slave_client.post(cmd='online-sync')
self.assertEqual([
@@ -252,7 +252,7 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([[4, None]], json.load(file('slave/pull.sequence')))
self.assertEqual([[2, None]], json.load(file('slave/push.sequence')))
- guid = slave.post(['document'], {'context': '', 'message': '1', 'title': '1', 'type': 'comment'})
+ guid = slave.post(['document'], {'context': '', 'message': '1', 'title': '1', 'type': 'post'})
slave.post(cmd='online-sync')
coroutine.sleep(1)
diff --git a/tests/units/node/volume.py b/tests/units/node/volume.py
deleted file mode 100755
index 01e71a7..0000000
--- a/tests/units/node/volume.py
+++ /dev/null
@@ -1,826 +0,0 @@
-#!/usr/bin/env python
-# sugar-lint: disable
-
-import os
-import time
-import urllib2
-import hashlib
-from cStringIO import StringIO
-
-from __init__ import tests
-
-from sugar_network import db, toolkit, model
-from sugar_network.node.volume import diff, merge
-from sugar_network.node.stats_node import Sniffer
-from sugar_network.node.routes import NodeRoutes
-from sugar_network.toolkit.rrd import Rrd
-from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, Blob, ACL, route
-
-
-current_time = time.time
-
-
-class VolumeTest(tests.Test):
-
- def setUp(self):
- tests.Test.setUp(self)
- self.override(time, 'time', lambda: 0)
- self.override(NodeRoutes, 'authorize', lambda self, user, role: True)
-
- def test_diff(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid1 = call(cp, method='POST', document='document', content={'prop': 'a'})
- self.utime('db/document/%s/%s' % (guid1[:2], guid1), 1)
- guid2 = call(cp, method='POST', document='document', content={'prop': 'b'})
- self.utime('db/document/%s/%s' % (guid2[:2], guid2), 2)
-
- in_seq = toolkit.Sequence([[1, None]])
- self.assertEqual([
- {'resource': 'document'},
- {'guid': guid1,
- 'diff': {
- 'guid': {'value': guid1, 'mtime': 1},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- 'prop': {'value': 'a', 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- },
- },
- {'guid': guid2,
- 'diff': {
- 'guid': {'value': guid2, 'mtime': 2},
- 'mtime': {'value': 0, 'mtime': 2},
- 'ctime': {'value': 0, 'mtime': 2},
- 'prop': {'value': 'b', 'mtime': 2},
- 'author': {'mtime': 2, 'value': {}},
- 'layer': {'mtime': 2, 'value': []},
- 'tags': {'mtime': 2, 'value': []},
- },
- },
- {'commit': [[1, 2]]},
- ],
- [i for i in diff(volume, in_seq)])
- self.assertEqual([[1, None]], in_seq)
-
- def test_diff_Partial(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid1 = call(cp, method='POST', document='document', content={'prop': 'a'})
- self.utime('db/document/%s/%s' % (guid1[:2], guid1), 1)
- guid2 = call(cp, method='POST', document='document', content={'prop': 'b'})
- self.utime('db/document/%s/%s' % (guid2[:2], guid2), 2)
-
- in_seq = toolkit.Sequence([[1, None]])
- patch = diff(volume, in_seq)
- self.assertEqual({'resource': 'document'}, next(patch))
- self.assertEqual(guid1, next(patch)['guid'])
- self.assertEqual({'commit': []}, patch.throw(StopIteration()))
- try:
- next(patch)
- assert False
- except StopIteration:
- pass
-
- patch = diff(volume, in_seq)
- self.assertEqual({'resource': 'document'}, next(patch))
- self.assertEqual(guid1, next(patch)['guid'])
- self.assertEqual(guid2, next(patch)['guid'])
- self.assertEqual({'commit': [[1, 1]]}, patch.throw(StopIteration()))
- try:
- next(patch)
- assert False
- except StopIteration:
- pass
-
- def test_diff_Stretch(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid1 = call(cp, method='POST', document='document', content={'prop': 'a'})
- self.utime('db/document/%s/%s' % (guid1[:2], guid1), 1)
- guid2 = call(cp, method='POST', document='document', content={'prop': 'b'})
- volume['document'].delete(guid2)
- guid3 = call(cp, method='POST', document='document', content={'prop': 'c'})
- self.utime('db/document/%s/%s' % (guid3[:2], guid3), 2)
- guid4 = call(cp, method='POST', document='document', content={'prop': 'd'})
- volume['document'].delete(guid4)
- guid5 = call(cp, method='POST', document='document', content={'prop': 'f'})
- self.utime('db/document/%s/%s' % (guid5[:2], guid5), 2)
-
- in_seq = toolkit.Sequence([[1, None]])
- patch = diff(volume, in_seq)
- self.assertEqual({'resource': 'document'}, patch.send(None))
- self.assertEqual(guid1, patch.send(None)['guid'])
- self.assertEqual(guid3, patch.send(None)['guid'])
- self.assertEqual(guid5, patch.send(None)['guid'])
- self.assertEqual({'commit': [[1, 1], [3, 3]]}, patch.throw(StopIteration()))
- try:
- patch.send(None)
- assert False
- except StopIteration:
- pass
-
- patch = diff(volume, in_seq)
- self.assertEqual({'resource': 'document'}, patch.send(None))
- self.assertEqual(guid1, patch.send(None)['guid'])
- self.assertEqual(guid3, patch.send(None)['guid'])
- self.assertEqual(guid5, patch.send(None)['guid'])
- self.assertEqual({'commit': [[1, 5]]}, patch.send(None))
- try:
- patch.send(None)
- assert False
- except StopIteration:
- pass
-
- def test_diff_DoNotStretchContinuesPacket(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid1 = call(cp, method='POST', document='document', content={'prop': 'a'})
- volume['document'].delete(guid1)
- guid2 = call(cp, method='POST', document='document', content={'prop': 'b'})
- volume['document'].delete(guid2)
- guid3 = call(cp, method='POST', document='document', content={'prop': 'c'})
- self.utime('db/document/%s/%s' % (guid3[:2], guid3), 2)
- guid4 = call(cp, method='POST', document='document', content={'prop': 'd'})
- volume['document'].delete(guid4)
- guid5 = call(cp, method='POST', document='document', content={'prop': 'f'})
- self.utime('db/document/%s/%s' % (guid5[:2], guid5), 2)
-
- in_seq = toolkit.Sequence([[1, None]])
- patch = diff(volume, in_seq, toolkit.Sequence([[1, 1]]))
- self.assertEqual({'resource': 'document'}, patch.send(None))
- self.assertEqual(guid3, patch.send(None)['guid'])
- self.assertEqual(guid5, patch.send(None)['guid'])
- self.assertEqual({'commit': [[1, 1], [3, 3], [5, 5]]}, patch.send(None))
- try:
- patch.send(None)
- assert False
- except StopIteration:
- pass
-
- def test_diff_TheSameInSeqForAllDocuments(self):
-
- class Document1(db.Resource):
- pass
-
- class Document2(db.Resource):
- pass
-
- class Document3(db.Resource):
- pass
-
- volume = db.Volume('db', [Document1, Document2, Document3])
- cp = NodeRoutes('guid', volume)
-
- guid3 = call(cp, method='POST', document='document1', content={})
- self.utime('db/document/%s/%s' % (guid3[:2], guid3), 3)
- guid2 = call(cp, method='POST', document='document2', content={})
- self.utime('db/document/%s/%s' % (guid2[:2], guid2), 2)
- guid1 = call(cp, method='POST', document='document3', content={})
- self.utime('db/document/%s/%s' % (guid1[:2], guid1), 1)
-
- in_seq = toolkit.Sequence([[1, None]])
- patch = diff(volume, in_seq)
- self.assertEqual({'resource': 'document1'}, patch.send(None))
- self.assertEqual(guid3, patch.send(None)['guid'])
- self.assertEqual({'resource': 'document2'}, patch.send(None))
- self.assertEqual(guid2, patch.send(None)['guid'])
- self.assertEqual({'resource': 'document3'}, patch.send(None))
- self.assertEqual(guid1, patch.send(None)['guid'])
- self.assertEqual({'commit': [[1, 3]]}, patch.send(None))
- try:
- patch.send(None)
- assert False
- except StopIteration:
- pass
-
- def test_merge_Create(self):
-
- class Document1(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- class Document2(db.Resource):
- pass
-
- self.touch(('db/seqno', '100'))
- volume = db.Volume('db', [Document1, Document2])
-
- records = [
- {'resource': 'document1'},
- {'guid': '1', 'diff': {
- 'guid': {'value': '1', 'mtime': 1.0},
- 'ctime': {'value': 2, 'mtime': 2.0},
- 'mtime': {'value': 3, 'mtime': 3.0},
- 'prop': {'value': '4', 'mtime': 4.0},
- }},
- {'resource': 'document2'},
- {'guid': '5', 'diff': {
- 'guid': {'value': '5', 'mtime': 5.0},
- 'ctime': {'value': 6, 'mtime': 6.0},
- 'mtime': {'value': 7, 'mtime': 7.0},
- }},
- {'commit': [[1, 2]]},
- ]
- self.assertEqual(([[1, 2]], [[101, 102]]), merge(volume, records))
-
- self.assertEqual(
- {'guid': '1', 'prop': '4', 'ctime': 2, 'mtime': 3},
- volume['document1'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
- self.assertEqual(1, os.stat('db/document1/1/1/guid').st_mtime)
- self.assertEqual(2, os.stat('db/document1/1/1/ctime').st_mtime)
- self.assertEqual(3, os.stat('db/document1/1/1/mtime').st_mtime)
- self.assertEqual(4, os.stat('db/document1/1/1/prop').st_mtime)
-
- self.assertEqual(
- {'guid': '5', 'ctime': 6, 'mtime': 7},
- volume['document2'].get('5').properties(['guid', 'ctime', 'mtime']))
- self.assertEqual(5, os.stat('db/document2/5/5/guid').st_mtime)
- self.assertEqual(6, os.stat('db/document2/5/5/ctime').st_mtime)
- self.assertEqual(7, os.stat('db/document2/5/5/mtime').st_mtime)
-
- def test_merge_Update(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- self.touch(('db/seqno', '100'))
- volume = db.Volume('db', [Document])
- volume['document'].create({'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1})
- for i in os.listdir('db/document/1/1'):
- os.utime('db/document/1/1/%s' % i, (2, 2))
-
- records = [
- {'resource': 'document'},
- {'guid': '1', 'diff': {'prop': {'value': '2', 'mtime': 1.0}}},
- {'commit': [[1, 1]]},
- ]
- self.assertEqual(([[1, 1]], []), merge(volume, records))
- self.assertEqual(
- {'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1},
- volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
- self.assertEqual(2, os.stat('db/document/1/1/prop').st_mtime)
-
- records = [
- {'resource': 'document'},
- {'guid': '1', 'diff': {'prop': {'value': '3', 'mtime': 2.0}}},
- {'commit': [[2, 2]]},
- ]
- self.assertEqual(([[2, 2]], []), merge(volume, records))
- self.assertEqual(
- {'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1},
- volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
- self.assertEqual(2, os.stat('db/document/1/1/prop').st_mtime)
-
- records = [
- {'resource': 'document'},
- {'guid': '1', 'diff': {'prop': {'value': '4', 'mtime': 3.0}}},
- {'commit': [[3, 3]]},
- ]
- self.assertEqual(([[3, 3]], [[102, 102]]), merge(volume, records))
- self.assertEqual(
- {'guid': '1', 'prop': '4', 'ctime': 1, 'mtime': 1},
- volume['document'].get('1').properties(['guid', 'ctime', 'mtime', 'prop']))
- self.assertEqual(3, os.stat('db/document/1/1/prop').st_mtime)
-
- def test_merge_MultipleCommits(self):
-
- class Document(db.Resource):
-
- @db.stored_property()
- def prop(self, value):
- return value
-
- self.touch(('db/seqno', '100'))
- volume = db.Volume('db', [Document])
-
- def generator():
- for i in [
- {'resource': 'document'},
- {'commit': [[1, 1]]},
- {'guid': '1', 'diff': {
- 'guid': {'value': '1', 'mtime': 1.0},
- 'ctime': {'value': 2, 'mtime': 2.0},
- 'mtime': {'value': 3, 'mtime': 3.0},
- 'prop': {'value': '4', 'mtime': 4.0},
- }},
- {'commit': [[2, 3]]},
- ]:
- yield i
-
- records = generator()
- self.assertEqual(([[1, 3]], [[101, 101]]), merge(volume, records))
- assert volume['document'].exists('1')
-
- def test_merge_UpdateStats(self):
- volume = db.Volume('db', model.RESOURCES)
- cp = NodeRoutes('guid', volume)
- stats = Sniffer(volume, 'stats/node')
-
- records = [
- {'resource': 'context'},
- {'guid': 'context', 'diff': {
- 'guid': {'value': 'context', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'type': {'value': ['package'], 'mtime': 1.0},
- 'title': {'value': {}, 'mtime': 1.0},
- 'summary': {'value': {}, 'mtime': 1.0},
- 'description': {'value': {}, 'mtime': 1.0},
- }},
- {'resource': 'post'},
- {'guid': 'topic_1', 'diff': {
- 'guid': {'value': 'topic_1', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'type': {'value': 'object', 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'title': {'value': {}, 'mtime': 1.0},
- 'message': {'value': {}, 'mtime': 1.0},
- 'solution': {'value': 'solution_1', 'mtime': 1.0},
- }},
- {'guid': 'topic_2', 'diff': {
- 'guid': {'value': 'topic_2', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'type': {'value': 'object', 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'title': {'value': {}, 'mtime': 1.0},
- 'message': {'value': {}, 'mtime': 1.0},
- 'solution': {'value': 'solution_2', 'mtime': 1.0},
- }},
- {'guid': 'context_review', 'diff': {
- 'guid': {'value': 'context_review', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'vote': {'value': 1, 'mtime': 1.0},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'type': {'value': 'review', 'mtime': 1.0},
- }},
- {'guid': 'topic_review', 'diff': {
- 'guid': {'value': 'topic_review', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'topic': {'value': 'topic_1', 'mtime': 1.0},
- 'vote': {'value': 1, 'mtime': 1.0},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'type': {'value': 'feedback', 'mtime': 1.0},
- }},
- {'guid': 'solution_1', 'diff': {
- 'guid': {'value': 'solution_1', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'topic': {'value': 'topic_1', 'mtime': 1.0},
- 'type': {'value': 'answer', 'mtime': 1.0},
- 'title': {'value': {}, 'mtime': 1.0},
- 'message': {'value': {}, 'mtime': 1.0},
- }},
- {'guid': 'solution_2', 'diff': {
- 'guid': {'value': 'solution_2', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'topic': {'value': 'topic_2', 'mtime': 1.0},
- 'type': {'value': 'answer', 'mtime': 1.0},
- 'title': {'value': {}, 'mtime': 1.0},
- 'message': {'value': {}, 'mtime': 1.0},
- }},
- {'resource': 'release'},
- {'guid': 'release', 'diff': {
- 'guid': {'value': 'release', 'mtime': 1.0},
- 'ctime': {'value': 1, 'mtime': 1.0},
- 'mtime': {'value': 1, 'mtime': 1.0},
- 'context': {'value': 'context', 'mtime': 1.0},
- 'license': {'value': ['GPL-3.0'], 'mtime': 1.0},
- 'version': {'value': '1', 'mtime': 1.0},
- 'stability': {'value': 'stable', 'mtime': 1.0},
- 'notes': {'value': {}, 'mtime': 1.0},
- }},
- {'commit': [[1, 1]]},
- ]
- merge(volume, records, stats=stats)
- ts = int(current_time())
- stats.commit(ts)
- stats.commit_objects()
-
- self.assertEqual([
- [('post', ts, {
- 'downloaded': 0.0,
- 'total': 6.0,
- })],
- [('user', ts, {
- 'total': 0.0,
- })],
- [('context', ts, {
- 'failed': 0.0,
- 'downloaded': 0.0,
- 'total': 1.0,
- 'released': 1.0,
- })],
- ],
- [[(j.name,) + i for i in j.get(j.last, j.last)] for j in Rrd('stats/node', 1)])
- self.assertEqual([1, 1], volume['context'].get('context')['rating'])
- self.assertEqual([1, 1], volume['post'].get('topic_1')['rating'])
-
- records = [
- {'resource': 'post'},
- {'guid': 'topic_2', 'diff': {'solution': {'value': '', 'mtime': 2.0}}},
- {'commit': [[2, 2]]},
- ]
- merge(volume, records, stats=stats)
- ts += 1
- stats.commit(ts)
- stats.commit_objects()
-
- self.assertEqual([
- [('post', ts, {
- 'downloaded': 0.0,
- 'total': 6.0,
- })],
- [('user', ts, {
- 'total': 0.0,
- })],
- [('context', ts, {
- 'failed': 0.0,
- 'downloaded': 0.0,
- 'total': 1.0,
- 'released': 1.0,
- })],
- ],
- [[(j.name,) + i for i in j.get(j.last, j.last)] for j in Rrd('stats/node', 1)])
-
- records = [
- {'resource': 'context'},
- {'guid': 'context', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'resource': 'post'},
- {'guid': 'topic_1', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'guid': 'topic_2', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'guid': 'context_review', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'guid': 'topic_review', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'guid': 'solution_1', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'guid': 'solution_2', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'resource': 'release'},
- {'guid': 'release', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}},
- {'commit': [[3, 3]]},
- ]
- merge(volume, records, stats=stats)
- ts += 1
- stats.commit(ts)
- stats.commit_objects()
-
- self.assertEqual([
- [('post', ts, {
- 'downloaded': 0.0,
- 'total': 0.0,
- })],
- [('user', ts, {
- 'total': 0.0,
- })],
- [('context', ts, {
- 'failed': 0.0,
- 'downloaded': 0.0,
- 'total': 0.0,
- 'released': 1.0,
- })],
- ],
- [[(j.name,) + i for i in j.get(j.last, j.last)] for j in Rrd('stats/node', 1)])
-
- def test_diff_Blobs(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid = call(cp, method='POST', document='document', content={})
- call(cp, method='PUT', document='document', guid=guid, content={'prop': 'payload'})
- self.utime('db', 0)
-
- patch = diff(volume, toolkit.Sequence([[1, None]]))
- self.assertEqual(
- {'resource': 'document'},
- next(patch))
- record = next(patch)
- self.assertEqual('payload', ''.join([i for i in record.pop('blob')]))
- self.assertEqual(
- {'guid': guid, 'blob_size': len('payload'), 'diff': {
- 'prop': {
- 'digest': hashlib.sha1('payload').hexdigest(),
- 'blob_size': len('payload'),
- 'mime_type': 'application/octet-stream',
- 'mtime': 0,
- },
- }},
- record)
- self.assertEqual(
- {'guid': guid, 'diff': {
- 'guid': {'value': guid, 'mtime': 0},
- 'author': {'mtime': 0, 'value': {}},
- 'layer': {'mtime': 0, 'value': []},
- 'tags': {'mtime': 0, 'value': []},
- 'mtime': {'value': 0, 'mtime': 0},
- 'ctime': {'value': 0, 'mtime': 0},
- }},
- next(patch))
- self.assertEqual(
- {'commit': [[1, 2]]},
- next(patch))
- self.assertRaises(StopIteration, next, patch)
-
- def test_diff_BlobUrls(self):
- url = 'http://src.sugarlabs.org/robots.txt'
- blob = urllib2.urlopen(url).read()
-
- class Document(db.Resource):
-
- @db.blob_property()
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid = call(cp, method='POST', document='document', content={})
- call(cp, method='PUT', document='document', guid=guid, content={'prop': {'url': url}})
- self.utime('db', 1)
-
- self.assertEqual([
- {'resource': 'document'},
- {'guid': guid,
- 'diff': {
- 'guid': {'value': guid, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- 'prop': {'url': url, 'mtime': 1},
- },
- },
- {'commit': [[1, 2]]},
- ],
- [i for i in diff(volume, toolkit.Sequence([[1, None]]))])
-
- patch = diff(volume, toolkit.Sequence([[1, None]]), fetch_blobs=True)
- self.assertEqual(
- {'resource': 'document'},
- next(patch))
- record = next(patch)
- self.assertEqual(blob, ''.join([i for i in record.pop('blob')]))
- self.assertEqual(
- {'guid': guid, 'blob_size': len(blob), 'diff': {'prop': {'mtime': 1}}},
- record)
- self.assertEqual(
- {'guid': guid, 'diff': {
- 'guid': {'value': guid, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- }},
- next(patch))
- self.assertEqual(
- {'commit': [[1, 2]]},
- next(patch))
- self.assertRaises(StopIteration, next, patch)
-
- def test_diff_SkipBrokenBlobUrls(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
- cp = NodeRoutes('guid', volume)
-
- guid1 = call(cp, method='POST', document='document', content={})
- call(cp, method='PUT', document='document', guid=guid1, content={'prop': {'url': 'http://foo/bar'}})
- guid2 = call(cp, method='POST', document='document', content={})
- self.utime('db', 1)
-
- self.assertEqual([
- {'resource': 'document'},
- {'guid': guid1,
- 'diff': {
- 'guid': {'value': guid1, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- 'prop': {'url': 'http://foo/bar', 'mtime': 1},
- },
- },
- {'guid': guid2,
- 'diff': {
- 'guid': {'value': guid2, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- },
- },
- {'commit': [[1, 3]]},
- ],
- [i for i in diff(volume, toolkit.Sequence([[1, None]]), fetch_blobs=False)])
-
- self.assertEqual([
- {'resource': 'document'},
- {'guid': guid1,
- 'diff': {
- 'guid': {'value': guid1, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- },
- },
- {'guid': guid2,
- 'diff': {
- 'guid': {'value': guid2, 'mtime': 1},
- 'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': []},
- 'tags': {'mtime': 1, 'value': []},
- 'mtime': {'value': 0, 'mtime': 1},
- 'ctime': {'value': 0, 'mtime': 1},
- },
- },
- {'commit': [[1, 3]]},
- ],
- [i for i in diff(volume, toolkit.Sequence([[1, None]]), fetch_blobs=True)])
-
- def test_merge_Blobs(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def prop(self, value):
- return value
-
- volume = db.Volume('db', [Document])
-
- merge(volume, [
- {'resource': 'document'},
- {'guid': '1', 'diff': {
- 'guid': {'value': '1', 'mtime': 1.0},
- 'ctime': {'value': 2, 'mtime': 2.0},
- 'mtime': {'value': 3, 'mtime': 3.0},
- 'prop': {
- 'blob': StringIO('payload'),
- 'blob_size': len('payload'),
- 'digest': hashlib.sha1('payload').hexdigest(),
- 'mime_type': 'foo/bar',
- 'mtime': 1,
- },
- }},
- {'commit': [[1, 1]]},
- ])
-
- assert volume['document'].exists('1')
- blob = volume['document'].get('1')['prop']
- self.assertEqual(1, blob['mtime'])
- self.assertEqual('foo/bar', blob['mime_type'])
- self.assertEqual(hashlib.sha1('payload').hexdigest(), blob['digest'])
- self.assertEqual(tests.tmpdir + '/db/document/1/1/prop.blob', blob['blob'])
- self.assertEqual('payload', file(blob['blob']).read())
-
- def test_diff_ByLayers(self):
-
- class Context(db.Resource):
- pass
-
- class release(db.Resource):
- pass
-
- class Review(db.Resource):
- pass
-
- volume = db.Volume('db', [Context, release, Review])
- volume['context'].create({'guid': '0', 'ctime': 1, 'mtime': 1, 'layer': ['layer0', 'common']})
- volume['context'].create({'guid': '1', 'ctime': 1, 'mtime': 1, 'layer': 'layer1'})
- volume['release'].create({'guid': '2', 'ctime': 2, 'mtime': 2, 'layer': 'layer2'})
- volume['review'].create({'guid': '3', 'ctime': 3, 'mtime': 3, 'layer': 'layer3'})
-
- volume['context'].update('0', {'tags': '0'})
- volume['context'].update('1', {'tags': '1'})
- volume['release'].update('2', {'tags': '2'})
- volume['review'].update('3', {'tags': '3'})
- self.utime('db', 0)
-
- self.assertEqual(sorted([
- {'resource': 'context'},
- {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
- {'guid': '1', 'diff': {'tags': {'value': '1', 'mtime': 0}}},
- {'resource': 'release'},
- {'guid': '2', 'diff': {'tags': {'value': '2', 'mtime': 0}}},
- {'resource': 'review'},
- {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
- {'commit': [[5, 8]]},
- ]),
- sorted([i for i in diff(volume, toolkit.Sequence([[5, None]]))]))
-
- self.assertEqual(sorted([
- {'resource': 'context'},
- {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
- {'guid': '1', 'diff': {'tags': {'value': '1', 'mtime': 0}}},
- {'resource': 'release'},
- {'resource': 'review'},
- {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
- {'commit': [[5, 8]]},
- ]),
- sorted([i for i in diff(volume, toolkit.Sequence([[5, None]]), layer='layer1')]))
-
- self.assertEqual(sorted([
- {'resource': 'context'},
- {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
- {'resource': 'release'},
- {'guid': '2', 'diff': {'tags': {'value': '2', 'mtime': 0}}},
- {'resource': 'review'},
- {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
- {'commit': [[5, 8]]},
- ]),
- sorted([i for i in diff(volume, toolkit.Sequence([[5, None]]), layer='layer2')]))
-
- self.assertEqual(sorted([
- {'resource': 'context'},
- {'guid': '0', 'diff': {'tags': {'value': '0', 'mtime': 0}}},
- {'resource': 'release'},
- {'resource': 'review'},
- {'guid': '3', 'diff': {'tags': {'value': '3', 'mtime': 0}}},
- {'commit': [[5, 8]]},
- ]),
- sorted([i for i in diff(volume, toolkit.Sequence([[5, None]]), layer='foo')]))
-
-
-def call(routes, method, document=None, guid=None, prop=None, cmd=None, content=None, **kwargs):
- path = []
- if document:
- path.append(document)
- if guid:
- path.append(guid)
- if prop:
- path.append(prop)
- request = Request(method=method, path=path, cmd=cmd, content=content)
- request.update(kwargs)
- request.environ['HTTP_HOST'] = '127.0.0.1'
- router = Router(routes)
- return router.call(request, Response())
-
-
-if __name__ == '__main__':
- tests.main()