From 9ca55b8b79fb0d92d5999b9466cc66218058a0c7 Mon Sep 17 00:00:00 2001 From: Brian Warner <warner@lothar.com> Date: Mon, 10 Mar 2008 23:16:28 -0700 Subject: [PATCH] test_mutable: make test-multiple-encodings work --- src/allmydata/test/test_mutable.py | 77 +++++++++++++++++++----------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py index f0a04273..395c2441 100644 --- a/src/allmydata/test/test_mutable.py +++ b/src/allmydata/test/test_mutable.py @@ -5,6 +5,7 @@ from twisted.trial import unittest from twisted.internet import defer, reactor from twisted.python import failure from allmydata import mutable, uri, dirnode, download +from allmydata.util.idlib import shortnodeid_b2a from allmydata.util.hashutil import tagged_hash from allmydata.encode import NotEnoughPeersError from allmydata.interfaces import IURI, INewDirectoryURI, \ @@ -88,7 +89,7 @@ class FakeStorage: if peerid in pending: d, shares = pending.pop(peerid) eventually(d.callback, shares) - for (d, shares) in pending.items(): + for (d, shares) in pending.values(): eventually(d.callback, shares) def write(self, peerid, storage_index, shnum, offset, data): @@ -704,7 +705,7 @@ class Roundtrip(unittest.TestCase): d.addCallback(_retrieved) return d - def OFF_test_multiple_encodings(self): # not finished yet + def test_multiple_encodings(self): # we encode the same file in two different ways (3-of-10 and 4-of-9), # then mix up the shares, to make sure that download survives seeing # a variety of encodings. This is actually kind of tricky to set up. @@ -763,45 +764,63 @@ class Roundtrip(unittest.TestCase): d.addCallback(_published_2) def _merge(res): log.msg("merging sharelists") - print len(self._shares1), len(self._shares2) - from allmydata.util import idlib - # we rearrange the shares, removing them from their original - # homes. - shares1 = self._shares1.values() - shares2 = self._shares2.values() - - print len(shares1), len(shares2) - # then we place shares in the following order: + # we merge the shares from the two sets, leaving each shnum in + # its original location, but using a share from set1 or set2 + # according to the following sequence: + # # 4-of-9 a s2 # 4-of-9 b s2 # 4-of-9 c s2 # 3-of-9 d s1 # 3-of-9 e s1 - # 4-of-9 f s2 - # 3-of-9 g s1 - # so that neither form can be recovered until fetch [f]. Later, - # when we implement code that handles multiple versions, we can - # use this framework to assert that all recoverable versions are - # retrieved, and test that 'epsilon' does its job - places = [2, 2, 2, 1, 1, 2, 1] + # 3-of-9 f s1 + # 4-of-9 g s2 + # + # so that neither form can be recovered until fetch [f], at which + # point version-s1 (the 3-of-10 form) should be recoverable. If + # the implementation latches on to the first version it sees, + # then s2 will be recoverable at fetch [g]. + + # Later, when we implement code that handles multiple versions, + # we can use this framework to assert that all recoverable + # versions are retrieved, and test that 'epsilon' does its job + + places = [2, 2, 2, 1, 1, 1, 2] + + sharemap = {} + for i in range(len(s._sequence)): peerid = s._sequence[i] - if not places: - print idlib.shortnodeid_b2a(peerid), "-", "-" - break - which = places.pop(0) - if which == 1: - print idlib.shortnodeid_b2a(peerid), "1", "-" - s._peers[peerid] = shares1.pop(0) - else: - print idlib.shortnodeid_b2a(peerid), "-", "2" - s._peers[peerid] = shares2.pop(0) + peerid_s = shortnodeid_b2a(peerid) + for shnum in self._shares1.get(peerid, {}): + sharemap[shnum] = peerid + if shnum < len(places): + which = places[shnum] + else: + which = "x" + s._peers[peerid] = peers = {} + in_1 = shnum in self._shares1[peerid] + in_2 = shnum in self._shares2.get(peerid, {}) + #print peerid_s, shnum, which, in_1, in_2 + if which == 1: + if in_1: + peers[shnum] = self._shares1[peerid][shnum] + elif which == 2: + if in_2: + peers[shnum] = self._shares2[peerid][shnum] + # we don't bother placing any other shares + # now sort the sequence so that share 0 is returned first + new_sequence = [sharemap[shnum] + for shnum in sorted(sharemap.keys())] + s._sequence = new_sequence log.msg("merge done") d.addCallback(_merge) d.addCallback(lambda res: r3.retrieve()) def _retrieved(new_contents): - # the current specified behavior is "first version recoverable" + ## the current specified behavior is "first version recoverable" + #self.failUnlessEqual(new_contents, contents1) + # the current behavior is "first version seen is sticky" self.failUnlessEqual(new_contents, contents2) d.addCallback(_retrieved) return d -- 2.45.2