Changeset 8844655 in trunk


Ignore:
Timestamp:
2010-08-04T18:45:49Z (15 years ago)
Author:
Brian Warner <warner@…>
Branches:
master
Children:
cd8d415
Parents:
2bd8749
Message:

One fix for bug #1154: webapi GETs with a 'Range' header broke new-downloader.

The Range header causes n.read() to be called with an offset= of type 'long',
which eventually got used in a Spans/DataSpans? object's len method.
Apparently python doesn't permit len() to return longs, only ints.
Rewrote Spans/DataSpans? to use s.len() instead of len(s) aka s.len() .
Added a test in test_download. Note that test_web didn't catch this because
it uses mock FileNodes? for speed: it's probably time to rewrite that.

There is still an unresolved error-recovery problem in #1154, so I'm not
closing the ticket quite yet.

Location:
src/allmydata
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/allmydata/immutable/downloader/share.py

    r2bd8749 r8844655  
    260260        # and sometimes you can't even get what you need
    261261        disappointment = needed & self._unavailable
    262         if len(disappointment):
     262        if disappointment.len():
    263263            self.had_corruption = True
    264264            raise DataUnavailable("need %s but will never get it" %
  • TabularUnified src/allmydata/test/test_download.py

    r2bd8749 r8844655  
    320320            self.failIfEqual(shares, [0,1,2])
    321321        d.addCallback(_check_failover)
     322        return d
     323
     324    def test_long_offset(self):
     325        # bug #1154: mplayer doing a seek-to-end results in an offset of type
     326        # 'long', rather than 'int', and apparently __len__ is required to
     327        # return an int. Rewrote Spans/DataSpans to provide s.len() instead
     328        # of len(s) .
     329        self.basedir = self.mktemp()
     330        self.set_up_grid()
     331        self.c0 = self.g.clients[0]
     332        self.load_shares()
     333        n = self.c0.create_node_from_uri(immutable_uri)
     334
     335        c = MemoryConsumer()
     336        d = n.read(c, 0L, 10L)
     337        d.addCallback(lambda c: len("".join(c.chunks)))
     338        d.addCallback(lambda size: self.failUnlessEqual(size, 10))
    322339        return d
    323340
  • TabularUnified src/allmydata/test/test_util.py

    r2bd8749 r8844655  
    16151615            yield (prevstart, prevend-prevstart+1)
    16161616
    1617     def __len__(self):
    1618         # this also gets us bool(s)
     1617    def __nonzero__(self): # this gets us bool()
     1618        return self.len()
     1619
     1620    def len(self):
    16191621        return len(self._have)
    16201622
     
    16601662        self.failIf(s)
    16611663        self.failIf((0,1) in s)
    1662         self.failUnlessEqual(len(s), 0)
     1664        self.failUnlessEqual(s.len(), 0)
    16631665
    16641666        s1 = Spans(3, 4) # 3,4,5,6
     
    16731675        self.failIf((10,1) in s1)
    16741676        self.failUnlessEqual(list(s2.each()), [3,4,5,6,10,11])
    1675         self.failUnlessEqual(len(s2), 6)
     1677        self.failUnlessEqual(s2.len(), 6)
    16761678
    16771679        s2.add(15,2).add(20,2)
    16781680        self.failUnlessEqual(list(s2.each()), [3,4,5,6,10,11,15,16,20,21])
    1679         self.failUnlessEqual(len(s2), 10)
     1681        self.failUnlessEqual(s2.len(), 10)
    16801682
    16811683        s2.remove(4,3).remove(15,1)
    16821684        self.failUnlessEqual(list(s2.each()), [3,10,11,16,20,21])
    1683         self.failUnlessEqual(len(s2), 6)
     1685        self.failUnlessEqual(s2.len(), 6)
    16841686
    16851687        s1 = SimpleSpans(3, 4) # 3 4 5 6
     
    16911693        self.failUnlessEqual(list(s), [(3,4)])
    16921694        self.failUnless(s)
    1693         self.failUnlessEqual(len(s), 4)
     1695        self.failUnlessEqual(s.len(), 4)
    16941696        self.failIf((0,1) in s)
    16951697        self.failUnless((3,4) in s)
     
    18181820            #print "s2 now %s" % s2.dump()
    18191821            self.failUnlessEqual(list(s1.each()), list(s2.each()))
    1820             self.failUnlessEqual(len(s1), len(s2))
     1822            self.failUnlessEqual(s1.len(), s2.len())
    18211823            self.failUnlessEqual(bool(s1), bool(s2))
    18221824            self.failUnlessEqual(list(s1), list(s2))
     
    18381840    # (start,length) in s -> True if (start..start+length-1) are all members
    18391841    #  NOT equivalent to x in list(s)
    1840     # len(s) -> number of bytes, for testing, bool(), and accounting/limiting
    1841     # bool(s)  (__len__)
     1842    # s.len() -> number of bytes, for testing, bool(), and accounting/limiting
     1843    # bool(s)  (__nonzeron__)
    18421844    # s = s1+s2, s1-s2, +=s1, -=s1
    18431845
     
    18941896                self.add(start, data)
    18951897
    1896     def __len__(self):
     1898    def __nonzero__(self): # this gets us bool()
     1899        return self.len()
     1900    def len(self):
    18971901        return len(self.missing.replace("1", ""))
    18981902    def _dump(self):
     
    19311935    def do_basic(self, klass):
    19321936        ds = klass()
    1933         self.failUnlessEqual(len(ds), 0)
     1937        self.failUnlessEqual(ds.len(), 0)
    19341938        self.failUnlessEqual(list(ds._dump()), [])
    19351939        self.failUnlessEqual(sum([len(d) for (s,d) in ds.get_chunks()]), 0)
     
    19401944
    19411945        ds.add(2, "four")
    1942         self.failUnlessEqual(len(ds), 4)
     1946        self.failUnlessEqual(ds.len(), 4)
    19431947        self.failUnlessEqual(list(ds._dump()), [2,3,4,5])
    19441948        self.failUnlessEqual(sum([len(d) for (s,d) in ds.get_chunks()]), 4)
     
    19501954
    19511955        ds2 = klass(ds)
    1952         self.failUnlessEqual(len(ds2), 4)
     1956        self.failUnlessEqual(ds2.len(), 4)
    19531957        self.failUnlessEqual(list(ds2._dump()), [2,3,4,5])
    19541958        self.failUnlessEqual(sum([len(d) for (s,d) in ds2.get_chunks()]), 4)
     
    19631967
    19641968        ds.add(0, "23")
    1965         self.failUnlessEqual(len(ds), 6)
     1969        self.failUnlessEqual(ds.len(), 6)
    19661970        self.failUnlessEqual(list(ds._dump()), [0,1,2,3,4,5])
    19671971        self.failUnlessEqual(sum([len(d) for (s,d) in ds.get_chunks()]), 6)
     
    21262130            #print "s1 now %s" % list(s1._dump())
    21272131            #print "s2 now %s" % list(s2._dump())
    2128             self.failUnlessEqual(len(s1), len(s2))
     2132            self.failUnlessEqual(s1.len(), s2.len())
    21292133            self.failUnlessEqual(list(s1._dump()), list(s2._dump()))
    21302134            for j in range(100):
  • TabularUnified src/allmydata/util/spans.py

    r2bd8749 r8844655  
    141141
    142142    def dump(self):
    143         return "len=%d: %s" % (len(self),
     143        return "len=%d: %s" % (self.len(),
    144144                               ",".join(["[%d-%d]" % (start,start+l-1)
    145145                                         for (start,l) in self._spans]) )
     
    154154            yield s
    155155
    156     def __len__(self):
    157         # this also gets us bool(s)
     156    def __nonzero__(self): # this gets us bool()
     157        return self.len()
     158
     159    def len(self):
     160        # guess what! python doesn't allow __len__ to return a long, only an
     161        # int. So we stop using len(spans), use spans.len() instead.
    158162        return sum([length for start,length in self._spans])
    159163
     
    229233                self.add(start, data)
    230234
    231     def __len__(self):
     235    def __nonzero__(self): # this gets us bool()
     236        return self.len()
     237
     238    def len(self):
    232239        # return number of bytes we're holding
    233240        return sum([len(data) for (start,data) in self.spans])
     
    240247
    241248    def dump(self):
    242         return "len=%d: %s" % (len(self),
     249        return "len=%d: %s" % (self.len(),
    243250                               ",".join(["[%d-%d]" % (start,start+len(data)-1)
    244251                                         for (start,data) in self.spans]) )
Note: See TracChangeset for help on using the changeset viewer.