Rev 2649: Merge in FileCollection. in http://people.ubuntu.com/~robertc/baz2.0/repository
Robert Collins
robertc at robertcollins.net
Sat Jul 14 11:39:33 BST 2007
At http://people.ubuntu.com/~robertc/baz2.0/repository
------------------------------------------------------------
revno: 2649
revision-id: robertc at robertcollins.net-20070714103927-p6bdl0v53vahje1r
parent: robertc at robertcollins.net-20070714085120-x1elgu9ddbeuolyv
parent: robertc at robertcollins.net-20070714101338-eu0cblg5ds2q2him
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Sat 2007-07-14 20:39:27 +1000
message:
Merge in FileCollection.
added:
bzrlib/file_collection.py file_collection.py-20070714100753-j2zz4ahtk331k5zm-1
bzrlib/tests/test_file_collection.py test_file_collection-20070714093417-5gc9d821to85zo4t-1
bzrlib/transport/unlistable.py unlistable.py-20070714093417-5gc9d821to85zo4t-2
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
------------------------------------------------------------
revno: 2592.1.28
revision-id: robertc at robertcollins.net-20070714101338-eu0cblg5ds2q2him
parent: robertc at robertcollins.net-20070714100801-bo0gezkinkusmtr3
committer: Robert Collins <robertc at robertcollins.net>
branch nick: file-collection
timestamp: Sat 2007-07-14 20:13:38 +1000
message:
Check loading empty collections and support removing items.
modified:
bzrlib/file_collection.py file_collection.py-20070714100753-j2zz4ahtk331k5zm-1
bzrlib/tests/test_file_collection.py test_file_collection-20070714093417-5gc9d821to85zo4t-1
------------------------------------------------------------
revno: 2592.1.27
revision-id: robertc at robertcollins.net-20070714100801-bo0gezkinkusmtr3
parent: robertc at robertcollins.net-20070714093531-n1kt1ch73qxhfw8i
committer: Robert Collins <robertc at robertcollins.net>
branch nick: file-collection
timestamp: Sat 2007-07-14 20:08:01 +1000
message:
Add FileCollection support class.
added:
bzrlib/file_collection.py file_collection.py-20070714100753-j2zz4ahtk331k5zm-1
bzrlib/tests/test_file_collection.py test_file_collection-20070714093417-5gc9d821to85zo4t-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
------------------------------------------------------------
revno: 2592.1.26
revision-id: robertc at robertcollins.net-20070714093531-n1kt1ch73qxhfw8i
parent: pqm at pqm.ubuntu.com-20070713074627-93zxs9uh528y0fki
committer: Robert Collins <robertc at robertcollins.net>
branch nick: file-collection
timestamp: Sat 2007-07-14 19:35:31 +1000
message:
Add a new transport decorator unlistable+ for testing.
added:
bzrlib/transport/unlistable.py unlistable.py-20070714093417-5gc9d821to85zo4t-2
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
=== added file 'bzrlib/file_collection.py'
--- a/bzrlib/file_collection.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/file_collection.py 2007-07-14 10:13:38 +0000
@@ -0,0 +1,82 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""A collection of file names which is persisted on a transport."""
+
+from bzrlib.lazy_import import lazy_import
+lazy_import(globals(), """
+from bzrlib import (
+ errors,
+ )
+""")
+
+
+class FileCollection(object):
+ """A collection of file names.
+
+ The file names are persisted to a file on a transport, and cand be
+ added, removed and initialised.
+
+ The set of names are stored in a flat file, one name per line.
+ New names are allocated sequentially.
+ Initialisation creates an empty file.
+
+ This is intended to support management of modest numbers of files in
+ write-locked environments which may be read from unlistable transports.
+
+ The save method must be called to cause the state to be saved to the
+ transport.
+
+ Finally, load is used to obtain a previously saved set.
+ """
+
+ def __init__(self, transport, index_name):
+ """Create a collection on transport called index_name."""
+ self._transport = transport
+ self._index_name = index_name
+ self._names = None
+ self._cap = 10000
+
+ def allocate(self):
+ for number in xrange(self._cap):
+ if str(number) not in self._names:
+ self._names.add(str(number))
+ return str(number)
+ raise errors.BzrError('too many files')
+
+ def initialise(self):
+ """Initialise the collection record on disk."""
+ self._names = set()
+
+ def load(self):
+ """Load the names from the transport."""
+ self._names = set(self._transport.get_bytes(
+ self._index_name).split('\n'))
+ if '' in self._names:
+ self._names.remove('')
+
+ def names(self):
+ """What are the names in this collection?"""
+ return frozenset(self._names)
+
+ def remove(self, name):
+ """Remove name from the collection."""
+ self._names.remove(name)
+
+ def save(self):
+ """Save the set of names."""
+ self._transport.put_bytes(self._index_name, '\n'.join(self._names))
+
=== added file 'bzrlib/tests/test_file_collection.py'
--- a/bzrlib/tests/test_file_collection.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_file_collection.py 2007-07-14 10:13:38 +0000
@@ -0,0 +1,103 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Tests for the FileCollection class."""
+
+from bzrlib import errors
+from bzrlib.file_collection import FileCollection
+from bzrlib.tests import TestCaseWithMemoryTransport
+from bzrlib.transport import get_transport
+
+
+class TestFileCollection(TestCaseWithMemoryTransport):
+
+ def test_initialise(self):
+ t = self.get_transport()
+ for name in ('index', '00index'):
+ collection = FileCollection(t, name)
+ collection.initialise()
+ self.assertFalse(t.has(name))
+ collection.save()
+ self.assertEqual('', t.get_bytes(name))
+
+ def test_allocate_trivial(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ name = collection.allocate()
+ self.assertEqual('0', name)
+ self.assertFalse(t.has('index'))
+ name = collection.allocate()
+ self.assertEqual('1', name)
+ self.assertFalse(t.has('index'))
+
+ def test_allocate_overrun(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ collection._cap = 5
+ for number in xrange(5):
+ name = collection.allocate()
+ self.assertRaises(errors.BzrError, collection.allocate)
+
+ def test_load(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ collection.allocate()
+ collection.allocate()
+ collection.save()
+ collection = FileCollection(t, 'index')
+ collection.load()
+ self.assertEqual(set(['0', '1']), collection.names())
+
+ def test_load_empty(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ collection.save()
+ collection = FileCollection(t, 'index')
+ collection.load()
+ self.assertEqual(set(), collection.names())
+
+ def test_names(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ collection.allocate()
+ collection.allocate()
+ self.assertEqual(set(['0', '1']), collection.names())
+
+ def test_names_on_unlistable_works(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ collection.allocate()
+ collection.allocate()
+ collection.save()
+ collection = FileCollection(
+ get_transport('unlistable+' + self.get_url()), 'index')
+ collection.load()
+ self.assertEqual(set(['0', '1']), collection.names())
+
+ def test_remove(self):
+ t = self.get_transport()
+ collection = FileCollection(t, 'index')
+ collection.initialise()
+ name1 = collection.allocate()
+ name2 = collection.allocate()
+ collection.remove(name1)
+ self.assertEqual(set([name2]), collection.names())
=== added file 'bzrlib/transport/unlistable.py'
--- a/bzrlib/transport/unlistable.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/transport/unlistable.py 2007-07-14 09:35:31 +0000
@@ -0,0 +1,52 @@
+# Copyright (C) 2005, 2006 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Transport implementation that disables listing to simulate HTTP cheaply."""
+
+import bzrlib.errors as errors
+from bzrlib.transport import Transport
+from bzrlib.transport.decorator import TransportDecorator, DecoratorServer
+
+
+class UnlistableTransportDecorator(TransportDecorator):
+ """A transport that disables file listing for testing."""
+
+ @classmethod
+ def _get_url_prefix(self):
+ """Unlistable transports are identified by 'unlistable+'"""
+ return 'unlistable+'
+
+ def iter_files_recursive(self):
+ Transport.iter_files_recursive(self)
+
+ def listable(self):
+ return False
+
+ def list_dir(self, relpath):
+ Transport.list_dir(self, relpath)
+
+
+class UnlistableServer(DecoratorServer):
+ """Server for the UnlistableTransportDecorator for testing with."""
+
+ def get_decorator_class(self):
+ return UnlistableTransportDecorator
+
+
+def get_test_permutations():
+ """Return the permutations to be used in testing."""
+ return [(UnlistableTransportDecorator, UnlistableServer),
+ ]
=== modified file 'NEWS'
--- a/NEWS 2007-07-13 15:05:36 +0000
+++ b/NEWS 2007-07-14 10:39:27 +0000
@@ -55,6 +55,12 @@
index performance is not optimised, however the API is stable to allow
development on top of the index. (Robert Collins)
+ * New transport decorator 'unlistable+' which disables the list_dir
+ functionality for testing.
+
+ * New ``file_collection.FileCollection`` support class which mananges names
+ for unlistable transport situations. (Robert Collins)
+
TESTING:
* Remove selftest ``--clean-output``, ``--numbered-dirs`` and
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2007-07-13 14:19:21 +0000
+++ b/bzrlib/tests/__init__.py 2007-07-14 10:39:27 +0000
@@ -2259,7 +2259,6 @@
'bzrlib.tests.test_commit_merge',
'bzrlib.tests.test_config',
'bzrlib.tests.test_conflicts',
- 'bzrlib.tests.test_pack',
'bzrlib.tests.test_counted_lock',
'bzrlib.tests.test_decorators',
'bzrlib.tests.test_delta',
@@ -2270,6 +2269,7 @@
'bzrlib.tests.test_escaped_store',
'bzrlib.tests.test_extract',
'bzrlib.tests.test_fetch',
+ 'bzrlib.tests.test_file_collection',
'bzrlib.tests.test_ftp_transport',
'bzrlib.tests.test_generate_docs',
'bzrlib.tests.test_generate_ids',
@@ -2305,6 +2305,7 @@
'bzrlib.tests.test_options',
'bzrlib.tests.test_osutils',
'bzrlib.tests.test_osutils_encodings',
+ 'bzrlib.tests.test_pack',
'bzrlib.tests.test_patch',
'bzrlib.tests.test_patches',
'bzrlib.tests.test_permissions',
=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py 2007-07-13 02:23:34 +0000
+++ b/bzrlib/transport/__init__.py 2007-07-14 09:35:31 +0000
@@ -1295,8 +1295,8 @@
)
register_lazy_transport('readonly+', 'bzrlib.transport.readonly', 'ReadonlyTransportDecorator')
-register_transport_proto('fakenfs+')
-register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs', 'FakeNFSTransportDecorator')
+register_transport_proto('unlistable+')
+register_lazy_transport('unlistable+', 'bzrlib.transport.unlistable', 'UnlistableTransportDecorator')
register_transport_proto('brokenrename+')
register_lazy_transport('brokenrename+', 'bzrlib.transport.brokenrename',
More information about the bazaar-commits
mailing list