diff options
author | Sascha Silbe <silbe@activitycentral.com> | 2011-03-06 13:10:23 (GMT) |
---|---|---|
committer | Sascha Silbe <silbe@activitycentral.com> | 2011-03-06 13:10:23 (GMT) |
commit | 3189ce89e7519e23818d18b6f17623f183d9a14c (patch) | |
tree | f57db25cc66fac07dce2128d3958b2b733151262 | |
parent | 0111be130ffbb3b3b3d792679ad19fddf51e47f1 (diff) | |
parent | e8fcefe4c19d45ab783e3513df178eea97a67b39 (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-- | AUTHORS | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/carquinyol/datastore.py | 3 | ||||
-rw-r--r-- | tests/basic_api_v2.txt | 59 | ||||
-rw-r--r-- | tests/test_massops.py | 68 | ||||
-rw-r--r-- | tests/test_migration_v1_v2.py | 175 | ||||
-rw-r--r-- | tests/test_migration_v2_v3.py | 20 |
7 files changed, 253 insertions, 76 deletions
@@ -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) |