immutable/filenode: implement unified filenode interface
authorKevan Carstensen <kevan@isnotajoke.com>
Tue, 2 Aug 2011 02:09:05 +0000 (19:09 -0700)
committerKevan Carstensen <kevan@isnotajoke.com>
Tue, 2 Aug 2011 02:09:05 +0000 (19:09 -0700)
src/allmydata/immutable/filenode.py
src/allmydata/test/test_immutable.py

index 84d75035a841a36a5b2350aa5692345eddb667a3..0ac47a6c2750c9708c6b733b717cc3815b062f90 100644 (file)
@@ -5,10 +5,15 @@ import time
 now = time.time
 from zope.interface import implements
 from twisted.internet import defer
-from twisted.internet.interfaces import IConsumer
 
-from allmydata.interfaces import IImmutableFileNode, IUploadResults
 from allmydata import uri
+from twisted.internet.interfaces import IConsumer
+from twisted.protocols import basic
+from foolscap.api import eventually
+from allmydata.interfaces import IImmutableFileNode, ICheckable, \
+     IDownloadTarget, IUploadResults
+from allmydata.util import dictutil, log, base32, consumer
+from allmydata.immutable.checker import Checker
 from allmydata.check_results import CheckResults, CheckAndRepairResults
 from allmydata.util.dictutil import DictOfSets
 from pycryptopp.cipher.aes import AES
@@ -277,3 +282,33 @@ class ImmutableFileNode:
         return self._cnode.check_and_repair(monitor, verify, add_lease)
     def check(self, monitor, verify=False, add_lease=False):
         return self._cnode.check(monitor, verify, add_lease)
+
+    def get_best_readable_version(self):
+        """
+        Return an IReadable of the best version of this file. Since
+        immutable files can have only one version, we just return the
+        current filenode.
+        """
+        return defer.succeed(self)
+
+
+    def download_best_version(self):
+        """
+        Download the best version of this file, returning its contents
+        as a bytestring. Since there is only one version of an immutable
+        file, we download and return the contents of this file.
+        """
+        d = consumer.download_to_data(self)
+        return d
+
+    # for an immutable file, download_to_data (specified in IReadable)
+    # is the same as download_best_version (specified in IFileNode). For
+    # mutable files, the difference is more meaningful, since they can
+    # have multiple versions.
+    download_to_data = download_best_version
+
+
+    # get_size() (IReadable), get_current_size() (IFilesystemNode), and
+    # get_size_of_best_version(IFileNode) are all the same for immutable
+    # files.
+    get_size_of_best_version = get_current_size
index b7aa6f65cb7d615f867509d82779c02fa915e73c..ee29977067835cda0cc7181b1c0c8c426dbb22bb 100644 (file)
@@ -287,6 +287,32 @@ class Test(GridTestMixin, unittest.TestCase, common.ShouldFailMixin):
         d.addCallback(_try_download)
         return d
 
+    def test_download_to_data(self):
+        d = self.n.download_to_data()
+        d.addCallback(lambda data:
+            self.failUnlessEqual(data, common.TEST_DATA))
+        return d
+
+
+    def test_download_best_version(self):
+        d = self.n.download_best_version()
+        d.addCallback(lambda data:
+            self.failUnlessEqual(data, common.TEST_DATA))
+        return d
+
+
+    def test_get_best_readable_version(self):
+        d = self.n.get_best_readable_version()
+        d.addCallback(lambda n2:
+            self.failUnlessEqual(n2, self.n))
+        return d
+
+    def test_get_size_of_best_version(self):
+        d = self.n.get_size_of_best_version()
+        d.addCallback(lambda size:
+            self.failUnlessEqual(size, len(common.TEST_DATA)))
+        return d
+
 
 # XXX extend these tests to show bad behavior of various kinds from servers:
 # raising exception from each remove_foo() method, for example