-
import os, re, base64
from cStringIO import StringIO
from twisted.trial import unittest
reader = MDMFSlotReadProxy(None, None, shnum, data)
# We need to get the offsets for the next part.
d = reader.get_verinfo()
- def _do_corruption(verinfo, data, shnum):
+ def _do_corruption(verinfo, data, shnum, shares):
(seqnum,
root_hash,
IV,
else:
f = flip_bit
shares[shnum] = f(data, real_offset)
- d.addCallback(_do_corruption, data, shnum)
+ d.addCallback(_do_corruption, data, shnum, shares)
ds.append(d)
dl = defer.DeferredList(ds)
dl.addCallback(lambda ignored: res)
keygen.set_default_keysize(TEST_RSA_KEY_SIZE)
nodemaker = NodeMaker(storage_broker, sh, None,
None, None,
- {"k": 3, "n": 10}, keygen)
+ {"k": 3, "n": 10}, SDMF_VERSION, keygen)
return nodemaker
class Filenode(unittest.TestCase, testutil.ShouldFailMixin):
self.nodemaker.default_encoding_parameters['n'] = 1
d = defer.succeed(None)
for v in (SDMF_VERSION, MDMF_VERSION):
- d.addCallback(lambda ignored:
+ d.addCallback(lambda ignored, v=v:
self.nodemaker.create_mutable_file(version=v))
def _created(n):
self.failUnless(isinstance(n, MutableFileNode))
return d
- def test_create_from_mdmf_writecap_with_extensions(self):
- # Test that the nodemaker is capable of creating an MDMF
- # filenode when given a writecap with extension parameters in
- # them.
- d = self.nodemaker.create_mutable_file(version=MDMF_VERSION)
- def _created(n):
- self.failUnless(isinstance(n, MutableFileNode))
- s = n.get_uri()
- # We need to cheat a little and delete the nodemaker's
- # cache, otherwise we'll get the same node instance back.
- self.failUnlessIn(":3:131073", s)
- n2 = self.nodemaker.create_from_cap(s)
-
- self.failUnlessEqual(n2.get_storage_index(), n.get_storage_index())
- self.failUnlessEqual(n.get_writekey(), n2.get_writekey())
- hints = n2._downloader_hints
- self.failUnlessEqual(hints['k'], 3)
- self.failUnlessEqual(hints['segsize'], 131073)
- d.addCallback(_created)
- return d
-
-
def test_create_from_mdmf_readcap(self):
d = self.nodemaker.create_mutable_file(version=MDMF_VERSION)
def _created(n):
return d
- def test_create_from_mdmf_readcap_with_extensions(self):
- # We should be able to create an MDMF filenode with the
- # extension parameters without it breaking.
- d = self.nodemaker.create_mutable_file(version=MDMF_VERSION)
- def _created(n):
- self.failUnless(isinstance(n, MutableFileNode))
- s = n.get_readonly_uri()
- self.failUnlessIn(":3:131073", s)
-
- n2 = self.nodemaker.create_from_cap(s)
- self.failUnless(isinstance(n2, MutableFileNode))
- self.failUnless(n2.is_readonly())
- self.failUnlessEqual(n.get_storage_index(), n2.get_storage_index())
- hints = n2._downloader_hints
- self.failUnlessEqual(hints["k"], 3)
- self.failUnlessEqual(hints["segsize"], 131073)
- d.addCallback(_created)
- return d
-
-
def test_internal_version_from_cap(self):
# MutableFileNodes and MutableFileVersions have an internal
# switch that tells them whether they're dealing with an SDMF or
d = self.nodemaker.create_mutable_file(version=MDMF_VERSION)
def _created(node):
self.uri = node.get_uri()
+ # also confirm that the cap has no extension fields
+ pieces = self.uri.split(":")
+ self.failUnlessEqual(len(pieces), 4)
return node.overwrite(MutableData("contents1" * 100000))
def _then(ignored):
return d
- def test_create_and_download_from_bare_mdmf_cap(self):
- # MDMF caps have extension parameters on them by default. We
- # need to make sure that they work without extension parameters.
- contents = MutableData("contents" * 100000)
- d = self.nodemaker.create_mutable_file(version=MDMF_VERSION,
- contents=contents)
- def _created(node):
- uri = node.get_uri()
- self._created = node
- self.failUnlessIn(":3:131073", uri)
- # Now strip that off the end of the uri, then try creating
- # and downloading the node again.
- bare_uri = uri.replace(":3:131073", "")
- assert ":3:131073" not in bare_uri
-
- return self.nodemaker.create_from_cap(bare_uri)
- d.addCallback(_created)
- def _created_bare(node):
- self.failUnlessEqual(node.get_writekey(),
- self._created.get_writekey())
- self.failUnlessEqual(node.get_readkey(),
- self._created.get_readkey())
- self.failUnlessEqual(node.get_storage_index(),
- self._created.get_storage_index())
- return node.download_best_version()
- d.addCallback(_created_bare)
- d.addCallback(lambda data:
- self.failUnlessEqual(data, "contents" * 100000))
- return d
-
-
def test_mdmf_write_count(self):
# Publishing an MDMF file should only cause one write for each
# share that is to be published. Otherwise, we introduce
return self.do_publish_surprise(SDMF_VERSION)
def test_publish_surprise_mdmf(self):
- raise unittest.SkipTest("this currently triggers a decoding error in unpack_checkstring (see #1540)")
return self.do_publish_surprise(MDMF_VERSION)
def test_retrieve_surprise(self):
self.failUnlessEqual(data, CONTENTS))
return d
+ def test_1654(self):
+ # test that the Retrieve object unconditionally verifies the block
+ # hash tree root for mutable shares. The failure mode is that
+ # carefully crafted shares can cause undetected corruption (the
+ # retrieve appears to finish successfully, but the result is
+ # corrupted). When fixed, these shares always cause a
+ # CorruptShareError, which results in NotEnoughSharesError in this
+ # 2-of-2 file.
+ self.basedir = "mutable/Problems/test_1654"
+ self.set_up_grid(num_servers=2)
+ cap = uri.from_string(TEST_1654_CAP)
+ si = cap.get_storage_index()
+
+ for share, shnum in [(TEST_1654_SH0, 0), (TEST_1654_SH1, 1)]:
+ sharedata = base64.b64decode(share)
+ storedir = self.get_serverdir(shnum)
+ storage_path = os.path.join(storedir, "shares",
+ storage_index_to_dir(si))
+ fileutil.make_dirs(storage_path)
+ fileutil.write(os.path.join(storage_path, "%d" % shnum),
+ sharedata)
+
+ nm = self.g.clients[0].nodemaker
+ n = nm.create_from_cap(TEST_1654_CAP)
+ # to exercise the problem correctly, we must ensure that sh0 is
+ # processed first, and sh1 second. NoNetworkGrid has facilities to
+ # stall the first request from a single server, but it's not
+ # currently easy to extend that to stall the second request (mutable
+ # retrievals will see two: first the mapupdate, then the fetch).
+ # However, repeated executions of this run without the #1654 fix
+ # suggests that we're failing reliably even without explicit stalls,
+ # probably because the servers are queried in a fixed order. So I'm
+ # ok with relying upon that.
+ d = self.shouldFail(NotEnoughSharesError, "test #1654 share corruption",
+ "ran out of peers",
+ n.download_best_version)
+ return d
+
+
+TEST_1654_CAP = "URI:SSK:6jthysgozssjnagqlcxjq7recm:yxawei54fmf2ijkrvs2shs6iey4kpdp6joi7brj2vrva6sp5nf3a"
+
+TEST_1654_SH0 = """\
+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
+72mXGlqyLyWYuAAAAAA="""
+
+TEST_1654_SH1 = """\
+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
+72mXGlqyLyWYuAAAAAA="""
+
class FileHandle(unittest.TestCase):
def setUp(self):
return d
- def test_version_extension_api(self):
- # We need to define an API by which an uploader can set the
- # extension parameters, and by which a downloader can retrieve
- # extensions.
- d = self.do_upload_mdmf()
- d.addCallback(lambda ign: self.mdmf_node.get_best_mutable_version())
- def _got_version(version):
- hints = version.get_downloader_hints()
- # Should be empty at this point.
- self.failUnlessIn("k", hints)
- self.failUnlessEqual(hints['k'], 3)
- self.failUnlessIn('segsize', hints)
- self.failUnlessEqual(hints['segsize'], 131073)
- d.addCallback(_got_version)
- return d
-
-
- def test_extensions_from_cap(self):
- # If we initialize a mutable file with a cap that has extension
- # parameters in it and then grab the extension parameters using
- # our API, we should see that they're set correctly.
- d = self.do_upload_mdmf()
- def _then(ign):
- mdmf_uri = self.mdmf_node.get_uri()
- new_node = self.nm.create_from_cap(mdmf_uri)
- return new_node.get_best_mutable_version()
- d.addCallback(_then)
- def _got_version(version):
- hints = version.get_downloader_hints()
- self.failUnlessIn("k", hints)
- self.failUnlessEqual(hints["k"], 3)
- self.failUnlessIn("segsize", hints)
- self.failUnlessEqual(hints["segsize"], 131073)
- d.addCallback(_got_version)
- return d
-
-
- def test_extensions_from_upload(self):
- # If we create a new mutable file with some contents, we should
- # get back an MDMF cap with the right hints in place.
- contents = "foo bar baz" * 100000
- d = self.nm.create_mutable_file(contents, version=MDMF_VERSION)
- def _got_mutable_file(n):
- rw_uri = n.get_uri()
- expected_k = str(self.c.DEFAULT_ENCODING_PARAMETERS['k'])
- self.failUnlessIn(expected_k, rw_uri)
- # XXX: Get this more intelligently.
- self.failUnlessIn("131073", rw_uri)
-
- ro_uri = n.get_readonly_uri()
- self.failUnlessIn(expected_k, ro_uri)
- self.failUnlessIn("131073", ro_uri)
- d.addCallback(_got_mutable_file)
- return d
-
-
def test_cap_after_upload(self):
# If we create a new mutable file and upload things to it, and
# it's an MDMF file, we should get an MDMF cap back from that
def _run(ign):
d = defer.succeed(None)
for node in (self.mdmf_node, self.mdmf_max_shares_node):
- d.addCallback(lambda ign: node.get_best_mutable_version())
+ # close over 'node'.
+ d.addCallback(lambda ign, node=node:
+ node.get_best_mutable_version())
d.addCallback(lambda mv:
- mv.update(MutableData(new_data), offset))
- # close around node.
- d.addCallback(lambda ignored, node=node:
- node.download_best_version())
+ mv.update(MutableData(new_data), offset))
+ d.addCallback(lambda ign, node=node:
+ node.download_best_version())
def _check(results):
if results != expected:
print
def _run(ign):
d = defer.succeed(None)
for node in (self.mdmf_node, self.mdmf_max_shares_node):
- d.addCallback(lambda ign: node.get_best_mutable_version())
+ # close over 'node'.
+ d.addCallback(lambda ign, node=node:
+ node.get_best_mutable_version())
d.addCallback(lambda mv:
- mv.update(MutableData(segment * 2), len(self.data)))
- d.addCallback(lambda ignored, node=node:
- node.download_best_version())
+ mv.update(MutableData(segment * 2), len(self.data)))
+ d.addCallback(lambda ign, node=node:
+ node.download_best_version())
d.addCallback(lambda results:
- self.failUnlessEqual(results, new_data))
+ self.failUnlessEqual(results, new_data))
return d
d0.addCallback(_run)
return d0
def _run(ign):
d = defer.succeed(None)
for node in (self.sdmf_node, self.sdmf_max_shares_node):
- d.addCallback(lambda ign: node.get_best_mutable_version())
+ # close over 'node'.
+ d.addCallback(lambda ign, node=node:
+ node.get_best_mutable_version())
d.addCallback(lambda mv:
- mv.update(MutableData("appended"), len(self.small_data)))
- d.addCallback(lambda ignored, node=node:
- node.download_best_version())
+ mv.update(MutableData("appended"), len(self.small_data)))
+ d.addCallback(lambda ign, node=node:
+ node.download_best_version())
d.addCallback(lambda results:
- self.failUnlessEqual(results, new_data))
+ self.failUnlessEqual(results, new_data))
return d
d0.addCallback(_run)
return d0
def _run(ign):
d = defer.succeed(None)
for node in (self.mdmf_node, self.mdmf_max_shares_node):
- d.addCallback(lambda ign: node.get_best_mutable_version())
+ # close over 'node'.
+ d.addCallback(lambda ign, node=node:
+ node.get_best_mutable_version())
d.addCallback(lambda mv:
- mv.update(MutableData("replaced"), replace_offset))
- d.addCallback(lambda ignored, node=node:
- node.download_best_version())
+ mv.update(MutableData("replaced"), replace_offset))
+ d.addCallback(lambda ign, node=node:
+ node.download_best_version())
d.addCallback(lambda results:
- self.failUnlessEqual(results, new_data))
+ self.failUnlessEqual(results, new_data))
return d
d0.addCallback(_run)
return d0
def _run(ign):
d = defer.succeed(None)
for node in (self.mdmf_node, self.mdmf_max_shares_node):
- d.addCallback(lambda ign: node.get_best_mutable_version())
+ # close over 'node'.
+ d.addCallback(lambda ign, node=node:
+ node.get_best_mutable_version())
d.addCallback(lambda mv:
- mv.update(MutableData((2 * new_segment) + "replaced"),
- replace_offset))
+ mv.update(MutableData((2 * new_segment) + "replaced"),
+ replace_offset))
d.addCallback(lambda ignored, node=node:
- node.download_best_version())
+ node.download_best_version())
d.addCallback(lambda results:
- self.failUnlessEqual(results, new_data))
+ self.failUnlessEqual(results, new_data))
return d
d0.addCallback(_run)
return d0