mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-23 23:02:25 +00:00
test_deepcheck: convert MutableChecker to no-network GridTest
This commit is contained in:
parent
2e7f64d392
commit
6cf4096156
@ -13,7 +13,9 @@ from allmydata.interfaces import IURI, IMutableFileNode, IFileNode, \
|
||||
from allmydata.check_results import CheckResults, CheckAndRepairResults, \
|
||||
DeepCheckResults, DeepCheckAndRepairResults
|
||||
from allmydata.mutable.common import CorruptShareError
|
||||
from allmydata.mutable.layout import unpack_header
|
||||
from allmydata.storage.server import storage_index_to_dir
|
||||
from allmydata.storage.mutable import MutableShareFile
|
||||
from allmydata.util import hashutil, log, fileutil, pollmixin
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.stats import StatsGathererService
|
||||
@ -1255,11 +1257,24 @@ def _corrupt_offset_of_uri_extension_to_force_short_read(data, debug=False):
|
||||
log.msg("testing: corrupting offset %d, size %d, changing %d to %d (len(data) == %d)" % (0x48, 8, struct.unpack(">Q", data[0x48:0x48+8])[0], len(data)-0x0c-3, len(data)))
|
||||
return data[:0x48] + struct.pack(">Q", len(data)-0x0c-3) + data[0x48+8:]
|
||||
|
||||
def _corrupt_mutable_share_data(data):
|
||||
prefix = data[:32]
|
||||
assert prefix == MutableShareFile.MAGIC, "This function is designed to corrupt mutable shares of v1, and the magic number doesn't look right: %r vs %r" % (prefix, MutableShareFile.MAGIC)
|
||||
data_offset = MutableShareFile.DATA_OFFSET
|
||||
sharetype = data[data_offset:data_offset+1]
|
||||
assert sharetype == "\x00", "non-SDMF mutable shares not supported"
|
||||
(version, ig_seqnum, ig_roothash, ig_IV, ig_k, ig_N, ig_segsize,
|
||||
ig_datalen, offsets) = unpack_header(data[data_offset:])
|
||||
assert version == 0, "this function only handles v0 SDMF files"
|
||||
start = data_offset + offsets["share_data"]
|
||||
length = data_offset + offsets["enc_privkey"] - start
|
||||
return corrupt_field(data, start, length)
|
||||
|
||||
def _corrupt_share_data(data):
|
||||
""" Scramble the file data -- the field containing the share data itself will have one
|
||||
bit flipped or else will be changed to a random value. """
|
||||
sharevernum = struct.unpack(">L", data[0x0c:0x0c+4])[0]
|
||||
assert sharevernum in (1, 2), "This test is designed to corrupt immutable shares of v1 or v2 in specific ways."
|
||||
assert sharevernum in (1, 2), "This test is designed to corrupt immutable shares of v1 or v2 in specific ways, not v%d." % sharevernum
|
||||
if sharevernum == 1:
|
||||
sharedatasize = struct.unpack(">L", data[0x0c+0x08:0x0c+0x08+4])[0]
|
||||
|
||||
|
@ -13,9 +13,11 @@ from allmydata.interfaces import ICheckResults, ICheckAndRepairResults, \
|
||||
from allmydata.monitor import Monitor, OperationCancelledError
|
||||
from twisted.web.client import getPage
|
||||
|
||||
from allmydata.test.common import SystemTestMixin, ErrorMixin
|
||||
from allmydata.test.common import SystemTestMixin, ErrorMixin, \
|
||||
_corrupt_mutable_share_data
|
||||
from allmydata.test.no_network import GridTestMixin
|
||||
|
||||
class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
class MutableChecker(GridTestMixin, unittest.TestCase, ErrorMixin):
|
||||
|
||||
def _run_cli(self, argv):
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
@ -25,21 +27,18 @@ class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
return stdout.getvalue()
|
||||
|
||||
def test_good(self):
|
||||
self.basedir = self.mktemp()
|
||||
d = self.set_up_nodes()
|
||||
self.basedir = "deepcheck/MutableChecker/good"
|
||||
self.set_up_grid()
|
||||
CONTENTS = "a little bit of data"
|
||||
d.addCallback(lambda res: self.clients[0].create_mutable_file(CONTENTS))
|
||||
d = self.g.clients[0].create_mutable_file(CONTENTS)
|
||||
def _created(node):
|
||||
self.node = node
|
||||
self.fileurl = "uri/" + urllib.quote(node.get_uri())
|
||||
si = self.node.get_storage_index()
|
||||
d.addCallback(_created)
|
||||
# now make sure the webapi verifier sees no problems
|
||||
def _do_check(res):
|
||||
url = (self.webish_url +
|
||||
"uri/%s" % urllib.quote(self.node.get_uri()) +
|
||||
"?t=check&verify=true")
|
||||
return getPage(url, method="POST")
|
||||
d.addCallback(_do_check)
|
||||
d.addCallback(lambda ign: self.GET(self.fileurl+"?t=check&verify=true",
|
||||
method="POST"))
|
||||
def _got_results(out):
|
||||
self.failUnless("<span>Healthy : Healthy</span>" in out, out)
|
||||
self.failUnless("Recoverable Versions: 10*seq1-" in out, out)
|
||||
@ -51,31 +50,19 @@ class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
return d
|
||||
|
||||
def test_corrupt(self):
|
||||
self.basedir = self.mktemp()
|
||||
d = self.set_up_nodes()
|
||||
self.basedir = "deepcheck/MutableChecker/corrupt"
|
||||
self.set_up_grid()
|
||||
CONTENTS = "a little bit of data"
|
||||
d.addCallback(lambda res: self.clients[0].create_mutable_file(CONTENTS))
|
||||
def _created(node):
|
||||
d = self.g.clients[0].create_mutable_file(CONTENTS)
|
||||
def _stash_and_corrupt(node):
|
||||
self.node = node
|
||||
si = self.node.get_storage_index()
|
||||
out = self._run_cli(["debug", "find-shares", base32.b2a(si),
|
||||
self.clients[1].basedir])
|
||||
files = out.split("\n")
|
||||
# corrupt one of them, using the CLI debug command
|
||||
f = files[0]
|
||||
shnum = os.path.basename(f)
|
||||
nodeid = self.clients[1].nodeid
|
||||
nodeid_prefix = idlib.shortnodeid_b2a(nodeid)
|
||||
self.corrupt_shareid = "%s-sh%s" % (nodeid_prefix, shnum)
|
||||
out = self._run_cli(["debug", "corrupt-share", files[0]])
|
||||
d.addCallback(_created)
|
||||
self.fileurl = "uri/" + urllib.quote(node.get_uri())
|
||||
self.corrupt_shares_numbered(node.get_uri(), [0],
|
||||
_corrupt_mutable_share_data)
|
||||
d.addCallback(_stash_and_corrupt)
|
||||
# now make sure the webapi verifier notices it
|
||||
def _do_check(res):
|
||||
url = (self.webish_url +
|
||||
"uri/%s" % urllib.quote(self.node.get_uri()) +
|
||||
"?t=check&verify=true")
|
||||
return getPage(url, method="POST")
|
||||
d.addCallback(_do_check)
|
||||
d.addCallback(lambda ign: self.GET(self.fileurl+"?t=check&verify=true",
|
||||
method="POST"))
|
||||
def _got_results(out):
|
||||
self.failUnless("Not Healthy!" in out, out)
|
||||
self.failUnless("Unhealthy: best version has only 9 shares (encoding is 3-of-10)" in out, out)
|
||||
@ -83,16 +70,14 @@ class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
d.addCallback(_got_results)
|
||||
|
||||
# now make sure the webapi repairer can fix it
|
||||
def _do_repair(res):
|
||||
url = (self.webish_url +
|
||||
"uri/%s" % urllib.quote(self.node.get_uri()) +
|
||||
"?t=check&verify=true&repair=true")
|
||||
return getPage(url, method="POST")
|
||||
d.addCallback(_do_repair)
|
||||
d.addCallback(lambda ign:
|
||||
self.GET(self.fileurl+"?t=check&verify=true&repair=true",
|
||||
method="POST"))
|
||||
def _got_repair_results(out):
|
||||
self.failUnless("<div>Repair successful</div>" in out, out)
|
||||
d.addCallback(_got_repair_results)
|
||||
d.addCallback(_do_check)
|
||||
d.addCallback(lambda ign: self.GET(self.fileurl+"?t=check&verify=true",
|
||||
method="POST"))
|
||||
def _got_postrepair_results(out):
|
||||
self.failIf("Not Healthy!" in out, out)
|
||||
self.failUnless("Recoverable Versions: 10*seq" in out, out)
|
||||
@ -102,31 +87,18 @@ class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
return d
|
||||
|
||||
def test_delete_share(self):
|
||||
self.basedir = self.mktemp()
|
||||
d = self.set_up_nodes()
|
||||
self.basedir = "deepcheck/MutableChecker/delete_share"
|
||||
self.set_up_grid()
|
||||
CONTENTS = "a little bit of data"
|
||||
d.addCallback(lambda res: self.clients[0].create_mutable_file(CONTENTS))
|
||||
def _created(node):
|
||||
d = self.g.clients[0].create_mutable_file(CONTENTS)
|
||||
def _stash_and_delete(node):
|
||||
self.node = node
|
||||
si = self.node.get_storage_index()
|
||||
out = self._run_cli(["debug", "find-shares", base32.b2a(si),
|
||||
self.clients[1].basedir])
|
||||
files = out.split("\n")
|
||||
# corrupt one of them, using the CLI debug command
|
||||
f = files[0]
|
||||
shnum = os.path.basename(f)
|
||||
nodeid = self.clients[1].nodeid
|
||||
nodeid_prefix = idlib.shortnodeid_b2a(nodeid)
|
||||
self.corrupt_shareid = "%s-sh%s" % (nodeid_prefix, shnum)
|
||||
os.unlink(files[0])
|
||||
d.addCallback(_created)
|
||||
self.fileurl = "uri/" + urllib.quote(node.get_uri())
|
||||
self.delete_shares_numbered(node.get_uri(), [0])
|
||||
d.addCallback(_stash_and_delete)
|
||||
# now make sure the webapi checker notices it
|
||||
def _do_check(res):
|
||||
url = (self.webish_url +
|
||||
"uri/%s" % urllib.quote(self.node.get_uri()) +
|
||||
"?t=check&verify=false")
|
||||
return getPage(url, method="POST")
|
||||
d.addCallback(_do_check)
|
||||
d.addCallback(lambda ign: self.GET(self.fileurl+"?t=check&verify=false",
|
||||
method="POST"))
|
||||
def _got_results(out):
|
||||
self.failUnless("Not Healthy!" in out, out)
|
||||
self.failUnless("Unhealthy: best version has only 9 shares (encoding is 3-of-10)" in out, out)
|
||||
@ -134,16 +106,14 @@ class MutableChecker(SystemTestMixin, unittest.TestCase, ErrorMixin):
|
||||
d.addCallback(_got_results)
|
||||
|
||||
# now make sure the webapi repairer can fix it
|
||||
def _do_repair(res):
|
||||
url = (self.webish_url +
|
||||
"uri/%s" % urllib.quote(self.node.get_uri()) +
|
||||
"?t=check&verify=false&repair=true")
|
||||
return getPage(url, method="POST")
|
||||
d.addCallback(_do_repair)
|
||||
d.addCallback(lambda ign:
|
||||
self.GET(self.fileurl+"?t=check&verify=false&repair=true",
|
||||
method="POST"))
|
||||
def _got_repair_results(out):
|
||||
self.failUnless("Repair successful" in out)
|
||||
d.addCallback(_got_repair_results)
|
||||
d.addCallback(_do_check)
|
||||
d.addCallback(lambda ign: self.GET(self.fileurl+"?t=check&verify=false",
|
||||
method="POST"))
|
||||
def _got_postrepair_results(out):
|
||||
self.failIf("Not Healthy!" in out, out)
|
||||
self.failUnless("Recoverable Versions: 10*seq" in out)
|
||||
|
Loading…
Reference in New Issue
Block a user