dirnode.py: dirnode.delete which hits UCWE should not fail with NoSuchChildError. Fixes #550.

This commit is contained in:
Brian Warner
2008-12-05 22:08:37 -07:00
parent fb9af2c7a0
commit 7a0afb59a4
2 changed files with 46 additions and 2 deletions

View File

@ -27,7 +27,7 @@ class Deleter:
def modify(self, old_contents, servermap, first_time): def modify(self, old_contents, servermap, first_time):
children = self.node._unpack_contents(old_contents) children = self.node._unpack_contents(old_contents)
if self.name not in children: if self.name not in children:
if self.must_exist: if first_time and self.must_exist:
raise NoSuchChildError(self.name) raise NoSuchChildError(self.name)
self.old_child = None self.old_child = None
return None return None

View File

@ -9,10 +9,12 @@ from allmydata.interfaces import IURI, IClient, IMutableFileNode, \
INewDirectoryURI, IReadonlyNewDirectoryURI, IFileNode, \ INewDirectoryURI, IReadonlyNewDirectoryURI, IFileNode, \
ExistingChildError, NoSuchChildError, \ ExistingChildError, NoSuchChildError, \
IDeepCheckResults, IDeepCheckAndRepairResults IDeepCheckResults, IDeepCheckAndRepairResults
from allmydata.mutable.node import MutableFileNode
from allmydata.mutable.common import UncoordinatedWriteError
from allmydata.util import hashutil, base32 from allmydata.util import hashutil, base32
from allmydata.monitor import Monitor from allmydata.monitor import Monitor
from allmydata.test.common import make_chk_file_uri, make_mutable_file_uri, \ from allmydata.test.common import make_chk_file_uri, make_mutable_file_uri, \
FakeDirectoryNode, create_chk_filenode, ErrorMixin FakeDirectoryNode, create_chk_filenode, ErrorMixin, SystemTestMixin
from allmydata.checker_results import CheckerResults, CheckAndRepairResults from allmydata.checker_results import CheckerResults, CheckAndRepairResults
import common_util as testutil import common_util as testutil
@ -761,3 +763,45 @@ class DeepStats(unittest.TestCase):
(3162277660169L, 10000000000000L, 1), (3162277660169L, 10000000000000L, 1),
]) ])
class UCWEingMutableFileNode(MutableFileNode):
please_ucwe_after_next_upload = False
def _upload(self, new_contents, servermap):
d = MutableFileNode._upload(self, new_contents, servermap)
def _ucwe(res):
raise UncoordinatedWriteError()
d.addCallback(_ucwe)
return d
class UCWEingNewDirectoryNode(dirnode.NewDirectoryNode):
filenode_class = UCWEingMutableFileNode
class Deleter(SystemTestMixin, unittest.TestCase):
def test_retry(self):
# ticket #550, a dirnode.delete which experiences an
# UncoordinatedWriteError will fail with an incorrect "you're
# deleting something which isn't there" NoSuchChildError exception.
# to trigger this, we start by creating a directory with a single
# file in it. Then we create a special dirnode that uses a modified
# MutableFileNode which will raise UncoordinatedWriteError once on
# demand. We then call dirnode.delete, which ought to retry and
# succeed.
self.basedir = self.mktemp()
d = self.set_up_nodes()
d.addCallback(lambda ignored: self.clients[0].create_empty_dirnode())
small = upload.Data("Small enough for a LIT", None)
def _created_dir(dn):
self.root = dn
self.root_uri = dn.get_uri()
return dn.add_file(u"file", small)
d.addCallback(_created_dir)
def _do_delete(ignored):
n = UCWEingNewDirectoryNode(self.clients[0]).init_from_uri(self.root_uri)
# This should succeed, not raise an exception
return n.delete(u"file")
d.addCallback(_do_delete)
return d