return shares
- def replace_shares(self, newshares):
+ def replace_shares(self, newshares, storage_index):
"""Replace shares on disk. Takes a dictionary in the same form
as find_shares() returns."""
else:
pathtosharefile = os.path.join(sharedir, dirp, fn)
os.unlink(pathtosharefile)
- newdata = newshares.get((i, sharenum))
- if newdata is not None:
- open(pathtosharefile, "w").write(newdata)
+ for ((clientnum, sharenum), newdata) in newshares.iteritems():
+ if clientnum == i:
+ fullsharedirp=os.path.join(sharedir, storage_index[:2], storage_index)
+ fileutil.make_dirs(fullsharedirp)
+ wf = open(os.path.join(fullsharedirp, str(sharenum)), "w")
+ wf.write(newdata)
class ShouldFailMixin:
def shouldFail(self, expected_failure, which, substring,
-from allmydata.immutable import upload
+from allmydata.immutable import encode, upload
from allmydata.test.common import SystemTestMixin, ShareManglingMixin
from allmydata.util import testutil
+from allmydata.interfaces import IURI
from twisted.internet import defer
from twisted.trial import unittest
import random, struct
def _upload_a_file(ignored):
d2 = self.clients[0].upload(upload.Data(TEST_DATA, convergence=""))
def _after_upload(u):
- self.uri = u.uri
+ self.uri = IURI(u.uri)
return self.clients[0].create_node_from_uri(self.uri)
d2.addCallback(_after_upload)
return d2
else:
k = random.choice(ks)
del shares[k]
- self.replace_shares(shares)
+ self.replace_shares(shares, storage_index=self.uri.storage_index)
return unused
corrupteddata = data[:0xc]+corruptedsharedata+data[0xc+size:]
shares[k] = corrupteddata
- self.replace_shares(shares)
+ self.replace_shares(shares, storage_index=self.uri.storage_index)
return unused
return res
d.addCallback(_stash_it)
- d.addCallback(self.replace_shares)
+ d.addCallback(self.replace_shares, storage_index=self.uri.storage_index)
def _compare(res):
oldshares = stash[0]
d.addCallback(self.find_shares)
d.addCallback(_compare)
- d.addCallback(lambda ignore: self.replace_shares({}))
+ d.addCallback(lambda ignore: self.replace_shares({}, storage_index=self.uri.storage_index))
d.addCallback(self.find_shares)
d.addCallback(lambda x: self.failUnlessEqual(x, {}))
+ # The following process of deleting 8 of the shares and asserting that you can't
+ # download it is more to test this test code than to test the Tahoe code...
+ def _then_delete_8(unused=None):
+ self.replace_shares(stash[0], storage_index=self.uri.storage_index)
+ for sharenum in range(2, 10):
+ self._delete_a_share()
+ d.addCallback(_then_delete_8)
+
+ def _then_download(unused=None):
+ self.downloader = self.clients[1].getServiceNamed("downloader")
+ d = self.downloader.download_to_data(self.uri)
+
+ def _after_download_callb(result):
+ self.fail() # should have gotten an errback instead
+ return result
+ def _after_download_errb(failure):
+ failure.trap(encode.NotEnoughSharesError)
+ return None # success!
+ d.addCallbacks(_after_download_callb, _after_download_errb)
+ d.addCallback(_then_download)
+
+ # The following process of leaving 8 of the shares deleted and asserting that you can't
+ # repair it is more to test this test code than to test the Tahoe code...
+ def _then_repair(unused=None):
+ d2 = self.filenode.check_and_repair(verify=False)
+ def _after_repair(checkandrepairresults):
+ prerepairres = checkandrepairresults.get_pre_repair_results()
+ postrepairres = checkandrepairresults.get_post_repair_results()
+ self.failIf(prerepairres.is_healthy())
+ self.failIf(postrepairres.is_healthy())
+ d2.addCallback(_after_repair)
+ return d2
+ d.addCallback(_then_repair)
return d
def _count_reads(self):
d.addCallback(_check2)
return d
- d.addCallback(lambda ignore: self.replace_shares({}))
+ d.addCallback(lambda ignore: self.replace_shares({}, storage_index=self.uri.storage_index))
def _check3(ignored):
before_check_reads = self._count_reads()
d2 = self.filenode.check(verify=False)
# assert that it succeeds at downloading and has the right contents. This can't
# work unless it has already repaired the previously-deleted share #2.
for sharenum in range(3, 10):
- self._delete_a_share(sharenum)
+ self._delete_a_share(sharenum=sharenum)
return self._download_and_check_plaintext()