Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <silbe@activitycentral.com>2011-03-06 13:10:23 (GMT)
committer Sascha Silbe <silbe@activitycentral.com>2011-03-06 13:10:23 (GMT)
commit3189ce89e7519e23818d18b6f17623f183d9a14c (patch)
treef57db25cc66fac07dce2128d3958b2b733151262
parent0111be130ffbb3b3b3d792679ad19fddf51e47f1 (diff)
parente8fcefe4c19d45ab783e3513df178eea97a67b39 (diff)
Merge commit 'e8fcefe' into t/versions
* commit 'e8fcefe': Release 0.92.0 don't choke if timestamp property is missing fix some _very_ long lines Cleanup AUTHORS file Conflicts: src/carquinyol/datastore.py tests/test_massops.py tests/test_migration_v2_v3.py
-rw-r--r--AUTHORS2
-rw-r--r--configure.ac2
-rw-r--r--src/carquinyol/datastore.py3
-rw-r--r--tests/basic_api_v2.txt59
-rw-r--r--tests/test_massops.py68
-rw-r--r--tests/test_migration_v1_v2.py175
-rw-r--r--tests/test_migration_v2_v3.py20
7 files changed, 253 insertions, 76 deletions
diff --git a/AUTHORS b/AUTHORS
index 815ace9..9928b94 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -21,4 +21,4 @@ Tomeu Vizoso <tomeu@sugarlabs.org>
Current maintainers
~~~~~~~~~~~~~~~~~~~
-Aleksey Lim <alsroot@member.fsf.org>
+http://wiki.sugarlabs.org/go/Development_Team/Release/Modules#Glucose
diff --git a/configure.ac b/configure.ac
index 6cc2837..beba511 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([sugar-datastore],[0.90.0],[],[sugar-datastore])
+AC_INIT([sugar-datastore],[0.92.0],[],[sugar-datastore])
AC_PREREQ([2.59])
diff --git a/src/carquinyol/datastore.py b/src/carquinyol/datastore.py
index 434f613..0ba944f 100644
--- a/src/carquinyol/datastore.py
+++ b/src/carquinyol/datastore.py
@@ -345,6 +345,9 @@ class DataStore(dbus.service.Object):
if os.path.exists(path):
props['filesize'] = os.stat(path).st_size
update_metadata = True
+ if 'timestamp' not in props:
+ props['timestamp'] = str(int(time.time()))
+ update_metadata = True
if 'creation_time' not in props:
if 'ctime' in props:
try:
diff --git a/tests/basic_api_v2.txt b/tests/basic_api_v2.txt
index 0e4c5a1..e95145d 100644
--- a/tests/basic_api_v2.txt
+++ b/tests/basic_api_v2.txt
@@ -41,8 +41,10 @@ Create something to play with:
Check everything is there:
->>> sorted(ds.find({}, ['title', 'activity'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 1', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest2', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 3', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest2', variant_level=1)}, signature=dbus.Signature('sv'))]
+>>> assert sorted(to_native(ds.find({}, ['title', 'activity'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 1', u'activity': 'org.sugarlabs.DataStoreTest1'},
+... {u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest2'},
+... {u'title': 'DS test object 3', u'activity': 'org.sugarlabs.DataStoreTest2'}]
>>> ds.get_filename(o1_uid, byte_arrays=True)
dbus.String(u'')
>>> ds.get_filename(o2_uid, byte_arrays=True)
@@ -62,11 +64,16 @@ Change some entries:
>>> ds.update(o2_uid, {'title': 'DS test object 2', 'mime_type': 'text/plain', 'activity': 'org.sugarlabs.DataStoreTest1', 'tags': 'bar baz'}, '', False)
>>> ds.update(o3_uid, {'title': 'DS test object 2', 'mime_type': 'text/html', 'activity': 'org.sugarlabs.DataStoreTest3', 'timestamp': 10000}, '', False)
-Note: This only gives this result with the non-version support compatibility because we didn't update the data, so change_metadata() could be used instead of save(). If we update the data, a new version will be created and because we backdate the timestamp the previous version would still be considered the "latest" one.
->>> sorted(to_native(ds.find({}, ['title', 'activity'], byte_arrays=True)[0]))
-[{u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'}, {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'}, {u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'}]
+Note: This only gives this result with the non-version support compatibility because we didn't update the data, so change_metadata() could be used instead of save().
+If we update the data, a new version will be created and because we backdate the timestamp the previous version would still be considered the "latest" one.
+>>> assert sorted(to_native(ds.find({}, ['title', 'activity'], byte_arrays=True)[0])) == \
+... [{u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'},
+... {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'},
+... {u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'}]
-previous: [dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 1 updated', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv'))]
+previous: [{u'title': 'DS test object 1 updated', u'activity': 'org.sugarlabs.DataStoreTest1'},
+ {u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest1'},
+ {u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest3'}]
Retrieve metadata for a single entry, ignoring variable data:
>>> d=dict(ds.get_properties(o3_uid, byte_arrays=True))
@@ -75,29 +82,37 @@ Retrieve metadata for a single entry, ignoring variable data:
Find entries using "known" metadata:
->>> sorted(ds.find({'mime_type': ['text/plain']}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/plain', variant_level=1), dbus.String(u'tags'): dbus.ByteArray('bar baz', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 1 updated', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/plain', variant_level=1), dbus.String(u'tags'): dbus.ByteArray('foo', variant_level=1)}, signature=dbus.Signature('sv'))]
->>> sorted(ds.find({'mime_type': ['text/html']}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/html', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv'))]
->>> sorted(ds.find({'uid': o3_uid}, ['title', 'activity', 'mime_type'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/html', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv'))]
->>> sorted(ds.find({'timestamp': (9000, 11000)}, ['title', 'activity', 'mime_type'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/html', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv'))]
+>>> assert sorted(to_native(ds.find({'mime_type': ['text/plain']}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest1', u'mime_type': 'text/plain', u'tags': 'bar baz'},
+... {u'title': 'DS test object 1 updated', u'activity': 'org.sugarlabs.DataStoreTest1', u'mime_type': 'text/plain', u'tags': 'foo'}]
+>>> assert sorted(to_native(ds.find({'mime_type': ['text/html']}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'mime_type': 'text/html', u'activity': 'org.sugarlabs.DataStoreTest3'}]
+>>> assert sorted(to_native(ds.find({'uid': o3_uid}, ['title', 'activity', 'mime_type'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'mime_type': 'text/html', u'activity': 'org.sugarlabs.DataStoreTest3'}]
+>>> assert sorted(to_native(ds.find({'timestamp': (9000, 11000)}, ['title', 'activity', 'mime_type'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'mime_type': 'text/html', u'activity': 'org.sugarlabs.DataStoreTest3'}]
Find entries using "unknown" metadata (=> returns all entries):
->>> sorted(ds.find({'title': 'DS test object 2'}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/html', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/plain', variant_level=1), dbus.String(u'tags'): dbus.ByteArray('bar baz', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 1 updated', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1), dbus.String(u'mime_type'): dbus.ByteArray('text/plain', variant_level=1), dbus.String(u'tags'): dbus.ByteArray('foo', variant_level=1)}, signature=dbus.Signature('sv'))]
+>>> assert sorted(to_native(ds.find({'title': 'DS test object 2'}, ['title', 'activity', 'mime_type', 'tags'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'mime_type': 'text/html', u'activity': 'org.sugarlabs.DataStoreTest3'},
+... {u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest1', u'mime_type': 'text/plain', u'tags': 'bar baz'},
+... {u'title': 'DS test object 1 updated', u'activity': 'org.sugarlabs.DataStoreTest1', u'mime_type': 'text/plain', u'tags': 'foo'}]
You can specify a (primary) sort order. Please note that the secondary sort order is undefined / implementation-dependent.
->>> to_native(ds.find({'order_by': ['+title']}, ['title', 'activity'], byte_arrays=True)[0])
-[{u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'}, {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'}, {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'}]
->>> to_native(ds.find({'order_by': ['-title']}, ['title', 'activity'], byte_arrays=True)[0])
-[{u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'}, {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'}, {u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'}]
+>>> assert to_native(ds.find({'order_by': ['+title']}, ['title', 'activity'], byte_arrays=True)[0]) == \
+... [{u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'},
+... {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'},
+... {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'}]
+>>> assert to_native(ds.find({'order_by': ['-title']}, ['title', 'activity'], byte_arrays=True)[0]) == \
+... [{u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 1 updated'},
+... {u'activity': 'org.sugarlabs.DataStoreTest1', u'title': 'DS test object 2'},
+... {u'activity': 'org.sugarlabs.DataStoreTest3', u'title': 'DS test object 2'}]
Delete an entry:
>>> ds.delete(o1_uid)
->>> sorted(ds.find({}, ['title', 'activity'], byte_arrays=True)[0])
-[dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest1', variant_level=1)}, signature=dbus.Signature('sv')), dbus.Dictionary({dbus.String(u'title'): dbus.ByteArray('DS test object 2', variant_level=1), dbus.String(u'activity'): dbus.ByteArray('org.sugarlabs.DataStoreTest3', variant_level=1)}, signature=dbus.Signature('sv'))]
+>>> assert sorted(to_native(ds.find({}, ['title', 'activity'], byte_arrays=True)[0])) == \
+... [{u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest1'},
+... {u'title': 'DS test object 2', u'activity': 'org.sugarlabs.DataStoreTest3'}]
Create an entry with content:
diff --git a/tests/test_massops.py b/tests/test_massops.py
index d7699db..5527549 100644
--- a/tests/test_massops.py
+++ b/tests/test_massops.py
@@ -44,7 +44,6 @@ class MassOpsTestCase(unittest.TestCase):
'title': 'DS test object',
'mime_type': 'text/plain',
'activity': 'org.sugarlabs.DataStoreTest1',
- 'filesize': str(len(_create_content)),
}
def test_create(self):
@@ -73,10 +72,9 @@ class MassOpsTestCase(unittest.TestCase):
@repeat
def test_find_all_reverse_time(self):
"""Run find() to list all entries in reverse chronological order."""
- entries, total_count = \
- self._datastore.find({}, {'metadata': ['number'],
- 'order_by': ['-timestamp']},
- byte_arrays=True)
+ options = {'metadata': ['number'], 'order_by': ['-timestamp']}
+ entries, total_count = self._datastore.find({}, options,
+ byte_arrays=True)
self.assertEquals(total_count, NUM_RUNS)
self.assertEquals(total_count, len(entries))
for position, entry in enumerate(entries):
@@ -85,20 +83,18 @@ class MassOpsTestCase(unittest.TestCase):
@repeat
def test_find_all_title(self):
"""Run find() to list all entries ordered by title."""
- entries, total_count = \
- self._datastore.find({}, {'metadata': ['tree_id'],
- 'order_by': ['+title']},
- byte_arrays=True)
+ options = {'metadata': ['tree_id'], 'order_by': ['+title']}
+ entries, total_count = self._datastore.find({}, options,
+ byte_arrays=True)
self.assertEquals(total_count, NUM_RUNS)
self.assertEquals(total_count, len(entries))
@repeat
def test_find_all_reverse_title(self):
"""Run find() to list all entries ordered by title (reversed)."""
- entries, total_count = \
- self._datastore.find({}, {'metadata': ['tree_id'],
- 'order_by': ['-title']},
- byte_arrays=True)
+ options = {'metadata': ['tree_id'], 'order_by': ['-title']}
+ entries, total_count = self._datastore.find({}, options,
+ byte_arrays=True)
self.assertEquals(total_count, NUM_RUNS)
self.assertEquals(total_count, len(entries))
@@ -107,11 +103,10 @@ class MassOpsTestCase(unittest.TestCase):
"""Run find() to list all entries in small chunks."""
chunk_size = 30
for chunk_start in range(0, NUM_RUNS, 30):
- entries, total_count = \
- self._datastore.find({}, {'offset': chunk_start,
- 'limit': chunk_size,
- 'metadata': ['number']},
- byte_arrays=True)
+ options = {'offset': chunk_start, 'limit': chunk_size,
+ 'metadata': ['number']}
+ entries, total_count = self._datastore.find({}, options,
+ byte_arrays=True)
self.assertEquals(len(entries),
min(chunk_size, NUM_RUNS - chunk_start))
self.assertEquals(total_count, NUM_RUNS)
@@ -121,23 +116,19 @@ class MassOpsTestCase(unittest.TestCase):
def test_get_properties(self):
"""Run find() to retrieve and verify single entry for all entries."""
- entries = self._datastore.find({}, {'metadata': ['tree_id',
- 'version_id']},
- byte_arrays=True)[0]
- for entry in entries:
- properties = \
- self._datastore.find({'tree_id': entry['tree_id'],
- 'version_id': entry['version_id']}, {},
- byte_arrays=True)[0][0]
+ options = {'metadata': ['tree_id', 'version_id']}
+ for entry in self._datastore.find({}, options, byte_arrays=True)[0]:
+ properties = self._datastore.find({'tree_id': entry['tree_id'],
+ 'version_id': entry['version_id']}, {}, byte_arrays=True)[0][0]
self._filter_properties(properties)
+ self.assertEquals(properties.pop('filesize'),
+ str(len(self._create_content)))
self.assertEquals(properties, self._create_properties)
def test_get_data(self):
"""Run get_data() on all entries and verify content."""
- entries = self._datastore.find({}, {'metadata': ['tree_id',
- 'version_id']},
- byte_arrays=True)[0]
- for entry in entries:
+ options = {'metadata': ['tree_id', 'version_id']}
+ for entry in self._datastore.find({}, options, byte_arrays=True)[0]:
filename = self._datastore.get_data(entry['tree_id'],
entry['version_id'], byte_arrays=True)
try:
@@ -150,7 +141,6 @@ class MassOpsTestCase(unittest.TestCase):
'title': 'DS test object (updated)',
'mime_type': 'text/plain',
'activity': 'org.sugarlabs.DataStoreTest1',
- 'filesize': str(len(_update_content)),
}
def test_update(self):
@@ -158,23 +148,19 @@ class MassOpsTestCase(unittest.TestCase):
content_file = tempfile.NamedTemporaryFile()
content_file.write(self._update_content)
content_file.flush()
- entries = self._datastore.find({}, {'metadata': ['tree_id',
- 'version_id']},
- byte_arrays=True)[0]
- for entry in entries:
-
+ options = {'metadata': ['tree_id', 'version_id']}
+ for entry in self._datastore.find({}, options, byte_arrays=True)[0]:
self._datastore.save(entry['tree_id'], entry['version_id'],
self._update_properties, content_file.name, False)
def test_update_verify(self):
- """
- Verify test_update() has changed content and metadata of all entries.
- """
+ """Verify test_update() has changed content and metadata of all entries."""
for entry in self._datastore.find({}, {}, byte_arrays=True)[0]:
filename = self._datastore.get_data(entry['tree_id'],
- entry['version_id'],
- byte_arrays=True)
+ entry['version_id'], byte_arrays=True)
self._filter_properties(entry)
+ self.assertEquals(entry.pop('filesize'),
+ str(len(self._update_content)))
try:
self.assertEquals(entry, self._update_properties)
self.assertEquals(file(filename).read(), self._update_content)
diff --git a/tests/test_migration_v1_v2.py b/tests/test_migration_v1_v2.py
new file mode 100644
index 0000000..6666f04
--- /dev/null
+++ b/tests/test_migration_v1_v2.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+"""Test datastore migration from version 1 to version 2."""
+
+import dbus
+import hashlib
+import os
+import time
+import unittest
+import uuid
+
+
+DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
+DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
+DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
+IGNORE_PROPERTIES = [
+ 'activity_id',
+ 'checksum',
+ 'creation_time',
+ 'ctime',
+ 'mtime',
+ 'number',
+ 'parent_id',
+ 'timestamp',
+ 'uid',
+]
+
+
+class MigrationV1V2TestCase(unittest.TestCase):
+ """Test datastore migration from version 1 to version 2."""
+
+ def __init__(self, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+ self._templates = self._v1_properties * 10
+
+ def setUp(self):
+ # pylint: disable=C0103
+ profile = os.environ.get('SUGAR_PROFILE', 'default')
+ base_dir = os.path.join(os.path.expanduser('~'), '.sugar', profile)
+ self._root_path = os.path.join(base_dir, 'datastore')
+ if not os.path.exists(self._root_path):
+ self._create_v1_datastore()
+
+ self._bus = dbus.SessionBus()
+ self._datastore = dbus.Interface(self._bus.get_object(DS_DBUS_SERVICE,
+ DS_DBUS_PATH),
+ DS_DBUS_INTERFACE)
+
+ _v1_properties = [
+ {
+ 'title': lambda number: 'DS test object %d' % (number, ),
+ 'mime_type': 'text/plain',
+ },
+ {
+ 'title': lambda number: 'DS test object %d' % (number, ),
+ 'mime_type': 'text/html',
+ },
+ {
+ 'title': lambda number: 'DS test object %d' % (number, ),
+ 'title_set_by_user': '1',
+ 'keep': '1',
+ 'mime_type': 'text/html',
+ 'activity': 'org.sugarlabs.DataStoreTest2',
+ 'activity_id': lambda number_: str(uuid.uuid4()),
+ 'timestamp': lambda number_: time.time(),
+ 'icon-color': '#00ff00,#0000ff',
+ 'buddies': '{}',
+ 'description': 'DS migration test object',
+ 'tags': lambda number: 'test tag%d' % (number, ),
+ 'preview': dbus.ByteArray(''.join([chr(i) for i in range(255)])),
+ },
+ {
+ 'title': lambda number: 'DS test object %d' % (number, ),
+ 'activity': 'org.sugarlabs.DataStoreTest3',
+ 'activity_id': lambda number_: str(uuid.uuid4()),
+ 'ctime': lambda number_: time.strftime('%Y-%m-%dT%H:%M:%S'),
+ },
+ {
+ 'title': lambda number: 'DS test object %d' % (number, ),
+ 'activity': 'org.sugarlabs.DataStoreTest4',
+ 'activity_id': lambda number_: str(uuid.uuid4()),
+ 'mtime': lambda number_: time.strftime('%Y-%m-%dT%H:%M:%S'),
+ },
+ {},
+ ]
+
+ def _v1_content(self, num):
+ return ('Foo bar %d\n' % (num, )) * 1000
+
+ def _create_v1_datastore(self):
+ """Create a version 1 datastore on disk."""
+ os.makedirs(self._root_path)
+ file(os.path.join(self._root_path, 'version'), 'w').write('1')
+ for i, template in enumerate(self._templates):
+ metadata = self._fill_template(template, i)
+ data = self._v1_content(i)
+ tree_id = str(uuid.uuid4())
+ metadata['uid'] = tree_id
+ metadata['number'] = i
+
+ self._create_v1_entry(tree_id, metadata, data)
+
+ def _fill_template(self, template, i):
+ metadata = {}
+ for (key, value) in template.items():
+ if callable(value):
+ value = value(i)
+
+ metadata[key] = value
+
+ return metadata
+
+ def _create_v1_entry(self, tree_id, metadata, data):
+ """Create a single version 1 datastore entry."""
+ checksum = hashlib.md5(data).hexdigest()
+ entry_dir = os.path.join(self._root_path, tree_id[:2], tree_id)
+ os.makedirs(entry_dir)
+ file(os.path.join(entry_dir, 'data'), 'w').write(data)
+ self._write_v1_metadata(os.path.join(entry_dir, 'metadata'), metadata)
+ checksum_dir = os.path.join(self._root_path, 'checksums', checksum)
+ os.makedirs(checksum_dir)
+ file(os.path.join(checksum_dir, tree_id), 'w').close()
+
+ def _write_v1_metadata(self, directory, metadata):
+ os.makedirs(directory)
+ for key, value in metadata.items():
+ file(os.path.join(directory, key), 'w').write(str(value))
+
+ def test_00_sleep(self):
+ """Temporary workaround for inability to wait for index completion."""
+ time.sleep(5)
+
+ def test_find_all(self):
+ """Run find() to list all migrated entries."""
+ entries_, count = self._find({}, ['uid'])
+ self.assertEquals(count, len(self._templates))
+
+ def test_get_properties(self):
+ """Run get_properties() on all entries and verify result."""
+ for entry in self._find({}, ['uid'])[0]:
+ properties = self._datastore.get_properties(entry['uid'],
+ byte_arrays=True)
+ number = int(properties['number'])
+ expected = self._fill_template(self._templates[number],
+ number)
+ self.assertEquals(properties.pop('filesize'),
+ str(len(self._v1_content(number))))
+ self._filter_properties(properties)
+ self._filter_properties(expected)
+ self.assertEquals(properties, expected)
+
+ def test_get_filename(self):
+ """Run get_filename() on all entries and verify content."""
+ for entry in self._find({}, ['number', 'uid'])[0]:
+ filename = self._datastore.get_filename(entry['uid'],
+ byte_arrays=True)
+ content = file(filename).read()
+ os.remove(filename)
+ number = int(entry['number'])
+ expected = self._v1_content(number)
+ self.assertEquals(content, expected)
+
+ def _find(self, query, properties):
+ return self._datastore.find(dbus.Dictionary(query, signature='sv'),
+ properties, byte_arrays=True)
+
+ def _filter_properties(self, properties):
+ for key in IGNORE_PROPERTIES:
+ properties.pop(key, None)
+
+
+def suite():
+ test_loader = unittest.TestLoader()
+ test_suite = test_loader.loadTestsFromTestCase(MigrationV1V2TestCase)
+ test_suite.__doc__ = MigrationV1V2TestCase.__doc__
+ return test_suite
diff --git a/tests/test_migration_v2_v3.py b/tests/test_migration_v2_v3.py
index 73d07c6..1c57016 100644
--- a/tests/test_migration_v2_v3.py
+++ b/tests/test_migration_v2_v3.py
@@ -132,15 +132,16 @@ class MigrationV2V3TestCase(unittest.TestCase):
entries_, count = self._datastore.find({}, {'metadata': ['tree_id']},
byte_arrays=True)
self.assertEquals(count, len(self._templates))
+ self.assertEquals(count, len(entries))
def test_get_properties(self):
"""Run find() to retrieve and verify single entry for all entries."""
- entries = self._datastore.find({}, {'metadata': ['tree_id',
- 'version_id']},
- byte_arrays=True)[0]
- for entry in entries:
- properties = self._datastore.find({'tree_id': entry['tree_id'],
- 'version_id': entry['version_id']}, {}, byte_arrays=True)[0][0]
+ options = {'metadata': ['tree_id', 'version_id']}
+ for entry in self._datastore.find({}, options, byte_arrays=True)[0]:
+ query = {'tree_id': entry['tree_id'],
+ 'version_id': entry['version_id']}
+ properties = self._datastore.find(query, {},
+ byte_arrays=True)[0][0]
if 'number' not in properties:
continue
@@ -154,11 +155,8 @@ class MigrationV2V3TestCase(unittest.TestCase):
def test_get_data(self):
"""Run get_data() on all entries and verify content."""
- entries = self._datastore.find({}, {'metadata': ['number',
- 'tree_id',
- 'version_id']},
- byte_arrays=True)[0]
- for entry in entries:
+ options = {'metadata': ['number', 'tree_id', 'version_id']}
+ for entry in self._datastore.find({}, options, byte_arrays=True)[0]:
filename = self._datastore.get_data(entry['tree_id'],
entry['version_id'],
byte_arrays=True)