Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tests/units/db
diff options
context:
space:
mode:
Diffstat (limited to 'tests/units/db')
-rw-r--r--tests/units/db/__main__.py7
-rwxr-xr-xtests/units/db/files.py320
-rwxr-xr-xtests/units/db/index.py157
-rwxr-xr-xtests/units/db/metadata.py71
-rwxr-xr-xtests/units/db/resource.py312
-rwxr-xr-xtests/units/db/routes.py1628
-rwxr-xr-xtests/units/db/storage.py19
7 files changed, 1469 insertions, 1045 deletions
diff --git a/tests/units/db/__main__.py b/tests/units/db/__main__.py
index fc91d7c..3b1b9ec 100644
--- a/tests/units/db/__main__.py
+++ b/tests/units/db/__main__.py
@@ -2,11 +2,12 @@
from __init__ import tests
-from resource import *
-from index import *
-#from migrate import *
+from metadata import *
from storage import *
+from index import *
+from resource import *
from routes import *
+#from migrate import *
if __name__ == '__main__':
tests.main()
diff --git a/tests/units/db/files.py b/tests/units/db/files.py
new file mode 100755
index 0000000..0d806df
--- /dev/null
+++ b/tests/units/db/files.py
@@ -0,0 +1,320 @@
+
+ def test_diff_WithBlobsSetByUrl(self):
+ URL = 'http://src.sugarlabs.org/robots.txt'
+ URL_content = urllib2.urlopen(URL).read()
+
+ class Document(db.Resource):
+
+ @db.blob_property()
+ def blob(self, value):
+ return value
+
+ directory = Directory(tests.tmpdir, Document, IndexWriter)
+
+ directory.create({'guid': '1', 'ctime': 1, 'mtime': 1})
+ directory.update('1', {'blob': {'url': URL}})
+ self.utime('1/1', 1)
+
+ out_seq = Sequence()
+ self.assertEqual([
+ {'guid': '1', 'diff': {
+ 'guid': {'value': '1', 'mtime': 1},
+ 'ctime': {'value': 1, 'mtime': 1},
+ 'mtime': {'value': 1, 'mtime': 1},
+ 'blob': {
+ 'url': URL,
+ 'mtime': 1,
+ },
+ }},
+ ],
+ [i for i in diff(directory, [[0, None]], out_seq)])
+ self.assertEqual([[1, 2]], out_seq)
+
+ def test_merge_AvoidCalculatedBlobs(self):
+
+ class Document(db.Resource):
+
+ @db.blob_property()
+ def blob(self, value):
+ return {'url': 'http://foo/bar', 'mime_type': 'image/png'}
+
+ directory1 = Directory('document1', Document, IndexWriter)
+ directory1.create({'guid': 'guid', 'ctime': 1, 'mtime': 1})
+ for i in os.listdir('document1/gu/guid'):
+ os.utime('document1/gu/guid/%s' % i, (1, 1))
+
+ directory2 = Directory('document2', Document, IndexWriter)
+ for patch in diff(directory1, [[0, None]], Sequence()):
+ directory2.merge(**patch)
+
+ doc = directory2.get('guid')
+ self.assertEqual(1, doc.get('seqno'))
+ self.assertEqual(1, doc.meta('guid')['mtime'])
+ assert not exists('document2/gu/guid/blob')
+
+ def test_merge_Blobs(self):
+
+ class Document(db.Resource):
+
+ @db.blob_property()
+ def blob(self, value):
+ return value
+
+ directory = Directory('document', Document, IndexWriter)
+ self.touch(('blob', 'blob-1'))
+ directory.merge('1', {
+ 'guid': {'mtime': 1, 'value': '1'},
+ 'ctime': {'mtime': 2, 'value': 2},
+ 'mtime': {'mtime': 3, 'value': 3},
+ 'blob': {'mtime': 4, 'blob': 'blob'},
+ })
+
+ self.assertEqual(
+ [(2, 3, '1')],
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory.find()[0]])
+
+ doc = directory.get('1')
+ self.assertEqual(1, doc.get('seqno'))
+ self.assertEqual(1, doc.meta('guid')['mtime'])
+ self.assertEqual(2, doc.meta('ctime')['mtime'])
+ self.assertEqual(3, doc.meta('mtime')['mtime'])
+ self.assertEqual(4, doc.meta('blob')['mtime'])
+ self.assertEqual('blob-1', file('document/1/1/blob.blob').read())
+
+ self.touch(('blob', 'blob-2'))
+ directory.merge('1', {
+ 'blob': {'mtime': 5, 'blob': 'blob'},
+ })
+
+ self.assertEqual(5, doc.meta('blob')['mtime'])
+ self.assertEqual('blob-2', file('document/1/1/blob.blob').read())
+
+
+ def test_DeleteOldBlobOnUpdate(self):
+
+ class Document(db.Resource):
+
+ @db.blob_property()
+ def blob(self, value):
+ return value
+
+ directory = Directory(tests.tmpdir, Document, IndexWriter)
+
+ directory.create({'guid': 'guid', 'blob': 'foo'})
+ assert exists('gu/guid/blob.blob')
+ directory.update('guid', {'blob': {'url': 'foo'}})
+ assert not exists('gu/guid/blob.blob')
+
+ directory.update('guid', {'blob': 'foo'})
+ assert exists('gu/guid/blob.blob')
+ directory.update('guid', {'blob': {}})
+ assert not exists('gu/guid/blob.blob')
+
+ 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())
+
diff --git a/tests/units/db/index.py b/tests/units/db/index.py
index 9d996b0..cb144c6 100755
--- a/tests/units/db/index.py
+++ b/tests/units/db/index.py
@@ -12,23 +12,22 @@ from __init__ import tests
from sugar_network import toolkit
from sugar_network.db import index
-from sugar_network.db.index import _fmt_prop_value
-from sugar_network.db.metadata import Metadata, IndexedProperty, GUID_PREFIX, Property
+from sugar_network.db.metadata import Metadata, Property, GUID_PREFIX, Boolean, Enum, List, Localized, Numeric
from sugar_network.toolkit.router import ACL
-from sugar_network.toolkit import coroutine
+from sugar_network.toolkit import coroutine, i18n
class IndexTest(tests.Test):
def test_Term_AvoidCollisionsWithGuid(self):
- self.assertRaises(RuntimeError, IndexedProperty, 'key', 0, 'I')
- self.assertRaises(RuntimeError, IndexedProperty, 'key', 0, 'K')
- self.assertRaises(RuntimeError, IndexedProperty, 'key', 1, 'I')
- IndexedProperty('key', 1, 'K')
- IndexedProperty('guid', 0, 'I')
+ self.assertRaises(RuntimeError, Property, 'key', 0, 'I')
+ self.assertRaises(RuntimeError, Property, 'key', 0, 'K')
+ self.assertRaises(RuntimeError, Property, 'key', 1, 'I')
+ Property('key', 1, 'K')
+ Property('guid', 0, 'I')
def test_Create(self):
- db = Index({'key': IndexedProperty('key', 1, 'K')})
+ db = Index({'key': Property('key', 1, 'K')})
self.assertEqual(
([], 0),
@@ -47,8 +46,8 @@ class IndexTest(tests.Test):
def test_update(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A'),
- 'var_2': IndexedProperty('var_2', 2, 'B'),
+ 'var_1': Property('var_1', 1, 'A'),
+ 'var_2': Property('var_2', 2, 'B'),
})
db.store('1', {'var_1': 'value_1', 'var_2': 'value_2'})
@@ -62,7 +61,7 @@ class IndexTest(tests.Test):
db._find(reply=['var_1', 'var_2']))
def test_delete(self):
- db = Index({'key': IndexedProperty('key', 1, 'K')})
+ db = Index({'key': Property('key', 1, 'K')})
db.store('1', {'key': 'value'})
self.assertEqual(
@@ -74,8 +73,17 @@ class IndexTest(tests.Test):
([], 0),
db._find(reply=['key']))
- def test_IndexByFmt(self):
- db = Index({'key': IndexedProperty('key', 1, 'K', fmt=lambda x: "foo" + x)})
+ def test_IndexCalculatedValue(self):
+
+ class Property2(Property):
+
+ def encode(self, value):
+ yield "foo" + value
+
+ def decode(self, value):
+ return "foo" + value
+
+ db = Index({'key': Property2('key', 1, 'K')})
db.store('1', {'key': 'bar'})
@@ -92,15 +100,17 @@ class IndexTest(tests.Test):
[],
db._find(key='fake', reply=['key'])[0])
- def test_IndexByFmtGenerator(self):
+ def test_IndexCalculatedValues(self):
- def iterate(value):
- if value != 'fake':
- yield 'foo'
- yield 'bar'
- yield value
+ class Property2(Property):
- db = Index({'key': IndexedProperty('key', 1, 'K', fmt=iterate)})
+ def encode(self, value):
+ if value != 'fake':
+ yield 'foo'
+ yield 'bar'
+ yield value
+
+ db = Index({'key': Property2('key', 1, 'K')})
db.store('1', {'key': 'value'})
self.assertEqual(
@@ -118,9 +128,9 @@ class IndexTest(tests.Test):
def test_find(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A', full_text=True),
- 'var_2': IndexedProperty('var_2', 2, 'B', full_text=True),
- 'var_3': IndexedProperty('var_3', 3, 'C', full_text=True),
+ 'var_1': Property('var_1', 1, 'A', full_text=True),
+ 'var_2': Property('var_2', 2, 'B', full_text=True),
+ 'var_3': Property('var_3', 3, 'C', full_text=True),
})
db.store('1', {'var_1': '1', 'var_2': 'у', 'var_3': 'г'})
@@ -149,7 +159,7 @@ class IndexTest(tests.Test):
def test_find_NoneFilters(self):
db = Index({
- 'prop': IndexedProperty('prop', 1, 'P', full_text=True),
+ 'prop': Property('prop', 1, 'P', full_text=True),
})
db.store('guid', {'prop': 'value'})
@@ -164,9 +174,9 @@ class IndexTest(tests.Test):
[{'guid': 'guid', 'prop': 'value'}],
db._find(guid=None, reply=['prop'])[0])
- def test_find_WithTypeCast(self):
+ def test_find_DecodeArgs(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A', typecast=bool),
+ 'var_1': Boolean('var_1', 1, 'A'),
})
db.store('1', {'var_1': True})
@@ -181,9 +191,9 @@ class IndexTest(tests.Test):
def test_find_WithProps(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A', full_text=True),
- 'var_2': IndexedProperty('var_2', 2, 'B', full_text=True),
- 'var_3': IndexedProperty('var_3', 3, 'C', full_text=True),
+ 'var_1': Property('var_1', 1, 'A', full_text=True),
+ 'var_2': Property('var_2', 2, 'B', full_text=True),
+ 'var_3': Property('var_3', 3, 'C', full_text=True),
})
db.store('1', {'var_1': '1', 'var_2': 'у', 'var_3': 'г'})
@@ -209,9 +219,9 @@ class IndexTest(tests.Test):
def test_find_WithAllBooleanProps(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A', boolean=True, full_text=True),
- 'var_2': IndexedProperty('var_2', 2, 'B', boolean=True, full_text=True),
- 'var_3': IndexedProperty('var_3', 3, 'C', boolean=True, full_text=True),
+ 'var_1': Property('var_1', 1, 'A', boolean=True, full_text=True),
+ 'var_2': Property('var_2', 2, 'B', boolean=True, full_text=True),
+ 'var_3': Property('var_3', 3, 'C', boolean=True, full_text=True),
})
db.store('1', {'var_1': '1', 'var_2': 'у', 'var_3': 'г'})
@@ -232,9 +242,9 @@ class IndexTest(tests.Test):
def test_find_WithBooleanProps(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A', boolean=True, full_text=True),
- 'var_2': IndexedProperty('var_2', 2, 'B', boolean=False, full_text=True),
- 'var_3': IndexedProperty('var_3', 3, 'C', boolean=True, full_text=True),
+ 'var_1': Property('var_1', 1, 'A', boolean=True, full_text=True),
+ 'var_2': Property('var_2', 2, 'B', boolean=False, full_text=True),
+ 'var_3': Property('var_3', 3, 'C', boolean=True, full_text=True),
})
db.store('1', {'var_1': '1', 'var_2': 'у', 'var_3': 'г'})
@@ -254,7 +264,7 @@ class IndexTest(tests.Test):
db._find(query='б', var_1='1', var_2='у', var_3='г', reply=['var_1']))
def test_find_ExactQuery(self):
- db = Index({'key': IndexedProperty('key', 1, 'K', full_text=True)})
+ db = Index({'key': Property('key', 1, 'K', full_text=True)})
db.store('1', {'key': 'фу'})
db.store('2', {'key': 'фу бар'})
@@ -280,7 +290,7 @@ class IndexTest(tests.Test):
def test_find_ExactQueryTerms(self):
term = 'azAZ09_'
- db = Index({term: IndexedProperty(term, 1, 'T', full_text=True)})
+ db = Index({term: Property(term, 1, 'T', full_text=True)})
db.store('1', {term: 'test'})
db.store('2', {term: 'test fail'})
@@ -290,7 +300,7 @@ class IndexTest(tests.Test):
db._find(query='%s:=test' % term, reply=['guid']))
def test_find_ReturnPortions(self):
- db = Index({'key': IndexedProperty('key', 1, 'K')})
+ db = Index({'key': Property('key', 1, 'K')})
db.store('1', {'key': '1'})
db.store('2', {'key': '2'})
@@ -311,8 +321,8 @@ class IndexTest(tests.Test):
def test_find_OrderBy(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A'),
- 'var_2': IndexedProperty('var_2', 2, 'B'),
+ 'var_1': Property('var_1', 1, 'A'),
+ 'var_2': Property('var_2', 2, 'B'),
})
db.store('1', {'var_1': '1', 'var_2': '3'})
@@ -341,15 +351,15 @@ class IndexTest(tests.Test):
def test_find_GroupBy(self):
db = Index({
- 'var_1': IndexedProperty('var_1', 1, 'A'),
- 'var_2': IndexedProperty('var_2', 2, 'B'),
- 'var_3': IndexedProperty('var_3', 3, 'C'),
- 'var_4': IndexedProperty('var_4', 4, 'D'),
+ 'var_1': Property('var_1', 1, 'A'),
+ 'var_2': Property('var_2', 2, 'B'),
+ 'var_3': Property('var_3', 3, 'C'),
+ 'var_4': Property('var_4', 4, 'D'),
})
- db.store('1', {'var_1': '1', 'var_2': '1', 'var_3': '3', 'var_4': 0})
- db.store('2', {'var_1': '2', 'var_2': '1', 'var_3': '4', 'var_4': 0})
- db.store('3', {'var_1': '3', 'var_2': '2', 'var_3': '4', 'var_4': 0})
+ db.store('1', {'var_1': '1', 'var_2': '1', 'var_3': '3', 'var_4': '0'})
+ db.store('2', {'var_1': '2', 'var_2': '1', 'var_3': '4', 'var_4': '0'})
+ db.store('3', {'var_1': '3', 'var_2': '2', 'var_3': '4', 'var_4': '0'})
self.assertEqual(
[{'guid': '1', 'var_1': '1'}, {'guid': '3', 'var_1': '3'}],
@@ -366,7 +376,7 @@ class IndexTest(tests.Test):
def test_MultipleValues(self):
db = Index({
- 'prop': IndexedProperty('prop', prefix='B', typecast=[1, 2], full_text=True),
+ 'prop': List(name='prop', prefix='B', subtype=Enum([1, 2, 3]), full_text=True),
})
db.store('1', {'prop': [1, 2]})
db.store('2', {'prop': [2, 3]})
@@ -385,7 +395,7 @@ class IndexTest(tests.Test):
db.close()
db = Index({
- 'prop': IndexedProperty('prop', prefix='B', typecast=[], full_text=True),
+ 'prop': List(name='prop', prefix='B', full_text=True),
})
db.store('1', {'prop': ['a', 'b']})
db.store('2', {'prop': ['b', 'c']})
@@ -448,7 +458,7 @@ class IndexTest(tests.Test):
db.close()
def test_find_OrderByGUIDAllTime(self):
- db = Index({'prop': IndexedProperty('prop', 1, 'P')})
+ db = Index({'prop': Property('prop', 1, 'P')})
db.store('3', {'prop': '1'})
db.store('2', {'prop': '1'})
@@ -469,7 +479,7 @@ class IndexTest(tests.Test):
def test_find_Region(self):
term = 'azAZ09_'
- db = Index({term: IndexedProperty(term, 1, 'T', full_text=True)})
+ db = Index({term: Property(term, 1, 'T', full_text=True)})
db.store('1', {term: 'test'})
db.store('2', {term: 'test fail'})
@@ -479,7 +489,7 @@ class IndexTest(tests.Test):
db._find(query='%s:=test' % term, reply=['guid']))
def test_find_WithListProps(self):
- db = Index({'prop': IndexedProperty('prop', None, 'A', full_text=True, typecast=[])})
+ db = Index({'prop': List(name='prop', prefix='A', full_text=True)})
db.store('1', {'prop': ('a', )})
db.store('2', {'prop': ('a', 'aa')})
@@ -571,10 +581,10 @@ class IndexTest(tests.Test):
self.assertEqual(1, len(commits))
def test_SortLocalizedProps(self):
- toolkit._default_langs = ['default_lang']
+ i18n._default_langs = ['default_lang']
current_lang = locale.getdefaultlocale()[0].replace('_', '-')
- db = Index({'prop': IndexedProperty('prop', 1, 'A', localized=True)})
+ db = Index({'prop': Localized(name='prop', slot=1, prefix='A')})
db.store('0', {'prop': {'foo': '5'}})
db.store('1', {'prop': {current_lang: '4', 'default_lang': '1', 'foo': '3'}})
@@ -598,7 +608,7 @@ class IndexTest(tests.Test):
db._find(order_by='-prop')[0])
def test_SearchByLocalizedProps(self):
- db = Index({'prop': IndexedProperty('prop', 1, 'A', localized=True, full_text=True)})
+ db = Index({'prop': Localized(name='prop', slot=1, prefix='A', full_text=True)})
db.store('1', {'prop': {'a': 'ё'}})
db.store('2', {'prop': {'a': 'ё', 'b': 'ю'}})
@@ -635,7 +645,7 @@ class IndexTest(tests.Test):
sorted(db._find(query='prop:я')[0]))
def test_find_MultipleFilter(self):
- db = Index({'prop': IndexedProperty('prop', 1, 'A')})
+ db = Index({'prop': Property('prop', 1, 'A')})
db.store('1', {'prop': 'a'})
db.store('2', {'prop': 'b'})
@@ -677,7 +687,7 @@ class IndexTest(tests.Test):
db._find(prop=['b', 'foo', 'bar'], reply=['guid'])[0])
def test_find_AndNotFilter(self):
- db = Index({'prop': IndexedProperty('prop', 1, 'A')})
+ db = Index({'prop': Property('prop', 1, 'A')})
db.store('1', {'prop': 'a'})
db.store('2', {'prop': 'b'})
@@ -721,24 +731,21 @@ class IndexTest(tests.Test):
]),
sorted(db._find(prop=['a', 'c'], reply=['guid'], **{'!prop': 'b'})[0]))
- def test_fmt_prop_value(self):
- prop = Property('prop')
- self.assertEqual(['0'], [i for i in _fmt_prop_value(prop, 0)])
- self.assertEqual(['1'], [i for i in _fmt_prop_value(prop, 1)])
- self.assertEqual(['0'], [i for i in _fmt_prop_value(prop, 0)])
- self.assertEqual(['1.1'], [i for i in _fmt_prop_value(prop, 1.1)])
- self.assertEqual(['0', '1'], [i for i in _fmt_prop_value(prop, [0, 1])])
- self.assertEqual(['2', '1'], [i for i in _fmt_prop_value(prop, [2, 1])])
- self.assertEqual(['probe', 'True', '0'], [i for i in _fmt_prop_value(prop, ['probe', True, 0])])
- self.assertEqual(['True'], [i for i in _fmt_prop_value(prop, True)])
- self.assertEqual(['False'], [i for i in _fmt_prop_value(prop, False)])
+ def test_find_CustomEncode(self):
+ db = Index({'trait': Numeric('trait', 1, 'A')})
+
+ db.store('1', {'trait': 1})
+ db.store('2', {'trait': 2})
+ db.store('11', {'trait': 11})
+
+ self.assertEqual([{'guid': '1'}], db._find(trait='1')[0])
+ self.assertEqual([{'guid': '1'}], db._find(trait=1)[0])
- prop = Property('prop', typecast=bool)
- self.assertEqual(['1'], [i for i in _fmt_prop_value(prop, True)])
- self.assertEqual(['0'], [i for i in _fmt_prop_value(prop, False)])
+ self.assertEqual([{'guid': '2'}], db._find(trait='2')[0])
+ self.assertEqual([{'guid': '2'}], db._find(trait=2)[0])
- prop = Property('prop', fmt=lambda x: x.keys())
- self.assertEqual(['a', '2'], [i for i in _fmt_prop_value(prop, {'a': 1, 2: 'b'})])
+ self.assertEqual([{'guid': '11'}], db._find(trait='11')[0])
+ self.assertEqual([{'guid': '11'}], db._find(trait=11)[0])
class Index(index.IndexWriter):
@@ -750,7 +757,7 @@ class Index(index.IndexWriter):
metadata = Metadata(Index)
metadata.update(props)
- metadata['guid'] = IndexedProperty('guid',
+ metadata['guid'] = Property('guid',
acl=ACL.CREATE | ACL.READ, slot=0,
prefix=GUID_PREFIX)
diff --git a/tests/units/db/metadata.py b/tests/units/db/metadata.py
new file mode 100755
index 0000000..a0ba512
--- /dev/null
+++ b/tests/units/db/metadata.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# sugar-lint: disable
+
+from __init__ import tests
+
+from sugar_network import db
+
+
+class MetadataTest(tests.Test):
+
+ def test_Typecast(self):
+ prop = db.Numeric()
+ self.assertEqual(1, prop.typecast(1))
+ self.assertEqual(1, prop.typecast(1.1))
+ self.assertEqual(1, prop.typecast('1'))
+ self.assertRaises(ValueError, prop.typecast, '1.0')
+ self.assertRaises(ValueError, prop.typecast, '')
+ self.assertRaises(TypeError, prop.typecast, None)
+
+ prop = db.Boolean()
+ self.assertEqual(False, prop.typecast(0))
+ self.assertEqual(True, prop.typecast(1))
+ self.assertEqual(True, prop.typecast(1.1))
+ self.assertEqual(True, prop.typecast('1'))
+ self.assertEqual(False, prop.typecast('false'))
+ self.assertEqual(True, prop.typecast(True))
+ self.assertEqual(False, prop.typecast(False))
+ self.assertEqual(False, prop.typecast('False'))
+ self.assertEqual(False, prop.typecast('0'))
+ self.assertEqual(False, prop.typecast(''))
+ self.assertEqual(False, prop.typecast(None))
+
+ prop = db.List(subtype=db.Numeric())
+ self.assertEqual([1], prop.typecast(1))
+ self.assertEqual([], prop.typecast(None))
+ self.assertRaises(ValueError, prop.typecast, '')
+ self.assertEqual([], prop.typecast([]))
+ self.assertEqual([123], prop.typecast('123'))
+ self.assertRaises(ValueError, prop.typecast, 'a')
+ self.assertEqual([123, 4, 5], prop.typecast(['123', 4, 5.6]))
+
+ prop = db.Enum(items=[1, 2])
+ self.assertRaises(ValueError, prop.typecast, 0)
+ self.assertRaises(TypeError, prop.typecast, None)
+ self.assertRaises(ValueError, prop.typecast, '')
+ self.assertRaises(ValueError, prop.typecast, 'A')
+ self.assertRaises(ValueError, prop.typecast, '3')
+ self.assertEqual(1, prop.typecast(1))
+ self.assertEqual(2, prop.typecast(2))
+ self.assertEqual(1, prop.typecast('1'))
+
+ prop = db.List()
+ self.assertEqual([], prop.typecast(None))
+ self.assertEqual([''], prop.typecast(''))
+ self.assertEqual([''], prop.typecast(['']))
+ self.assertEqual([], prop.typecast([]))
+ self.assertEqual([0], prop.typecast(0))
+ self.assertEqual([''], prop.typecast(''))
+ self.assertEqual(['foo'], prop.typecast('foo'))
+
+ prop = db.List(subtype=db.Enum(['A', 'B', 'C']))
+ self.assertRaises(ValueError, prop.typecast, '')
+ self.assertRaises(ValueError, prop.typecast, [''])
+ self.assertEqual([], prop.typecast([]))
+ self.assertEqual(['A', 'B', 'C'], prop.typecast(['A', 'B', 'C']))
+ self.assertRaises(ValueError, prop.typecast, ['a'])
+ self.assertRaises(ValueError, prop.typecast, ['A', 'x'])
+
+
+if __name__ == '__main__':
+ tests.main()
diff --git a/tests/units/db/resource.py b/tests/units/db/resource.py
index d09010e..ef305ec 100755
--- a/tests/units/db/resource.py
+++ b/tests/units/db/resource.py
@@ -23,11 +23,16 @@ from sugar_network.db import directory as directory_
from sugar_network.db.directory import Directory
from sugar_network.db.index import IndexWriter
from sugar_network.toolkit.router import ACL
+from sugar_network.toolkit.coroutine import this
from sugar_network.toolkit import http, Sequence
class ResourceTest(tests.Test):
+ def setUp(self, fork_num=0):
+ tests.Test.setUp(self, fork_num)
+ this.broadcast = lambda x: x
+
def test_ActiveProperty_Slotted(self):
class Document(db.Resource):
@@ -345,31 +350,31 @@ class ResourceTest(tests.Test):
return value
directory = Directory(tests.tmpdir, Document, IndexWriter)
+ guid = directory.create({'guid': '1', 'prop1': '1', 'prop2': '2'})
+ doc = directory.get(guid)
- self.assertRaises(http.NotFound, directory.patch, 'absent', {})
-
- directory.create({'guid': '1', 'prop1': '1', 'prop2': '2'})
- self.assertEqual({}, directory.patch('1', {}))
- self.assertEqual({}, directory.patch('1', {'prop1': '1', 'prop2': '2'}))
- self.assertEqual({'prop1': '1_'}, directory.patch('1', {'prop1': '1_', 'prop2': '2'}))
- self.assertEqual({'prop1': '1_', 'prop2': '2_'}, directory.patch('1', {'prop1': '1_', 'prop2': '2_'}))
+ self.assertEqual({}, doc.patch({}))
+ self.assertEqual({}, doc.patch({'prop1': '1', 'prop2': '2'}))
+ self.assertEqual({'prop1': '1_'}, doc.patch({'prop1': '1_', 'prop2': '2'}))
+ self.assertEqual({'prop1': '1_', 'prop2': '2_'}, doc.patch({'prop1': '1_', 'prop2': '2_'}))
def test_patch_LocalizedProps(self):
class Document(db.Resource):
- @db.indexed_property(slot=1, localized=True)
+ @db.indexed_property(db.Localized, slot=1)
def prop(self, value):
return value
directory = Directory(tests.tmpdir, Document, IndexWriter)
+ guid = directory.create({'guid': '1', 'prop': {'ru': 'ru'}})
+ doc = directory.get(guid)
- directory.create({'guid': '1', 'prop': {'ru': 'ru'}})
- self.assertEqual({}, directory.patch('1', {'prop': 'ru'}))
- self.assertEqual({'prop': {'ru': 'ru_'}}, directory.patch('1', {'prop': {'ru': 'ru_'}}))
- self.assertEqual({'prop': {'en': 'en'}}, directory.patch('1', {'prop': {'en': 'en'}}))
- self.assertEqual({'prop': {'ru': 'ru', 'en': 'en'}}, directory.patch('1', {'prop': {'ru': 'ru', 'en': 'en'}}))
- self.assertEqual({'prop': {'ru': 'ru_', 'en': 'en'}}, directory.patch('1', {'prop': {'ru': 'ru_', 'en': 'en'}}))
+ self.assertEqual({}, doc.patch({'prop': {'ru': 'ru'}}))
+ self.assertEqual({'prop': {'ru': 'ru_'}}, doc.patch({'prop': {'ru': 'ru_'}}))
+ self.assertEqual({'prop': {'en': 'en'}}, doc.patch({'prop': {'en': 'en'}}))
+ self.assertEqual({'prop': {'ru': 'ru', 'en': 'en'}}, doc.patch({'prop': {'ru': 'ru', 'en': 'en'}}))
+ self.assertEqual({'prop': {'ru': 'ru_', 'en': 'en'}}, doc.patch({'prop': {'ru': 'ru_', 'en': 'en'}}))
def test_diff(self):
@@ -379,21 +384,13 @@ class ResourceTest(tests.Test):
def prop(self, value):
return value
- @db.blob_property()
- def blob(self, value):
- return value
-
directory = Directory(tests.tmpdir, Document, IndexWriter)
- self.touch(('blob', '1'))
directory.create({'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1})
- directory.update('1', {'blob': {'blob': 'blob'}})
for i in os.listdir('1/1'):
os.utime('1/1/%s' % i, (1, 1))
- self.touch(('blob', '2'))
directory.create({'guid': '2', 'prop': '2', 'ctime': 2, 'mtime': 2})
- directory.update('2', {'blob': {'blob': 'blob'}})
for i in os.listdir('2/2'):
os.utime('2/2/%s' % i, (2, 2))
@@ -408,22 +405,12 @@ class ResourceTest(tests.Test):
'ctime': {'value': 1, 'mtime': 1},
'prop': {'value': '1', 'mtime': 1},
'mtime': {'value': 1, 'mtime': 1},
- 'blob': {
- 'mtime': 1,
- 'blob': tests.tmpdir + '/1/1/blob.blob',
- 'blob_size': 1,
- },
}},
{'guid': '2', 'diff': {
'guid': {'value': '2', 'mtime': 2},
'ctime': {'value': 2, 'mtime': 2},
'prop': {'value': '2', 'mtime': 2},
'mtime': {'value': 2, 'mtime': 2},
- 'blob': {
- 'mtime': 2,
- 'blob': tests.tmpdir + '/2/2/blob.blob',
- 'blob_size': 1,
- },
}},
{'guid': '3', 'diff': {
'guid': {'value': '3', 'mtime': 3},
@@ -433,7 +420,7 @@ class ResourceTest(tests.Test):
}},
],
[i for i in diff(directory, [[0, None]], out_seq)])
- self.assertEqual([[1, 5]], out_seq)
+ self.assertEqual([[1, 3]], out_seq)
out_seq = Sequence()
self.assertEqual([
@@ -442,26 +429,15 @@ class ResourceTest(tests.Test):
'ctime': {'value': 2, 'mtime': 2},
'prop': {'value': '2', 'mtime': 2},
'mtime': {'value': 2, 'mtime': 2},
- 'blob': {
- 'mtime': 2,
- 'blob': tests.tmpdir + '/2/2/blob.blob',
- 'blob_size': 1,
- },
}},
],
- [i for i in diff(directory, [[3, 4]], out_seq)])
- self.assertEqual([[3, 4]], out_seq)
-
- out_seq = Sequence()
- self.assertEqual([
- ],
- [i for i in diff(directory, [[3, 3]], out_seq)])
- self.assertEqual([], out_seq)
+ [i for i in diff(directory, [[2, 2]], out_seq)])
+ self.assertEqual([[2, 2]], out_seq)
out_seq = Sequence()
self.assertEqual([
],
- [i for i in diff(directory, [[6, 100]], out_seq)])
+ [i for i in diff(directory, [[4, 100]], out_seq)])
self.assertEqual([], out_seq)
directory.update('2', {'prop': '22'})
self.assertEqual([
@@ -469,8 +445,8 @@ class ResourceTest(tests.Test):
'prop': {'value': '22', 'mtime': int(os.stat('2/2/prop').st_mtime)},
}},
],
- [i for i in diff(directory, [[6, 100]], out_seq)])
- self.assertEqual([[6, 6]], out_seq)
+ [i for i in diff(directory, [[4, 100]], out_seq)])
+ self.assertEqual([[4, 4]], out_seq)
def test_diff_IgnoreCalcProps(self):
@@ -535,37 +511,6 @@ class ResourceTest(tests.Test):
self.assertEqual([[1, 1], [4, 4]], out_seq)
- def test_diff_WithBlobsSetByUrl(self):
- URL = 'http://src.sugarlabs.org/robots.txt'
- URL_content = urllib2.urlopen(URL).read()
-
- class Document(db.Resource):
-
- @db.blob_property()
- def blob(self, value):
- return value
-
- directory = Directory(tests.tmpdir, Document, IndexWriter)
-
- directory.create({'guid': '1', 'ctime': 1, 'mtime': 1})
- directory.update('1', {'blob': {'url': URL}})
- self.utime('1/1', 1)
-
- out_seq = Sequence()
- self.assertEqual([
- {'guid': '1', 'diff': {
- 'guid': {'value': '1', 'mtime': 1},
- 'ctime': {'value': 1, 'mtime': 1},
- 'mtime': {'value': 1, 'mtime': 1},
- 'blob': {
- 'url': URL,
- 'mtime': 1,
- },
- }},
- ],
- [i for i in diff(directory, [[0, None]], out_seq)])
- self.assertEqual([[1, 2]], out_seq)
-
def test_diff_Filter(self):
class Document(db.Resource):
@@ -626,7 +571,7 @@ class ResourceTest(tests.Test):
class Document(db.Resource):
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType())
+ @db.stored_property(db.Aggregated)
def prop(self, value):
return value
@@ -768,21 +713,13 @@ class ResourceTest(tests.Test):
def prop(self, value):
return value
- @db.blob_property()
- def blob(self, value):
- return value
-
directory1 = Directory('document1', Document, IndexWriter)
directory1.create({'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1})
- self.touch(('blob', '1'))
- directory1.update('1', {'blob': {'blob': 'blob'}})
for i in os.listdir('document1/1/1'):
os.utime('document1/1/1/%s' % i, (1, 1))
directory1.create({'guid': '2', 'prop': '2', 'ctime': 2, 'mtime': 2})
- self.touch(('blob', '2'))
- directory1.update('2', {'blob': {'blob': 'blob'}})
for i in os.listdir('document1/2/2'):
os.utime('document1/2/2/%s' % i, (2, 2))
@@ -808,7 +745,6 @@ class ResourceTest(tests.Test):
self.assertEqual(1, doc.meta('ctime')['mtime'])
self.assertEqual(1, doc.meta('prop')['mtime'])
self.assertEqual(1, doc.meta('mtime')['mtime'])
- self.assertEqual(1, doc.meta('blob')['mtime'])
doc = directory2.get('2')
self.assertEqual(2, doc.get('seqno'))
@@ -816,7 +752,6 @@ class ResourceTest(tests.Test):
self.assertEqual(2, doc.meta('ctime')['mtime'])
self.assertEqual(2, doc.meta('prop')['mtime'])
self.assertEqual(2, doc.meta('mtime')['mtime'])
- self.assertEqual(2, doc.meta('blob')['mtime'])
doc = directory2.get('3')
self.assertEqual(3, doc.get('seqno'))
@@ -824,28 +759,25 @@ class ResourceTest(tests.Test):
self.assertEqual(3, doc.meta('ctime')['mtime'])
self.assertEqual(3, doc.meta('prop')['mtime'])
self.assertEqual(3, doc.meta('mtime')['mtime'])
- self.assertEqual(None, doc.meta('blob'))
def test_merge_Update(self):
class Document(db.Resource):
- @db.blob_property()
- def blob(self, value):
+ @db.stored_property(default='')
+ def prop(self, value):
return value
directory1 = Directory('document1', Document, IndexWriter)
directory2 = Directory('document2', Document, IndexWriter)
directory1.create({'guid': 'guid', 'ctime': 1, 'mtime': 1})
- self.touch(('blob', '1'))
- directory1.update('guid', {'blob': {'blob': 'blob'}})
+ directory1.update('guid', {'prop': '1'})
for i in os.listdir('document1/gu/guid'):
os.utime('document1/gu/guid/%s' % i, (1, 1))
directory2.create({'guid': 'guid', 'ctime': 2, 'mtime': 2})
- self.touch(('blob', '2'))
- directory2.update('guid', {'blob': {'blob': 'blob'}})
+ directory2.update('guid', {'prop': '2'})
for i in os.listdir('document2/gu/guid'):
os.utime('document2/gu/guid/%s' % i, (2, 2))
@@ -858,8 +790,8 @@ class ResourceTest(tests.Test):
self.assertEqual(2, doc.meta('guid')['mtime'])
self.assertEqual(2, doc.meta('ctime')['mtime'])
self.assertEqual(2, doc.meta('mtime')['mtime'])
- self.assertEqual(2, doc.meta('blob')['mtime'])
- self.assertEqual('2', file('document2/gu/guid/blob.blob').read())
+ self.assertEqual(2, doc.meta('prop')['mtime'])
+ self.assertEqual('2', doc.meta('prop')['value'])
for patch in diff(directory1, [[0, None]], Sequence()):
directory2.merge(**patch)
@@ -872,8 +804,8 @@ class ResourceTest(tests.Test):
self.assertEqual(2, doc.meta('guid')['mtime'])
self.assertEqual(2, doc.meta('ctime')['mtime'])
self.assertEqual(2, doc.meta('mtime')['mtime'])
- self.assertEqual(2, doc.meta('blob')['mtime'])
- self.assertEqual('2', file('document2/gu/guid/blob.blob').read())
+ self.assertEqual(2, doc.meta('prop')['mtime'])
+ self.assertEqual('2', doc.meta('prop')['value'])
os.utime('document1/gu/guid/mtime', (3, 3))
for patch in diff(directory1, [[0, None]], Sequence()):
@@ -887,10 +819,10 @@ class ResourceTest(tests.Test):
self.assertEqual(2, doc.meta('guid')['mtime'])
self.assertEqual(2, doc.meta('ctime')['mtime'])
self.assertEqual(3, doc.meta('mtime')['mtime'])
- self.assertEqual(2, doc.meta('blob')['mtime'])
- self.assertEqual('2', file('document2/gu/guid/blob.blob').read())
+ self.assertEqual(2, doc.meta('prop')['mtime'])
+ self.assertEqual('2', doc.meta('prop')['value'])
- os.utime('document1/gu/guid/blob', (4, 4))
+ os.utime('document1/gu/guid/prop', (4, 4))
for patch in diff(directory1, [[0, None]], Sequence()):
directory2.merge(**patch)
@@ -902,132 +834,14 @@ class ResourceTest(tests.Test):
self.assertEqual(2, doc.meta('guid')['mtime'])
self.assertEqual(2, doc.meta('ctime')['mtime'])
self.assertEqual(3, doc.meta('mtime')['mtime'])
- self.assertEqual(4, doc.meta('blob')['mtime'])
- self.assertEqual('1', file('document2/gu/guid/blob.blob').read())
-
- def test_merge_SeqnoLessMode(self):
-
- class Document(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop(self, value):
- return value
-
- directory1 = Directory('document1', Document, IndexWriter)
- directory1.create({'guid': '1', 'prop': '1', 'ctime': 1, 'mtime': 1})
-
- directory2 = Directory('document2', Document, IndexWriter)
- for patch in diff(directory1, [[0, None]], Sequence()):
- directory2.merge(shift_seqno=False, **patch)
- self.assertEqual(
- [(1, 1, '1', '1')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory2.find()[0]])
- doc = directory2.get('1')
- self.assertEqual(0, doc.get('seqno'))
- self.assertEqual(0, doc.meta('guid')['seqno'])
- self.assertEqual(0, doc.meta('prop')['seqno'])
-
- directory3 = Directory('document3', Document, IndexWriter)
- for patch in diff(directory1, [[0, None]], Sequence()):
- directory3.merge(**patch)
- self.assertEqual(
- [(1, 1, '1', '1')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
- doc = directory3.get('1')
- self.assertEqual(1, doc.get('seqno'))
- self.assertEqual(1, doc.meta('guid')['seqno'])
- self.assertEqual(1, doc.meta('prop')['seqno'])
-
- time.sleep(1)
- directory1.update('1', {'prop': '2', 'ctime': 2, 'mtime': 2})
-
- for patch in diff(directory1, [[0, None]], Sequence()):
- directory3.merge(shift_seqno=False, **patch)
- self.assertEqual(
- [(2, 2, '1', '2')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
- doc = directory3.get('1')
- self.assertEqual(1, doc.get('seqno'))
- self.assertEqual(1, doc.meta('guid')['seqno'])
- self.assertEqual(1, doc.meta('prop')['seqno'])
-
- time.sleep(1)
- directory1.update('1', {'prop': '3', 'ctime': 3, 'mtime': 3})
-
- for patch in diff(directory1, [[0, None]], Sequence()):
- directory3.merge(**patch)
- self.assertEqual(
- [(3, 3, '1', '3')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
- doc = directory3.get('1')
- self.assertEqual(2, doc.get('seqno'))
- self.assertEqual(1, doc.meta('guid')['seqno'])
- self.assertEqual(2, doc.meta('prop')['seqno'])
-
- def test_merge_AvoidCalculatedBlobs(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def blob(self, value):
- return {'url': 'http://foo/bar', 'mime_type': 'image/png'}
-
- directory1 = Directory('document1', Document, IndexWriter)
- directory1.create({'guid': 'guid', 'ctime': 1, 'mtime': 1})
- for i in os.listdir('document1/gu/guid'):
- os.utime('document1/gu/guid/%s' % i, (1, 1))
-
- directory2 = Directory('document2', Document, IndexWriter)
- for patch in diff(directory1, [[0, None]], Sequence()):
- directory2.merge(**patch)
-
- doc = directory2.get('guid')
- self.assertEqual(1, doc.get('seqno'))
- self.assertEqual(1, doc.meta('guid')['mtime'])
- assert not exists('document2/gu/guid/blob')
-
- def test_merge_Blobs(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def blob(self, value):
- return value
-
- directory = Directory('document', Document, IndexWriter)
- self.touch(('blob', 'blob-1'))
- directory.merge('1', {
- 'guid': {'mtime': 1, 'value': '1'},
- 'ctime': {'mtime': 2, 'value': 2},
- 'mtime': {'mtime': 3, 'value': 3},
- 'blob': {'mtime': 4, 'blob': 'blob'},
- })
-
- self.assertEqual(
- [(2, 3, '1')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory.find()[0]])
-
- doc = directory.get('1')
- self.assertEqual(1, doc.get('seqno'))
- self.assertEqual(1, doc.meta('guid')['mtime'])
- self.assertEqual(2, doc.meta('ctime')['mtime'])
- self.assertEqual(3, doc.meta('mtime')['mtime'])
- self.assertEqual(4, doc.meta('blob')['mtime'])
- self.assertEqual('blob-1', file('document/1/1/blob.blob').read())
-
- self.touch(('blob', 'blob-2'))
- directory.merge('1', {
- 'blob': {'mtime': 5, 'blob': 'blob'},
- })
-
- self.assertEqual(5, doc.meta('blob')['mtime'])
- self.assertEqual('blob-2', file('document/1/1/blob.blob').read())
+ self.assertEqual(4, doc.meta('prop')['mtime'])
+ self.assertEqual('1', doc.meta('prop')['value'])
def test_merge_Aggprops(self):
class Document(db.Resource):
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType())
+ @db.stored_property(db.Aggregated)
def prop(self, value):
return value
@@ -1079,6 +893,28 @@ class ResourceTest(tests.Test):
},
directory.get('1')['prop'])
+ def test_merge_CallSetters(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Numeric)
+ def prop(self, value):
+ return value
+
+ @prop.setter
+ def prop(self, value):
+ return value + 1
+
+ directory = Directory('document', Document, IndexWriter)
+
+ directory.merge('1', {
+ 'guid': {'mtime': 1, 'value': '1'},
+ 'ctime': {'mtime': 1, 'value': 1},
+ 'mtime': {'mtime': 1, 'value': 1},
+ 'prop': {'mtime': 1, 'value': 1},
+ })
+ self.assertEqual(2, directory.get('1')['prop'])
+
def test_wipe(self):
class Document(db.Resource):
@@ -1088,31 +924,11 @@ class ResourceTest(tests.Test):
guid = directory.create({'prop': '1'})
self.assertEqual([guid], [i.guid for i in directory.find()[0]])
directory.commit()
- assert directory.mtime != 0
+ assert exists('index/mtime')
directory.wipe()
self.assertEqual([], [i.guid for i in directory.find()[0]])
- assert directory.mtime == 0
-
- def test_DeleteOldBlobOnUpdate(self):
-
- class Document(db.Resource):
-
- @db.blob_property()
- def blob(self, value):
- return value
-
- directory = Directory(tests.tmpdir, Document, IndexWriter)
-
- directory.create({'guid': 'guid', 'blob': 'foo'})
- assert exists('gu/guid/blob.blob')
- directory.update('guid', {'blob': {'url': 'foo'}})
- assert not exists('gu/guid/blob.blob')
-
- directory.update('guid', {'blob': 'foo'})
- assert exists('gu/guid/blob.blob')
- directory.update('guid', {'blob': {}})
- assert not exists('gu/guid/blob.blob')
+ assert not exists('index/mtime')
def diff(directory, in_seq, out_seq, exclude_seq=None, **kwargs):
diff --git a/tests/units/db/routes.py b/tests/units/db/routes.py
index 5908d0f..8824ca8 100755
--- a/tests/units/db/routes.py
+++ b/tests/units/db/routes.py
@@ -16,10 +16,11 @@ src_root = abspath(dirname(__file__))
from __init__ import tests
from sugar_network import db, toolkit
-from sugar_network.db.routes import _typecast_prop_value
-from sugar_network.db.metadata import Property
-from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, Blob, ACL
-from sugar_network.toolkit import coroutine, http
+from sugar_network.db import files
+from sugar_network.model.user import User
+from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, ACL
+from sugar_network.toolkit.coroutine import this
+from sugar_network.toolkit import coroutine, http, i18n
class RoutesTest(tests.Test):
@@ -36,18 +37,19 @@ class RoutesTest(tests.Test):
def wo_default(self, value):
return value
- @db.indexed_property(slot=1, default='not_stored_default')
+ @db.stored_property(default='not_stored_default')
def not_stored_default(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [Document], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
- self.assertRaises(RuntimeError, self.call, 'POST', ['document'], content={})
+ self.assertRaises(RuntimeError, this.call, method='POST', path=['document'], content={})
- guid = self.call('POST', ['document'], content={'wo_default': 'wo_default'})
- self.assertEqual('default', self.call('GET', ['document', guid, 'w_default']))
- self.assertEqual('wo_default', self.call('GET', ['document', guid, 'wo_default']))
- self.assertEqual('not_stored_default', self.call('GET', ['document', guid, 'not_stored_default']))
+ guid = this.call(method='POST', path=['document'], content={'wo_default': 'wo_default'})
+ self.assertEqual('default', this.call(method='GET', path=['document', guid, 'w_default']))
+ self.assertEqual('wo_default', this.call(method='GET', path=['document', guid, 'wo_default']))
+ self.assertEqual('not_stored_default', this.call(method='GET', path=['document', guid, 'not_stored_default']))
def test_Populate(self):
self.touch(
@@ -65,10 +67,10 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- with db.Volume(tests.tmpdir, [Document], lambda event: None) as volume:
- for cls in volume.values():
- for __ in cls.populate():
- pass
+ with db.Volume(tests.tmpdir, [Document]) as volume:
+ router = Router(db.Routes(volume))
+ for __ in volume['document'].populate():
+ pass
self.assertEqual(
sorted(['1', '2']),
sorted([i.guid for i in volume['document'].find()[0]]))
@@ -78,10 +80,10 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- with db.Volume(tests.tmpdir, [Document], lambda event: None) as volume:
- for cls in volume.values():
- for __ in cls.populate():
- pass
+ with db.Volume(tests.tmpdir, [Document]) as volume:
+ router = Router(db.Routes(volume))
+ for __ in volume['document'].populate():
+ pass
self.assertEqual(
sorted(['1', '2']),
sorted([i.guid for i in volume['document'].find()[0]]))
@@ -94,12 +96,14 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- self.volume['testdocument'].create({'guid': 'guid'})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ volume['testdocument'].create({'guid': 'guid'})
self.assertEqual({
'total': 1,
@@ -107,11 +111,11 @@ class RoutesTest(tests.Test):
{'guid': 'guid', 'prop': ''},
],
},
- self.call('GET', path=['testdocument'], reply=['guid', 'prop']))
+ this.call(method='GET', path=['testdocument'], reply=['guid', 'prop']))
- guid_1 = self.call('POST', path=['testdocument'], content={'prop': 'value_1'})
+ guid_1 = this.call(method='POST', path=['testdocument'], content={'prop': 'value_1'})
assert guid_1
- guid_2 = self.call('POST', path=['testdocument'], content={'prop': 'value_2'})
+ guid_2 = this.call(method='POST', path=['testdocument'], content={'prop': 'value_2'})
assert guid_2
self.assertEqual(
@@ -120,9 +124,9 @@ class RoutesTest(tests.Test):
{'guid': guid_1, 'prop': 'value_1'},
{'guid': guid_2, 'prop': 'value_2'},
]),
- sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
+ sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
- self.call('PUT', path=['testdocument', guid_1], content={'prop': 'value_3'})
+ this.call(method='PUT', path=['testdocument', guid_1], content={'prop': 'value_3'})
self.assertEqual(
sorted([
@@ -130,240 +134,397 @@ class RoutesTest(tests.Test):
{'guid': guid_1, 'prop': 'value_3'},
{'guid': guid_2, 'prop': 'value_2'},
]),
- sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
+ sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
- self.call('DELETE', path=['testdocument', guid_2])
+ this.call(method='DELETE', path=['testdocument', guid_2])
self.assertEqual(
sorted([
{'guid': 'guid', 'prop': ''},
{'guid': guid_1, 'prop': 'value_3'},
]),
- sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
+ sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result']))
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid_2])
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid_2])
self.assertEqual(
{'guid': guid_1, 'prop': 'value_3'},
- self.call('GET', path=['testdocument', guid_1], reply=['guid', 'prop']))
+ this.call(method='GET', path=['testdocument', guid_1], reply=['guid', 'prop']))
self.assertEqual(
'value_3',
- self.call('GET', path=['testdocument', guid_1, 'prop']))
+ this.call(method='GET', path=['testdocument', guid_1, 'prop']))
def test_SetBLOBs(self):
class TestDocument(db.Resource):
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1')
- self.assertEqual('blob1', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
- self.call('PUT', path=['testdocument', guid, 'blob'], content_stream=StringIO('blob2'))
- self.assertEqual('blob2', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content='blob1')
+ self.assertEqual('blob1', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read())
- self.call('PUT', path=['testdocument', guid, 'blob'], content=None)
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob'])
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content_stream=StringIO('blob2'))
+ self.assertEqual('blob2', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read())
- def test_SetBLOBsByMeta(self):
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content=None)
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
+
+ def test_CreateBLOBsWithMeta(self):
class TestDocument(db.Resource):
- @db.blob_property(mime_type='default')
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={})
- self.assertRaises(RuntimeError, self.call, 'PUT', path=['testdocument', guid, 'blob'],
+ self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'],
content={}, content_type='application/json')
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob'])
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
+
+ self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'],
+ content={'url': 'foo'}, content_type='application/json')
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content={'url': 'url', 'digest': 'digest', 'foo': 'bar'}, content_type='application/json')
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'url': 'url',
+ 'foo': 'bar',
+ },
+ this.call(method='GET', path=['testdocument', guid, 'blob']))
+
+ def test_UpdateUrlBLOBsWithMeta(self):
+
+ class TestDocument(db.Resource):
+
+ @db.stored_property(db.Blob)
+ def blob(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={'blob': {'digest': 'digest', 'url': 'url'}})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'url': 'url',
+ },
+ this.call(method='GET', path=['testdocument', guid, 'blob']))
+
+ self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'],
+ content={'digest': 'fake'}, content_type='application/json')
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'url': 'url',
+ },
+ this.call(method='GET', path=['testdocument', guid, 'blob']))
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content={'foo': 'bar'}, content_type='application/json')
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'url': 'url',
+ 'foo': 'bar',
+ },
+ this.call(method='GET', path=['testdocument', guid, 'blob']))
+
+ def test_UpdateFileBLOBsWithMeta(self):
+
+ class TestDocument(db.Resource):
+
+ @db.stored_property(db.Blob)
+ def blob(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'})
+ blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'size': os.stat(blob.path).st_size,
+ 'mtime': int(os.stat(blob.path).st_mtime),
+ 'url': 'http://localhost/blobs/%s' % hash('blob'),
+ 'digest': str(hash('blob')),
+ },
+ blob)
+ self.assertEqual('blob', file(blob.path).read())
+
+ self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'],
+ content={'digest': 'fake'}, content_type='application/json')
+ blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'size': os.stat(blob.path).st_size,
+ 'mtime': int(os.stat(blob.path).st_mtime),
+ 'digest': str(hash('blob')),
+ 'url': 'http://localhost/blobs/%s' % hash('blob'),
+ },
+ blob)
+ self.assertEqual('blob', file(blob.path).read())
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content={'foo': 'bar'}, content_type='application/json')
+ blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'size': os.stat(blob.path).st_size,
+ 'mtime': int(os.stat(blob.path).st_mtime),
+ 'digest': str(hash('blob')),
+ 'url': 'http://localhost/blobs/%s' % hash('blob'),
+ 'foo': 'bar',
+ },
+ blob)
+ self.assertEqual('blob', file(blob.path).read())
+
+ def test_SwitchBLOBsType(self):
+
+ class TestDocument(db.Resource):
+
+ @db.stored_property(db.Blob)
+ def blob(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.call('PUT', path=['testdocument', guid, 'blob'],
- content={'url': 'foo', 'bar': 'probe'}, content_type='application/json')
- blob = self.call('GET', path=['testdocument', guid, 'blob'])
- self.assertEqual('foo', blob['url'])
+ guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'})
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content={'foo': 'bar'}, content_type='application/json')
+
+ file_blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'size': os.stat(file_blob.path).st_size,
+ 'mtime': int(os.stat(file_blob.path).st_mtime),
+ 'digest': str(hash('blob')),
+ 'url': 'http://localhost/blobs/%s' % hash('blob'),
+ 'foo': 'bar',
+ }, file_blob)
+ self.assertEqual('blob', file(file_blob.path).read())
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content={'url': 'url'}, content_type='application/json')
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'url': 'url',
+ 'foo': 'bar',
+ }, this.call(method='GET', path=['testdocument', guid, 'blob']))
+ assert not exists(file_blob.path)
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'],
+ content='blob', content_type='application/octet-stream', environ={'HTTP_HOST': 'localhost'})
+ self.assertEqual({
+ 'mime_type': 'application/octet-stream',
+ 'size': os.stat(file_blob.path).st_size,
+ 'mtime': int(os.stat(file_blob.path).st_mtime),
+ 'digest': str(hash('blob')),
+ 'url': 'http://localhost/blobs/%s' % hash('blob'),
+ }, this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'}))
+ self.assertEqual('blob', file(file_blob.path).read())
def test_RemoveBLOBs(self):
class TestDocument(db.Resource):
- @db.blob_property(mime_type='default')
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'blob': 'blob'})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'})
- self.assertEqual('blob', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
+ self.assertEqual('blob', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read())
- self.call('PUT', path=['testdocument', guid, 'blob'])
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob'])
+ this.call(method='PUT', path=['testdocument', guid, 'blob'])
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
- def test_RemoveTempBLOBFilesOnFails(self):
+ def test_ReuploadBLOBs(self):
class TestDocument(db.Resource):
- @db.blob_property(mime_type='default')
+ @db.stored_property(db.Blob)
+ def blob(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob1'})
+
+ blob1 = this.call(method='GET', path=['testdocument', guid, 'blob'])
+ self.assertEqual('blob1', file(blob1.path).read())
+
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content='blob2')
+ blob2 = this.call(method='GET', path=['testdocument', guid, 'blob'])
+ self.assertEqual('blob2', file(blob2.path).read())
+ assert blob1.path != blob2.path
+ assert not exists(blob1.path)
+
+ def test_RemoveBLOBsOnFailedSetter(self):
+
+ class TestDocument(db.Resource):
+
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
@blob.setter
def blob(self, value):
- raise RuntimeError()
+ if value:
+ raise RuntimeError()
+ return value
+
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
- self.assertRaises(RuntimeError, self.call, 'PUT', path=['testdocument', guid, 'blob'], content='probe')
- self.assertEqual(0, len(os.listdir('tmp')))
+ self.assertRaises(RuntimeError, this.call, method='PUT', path=['testdocument', guid, 'blob'], content='probe')
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
+ assert not exists('blobs/%s' % hash('probe'))
def test_SetBLOBsWithMimeType(self):
class TestDocument(db.Resource):
- @db.blob_property(mime_type='default')
+ @db.stored_property(db.Blob, mime_type='default')
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={})
- self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1')
- self.assertEqual('default', self.call('GET', path=['testdocument', guid, 'blob'])['mime_type'])
- self.assertEqual('default', self.response.content_type)
+ response = Response()
+ this.call(response=response,
+ method='PUT', path=['testdocument', guid, 'blob'], content='blob1')
+ response = Response()
+ self.assertEqual('default', this.call(response=response,
+ method='GET', path=['testdocument', guid, 'blob'])['mime_type'])
+ self.assertEqual('default', response.content_type)
- self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1', content_type='foo')
- self.assertEqual('foo', self.call('GET', path=['testdocument', guid, 'blob'])['mime_type'])
- self.assertEqual('foo', self.response.content_type)
+ response = Response()
+ this.call(response=response,
+ method='PUT', path=['testdocument', guid, 'blob'], content='blob1', content_type='foo')
+ response = Response()
+ self.assertEqual('foo', this.call(response=response,
+ method='GET', path=['testdocument', guid, 'blob'])['mime_type'])
+ self.assertEqual('foo', response.content_type)
def test_GetBLOBs(self):
class TestDocument(db.Resource):
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={})
blob = 'blob'
- self.call('PUT', path=['testdocument', guid, 'blob'], content=blob)
-
- blob_path = tests.tmpdir + '/testdocument/%s/%s/blob' % (guid[:2], guid)
- blob_meta = {
- 'seqno': 2,
- 'blob': blob_path + '.blob',
- 'blob_size': len(blob),
- 'digest': hashlib.sha1(blob).hexdigest(),
- 'mime_type': 'application/octet-stream',
- 'mtime': int(os.stat(blob_path).st_mtime),
- }
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content=blob)
+ digest = str(hash(blob))
+ blob_path = 'blobs/%s' % digest
- self.assertEqual('blob', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
+ self.assertEqual('blob', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read())
self.assertEqual({
'blob': {
- 'url': 'http://localhost/testdocument/%s/blob' % guid,
- 'blob_size': len(blob),
- 'digest': hashlib.sha1(blob).hexdigest(),
'mime_type': u'application/octet-stream',
+ 'url': 'http://localhost/blobs/%s' % digest,
+ 'size': len(blob),
+ 'digest': digest,
+ 'mtime': int(os.stat(blob_path).st_mtime),
},
},
- self.call('GET', path=['testdocument', guid], reply=['blob'], host='localhost'))
+ this.call(method='GET', path=['testdocument', guid], reply=['blob'], environ={'HTTP_HOST': 'localhost'}))
self.assertEqual([{
'blob': {
- 'url': 'http://localhost/testdocument/%s/blob' % guid,
- 'blob_size': len(blob),
- 'digest': hashlib.sha1(blob).hexdigest(),
'mime_type': u'application/octet-stream',
+ 'url': 'http://localhost/blobs/%s' % digest,
+ 'size': len(blob),
+ 'digest': digest,
+ 'mtime': int(os.stat(blob_path).st_mtime),
},
}],
- self.call('GET', path=['testdocument'], reply=['blob'], host='localhost')['result'])
+ this.call(method='GET', path=['testdocument'], reply=['blob'], environ={'HTTP_HOST': 'localhost'})['result'])
def test_GetBLOBsByUrls(self):
class TestDocument(db.Resource):
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid1 = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid1 = this.call(method='POST', path=['testdocument'], content={})
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid1, 'blob'])
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid1, 'blob'])
self.assertEqual(
- {'blob': {'url': 'http://127.0.0.1/testdocument/%s/blob' % guid1}},
- self.call('GET', path=['testdocument', guid1], reply=['blob'], host='127.0.0.1'))
+ {'blob': {}},
+ this.call(method='GET', path=['testdocument', guid1], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'}))
blob = 'file'
- guid2 = self.call('POST', path=['testdocument'], content={'blob': blob})
- self.assertEqual('file', file(self.call('GET', path=['testdocument', guid2, 'blob'])['blob']).read())
- self.assertEqual({
- 'blob': {
- 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid2,
- 'blob_size': len(blob),
- 'digest': hashlib.sha1(blob).hexdigest(),
- 'mime_type': u'application/octet-stream',
- },
- },
- self.call('GET', path=['testdocument', guid2], reply=['blob'], host='127.0.0.1'))
+ guid2 = this.call(method='POST', path=['testdocument'], content={'blob': blob})
+ self.assertEqual(
+ 'http://127.0.0.1/blobs/%s' % hash(blob),
+ this.call(method='GET', path=['testdocument', guid2], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'})['blob']['url'])
- guid3 = self.call('POST', path=['testdocument'], content={'blob': {'url': 'http://foo'}}, content_type='application/json')
- self.assertEqual('http://foo', self.call('GET', path=['testdocument', guid3, 'blob'])['url'])
- self.assertEqual({
- 'blob': {
- 'url': 'http://foo',
- },
- },
- self.call('GET', path=['testdocument', guid3], reply=['blob'], host='127.0.0.1'))
+ guid3 = this.call(method='POST', path=['testdocument'], content={'blob': {'url': 'http://foo', 'digest': 'digest'}}, content_type='application/json')
+ self.assertEqual(
+ 'http://foo',
+ this.call(method='GET', path=['testdocument', guid3, 'blob'])['url'])
+ self.assertEqual(
+ 'http://foo',
+ this.call(method='GET', path=['testdocument', guid3], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'})['blob']['url'])
self.assertEqual(
sorted([
- {'blob': {
- 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid1,
- }},
- { 'blob': {
- 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid2,
- 'blob_size': len(blob),
- 'digest': hashlib.sha1(blob).hexdigest(),
- 'mime_type': u'application/octet-stream',
- }},
- { 'blob': {
- 'url': 'http://foo',
- }},
+ None,
+ 'http://127.0.0.1/blobs/%s' % hash(blob),
+ 'http://foo',
]),
- sorted(self.call('GET', path=['testdocument'], reply=['blob'], host='127.0.0.1')['result']))
+ sorted([i['blob'].get('url') for i in this.call(method='GET', path=['testdocument'], reply=['blob'],
+ environ={'HTTP_HOST': '127.0.0.1'})['result']]))
def test_CommandsGetAbsentBlobs(self):
class TestDocument(db.Resource):
- @db.indexed_property(slot=1, default='')
- def prop(self, value):
- return value
-
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- guid = self.call('POST', path=['testdocument'], content={'prop': 'value'})
- self.assertEqual('value', self.call('GET', path=['testdocument', guid, 'prop']))
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob'])
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob'])
self.assertEqual(
- {'blob': {'url': 'http://localhost/testdocument/%s/blob' % guid}},
- self.call('GET', path=['testdocument', guid], reply=['blob'], host='localhost'))
+ {'blob': {}},
+ this.call(method='GET', path=['testdocument', guid], reply=['blob'], environ={'HTTP_HOST': 'localhost'}))
def test_Command_ReplyForGET(self):
@@ -373,44 +534,46 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'prop': 'value'})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': 'value'})
self.assertEqual(
['guid', 'prop'],
- self.call('GET', path=['testdocument', guid], reply=['guid', 'prop']).keys())
+ this.call(method='GET', path=['testdocument', guid], reply=['guid', 'prop']).keys())
self.assertEqual(
['guid'],
- self.call('GET', path=['testdocument'])['result'][0].keys())
+ this.call(method='GET', path=['testdocument'])['result'][0].keys())
self.assertEqual(
sorted(['guid', 'prop']),
- sorted(self.call('GET', path=['testdocument'], reply=['prop', 'guid'])['result'][0].keys()))
+ sorted(this.call(method='GET', path=['testdocument'], reply=['prop', 'guid'])['result'][0].keys()))
self.assertEqual(
sorted(['prop']),
- sorted(self.call('GET', path=['testdocument'], reply=['prop'])['result'][0].keys()))
+ sorted(this.call(method='GET', path=['testdocument'], reply=['prop'])['result'][0].keys()))
def test_DecodeBeforeSetting(self):
class TestDocument(db.Resource):
- @db.indexed_property(slot=1, typecast=int)
+ @db.indexed_property(db.Numeric, slot=1)
def prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- guid = self.call('POST', path=['testdocument'], content={'prop': '-1'})
- self.assertEqual(-1, self.call('GET', path=['testdocument', guid, 'prop']))
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': '-1'})
+ self.assertEqual(-1, this.call(method='GET', path=['testdocument', guid, 'prop']))
def test_LocalizedSet(self):
- toolkit._default_langs = ['en']
+ i18n._default_langs = ['en']
class TestDocument(db.Resource):
@@ -418,32 +581,23 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- directory = self.volume['testdocument']
-
- guid = directory.create({'localized_prop': 'value_raw'})
- self.assertEqual({'en': 'value_raw'}, directory.get(guid)['localized_prop'])
- self.assertEqual(
- [guid],
- [i.guid for i in directory.find(localized_prop='value_raw')[0]])
-
- directory.update(guid, {'localized_prop': 'value_raw2'})
- self.assertEqual({'en': 'value_raw2'}, directory.get(guid)['localized_prop'])
- self.assertEqual(
- [guid],
- [i.guid for i in directory.find(localized_prop='value_raw2')[0]])
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ directory = volume['testdocument']
+ guid = this.call(method='POST', path=['testdocument'], content={'localized_prop': 'value_ru'},
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru'})
- guid = self.call('POST', path=['testdocument'], accept_language=['ru'], content={'localized_prop': 'value_ru'})
self.assertEqual({'ru': 'value_ru'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
[i.guid for i in directory.find(localized_prop='value_ru')[0]])
- self.call('PUT', path=['testdocument', guid], accept_language=['en'], content={'localized_prop': 'value_en'})
+ this.call(method='PUT', path=['testdocument', guid], content={'localized_prop': 'value_en'},
+ environ={'HTTP_ACCEPT_LANGUAGE': 'en'})
self.assertEqual({'ru': 'value_ru', 'en': 'value_en'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
@@ -460,14 +614,15 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- directory = self.volume['testdocument']
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ directory = volume['testdocument']
- guid = self.call('POST', path=['testdocument'], content={
+ guid = this.call(method='POST', path=['testdocument'], content={
'localized_prop': {
'ru': 'value_ru',
'es': 'value_es',
@@ -475,63 +630,78 @@ class RoutesTest(tests.Test):
},
})
- toolkit._default_langs = ['en']
+ i18n._default_langs = ['en']
self.assertEqual(
{'localized_prop': 'value_en'},
- self.call('GET', path=['testdocument', guid], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop']))
self.assertEqual(
{'localized_prop': 'value_ru'},
- self.call('GET', path=['testdocument', guid], accept_language=['ru'], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru'}))
self.assertEqual(
'value_ru',
- self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['ru', 'es']))
+ this.call(method='GET', path=['testdocument', guid, 'localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru,es'}))
self.assertEqual(
[{'localized_prop': 'value_ru'}],
- self.call('GET', path=['testdocument'], accept_language=['foo', 'ru', 'es'], reply=['localized_prop'])['result'])
+ this.call(method='GET', path=['testdocument'], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'foo,ru,es'})['result'])
self.assertEqual(
{'localized_prop': 'value_ru'},
- self.call('GET', path=['testdocument', guid], accept_language=['ru-RU'], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU'}))
self.assertEqual(
'value_ru',
- self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['ru-RU', 'es']))
+ this.call(method='GET', path=['testdocument', guid, 'localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU,es'}))
self.assertEqual(
[{'localized_prop': 'value_ru'}],
- self.call('GET', path=['testdocument'], accept_language=['foo', 'ru-RU', 'es'], reply=['localized_prop'])['result'])
+ this.call(method='GET', path=['testdocument'], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU,es'})['result'])
self.assertEqual(
{'localized_prop': 'value_es'},
- self.call('GET', path=['testdocument', guid], accept_language=['es'], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'es'}))
self.assertEqual(
'value_es',
- self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['es', 'ru']))
+ this.call(method='GET', path=['testdocument', guid, 'localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'es,ru'}))
self.assertEqual(
[{'localized_prop': 'value_es'}],
- self.call('GET', path=['testdocument'], accept_language=['foo', 'es', 'ru'], reply=['localized_prop'])['result'])
+ this.call(method='GET', path=['testdocument'], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'foo,es,ru'})['result'])
self.assertEqual(
{'localized_prop': 'value_en'},
- self.call('GET', path=['testdocument', guid], accept_language=['fr'], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'fr'}))
self.assertEqual(
'value_en',
- self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['fr', 'za']))
+ this.call(method='GET', path=['testdocument', guid, 'localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'fr,za'}))
self.assertEqual(
[{'localized_prop': 'value_en'}],
- self.call('GET', path=['testdocument'], accept_language=['foo', 'fr', 'za'], reply=['localized_prop'])['result'])
+ this.call(method='GET', path=['testdocument'], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'foo,fr,za'})['result'])
- toolkit._default_langs = ['foo']
+ i18n._default_langs = ['foo']
fallback_lang = sorted(['ru', 'es', 'en'])[0]
self.assertEqual(
{'localized_prop': 'value_%s' % fallback_lang},
- self.call('GET', path=['testdocument', guid], accept_language=['fr'], reply=['localized_prop']))
+ this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'fr'}))
self.assertEqual(
'value_%s' % fallback_lang,
- self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['fr', 'za']))
+ this.call(method='GET', path=['testdocument', guid, 'localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'fr,za'}))
self.assertEqual(
[{'localized_prop': 'value_%s' % fallback_lang}],
- self.call('GET', path=['testdocument'], accept_language=['foo', 'fr', 'za'], reply=['localized_prop'])['result'])
+ this.call(method='GET', path=['testdocument'], reply=['localized_prop'],
+ environ={'HTTP_ACCEPT_LANGUAGE': 'foo,fr,za'})['result'])
def test_OpenByModuleName(self):
self.touch(
@@ -543,9 +713,9 @@ class RoutesTest(tests.Test):
)
sys.path.insert(0, '.')
- volume = db.Volume('.', ['foo.bar'], lambda event: None)
- assert exists('bar/index')
+ volume = db.Volume('.', ['foo.bar'])
volume['bar'].find()
+ assert exists('bar/index')
volume.close()
def test_Command_GetBlobSetByUrl(self):
@@ -556,21 +726,25 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
- self.call('PUT', path=['testdocument', guid, 'blob'], url='http://sugarlabs.org')
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content={
+ 'digest': 'digest',
+ 'url': 'http://sugarlabs.org',
+ }, content_type='application/json')
self.assertEqual(
'http://sugarlabs.org',
- self.call('GET', path=['testdocument', guid, 'blob'])['url'])
+ this.call(method='GET', path=['testdocument', guid, 'blob'])['url'])
def test_on_create(self):
@@ -580,24 +754,25 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
ts = int(time.time())
- guid = self.call('POST', path=['testdocument'], content={})
- assert self.volume['testdocument'].get(guid)['ctime'] in range(ts - 1, ts + 1)
- assert self.volume['testdocument'].get(guid)['mtime'] in range(ts - 1, ts + 1)
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ assert volume['testdocument'].get(guid)['ctime'] in range(ts - 1, ts + 1)
+ assert volume['testdocument'].get(guid)['mtime'] in range(ts - 1, ts + 1)
def test_on_create_Override(self):
class Routes(db.Routes):
- def on_create(self, request, props, event):
+ def on_create(self, request, props):
props['prop'] = 'overriden'
- db.Routes.on_create(self, request, props, event)
+ db.Routes.on_create(self, request, props)
class TestDocument(db.Resource):
@@ -605,17 +780,18 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(Routes(volume))
- guid = self.call('POST', ['testdocument'], content={'prop': 'foo'}, routes=Routes)
- self.assertEqual('overriden', self.volume['testdocument'].get(guid)['prop'])
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': 'foo'}, routes=Routes)
+ self.assertEqual('overriden', volume['testdocument'].get(guid)['prop'])
- self.call('PUT', ['testdocument', guid], content={'prop': 'bar'}, routes=Routes)
- self.assertEqual('bar', self.volume['testdocument'].get(guid)['prop'])
+ this.call(method='PUT', path=['testdocument', guid], content={'prop': 'bar'}, routes=Routes)
+ self.assertEqual('bar', volume['testdocument'].get(guid)['prop'])
def test_on_update(self):
@@ -625,26 +801,28 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
- prev_mtime = self.volume['testdocument'].get(guid)['mtime']
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ prev_mtime = volume['testdocument'].get(guid)['mtime']
time.sleep(1)
- self.call('PUT', path=['testdocument', guid], content={'prop': 'probe'})
- assert self.volume['testdocument'].get(guid)['mtime'] - prev_mtime >= 1
+ this.call(method='PUT', path=['testdocument', guid], content={'prop': 'probe'})
+ assert volume['testdocument'].get(guid)['mtime'] - prev_mtime >= 1
def test_on_update_Override(self):
class Routes(db.Routes):
- def on_update(self, request, props, event):
+ def on_update(self, request, props):
props['prop'] = 'overriden'
- db.Routes.on_update(self, request, props, event)
+ db.Routes.on_update(self, request, props)
class TestDocument(db.Resource):
@@ -652,17 +830,18 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(Routes(volume))
- guid = self.call('POST', ['testdocument'], content={'prop': 'foo'}, routes=Routes)
- self.assertEqual('foo', self.volume['testdocument'].get(guid)['prop'])
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': 'foo'}, routes=Routes)
+ self.assertEqual('foo', volume['testdocument'].get(guid)['prop'])
- self.call('PUT', ['testdocument', guid], content={'prop': 'bar'}, routes=Routes)
- self.assertEqual('overriden', self.volume['testdocument'].get(guid)['prop'])
+ this.call(method='PUT', path=['testdocument', guid], content={'prop': 'bar'}, routes=Routes)
+ self.assertEqual('overriden', volume['testdocument'].get(guid)['prop'])
def __test_DoNotPassGuidsForCreate(self):
@@ -672,13 +851,15 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.indexed_property(prefix='L', localized=True, default='')
+ @db.indexed_property(db.Localized, prefix='L', default={})
def localized_prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'guid': 'foo'})
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'guid': 'foo'})
+ guid = this.call(method='POST', path=['testdocument'], content={})
assert guid
def test_seqno(self):
@@ -689,7 +870,8 @@ class RoutesTest(tests.Test):
class Document2(db.Resource):
pass
- volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [Document1, Document2])
+ router = Router(db.Routes(volume))
assert not exists('seqno')
self.assertEqual(0, volume.seqno.value)
@@ -706,8 +888,8 @@ class RoutesTest(tests.Test):
self.assertEqual(4, volume.seqno.value)
assert not exists('seqno')
volume.seqno.commit()
- assert exists('seqno')
- volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: None)
+ assert exists('db.seqno')
+ volume = db.Volume(tests.tmpdir, [Document1, Document2])
self.assertEqual(4, volume.seqno.value)
def test_Events(self):
@@ -726,7 +908,7 @@ class RoutesTest(tests.Test):
def prop(self, value):
pass
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, value):
return value
@@ -739,13 +921,15 @@ class RoutesTest(tests.Test):
)
events = []
- volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: events.append(event))
+ this.broadcast = lambda x: events.append(x)
+ volume = db.Volume(tests.tmpdir, [Document1, Document2])
+ volume['document1']
+ volume['document2']
coroutine.sleep(.1)
mtime = int(os.stat('document1/index/mtime').st_mtime)
self.assertEqual([
{'event': 'commit', 'resource': 'document1', 'mtime': mtime},
- {'event': 'populate', 'resource': 'document1', 'mtime': mtime},
],
events)
del events[:]
@@ -794,43 +978,45 @@ class RoutesTest(tests.Test):
def prop(self, value):
pass
- @db.blob_property(acl=ACL.READ)
+ @db.stored_property(db.Blob, acl=ACL.READ)
def blob(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={})
- self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'prop': 'value'})
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'prop': 'value'})
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'blob': 'value'})
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'prop'], content='value')
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'blob'], content='value')
+ self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'prop': 'value'})
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'prop': 'value'})
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'blob': 'value'})
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'prop'], content='value')
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'blob'], content='value')
def test_BlobsWritePermissions(self):
class TestDocument(db.Resource):
- @db.blob_property(acl=ACL.CREATE | ACL.WRITE)
+ @db.stored_property(db.Blob, acl=ACL.CREATE | ACL.WRITE)
def blob1(self, value):
return value
- @db.blob_property(acl=ACL.CREATE)
+ @db.stored_property(db.Blob, acl=ACL.CREATE)
def blob2(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- guid = self.call('POST', path=['testdocument'], content={})
- self.call('PUT', path=['testdocument', guid], content={'blob1': 'value1', 'blob2': 'value2'})
- self.call('PUT', path=['testdocument', guid], content={'blob1': 'value1'})
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'blob2': 'value2_'})
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ this.call(method='PUT', path=['testdocument', guid], content={'blob1': 'value1', 'blob2': 'value2'})
+ this.call(method='PUT', path=['testdocument', guid], content={'blob1': 'value1'})
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'blob2': 'value2_'})
- guid = self.call('POST', path=['testdocument'], content={})
- self.call('PUT', path=['testdocument', guid, 'blob1'], content='value1')
- self.call('PUT', path=['testdocument', guid, 'blob2'], content='value2')
- self.call('PUT', path=['testdocument', guid, 'blob1'], content='value1_')
- self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'blob2'], content='value2_')
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ this.call(method='PUT', path=['testdocument', guid, 'blob1'], content='value1')
+ this.call(method='PUT', path=['testdocument', guid, 'blob2'], content='value2')
+ this.call(method='PUT', path=['testdocument', guid, 'blob1'], content='value1_')
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'blob2'], content='value2_')
def test_properties_OverrideGet(self):
@@ -844,30 +1030,32 @@ class RoutesTest(tests.Test):
def prop2(self, value):
return -1
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob(self, meta):
meta['blob'] = 'new-blob'
return meta
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={})
self.touch(('new-blob', 'new-blob'))
- self.call('PUT', path=['testdocument', guid, 'blob'], content='old-blob')
+ this.call(method='PUT', path=['testdocument', guid, 'blob'], content='old-blob')
self.assertEqual(
'new-blob',
- self.call('GET', path=['testdocument', guid, 'blob'])['blob'])
+ this.call(method='GET', path=['testdocument', guid, 'blob'])['blob'])
self.assertEqual(
'1',
- self.call('GET', path=['testdocument', guid, 'prop1']))
+ this.call(method='GET', path=['testdocument', guid, 'prop1']))
self.assertEqual(
-1,
- self.call('GET', path=['testdocument', guid, 'prop2']))
+ this.call(method='GET', path=['testdocument', guid, 'prop2']))
self.assertEqual(
{'prop1': '1', 'prop2': -1},
- self.call('GET', path=['testdocument', guid], reply=['prop1', 'prop2']))
+ this.call(method='GET', path=['testdocument', guid], reply=['prop1', 'prop2']))
- def test_properties_OverrideSet(self):
+ def test_properties_OverrideSetter(self):
class TestDocument(db.Resource):
@@ -879,53 +1067,47 @@ class RoutesTest(tests.Test):
def prop(self, value):
return '_%s' % value
- @db.blob_property()
- def blob1(self, meta):
- return meta
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={})
- @blob1.setter
- def blob1(self, value):
- return Blob({'url': file(value['blob']).read()})
+ self.assertEqual('_1', this.call(method='GET', path=['testdocument', guid, 'prop']))
- @db.blob_property()
- def blob2(self, meta):
- return meta
+ this.call(method='PUT', path=['testdocument', guid, 'prop'], content='2')
+ self.assertEqual('_2', this.call(method='GET', path=['testdocument', guid, 'prop']))
- @blob2.setter
- def blob2(self, value):
- with toolkit.NamedTemporaryFile(delete=False) as f:
- f.write(' %s ' % file(value['blob']).read())
- value['blob'] = f.name
- return value
+ this.call(method='PUT', path=['testdocument', guid], content={'prop': 3})
+ self.assertEqual('_3', this.call(method='GET', path=['testdocument', guid, 'prop']))
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={})
+ def test_properties_AccessToOldValuesInSetters(self):
+
+ class TestDocument(db.Resource):
- self.assertEqual('_1', self.call('GET', path=['testdocument', guid, 'prop']))
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1'])
+ @db.stored_property(db.Numeric)
+ def prop(self, value):
+ return value
- self.call('PUT', path=['testdocument', guid, 'prop'], content='2')
- self.assertEqual('_2', self.call('GET', path=['testdocument', guid, 'prop']))
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1'])
+ @prop.setter
+ def prop(self, value):
+ return value + (self['prop'] or 0)
- self.call('PUT', path=['testdocument', guid], content={'prop': 3})
- self.assertEqual('_3', self.call('GET', path=['testdocument', guid, 'prop']))
- self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1'])
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.call('PUT', path=['testdocument', guid, 'blob1'], content='blob_url')
- self.assertEqual('blob_url', self.call('GET', path=['testdocument', guid, 'blob1'])['url'])
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': 1})
+ self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop']))
- guid = self.call('POST', path=['testdocument'], content={'blob2': 'foo'})
- self.assertEqual(' foo ', file(self.call('GET', path=['testdocument', guid, 'blob2'])['blob']).read())
+ this.call(method='PUT', path=['testdocument', guid, 'prop'], content='2')
+ self.assertEqual(3, this.call(method='GET', path=['testdocument', guid, 'prop']))
- self.call('PUT', path=['testdocument', guid, 'blob2'], content='bar')
- self.assertEqual(' bar ', file(self.call('GET', path=['testdocument', guid, 'blob2'])['blob']).read())
+ this.call(method='PUT', path=['testdocument', guid], content={'prop': 3})
+ self.assertEqual(6, this.call(method='GET', path=['testdocument', guid, 'prop']))
def test_properties_CallSettersAtTheEnd(self):
class TestDocument(db.Resource):
- @db.indexed_property(slot=1, typecast=int)
+ @db.indexed_property(db.Numeric, slot=1)
def prop1(self, value):
return value
@@ -933,7 +1115,7 @@ class RoutesTest(tests.Test):
def prop1(self, value):
return self['prop3'] + value
- @db.indexed_property(slot=2, typecast=int)
+ @db.indexed_property(db.Numeric, slot=2)
def prop2(self, value):
return value
@@ -941,107 +1123,40 @@ class RoutesTest(tests.Test):
def prop2(self, value):
return self['prop3'] - value
- @db.indexed_property(slot=3, typecast=int)
+ @db.indexed_property(db.Numeric, slot=3)
def prop3(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'prop1': 1, 'prop2': 2, 'prop3': 3})
- self.assertEqual(4, self.call('GET', path=['testdocument', guid, 'prop1']))
- self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop2']))
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+
+ guid = this.call(method='POST', path=['testdocument'], content={'prop1': 1, 'prop2': 2, 'prop3': 3})
+ self.assertEqual(4, this.call(method='GET', path=['testdocument', guid, 'prop1']))
+ self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop2']))
def test_properties_PopulateRequiredPropsInSetters(self):
class TestDocument(db.Resource):
- @db.indexed_property(slot=1, typecast=int)
+ @db.indexed_property(db.Numeric, slot=1)
def prop1(self, value):
return value
@prop1.setter
def prop1(self, value):
- self['prop2'] = value + 1
+ self.post('prop2', value + 1)
return value
- @db.indexed_property(slot=2, typecast=int)
+ @db.indexed_property(db.Numeric, slot=2)
def prop2(self, value):
return value
- @db.blob_property()
- def prop3(self, value):
- return value
-
- @prop3.setter
- def prop3(self, value):
- self['prop1'] = -1
- self['prop2'] = -2
- return value
-
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'prop1': 1})
- self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop1']))
- self.assertEqual(2, self.call('GET', path=['testdocument', guid, 'prop2']))
-
- def test_properties_PopulateRequiredPropsInBlobSetter(self):
-
- class TestDocument(db.Resource):
-
- @db.blob_property()
- def blob(self, value):
- return value
-
- @blob.setter
- def blob(self, value):
- self['prop1'] = 1
- self['prop2'] = 2
- return value
-
- @db.indexed_property(slot=1, typecast=int)
- def prop1(self, value):
- return value
-
- @db.indexed_property(slot=2, typecast=int)
- def prop2(self, value):
- return value
-
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'blob': ''})
- self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop1']))
- self.assertEqual(2, self.call('GET', path=['testdocument', guid, 'prop2']))
-
- def __test_SubCall(self):
-
- class TestDocument(db.Resource):
-
- @db.blob_property(mime_type='application/json')
- def blob(self, value):
- return value
-
- @blob.setter
- def blob(self, value):
- blob = file(value['blob']).read()
- if '!' not in blob:
- meta = self.meta('blob')
- if meta:
- blob = file(meta['blob']).read() + blob
- with toolkit.NamedTemporaryFile(delete=False) as f:
- f.write(blob)
- value['blob'] = f.name
- coroutine.spawn(self.post, blob)
- return value
-
- def post(self, value):
- self.request.call('PUT', path=['testdocument', self.guid, 'blob'], content=value + '!')
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
-
- guid = self.call('POST', path=['testdocument'], content={'blob': '0'})
- coroutine.dispatch()
- self.assertEqual('0!', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
-
- self.call('PUT', path=['testdocument', guid, 'blob'], content='1')
- coroutine.dispatch()
- self.assertEqual('0!1!', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read())
+ guid = this.call(method='POST', path=['testdocument'], content={'prop1': 1})
+ self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop1']))
+ self.assertEqual(2, this.call(method='GET', path=['testdocument', guid, 'prop2']))
def test_Group(self):
@@ -1051,15 +1166,16 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.call('POST', path=['testdocument'], content={'prop': 1})
- self.call('POST', path=['testdocument'], content={'prop': 2})
- self.call('POST', path=['testdocument'], content={'prop': 1})
+ this.call(method='POST', path=['testdocument'], content={'prop': 1})
+ this.call(method='POST', path=['testdocument'], content={'prop': 2})
+ this.call(method='POST', path=['testdocument'], content={'prop': 1})
self.assertEqual(
sorted([{'prop': 1}, {'prop': 2}]),
- sorted(self.call('GET', path=['testdocument'], reply='prop', group_by='prop')['result']))
+ sorted(this.call(method='GET', path=['testdocument'], reply='prop', group_by='prop')['result']))
def test_CallSetterEvenIfThereIsNoCreatePermissions(self):
@@ -1073,12 +1189,13 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value + 1
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
- self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'prop': 1})
+ self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'prop': 1})
- guid = self.call('POST', path=['testdocument'], content={})
- self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop']))
+ guid = this.call(method='POST', path=['testdocument'], content={})
+ self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop']))
def test_ReturnDefualtsForMissedProps(self):
@@ -1088,57 +1205,34 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', path=['testdocument'], content={'prop': 'set'})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content={'prop': 'set'})
self.assertEqual(
[{'prop': 'set'}],
- self.call('GET', path=['testdocument'], reply='prop')['result'])
+ this.call(method='GET', path=['testdocument'], reply='prop')['result'])
self.assertEqual(
{'prop': 'set'},
- self.call('GET', path=['testdocument', guid], reply='prop'))
+ this.call(method='GET', path=['testdocument', guid], reply='prop'))
self.assertEqual(
'set',
- self.call('GET', path=['testdocument', guid, 'prop']))
+ this.call(method='GET', path=['testdocument', guid, 'prop']))
os.unlink('testdocument/%s/%s/prop' % (guid[:2], guid))
self.assertEqual(
[{'prop': 'default'}],
- self.call('GET', path=['testdocument'], reply='prop')['result'])
+ this.call(method='GET', path=['testdocument'], reply='prop')['result'])
self.assertEqual(
{'prop': 'default'},
- self.call('GET', path=['testdocument', guid], reply='prop'))
+ this.call(method='GET', path=['testdocument', guid], reply='prop'))
self.assertEqual(
'default',
- self.call('GET', path=['testdocument', guid, 'prop']))
-
- def test_PopulateNonDefualtPropsInSetters(self):
-
- class TestDocument(db.Resource):
-
- @db.indexed_property(slot=1)
- def prop1(self, value):
- return value
-
- @db.indexed_property(slot=2, default='default')
- def prop2(self, value):
- return all
-
- @prop2.setter
- def prop2(self, value):
- if value != 'default':
- self['prop1'] = value
- return value
-
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
-
- self.assertRaises(RuntimeError, self.call, 'POST', path=['testdocument'], content={})
-
- guid = self.call('POST', path=['testdocument'], content={'prop2': 'value2'})
- self.assertEqual('value2', self.call('GET', path=['testdocument', guid, 'prop1']))
+ this.call(method='GET', path=['testdocument', guid, 'prop']))
def test_prop_meta(self):
+ files.update('url', {'url': 'http://new', 'foo': 'bar', 'size': 100})
class TestDocument(db.Resource):
@@ -1146,44 +1240,55 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob1(self, value):
return value
- @db.blob_property()
+ @db.stored_property(db.Blob)
def blob2(self, value):
return value
@blob2.setter
def blob2(self, value):
- return {'url': 'http://new', 'foo': 'bar', 'blob_size': 100}
+ return 'url'
- self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None)
- guid = self.call('POST', ['testdocument'], content = {'prop': 'prop', 'blob1': 'blob', 'blob2': ''})
+ volume = db.Volume(tests.tmpdir, [TestDocument])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['testdocument'], content = {'prop': 'prop', 'blob1': 'blob', 'blob2': ''})
- assert self.call('HEAD', ['testdocument', guid, 'prop']) is None
- meta = self.volume['testdocument'].get(guid).meta('prop')
+ response = Response()
+ assert this.call(response=response,
+ method='HEAD', path=['testdocument', guid, 'prop']) is None
+ meta = volume['testdocument'].get(guid).meta('prop')
meta.pop('value')
- self.assertEqual(meta, self.response.meta)
- self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified)
-
- assert self.call('HEAD', ['testdocument', guid, 'blob1'], host='localhost') is None
- meta = self.volume['testdocument'].get(guid).meta('blob1')
- meta.pop('blob')
- self.assertEqual(meta, self.response.meta)
- self.assertEqual(len('blob'), self.response.content_length)
- self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified)
-
- assert self.call('HEAD', ['testdocument', guid, 'blob2']) is None
- meta = self.volume['testdocument'].get(guid).meta('blob2')
- self.assertEqual(meta, self.response.meta)
- self.assertEqual(100, self.response.content_length)
- self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified)
-
- assert self.call('GET', ['testdocument', guid, 'blob2']) is not None
- meta = self.volume['testdocument'].get(guid).meta('blob2')
- self.assertEqual(meta, self.response.meta)
- self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified)
+ self.assertEqual(meta, response.meta)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
+
+ response = Response()
+ assert this.call(response=response,
+ method='HEAD', path=['testdocument', guid, 'blob1'], environ={'HTTP_HOST': 'localhost'}) is None
+ meta = volume['testdocument'].get(guid).meta('blob1')
+ meta.pop('value')
+ self.assertEqual(meta, response.meta)
+ self.assertEqual(len('blob'), response.content_length)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
+
+ response = Response()
+ assert this.call(response=response,
+ method='HEAD', path=['testdocument', guid, 'blob2']) is None
+ meta = volume['testdocument'].get(guid).meta('blob2')
+ meta.pop('value')
+ self.assertEqual(meta, response.meta)
+ self.assertEqual(100, response.content_length)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
+
+ response = Response()
+ assert this.call(response=response,
+ method='GET', path=['testdocument', guid, 'blob2']) is not None
+ meta = volume['testdocument'].get(guid).meta('blob2')
+ meta.pop('value')
+ self.assertEqual(meta, response.meta)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
def test_DefaultAuthor(self):
@@ -1196,25 +1301,26 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- guid = self.call('POST', ['document'], content={}, principal='user')
+ guid = this.call(method='POST', path=['document'], content={}, principal='user')
self.assertEqual(
[{'name': 'user', 'role': 2}],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual(
{'user': {'role': 2, 'order': 0}},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'})
+ volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'})
- guid = self.call('POST', ['document'], content={}, principal='user')
+ guid = this.call(method='POST', path=['document'], content={}, principal='user')
self.assertEqual(
[{'guid': 'user', 'name': 'User', 'role': 3}],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual(
{'user': {'name': 'User', 'role': 3, 'order': 0}},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
def test_FindByAuthor(self):
@@ -1227,36 +1333,37 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'UserName1'})
- self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User Name2'})
- self.volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User Name 3'})
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'UserName1'})
+ volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User Name2'})
+ volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User Name 3'})
- guid1 = self.call('POST', ['document'], content={}, principal='user1')
- guid2 = self.call('POST', ['document'], content={}, principal='user2')
- guid3 = self.call('POST', ['document'], content={}, principal='user3')
+ guid1 = this.call(method='POST', path=['document'], content={}, principal='user1')
+ guid2 = this.call(method='POST', path=['document'], content={}, principal='user2')
+ guid3 = this.call(method='POST', path=['document'], content={}, principal='user3')
self.assertEqual(sorted([
{'guid': guid1},
]),
- self.call('GET', ['document'], author='UserName1')['result'])
+ this.call(method='GET', path=['document'], author='UserName1')['result'])
self.assertEqual(sorted([
{'guid': guid1},
]),
- sorted(self.call('GET', ['document'], query='author:UserName')['result']))
+ sorted(this.call(method='GET', path=['document'], query='author:UserName')['result']))
self.assertEqual(sorted([
{'guid': guid1},
{'guid': guid2},
{'guid': guid3},
]),
- sorted(self.call('GET', ['document'], query='author:User')['result']))
+ sorted(this.call(method='GET', path=['document'], query='author:User')['result']))
self.assertEqual(sorted([
{'guid': guid2},
{'guid': guid3},
]),
- sorted(self.call('GET', ['document'], query='author:Name')['result']))
+ sorted(this.call(method='GET', path=['document'], query='author:Name')['result']))
def test_PreserveAuthorsOrder(self):
@@ -1269,99 +1376,77 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
- self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
- self.volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User3'})
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
+ volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
+ volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User3'})
- guid = self.call('POST', ['document'], content={}, principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0)
- self.call('PUT', ['document', guid], cmd='useradd', user='user3', role=0)
+ guid = this.call(method='POST', path=['document'], content={}, principal='user1')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user3', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 1},
{'guid': 'user3', 'name': 'User3', 'role': 1},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 1, 'order': 1},
'user3': {'name': 'User3', 'role': 1, 'order': 2},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='userdel', user='user2', principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user1')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user3', 'name': 'User3', 'role': 1},
{'guid': 'user2', 'name': 'User2', 'role': 1},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user3': {'name': 'User3', 'role': 1, 'order': 2},
'user2': {'name': 'User2', 'role': 1, 'order': 3},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='userdel', user='user2', principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user1')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user3', 'name': 'User3', 'role': 1},
{'guid': 'user2', 'name': 'User2', 'role': 1},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user3': {'name': 'User3', 'role': 1, 'order': 2},
'user2': {'name': 'User2', 'role': 1, 'order': 3},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='userdel', user='user3', principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='user3', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='userdel', user='user3', principal='user1')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user3', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 1},
{'guid': 'user3', 'name': 'User3', 'role': 1},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 1, 'order': 3},
'user3': {'name': 'User3', 'role': 1, 'order': 4},
},
- self.volume['document'].get(guid)['author'])
-
- def test_CopyAthors(self):
-
- class User(db.Resource):
-
- @db.indexed_property(slot=1)
- def name(self, value):
- return value
-
- class Document(db.Resource):
- pass
-
- self.volume = db.Volume('db', [User, Document])
- self.volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'})
-
- guid1 = self.call('POST', ['document'], content={}, principal='user')
- self.assertEqual({'user': {'name': 'User', 'role': 3, 'order': 0}}, self.volume['document'].get(guid1)['author'])
- author = self.call('GET', ['document', guid1, 'author'])
- self.assertEqual([{'guid': 'user', 'role': 3, 'name': 'User'}], author)
-
- guid2 = self.volume['document'].create({'author': author}, setters=True)
- author = self.call('GET', ['document', guid1, 'author'])
- self.assertEqual({'user': {'name': 'User', 'role': 3, 'order': 0}}, self.volume['document'].get(guid2)['author'])
+ volume['document'].get(guid)['author'])
def test_AddUser(self):
@@ -1374,62 +1459,63 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
- self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
+ volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
- guid = self.call('POST', ['document'], content={}, principal='user1')
+ guid = this.call(method='POST', path=['document'], content={}, principal='user1')
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=2)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=2)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 3},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 3, 'order': 1},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='useradd', user='User3', role=3)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='User3', role=3)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 3},
{'name': 'User3', 'role': 2},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 3, 'order': 1},
'User3': {'role': 2, 'order': 2},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='useradd', user='User4', role=4)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='User4', role=4)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 3},
{'name': 'User3', 'role': 2},
{'name': 'User4', 'role': 0},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 3, 'order': 1},
'User3': {'role': 2, 'order': 2},
'User4': {'role': 0, 'order': 3},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
def test_UpdateAuthor(self):
@@ -1442,46 +1528,47 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
- guid = self.call('POST', ['document'], content={}, principal='user1')
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
+ guid = this.call(method='POST', path=['document'], content={}, principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='User2', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='User2', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'name': 'User2', 'role': 0},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'User2': {'role': 0, 'order': 1},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='useradd', user='user1', role=0)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user1', role=0)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 1},
{'name': 'User2', 'role': 0},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 1, 'order': 0},
'User2': {'role': 0, 'order': 1},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='useradd', user='User2', role=2)
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='User2', role=2)
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 1},
{'name': 'User2', 'role': 2},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 1, 'order': 0},
'User2': {'role': 2, 'order': 1},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
def test_DelUser(self):
@@ -1494,150 +1581,73 @@ class RoutesTest(tests.Test):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [User, Document])
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
- self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
- self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
- guid = self.call('POST', ['document'], content={}, principal='user1')
- self.call('PUT', ['document', guid], cmd='useradd', user='user2')
- self.call('PUT', ['document', guid], cmd='useradd', user='User3')
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
+ volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
+ guid = this.call(method='POST', path=['document'], content={}, principal='user1')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2')
+ this.call(method='PUT', path=['document', guid], cmd='useradd', user='User3')
self.assertEqual([
{'guid': 'user1', 'name': 'User1', 'role': 3},
{'guid': 'user2', 'name': 'User2', 'role': 1},
{'name': 'User3', 'role': 0},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user1': {'name': 'User1', 'role': 3, 'order': 0},
'user2': {'name': 'User2', 'role': 1, 'order': 1},
'User3': {'role': 0, 'order': 2},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
# Do not remove yourself
- self.assertRaises(RuntimeError, self.call, 'PUT', ['document', guid], cmd='userdel', user='user1', principal='user1')
- self.assertRaises(RuntimeError, self.call, 'PUT', ['document', guid], cmd='userdel', user='user2', principal='user2')
+ self.assertRaises(RuntimeError, this.call, method='PUT', path=['document', guid], cmd='userdel', user='user1', principal='user1')
+ self.assertRaises(RuntimeError, this.call, method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user2')
- self.call('PUT', ['document', guid], cmd='userdel', user='user1', principal='user2')
+ this.call(method='PUT', path=['document', guid], cmd='userdel', user='user1', principal='user2')
self.assertEqual([
{'guid': 'user2', 'name': 'User2', 'role': 1},
{'name': 'User3', 'role': 0},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user2': {'name': 'User2', 'role': 1, 'order': 1},
'User3': {'role': 0, 'order': 2},
},
- self.volume['document'].get(guid)['author'])
+ volume['document'].get(guid)['author'])
- self.call('PUT', ['document', guid], cmd='userdel', user='User3', principal='user2')
+ this.call(method='PUT', path=['document', guid], cmd='userdel', user='User3', principal='user2')
self.assertEqual([
{'guid': 'user2', 'name': 'User2', 'role': 1},
],
- self.call('GET', ['document', guid, 'author']))
+ this.call(method='GET', path=['document', guid, 'author']))
self.assertEqual({
'user2': {'name': 'User2', 'role': 1, 'order': 1},
},
- self.volume['document'].get(guid)['author'])
-
- def test_typecast_prop_value(self):
- prop = Property('prop', typecast=int)
- self.assertEqual(1, _typecast_prop_value(prop.typecast, 1))
- self.assertEqual(1, _typecast_prop_value(prop.typecast, 1.1))
- self.assertEqual(1, _typecast_prop_value(prop.typecast, '1'))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '1.0')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
-
- prop = Property('prop', typecast=float)
- self.assertEqual(1.0, _typecast_prop_value(prop.typecast, 1))
- self.assertEqual(1.1, _typecast_prop_value(prop.typecast, 1.1))
- self.assertEqual(1.0, _typecast_prop_value(prop.typecast, '1'))
- self.assertEqual(1.1, _typecast_prop_value(prop.typecast, '1.1'))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
-
- prop = Property('prop', typecast=bool)
- self.assertEqual(False, _typecast_prop_value(prop.typecast, 0))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, 1))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, 1.1))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, '1'))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, 'false'))
- self.assertEqual(False, _typecast_prop_value(prop.typecast, ''))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
-
- prop = Property('prop', typecast=[int])
- self.assertEqual((1,), _typecast_prop_value(prop.typecast, 1))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '')
- self.assertEqual((), _typecast_prop_value(prop.typecast, []))
- self.assertEqual((123,), _typecast_prop_value(prop.typecast, '123'))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 'a')
- self.assertEqual((123, 4, 5), _typecast_prop_value(prop.typecast, ['123', 4, 5.6]))
-
- prop = Property('prop', typecast=[1, 2])
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 0)
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 'A')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '3')
- self.assertEqual(1, _typecast_prop_value(prop.typecast, 1))
- self.assertEqual(2, _typecast_prop_value(prop.typecast, 2))
- self.assertEqual(1, _typecast_prop_value(prop.typecast, '1'))
-
- prop = Property('prop', typecast=[str])
- self.assertEqual(('',), _typecast_prop_value(prop.typecast, ''))
- self.assertEqual(('',), _typecast_prop_value(prop.typecast, ['']))
- self.assertEqual((), _typecast_prop_value(prop.typecast, []))
-
- prop = Property('prop', typecast=[])
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None)
- self.assertEqual(('',), _typecast_prop_value(prop.typecast, ''))
- self.assertEqual(('',), _typecast_prop_value(prop.typecast, ['']))
- self.assertEqual((), _typecast_prop_value(prop.typecast, []))
- self.assertEqual(('0',), _typecast_prop_value(prop.typecast, 0))
- self.assertEqual(('',), _typecast_prop_value(prop.typecast, ''))
- self.assertEqual(('foo',), _typecast_prop_value(prop.typecast, 'foo'))
-
- prop = Property('prop', typecast=[['A', 'B', 'C']])
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '')
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, [''])
- self.assertEqual((), _typecast_prop_value(prop.typecast, []))
- self.assertEqual(('A', 'B', 'C'), _typecast_prop_value(prop.typecast, ['A', 'B', 'C']))
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, ['a'])
- self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, ['A', 'x'])
-
- prop = Property('prop', typecast=bool)
- self.assertEqual(True, _typecast_prop_value(prop.typecast, True))
- self.assertEqual(False, _typecast_prop_value(prop.typecast, False))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, 'False'))
- self.assertEqual(True, _typecast_prop_value(prop.typecast, '0'))
-
- prop = Property('prop', typecast=[['A', 'B', 'C']])
- self.assertEqual(('A', 'B', 'C'), _typecast_prop_value(prop.typecast, ['A', 'B', 'C']))
-
- prop = Property('prop', typecast=lambda x: x + 1)
- self.assertEqual(1, _typecast_prop_value(prop.typecast, 0))
+ volume['document'].get(guid)['author'])
def test_DefaultOrder(self):
class Document(db.Resource):
pass
- self.volume = db.Volume('db', [Document])
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
- self.volume['document'].create({'guid': '3', 'ctime': 3})
- self.volume['document'].create({'guid': '2', 'ctime': 2})
- self.volume['document'].create({'guid': '1', 'ctime': 1})
+ volume['document'].create({'guid': '3', 'ctime': 3})
+ volume['document'].create({'guid': '2', 'ctime': 2})
+ volume['document'].create({'guid': '1', 'ctime': 1})
self.assertEqual([
{'guid': '1'},
{'guid': '2'},
{'guid': '3'},
],
- self.call('GET', ['document'])['result'])
+ this.call(method='GET', path=['document'])['result'])
- def test_SetDefaultPropsOnNoneValues(self):
+ def test_DefaultsOnNonePostValues(self):
class Document(db.Resource):
@@ -1645,10 +1655,11 @@ class RoutesTest(tests.Test):
def prop(self, value):
return value
- self.volume = db.Volume('db', [Document])
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
- guid = self.call('POST', ['document'], content={'prop': None})
- self.assertEqual('default', self.volume['document'].get(guid).meta('prop')['value'])
+ guid = this.call(method='POST', path=['document'], content={'prop': None})
+ self.assertEqual('default', this.call(method='GET', path=['document', guid, 'prop']))
def test_InsertAggprops(self):
@@ -1658,117 +1669,316 @@ class RoutesTest(tests.Test):
def prop1(self, value):
return value
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.WRITE)
- def prop2(self, value):
- return value
-
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT)
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT)
def prop3(self, value):
return value
events = []
- self.volume = db.Volume('db', [Document], lambda event: events.append(event))
- guid = self.call('POST', ['document'], content={})
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ this.broadcast = lambda x: events.append(x)
+ guid = this.call(method='POST', path=['document'], content={})
- self.assertRaises(http.NotFound, self.call, 'POST', ['document', 'foo', 'bar'], content={})
- self.assertRaises(http.NotFound, self.call, 'POST', ['document', guid, 'bar'], content={})
- self.assertRaises(http.BadRequest, self.call, 'POST', ['document', guid, 'prop1'], content={})
- self.assertRaises(http.Forbidden, self.call, 'POST', ['document', guid, 'prop2'], content={})
+ self.assertRaises(http.NotFound, this.call, method='POST', path=['document', 'foo', 'bar'], content={})
+ self.assertRaises(http.NotFound, this.call, method='POST', path=['document', guid, 'bar'], content={})
+ self.assertRaises(http.BadRequest, this.call, method='POST', path=['document', guid, 'prop1'], content={})
del events[:]
self.override(time, 'time', lambda: 0)
self.override(toolkit, 'uuid', lambda: '0')
- self.assertEqual('0', self.call('POST', ['document', guid, 'prop3'], content={}))
+ self.assertEqual('0', this.call(method='POST', path=['document', guid, 'prop3'], content=0))
self.assertEqual({
- '0': {'seqno': 2},
+ '0': {'seqno': 2, 'value': 0},
},
- self.volume['document'].get(guid)['prop3'])
+ volume['document'].get(guid)['prop3'])
self.assertEqual([
{'event': 'update', 'resource': 'document', 'guid': guid},
],
events)
self.override(time, 'time', lambda: 1)
- self.assertEqual('1', self.call('POST', ['document', guid, 'prop3'], content={'guid': '1', 'foo': 'bar'}))
+ self.override(toolkit, 'uuid', lambda: '1')
+ self.assertEqual('1', this.call(method='POST', path=['document', guid, 'prop3'], content={'foo': 'bar'}))
self.assertEqual({
- '0': {'seqno': 2},
- '1': {'seqno': 3, 'foo': 'bar'},
+ '0': {'seqno': 2, 'value': 0},
+ '1': {'seqno': 3, 'value': {'foo': 'bar'}},
},
- self.volume['document'].get(guid)['prop3'])
+ volume['document'].get(guid)['prop3'])
self.override(time, 'time', lambda: 2)
self.override(toolkit, 'uuid', lambda: '2')
- self.assertEqual('2', self.call('POST', ['document', guid, 'prop3'], content={'prop': 'more'}))
+ self.assertEqual('2', this.call(method='POST', path=['document', guid, 'prop3'], content=None))
self.assertEqual({
- '0': {'seqno': 2},
- '1': {'seqno': 3, 'foo': 'bar'},
- '2': {'seqno': 4, 'prop': 'more'},
+ '0': {'seqno': 2, 'value': 0},
+ '1': {'seqno': 3, 'value': {'foo': 'bar'}},
+ '2': {'seqno': 4, 'value': None},
},
- self.volume['document'].get(guid)['prop3'])
+ volume['document'].get(guid)['prop3'])
def test_RemoveAggprops(self):
class Document(db.Resource):
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT)
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT)
def prop1(self, value):
return value
- @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT | ACL.REMOVE)
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE)
def prop2(self, value):
return value
events = []
- self.volume = db.Volume('db', [Document], lambda event: events.append(event))
- guid = self.call('POST', ['document'], content={})
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ this.broadcast = lambda x: events.append(x)
+ guid = this.call(method='POST', path=['document'], content={})
- agg_guid = self.call('POST', ['document', guid, 'prop1'], content={'probe': 'value'})
+ agg_guid = this.call(method='POST', path=['document', guid, 'prop1'], content=2)
del events[:]
self.assertEqual(
- {agg_guid: {'seqno': 2, 'probe': 'value'}},
- self.volume['document'].get(guid)['prop1'])
- self.assertRaises(http.Forbidden, self.call, 'DELETE', ['document', guid, 'prop1', agg_guid])
+ {agg_guid: {'seqno': 2, 'value': 2}},
+ volume['document'].get(guid)['prop1'])
+ self.assertRaises(http.Forbidden, this.call, method='DELETE', path=['document', guid, 'prop1', agg_guid])
self.assertEqual(
- {agg_guid: {'seqno': 2, 'probe': 'value'}},
- self.volume['document'].get(guid)['prop1'])
+ {agg_guid: {'seqno': 2, 'value': 2}},
+ volume['document'].get(guid)['prop1'])
self.assertEqual([], events)
- agg_guid = self.call('POST', ['document', guid, 'prop2'], content={'probe': 'value'})
+ agg_guid = this.call(method='POST', path=['document', guid, 'prop2'], content=3)
del events[:]
self.assertEqual(
- {agg_guid: {'seqno': 3, 'probe': 'value'}},
- self.volume['document'].get(guid)['prop2'])
- self.call('DELETE', ['document', guid, 'prop2', agg_guid])
+ {agg_guid: {'seqno': 3, 'value': 3}},
+ volume['document'].get(guid)['prop2'])
+ this.call(method='DELETE', path=['document', guid, 'prop2', agg_guid])
self.assertEqual(
{agg_guid: {'seqno': 4}},
- self.volume['document'].get(guid)['prop2'])
+ volume['document'].get(guid)['prop2'])
+ self.assertEqual([
+ {'event': 'update', 'resource': 'document', 'guid': guid},
+ ],
+ events)
+
+ def test_FailOnAbsentAggprops(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE)
+ def prop(self, value):
+ return value
+
+ events = []
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ this.broadcast = lambda x: events.append(x)
+ guid = this.call(method='POST', path=['document'], content={})
+ del events[:]
+
+ self.assertRaises(http.NotFound, this.call, method='DELETE', path=['document', guid, 'prop', 'absent'])
+ self.assertEqual([], events)
+
+ def test_UpdateAggprops(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated)
+ def prop1(self, value):
+ return value
+
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE)
+ def prop2(self, value):
+ return value
+
+ events = []
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ this.broadcast = lambda x: events.append(x)
+ guid = this.call(method='POST', path=['document'], content={})
+
+ agg_guid = this.call(method='POST', path=['document', guid, 'prop1'], content=1)
+ del events[:]
+ self.assertEqual(
+ {agg_guid: {'seqno': 2, 'value': 1}},
+ volume['document'].get(guid)['prop1'])
+ self.assertRaises(http.Forbidden, this.call, method='PUT', path=['document', guid, 'prop1', agg_guid], content=2)
+ self.assertEqual(
+ {agg_guid: {'seqno': 2, 'value': 1}},
+ volume['document'].get(guid)['prop1'])
+ self.assertEqual([], events)
+
+ agg_guid = this.call(method='POST', path=['document', guid, 'prop2'], content=2)
+ del events[:]
+ self.assertEqual(
+ {agg_guid: {'seqno': 3, 'value': 2}},
+ volume['document'].get(guid)['prop2'])
+ this.call(method='PUT', path=['document', guid, 'prop2', agg_guid], content=3)
+ self.assertEqual(
+ {agg_guid: {'seqno': 4, 'value': 3}},
+ volume['document'].get(guid)['prop2'])
+ self.assertEqual([
+ {'event': 'update', 'resource': 'document', 'guid': guid},
+ ],
+ events)
+
+ def test_PostAbsentAggpropsOnUpdate(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE)
+ def prop(self, value):
+ return value
+
+ events = []
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ this.broadcast = lambda x: events.append(x)
+ guid = this.call(method='POST', path=['document'], content={})
+ del events[:]
+
+ this.call(method='PUT', path=['document', guid, 'prop', 'absent'], content='probe')
+ self.assertEqual(
+ {'absent': {'seqno': 2, 'value': 'probe'}},
+ volume['document'].get(guid)['prop'])
self.assertEqual([
{'event': 'update', 'resource': 'document', 'guid': guid},
],
events)
- def call(self, method=None, path=None,
- accept_language=None, content=None, content_stream=None, cmd=None,
- content_type=None, host=None, request=None, routes=db.Routes, principal=None,
- **kwargs):
- if request is None:
- environ = {
- 'REQUEST_METHOD': method,
- 'PATH_INFO': '/'.join([''] + path),
- 'HTTP_ACCEPT_LANGUAGE': ','.join(accept_language or []),
- 'HTTP_HOST': host,
- 'wsgi.input': content_stream,
- }
- if content_type:
- environ['CONTENT_TYPE'] = content_type
- if content_stream is not None:
- environ['CONTENT_LENGTH'] = str(len(content_stream.getvalue()))
- request = Request(environ, cmd=cmd, content=content)
- request.update(kwargs)
- request.principal = principal
- router = Router(routes(self.volume))
- self.response = Response()
- return router._call_route(request, self.response)
+ def test_OriginalAggprops(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE)
+ def prop(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [User, Document])
+ router = Router(db.Routes(volume))
+ volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'})
+ volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'})
+
+ guid = this.call(method='POST', path=['document'], content={}, principal=tests.UID)
+ assert ACL.ORIGINAL & volume['document'][guid]['author'][tests.UID]['role']
+
+ agg_guid1 = this.call(method='POST', path=['document', guid, 'prop'], content=1, principal=tests.UID)
+ assert tests.UID2 not in volume['document'][guid]['prop'][agg_guid1]['author']
+ assert ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid1]['author'][tests.UID]['role']
+
+ agg_guid2 = this.call(method='POST', path=['document', guid, 'prop'], content=1, principal=tests.UID2)
+ assert tests.UID not in volume['document'][guid]['prop'][agg_guid2]['author']
+ assert not (ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid2]['author'][tests.UID2]['role'])
+
+ this.call(method='DELETE', path=['document', guid, 'prop', agg_guid2], principal=tests.UID2)
+ assert tests.UID not in volume['document'][guid]['prop'][agg_guid2]['author']
+ assert not (ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid2]['author'][tests.UID2]['role'])
+
+ def test_AggregatedBlobs(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated, subtype=db.Blob())
+ def blobs(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+ guid = this.call(method='POST', path=['document'], content={})
+
+ agg1 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob1')
+ self.assertEqual({
+ agg1: {'seqno': 2, 'value': str(hash('blob1'))},
+ },
+ volume['document'].get(guid)['blobs'])
+ assert files.get(str(hash('blob1')))
+
+ agg2 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob2')
+ self.assertEqual({
+ agg1: {'seqno': 2, 'value': str(hash('blob1'))},
+ agg2: {'seqno': 3, 'value': str(hash('blob2'))},
+ },
+ volume['document'].get(guid)['blobs'])
+ assert files.get(str(hash('blob2')))
+
+ this.call(method='DELETE', path=['document', guid, 'blobs', agg1])
+ self.assertEqual({
+ agg1: {'seqno': 4},
+ agg2: {'seqno': 3, 'value': str(hash('blob2'))},
+ },
+ volume['document'].get(guid)['blobs'])
+ assert files.get(str(hash('blob1'))) is None
+ assert files.get(str(hash('blob2')))
+
+ this.call(method='DELETE', path=['document', guid, 'blobs', agg2])
+ self.assertEqual({
+ agg1: {'seqno': 4},
+ agg2: {'seqno': 5},
+ },
+ volume['document'].get(guid)['blobs'])
+ assert files.get(str(hash('blob1'))) is None
+ assert files.get(str(hash('blob2'))) is None
+
+ agg3 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob3')
+ self.assertEqual({
+ agg1: {'seqno': 4},
+ agg2: {'seqno': 5},
+ agg3: {'seqno': 6, 'value': str(hash('blob3'))},
+ },
+ volume['document'].get(guid)['blobs'])
+ assert files.get(str(hash('blob1'))) is None
+ assert files.get(str(hash('blob2'))) is None
+ assert files.get(str(hash('blob3')))
+
+ def test_AggregatedSearch(self):
+
+ class Document(db.Resource):
+
+ @db.stored_property(db.Aggregated, prefix='A', full_text=True)
+ def comments(self, value):
+ return value
+
+ @db.stored_property(prefix='B', full_text=False, default='')
+ def prop(self, value):
+ return value
+
+ volume = db.Volume(tests.tmpdir, [Document])
+ router = Router(db.Routes(volume))
+
+ guid1 = this.call(method='POST', path=['document'], content={})
+ this.call(method='POST', path=['document', guid1, 'comments'], content='a')
+ this.call(method='POST', path=['document', guid1, 'comments'], content='b')
+ this.call(method='PUT', path=['document', guid1, 'prop'], content='c')
+
+ guid2 = this.call(method='POST', path=['document'], content={})
+ this.call(method='POST', path=['document', guid2, 'comments'], content='c')
+ this.call(method='POST', path=['document', guid2, 'comments'], content='a')
+ this.call(method='PUT', path=['document', guid2, 'prop'], content='b')
+
+ guid3 = this.call(method='POST', path=['document'], content={})
+ this.call(method='POST', path=['document', guid3, 'comments'], content='a c')
+ this.call(method='POST', path=['document', guid3, 'comments'], content='b d')
+ this.call(method='PUT', path=['document', guid3, 'prop'], content='e')
+
+ self.assertEqual(
+ sorted([guid1, guid2, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='a')['result']]))
+ self.assertEqual(
+ sorted([guid1, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='b')['result']]))
+ self.assertEqual(
+ sorted([guid2, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='c')['result']]))
+ self.assertEqual(
+ sorted([]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='absent')['result']]))
+
+ self.assertEqual(
+ sorted([guid1, guid2, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:a')['result']]))
+ self.assertEqual(
+ sorted([guid1, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:b')['result']]))
+ self.assertEqual(
+ sorted([guid2, guid3]),
+ sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:c')['result']]))
if __name__ == '__main__':
diff --git a/tests/units/db/storage.py b/tests/units/db/storage.py
index 6eb62e5..bb61f8a 100755
--- a/tests/units/db/storage.py
+++ b/tests/units/db/storage.py
@@ -11,8 +11,7 @@ from os.path import exists
from __init__ import tests
-from sugar_network.db.metadata import Metadata, StoredProperty
-from sugar_network.db.metadata import BlobProperty
+from sugar_network.db.metadata import Metadata, Property
from sugar_network.db.storage import Storage
from sugar_network.toolkit import BUFFER_SIZE
@@ -30,7 +29,7 @@ class StorageTest(tests.Test):
return Storage(tests.tmpdir, metadata)
def test_Record_get(self):
- storage = self.storage([StoredProperty('prop')])
+ storage = self.storage([Property('prop')])
self.assertEqual(None, storage.get('guid').get('prop'))
self.touch(('gu/guid/prop', json.dumps({
@@ -45,7 +44,7 @@ class StorageTest(tests.Test):
storage.get('guid').get('prop'))
def test_Record_set(self):
- storage = self.storage([StoredProperty('prop')])
+ storage = self.storage([Property('prop')])
storage.get('guid').set('prop', value='value', foo='bar')
self.assertEqual({
@@ -56,7 +55,7 @@ class StorageTest(tests.Test):
storage.get('guid').get('prop'))
def test_delete(self):
- storage = self.storage([StoredProperty('prop')])
+ storage = self.storage([Property('prop')])
assert not exists('ab/absent')
storage.delete('absent')
@@ -69,8 +68,8 @@ class StorageTest(tests.Test):
def test_Record_consistent(self):
storage = self.storage([
- StoredProperty('guid'),
- StoredProperty('prop'),
+ Property('guid'),
+ Property('prop'),
])
record = storage.get('guid')
@@ -83,7 +82,7 @@ class StorageTest(tests.Test):
self.assertEqual(True, record.consistent)
def test_walk(self):
- storage = self.storage([StoredProperty('guid')])
+ storage = self.storage([Property('guid')])
storage.get('guid1').set('guid', value=1, mtime=1)
storage.get('guid2').set('guid', value=2, mtime=2)
@@ -107,8 +106,8 @@ class StorageTest(tests.Test):
def test_walk_SkipGuidLess(self):
storage = self.storage([
- StoredProperty('guid'),
- StoredProperty('prop'),
+ Property('guid'),
+ Property('prop'),
])
record = storage.get('guid1')