mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-19 21:17:54 +00:00
interface name cleanups: IFileNode, IImmutableFileNode, IMutableFileNode
The proper hierarchy is: IFilesystemNode +IFileNode ++IMutableFileNode ++IImmutableFileNode +IDirectoryNode Also expand test_client.py (NodeMaker) to hit all IFilesystemNode types.
This commit is contained in:
parent
d2badbea78
commit
0cf320c2ab
@ -8,8 +8,8 @@ import simplejson
|
||||
from allmydata.mutable.common import NotMutableError
|
||||
from allmydata.mutable.filenode import MutableFileNode
|
||||
from allmydata.unknown import UnknownNode
|
||||
from allmydata.interfaces import IMutableFileNode, IDirectoryNode,\
|
||||
IFileNode, IFilesystemNode, \
|
||||
from allmydata.interfaces import IFilesystemNode, IDirectoryNode, IFileNode, \
|
||||
IImmutableFileNode, IMutableFileNode, \
|
||||
ExistingChildError, NoSuchChildError, ICheckable, IDeepCheckable, \
|
||||
CannotPackUnknownNodeError
|
||||
from allmydata.check_results import DeepCheckResults, \
|
||||
@ -687,7 +687,7 @@ class DeepStats:
|
||||
self.add("count-mutable-files")
|
||||
# TODO: update the servermap, compute a size, add it to
|
||||
# size-mutable-files, max it into "largest-mutable-file"
|
||||
elif IFileNode.providedBy(node): # CHK and LIT
|
||||
elif IImmutableFileNode.providedBy(node): # CHK and LIT
|
||||
self.add("count-files")
|
||||
size = node.get_size()
|
||||
self.histogram("size-files-histogram", size)
|
||||
|
@ -5,7 +5,7 @@ from twisted.internet import defer
|
||||
from twisted.internet.interfaces import IPushProducer, IConsumer
|
||||
from twisted.protocols import basic
|
||||
from foolscap.api import eventually
|
||||
from allmydata.interfaces import IFileNode, ICheckable, \
|
||||
from allmydata.interfaces import IImmutableFileNode, ICheckable, \
|
||||
IDownloadTarget, IUploadResults
|
||||
from allmydata.util import dictutil, log, base32
|
||||
from allmydata.uri import CHKFileURI, LiteralFileURI
|
||||
@ -15,7 +15,7 @@ from allmydata.immutable.repairer import Repairer
|
||||
from allmydata.immutable import download
|
||||
|
||||
class _ImmutableFileNodeBase(object):
|
||||
implements(IFileNode, ICheckable)
|
||||
implements(IImmutableFileNode, ICheckable)
|
||||
|
||||
def get_readonly_uri(self):
|
||||
return self.get_uri()
|
||||
@ -29,12 +29,12 @@ class _ImmutableFileNodeBase(object):
|
||||
def __hash__(self):
|
||||
return self.u.__hash__()
|
||||
def __eq__(self, other):
|
||||
if IFileNode.providedBy(other):
|
||||
if isinstance(other, _ImmutableFileNodeBase):
|
||||
return self.u.__eq__(other.u)
|
||||
else:
|
||||
return False
|
||||
def __ne__(self, other):
|
||||
if IFileNode.providedBy(other):
|
||||
if isinstance(other, _ImmutableFileNodeBase):
|
||||
return self.u.__eq__(other.u)
|
||||
else:
|
||||
return True
|
||||
|
@ -483,6 +483,13 @@ class UnhandledCapTypeError(Exception):
|
||||
class NotDeepImmutableError(Exception):
|
||||
"""Deep-immutable directories can only contain deep-immutable children"""
|
||||
|
||||
# The hierarchy looks like this:
|
||||
# IFilesystemNode
|
||||
# IFileNode
|
||||
# IMutableFileNode
|
||||
# IImmutableFileNode
|
||||
# IDirectoryNode
|
||||
|
||||
class IFilesystemNode(Interface):
|
||||
def get_cap():
|
||||
"""Return the strongest 'cap instance' associated with this node.
|
||||
@ -563,10 +570,11 @@ class IFilesystemNode(Interface):
|
||||
data this node represents.
|
||||
"""
|
||||
|
||||
class IMutableFilesystemNode(IFilesystemNode):
|
||||
pass
|
||||
|
||||
class IFileNode(IFilesystemNode):
|
||||
"""I am a node which represents a file: a sequence of bytes. I am not a
|
||||
container, like IDirectoryNode."""
|
||||
|
||||
class IImmutableFileNode(IFileNode):
|
||||
def download(target):
|
||||
"""Download the file's contents to a given IDownloadTarget"""
|
||||
|
||||
@ -626,7 +634,7 @@ class IFileNode(IFilesystemNode):
|
||||
|
||||
"""
|
||||
|
||||
class IMutableFileNode(IFileNode, IMutableFilesystemNode):
|
||||
class IMutableFileNode(IFileNode):
|
||||
"""I provide access to a 'mutable file', which retains its identity
|
||||
regardless of what contents are put in it.
|
||||
|
||||
@ -819,10 +827,11 @@ class ExistingChildError(Exception):
|
||||
class NoSuchChildError(Exception):
|
||||
"""A directory node was asked to fetch a child which does not exist."""
|
||||
|
||||
class IDirectoryNode(IMutableFilesystemNode):
|
||||
"""I represent a name-to-child mapping, holding the tahoe equivalent of a
|
||||
directory. All child names are unicode strings, and all children are some
|
||||
sort of IFilesystemNode (either files or subdirectories).
|
||||
class IDirectoryNode(IFilesystemNode):
|
||||
"""I represent a filesystem node that is a container, with a
|
||||
name-to-child mapping, holding the tahoe equivalent of a directory. All
|
||||
child names are unicode strings, and all children are some sort of
|
||||
IFilesystemNode (either files or subdirectories).
|
||||
"""
|
||||
|
||||
def get_uri():
|
||||
@ -846,8 +855,8 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
def list():
|
||||
"""I return a Deferred that fires with a dictionary mapping child
|
||||
name (a unicode string) to (node, metadata_dict) tuples, in which
|
||||
'node' is either an IFileNode or IDirectoryNode, and 'metadata_dict'
|
||||
is a dictionary of metadata."""
|
||||
'node' is an IFilesystemNode (either IFileNode or IDirectoryNode),
|
||||
and 'metadata_dict' is a dictionary of metadata."""
|
||||
|
||||
def has_child(name):
|
||||
"""I return a Deferred that fires with a boolean, True if there
|
||||
@ -877,7 +886,7 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
name."""
|
||||
|
||||
def get_child_at_path(path):
|
||||
"""Transform a child path into an IDirectoryNode or IFileNode.
|
||||
"""Transform a child path into an IFilesystemNode.
|
||||
|
||||
I perform a recursive series of 'get' operations to find the named
|
||||
descendant node. I return a Deferred that fires with the node, or
|
||||
@ -888,8 +897,7 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
"""
|
||||
|
||||
def get_child_and_metadata_at_path(path):
|
||||
"""Transform a child path into an IDirectoryNode/IFileNode and
|
||||
metadata.
|
||||
"""Transform a child path into an IFilesystemNode and metadata.
|
||||
|
||||
I am like get_child_at_path(), but my Deferred fires with a tuple of
|
||||
(node, metadata). The metadata comes from the last edge. If the path
|
||||
@ -934,7 +942,7 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
when the operation finishes. This Deferred will fire with the child
|
||||
node that was just added. I will replace any existing child of the
|
||||
same name. The child name must be a unicode string. The 'child'
|
||||
instance must be an instance providing IDirectoryNode or IFileNode.
|
||||
instance must be an instance providing IFilesystemNode.
|
||||
|
||||
If metadata= is provided, I will use it as the metadata for the named
|
||||
edge. This will replace any existing metadata. If metadata= is left
|
||||
@ -2068,10 +2076,10 @@ class IClient(Interface):
|
||||
|
||||
@return: an instance that provides IFilesystemNode (or more usefully
|
||||
one of its subclasses). File-specifying URIs will result in
|
||||
IFileNode or IMutableFileNode -providing instances, like
|
||||
ImmutableFileNode, LiteralFileNode, or MutableFileNode.
|
||||
Directory-specifying URIs will result in
|
||||
IDirectoryNode-providing instances, like DirectoryNode.
|
||||
IFileNode-providing instances, like ImmutableFileNode,
|
||||
LiteralFileNode, or MutableFileNode. Directory-specifying
|
||||
URIs will result in IDirectoryNode-providing instances, like
|
||||
DirectoryNode.
|
||||
"""
|
||||
|
||||
class INodeMaker(Interface):
|
||||
@ -2083,7 +2091,7 @@ class INodeMaker(Interface):
|
||||
or modify its contents.
|
||||
|
||||
The NodeMaker encapsulates all the authorities that these
|
||||
IfilesystemNodes require (like references to the StorageFarmBroker). Each
|
||||
IFilesystemNodes require (like references to the StorageFarmBroker). Each
|
||||
Tahoe process will typically have a single NodeMaker, but unit tests may
|
||||
create simplified/mocked forms for testing purposes.
|
||||
"""
|
||||
|
@ -8,7 +8,7 @@ from twisted.web.error import Error as WebError
|
||||
from foolscap.api import flushEventualQueue, fireEventually
|
||||
from allmydata import uri, dirnode, client
|
||||
from allmydata.introducer.server import IntroducerNode
|
||||
from allmydata.interfaces import IMutableFileNode, IFileNode, \
|
||||
from allmydata.interfaces import IMutableFileNode, IImmutableFileNode, \
|
||||
FileTooLargeError, NotEnoughSharesError, ICheckable
|
||||
from allmydata.check_results import CheckResults, CheckAndRepairResults, \
|
||||
DeepCheckResults, DeepCheckAndRepairResults
|
||||
@ -32,9 +32,9 @@ def flush_but_dont_ignore(res):
|
||||
return d
|
||||
|
||||
class FakeCHKFileNode:
|
||||
"""I provide IFileNode, but all of my data is stored in a class-level
|
||||
dictionary."""
|
||||
implements(IFileNode)
|
||||
"""I provide IImmutableFileNode, but all of my data is stored in a
|
||||
class-level dictionary."""
|
||||
implements(IImmutableFileNode)
|
||||
all_contents = {}
|
||||
bad_shares = {}
|
||||
|
||||
|
@ -9,7 +9,8 @@ from allmydata import client
|
||||
from allmydata.storage_client import StorageFarmBroker
|
||||
from allmydata.introducer.client import IntroducerClient
|
||||
from allmydata.util import base32, fileutil
|
||||
from allmydata.interfaces import IFilesystemNode, IFileNode, IDirectoryNode
|
||||
from allmydata.interfaces import IFilesystemNode, IFileNode, \
|
||||
IImmutableFileNode, IMutableFileNode, IDirectoryNode
|
||||
from foolscap.api import flushEventualQueue
|
||||
import common_util as testutil
|
||||
|
||||
@ -247,13 +248,44 @@ class NodeMaker(unittest.TestCase):
|
||||
n = c.create_node_from_uri("URI:CHK:6nmrpsubgbe57udnexlkiwzmlu:bjt7j6hshrlmadjyr7otq3dc24end5meo5xcr5xe5r663po6itmq:3:10:7277")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failUnless(IFileNode.providedBy(n))
|
||||
self.failUnless(IImmutableFileNode.providedBy(n))
|
||||
self.failIf(IMutableFileNode.providedBy(n))
|
||||
self.failIf(IDirectoryNode.providedBy(n))
|
||||
self.failUnless(n.is_readonly())
|
||||
self.failIf(n.is_mutable())
|
||||
|
||||
n = c.create_node_from_uri("URI:LIT:n5xgk")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failUnless(IFileNode.providedBy(n))
|
||||
self.failUnless(IImmutableFileNode.providedBy(n))
|
||||
self.failIf(IMutableFileNode.providedBy(n))
|
||||
self.failIf(IDirectoryNode.providedBy(n))
|
||||
self.failUnless(n.is_readonly())
|
||||
self.failIf(n.is_mutable())
|
||||
|
||||
n = c.create_node_from_uri("URI:SSK:n6x24zd3seu725yluj75q5boaa:mm6yoqjhl6ueh7iereldqxue4nene4wl7rqfjfybqrehdqmqskvq")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failUnless(IFileNode.providedBy(n))
|
||||
self.failIf(IImmutableFileNode.providedBy(n))
|
||||
self.failUnless(IMutableFileNode.providedBy(n))
|
||||
self.failIf(IDirectoryNode.providedBy(n))
|
||||
self.failIf(n.is_readonly())
|
||||
self.failUnless(n.is_mutable())
|
||||
|
||||
n = c.create_node_from_uri("URI:SSK-RO:b7sr5qsifnicca7cbk3rhrhbvq:mm6yoqjhl6ueh7iereldqxue4nene4wl7rqfjfybqrehdqmqskvq")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failUnless(IFileNode.providedBy(n))
|
||||
self.failIf(IImmutableFileNode.providedBy(n))
|
||||
self.failUnless(IMutableFileNode.providedBy(n))
|
||||
self.failIf(IDirectoryNode.providedBy(n))
|
||||
self.failUnless(n.is_readonly())
|
||||
self.failUnless(n.is_mutable())
|
||||
|
||||
n = c.create_node_from_uri("URI:DIR2:n6x24zd3seu725yluj75q5boaa:mm6yoqjhl6ueh7iereldqxue4nene4wl7rqfjfybqrehdqmqskvq")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failIf(IFileNode.providedBy(n))
|
||||
self.failIf(IImmutableFileNode.providedBy(n))
|
||||
self.failIf(IMutableFileNode.providedBy(n))
|
||||
self.failUnless(IDirectoryNode.providedBy(n))
|
||||
self.failIf(n.is_readonly())
|
||||
self.failUnless(n.is_mutable())
|
||||
@ -261,6 +293,8 @@ class NodeMaker(unittest.TestCase):
|
||||
n = c.create_node_from_uri("URI:DIR2-RO:b7sr5qsifnicca7cbk3rhrhbvq:mm6yoqjhl6ueh7iereldqxue4nene4wl7rqfjfybqrehdqmqskvq")
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failIf(IFileNode.providedBy(n))
|
||||
self.failIf(IImmutableFileNode.providedBy(n))
|
||||
self.failIf(IMutableFileNode.providedBy(n))
|
||||
self.failUnless(IDirectoryNode.providedBy(n))
|
||||
self.failUnless(n.is_readonly())
|
||||
self.failUnless(n.is_mutable())
|
||||
@ -269,5 +303,7 @@ class NodeMaker(unittest.TestCase):
|
||||
n = c.create_node_from_uri(future)
|
||||
self.failUnless(IFilesystemNode.providedBy(n))
|
||||
self.failIf(IFileNode.providedBy(n))
|
||||
self.failIf(IImmutableFileNode.providedBy(n))
|
||||
self.failIf(IMutableFileNode.providedBy(n))
|
||||
self.failIf(IDirectoryNode.providedBy(n))
|
||||
self.failUnlessEqual(n.get_uri(), future)
|
||||
|
@ -6,7 +6,7 @@ from twisted.internet import defer
|
||||
from allmydata import uri, dirnode
|
||||
from allmydata.client import Client
|
||||
from allmydata.immutable import upload
|
||||
from allmydata.interfaces import IFileNode, IMutableFileNode, \
|
||||
from allmydata.interfaces import IImmutableFileNode, IMutableFileNode, \
|
||||
ExistingChildError, NoSuchChildError, NotDeepImmutableError, \
|
||||
IDeepCheckResults, IDeepCheckAndRepairResults, CannotPackUnknownNodeError
|
||||
from allmydata.mutable.filenode import MutableFileNode
|
||||
@ -762,7 +762,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
uploadable1 = upload.Data("some data", convergence="converge")
|
||||
d.addCallback(lambda res: n.add_file(u"newfile", uploadable1))
|
||||
d.addCallback(lambda newnode:
|
||||
self.failUnless(IFileNode.providedBy(newnode)))
|
||||
self.failUnless(IImmutableFileNode.providedBy(newnode)))
|
||||
uploadable2 = upload.Data("some data", convergence="stuff")
|
||||
d.addCallback(lambda res:
|
||||
self.shouldFail(ExistingChildError, "add_file-no",
|
||||
@ -784,7 +784,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
uploadable3,
|
||||
{"key": "value"}))
|
||||
d.addCallback(lambda newnode:
|
||||
self.failUnless(IFileNode.providedBy(newnode)))
|
||||
self.failUnless(IImmutableFileNode.providedBy(newnode)))
|
||||
d.addCallback(lambda res: n.get_metadata_for(u"newfile-metadata"))
|
||||
d.addCallback(lambda metadata:
|
||||
self.failUnless((set(metadata.keys()) == set(["key", "tahoe"])) and
|
||||
|
@ -14,8 +14,8 @@ from foolscap.api import fireEventually
|
||||
|
||||
from allmydata.util import base32, time_format
|
||||
from allmydata.uri import from_string_dirnode
|
||||
from allmydata.interfaces import IDirectoryNode, IFileNode, IMutableFileNode, \
|
||||
IFilesystemNode, ExistingChildError, NoSuchChildError
|
||||
from allmydata.interfaces import IDirectoryNode, IFileNode, IFilesystemNode, \
|
||||
IImmutableFileNode, IMutableFileNode, ExistingChildError, NoSuchChildError
|
||||
from allmydata.monitor import Monitor, OperationCancelledError
|
||||
from allmydata import dirnode
|
||||
from allmydata.web.common import text_plain, WebError, \
|
||||
@ -40,8 +40,6 @@ class BlockingFileError(Exception):
|
||||
def make_handler_for(node, client, parentnode=None, name=None):
|
||||
if parentnode:
|
||||
assert IDirectoryNode.providedBy(parentnode)
|
||||
if IMutableFileNode.providedBy(node):
|
||||
return FileNodeHandler(client, node, parentnode, name)
|
||||
if IFileNode.providedBy(node):
|
||||
return FileNodeHandler(client, node, parentnode, name)
|
||||
if IDirectoryNode.providedBy(node):
|
||||
@ -687,7 +685,7 @@ class DirectoryAsHTML(rend.Page):
|
||||
|
||||
info_link = "%s/uri/%s?t=info" % (root, quoted_uri)
|
||||
|
||||
elif IFileNode.providedBy(target):
|
||||
elif IImmutableFileNode.providedBy(target):
|
||||
dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)
|
||||
|
||||
ctx.fillSlots("filename",
|
||||
@ -789,17 +787,16 @@ def DirectoryJSONMetadata(ctx, dirnode):
|
||||
assert IFilesystemNode.providedBy(childnode), childnode
|
||||
rw_uri = childnode.get_uri()
|
||||
ro_uri = childnode.get_readonly_uri()
|
||||
if (IDirectoryNode.providedBy(childnode)
|
||||
or IFileNode.providedBy(childnode)):
|
||||
if IFileNode.providedBy(childnode):
|
||||
if childnode.is_readonly():
|
||||
rw_uri = None
|
||||
if IFileNode.providedBy(childnode):
|
||||
kiddata = ("filenode", {'size': childnode.get_size(),
|
||||
'mutable': childnode.is_mutable(),
|
||||
})
|
||||
elif IDirectoryNode.providedBy(childnode):
|
||||
kiddata = ("dirnode", {'mutable': childnode.is_mutable(),
|
||||
})
|
||||
if childnode.is_readonly():
|
||||
rw_uri = None
|
||||
kiddata = ("dirnode", {'mutable': childnode.is_mutable()})
|
||||
else:
|
||||
kiddata = ("unknown", {})
|
||||
kiddata[1]["metadata"] = metadata
|
||||
|
Loading…
Reference in New Issue
Block a user