Rev 11: Start working on the FileLockStore object itself. in lp:~jameinel/+junk/file_locking

John Arbash Meinel john at arbash-meinel.com
Mon Sep 21 16:41:51 BST 2009


At lp:~jameinel/+junk/file_locking

------------------------------------------------------------
revno: 11
revision-id: john at arbash-meinel.com-20090921154143-4u6o17tdinepjvy6
parent: john at arbash-meinel.com-20090921151131-jnh3yhispypxjfx9
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: file_locking
timestamp: Mon 2009-09-21 10:41:43 -0500
message:
  Start working on the FileLockStore object itself.
-------------- next part --------------
=== modified file 'file_lock.py'
--- a/file_lock.py	2009-09-21 15:11:31 +0000
+++ b/file_lock.py	2009-09-21 15:41:43 +0000
@@ -18,6 +18,7 @@
 
 from bzrlib import (
     errors,
+    lockdir,
     rio,
     )
 
@@ -157,6 +158,60 @@
         self._tracked_ids = set(tracked_ids)
 
 
+class FileLockStore(object):
+    """This is the actual location where file locks are tracked.
+
+    It tracks:
+        1) What file_ids should have locks taken out
+        2) What locks are currently taken
+        3) Logging of locking/unlocking actions.
+    """
+
+    def __init__(self, transport, locking_info, lock):
+        """You should not call this directly.
+
+        Instead call FileLockStore.initialize() or FileLockStore.open()
+        """
+        self._transport = transport
+        self._lock = lock
+        self._locking_info = locking_info
+
+    @classmethod
+    def initialize(cls, transport):
+        """Create a new FileLockStore.
+
+        The returned object is opened write-locked. Callers are responsible for
+        unlocking it.
+        """
+        # TODO: What to do about mode bits?
+        transport.ensure_base()
+        lock = lockdir.LockDir(transport, 'lock')
+        lock.create()
+        nonce = lock.attempt_lock()
+        try:
+            transport.put_bytes('README.txt',
+                'This is a Bazaar File Locking Lock Store\n'
+                'You should not need to modify any files in this directory.\n')
+            locking_info = FileLockingInfo([])
+            s = FileLockingInfoSerializer()
+            bytes = s.to_bytes(locking_info)
+            transport.put_bytes('info', bytes)
+            store = cls(transport, locking_info, lock)
+        except:
+            lock.unlock()
+            raise
+        return store
+
+    @classmethod
+    def open(cls, transport):
+        """Open a FileLockStore at the given URL."""
+        info_bytes = transport.get_bytes('info')
+        s = FileLockingInfoSerializer()
+        locking_info = s.from_bytes(info_bytes)
+        lock = lockdir.LockDir(transport, 'lock')
+        return cls(transport, locking_info, lock)
+
+
 class FileLockManager(object):
     """This is the overall manager that tracks everything we need to know."""
 

=== modified file 'tests/test_file_lock.py'
--- a/tests/test_file_lock.py	2009-09-21 15:11:31 +0000
+++ b/tests/test_file_lock.py	2009-09-21 15:41:43 +0000
@@ -16,7 +16,10 @@
 
 """Tests for cooperative file locking."""
 
-from bzrlib import tests
+from bzrlib import (
+    errors,
+    tests,
+    )
 
 from bzrlib.plugins.file_locking import file_lock
 
@@ -131,3 +134,39 @@
         self.assertFalse(manager.is_tracked(''))
         manager.initialize_lock_store('.')
         self.assertFalse(manager.is_tracked(''))
+
+
+
+class TestFileLockStore(tests.TestCaseWithMemoryTransport):
+
+    def test_initialize(self):
+        trans = self.get_transport('lock-store')
+        fls = file_lock.FileLockStore.initialize(trans)
+        self.addCleanup(fls._lock.unlock)
+        self.assertIsInstance(fls, file_lock.FileLockStore)
+        self.assertEqual(trans, fls._transport)
+        self.assertEqual(['README.txt', 'info', 'lock'],
+                         sorted(trans.list_dir('')))
+        self.assertIsInstance(fls._locking_info, file_lock.FileLockingInfo)
+
+    def test_open_not_there(self):
+        trans = self.get_transport('lock-store')
+        # Not ideal, but useable
+        self.assertRaises(errors.NoSuchFile,
+                          file_lock.FileLockStore.open, trans)
+
+    def test_open_invalid_info_file(self):
+        trans = self.get_transport('lock-store')
+        trans.ensure_base()
+        trans.put_bytes('info', 'random\ngarbage\n')
+        self.assertRaises(ValueError,
+                          file_lock.FileLockStore.open, trans)
+
+    def test_open_trivial(self):
+        trans = self.get_transport('lock-store')
+        fls = file_lock.FileLockStore.initialize(trans)
+        fls._lock.unlock()
+        fls = file_lock.FileLockStore.open(trans)
+        self.assertIsInstance(fls, file_lock.FileLockStore)
+        self.assertEqual(trans, fls._transport)
+        self.assertIsInstance(fls._locking_info, file_lock.FileLockingInfo)



More information about the bazaar-commits mailing list