From 8cc1f143a217bf0e6a2a9a71c37311ca14110798 Mon Sep 17 00:00:00 2001 From: Cameron Dale Date: Sun, 20 Apr 2008 19:39:33 -0700 Subject: [PATCH] Fix an HTTP download bug that caused HEAD requests to not pipeline. Also improve the testing for this. --- apt_p2p/HTTPDownloader.py | 29 ++++++++++++++++++----------- test.py | 28 +++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/apt_p2p/HTTPDownloader.py b/apt_p2p/HTTPDownloader.py index 97346db..1831cea 100644 --- a/apt_p2p/HTTPDownloader.py +++ b/apt_p2p/HTTPDownloader.py @@ -83,7 +83,7 @@ class Peer(ClientFactory): self.closed = False self.connecting = False self.proto = proto - self.processQueue() + reactor.callLater(0, self.processQueue) def connectionError(self, err): """Cancel the requests.""" @@ -117,7 +117,7 @@ class Peer(ClientFactory): request.deferRequest = defer.Deferred() self.request_queue.append(request) self.rerank() - self.processQueue() + reactor.callLater(0, self.processQueue) return request.deferRequest def processQueue(self): @@ -177,13 +177,13 @@ class Peer(ClientFactory): """Try to send a new request.""" self._processLastResponse() self.busy = False - self.processQueue() + reactor.callLater(0, self.processQueue) self.rerank() def clientPipelining(self, proto): """Try to send a new request.""" self.pipeline = True - self.processQueue() + reactor.callLater(0, self.processQueue) def clientGone(self, proto): """Mark sent requests as errors.""" @@ -199,7 +199,7 @@ class Peer(ClientFactory): self.proto = None self.rerank() if self.request_queue: - self.processQueue() + reactor.callLater(0, self.processQueue) #{ Downloading request interface def setCommonHeaders(self): @@ -329,16 +329,23 @@ class TestClientManager(unittest.TestCase): client = None pending_calls = [] + length = [] def gotResp(self, resp, num, expect): self.failUnless(resp.code >= 200 and resp.code < 300, "Got a non-200 response: %r" % resp.code) if expect is not None: self.failUnless(resp.stream.length == expect, "Length was incorrect, got %r, expected %r" % (resp.stream.length, expect)) - def print_(n): - pass - def printdone(n): - pass - stream_mod.readStream(resp.stream, print_).addCallback(printdone) + while len(self.length) <= num: + self.length.append(0) + self.length[num] = 0 + def addData(data, self = self, num = num): + self.length[num] += len(data) + def checkLength(resp, self = self, num = num, length = resp.stream.length): + self.failUnlessEqual(self.length[num], length) + return resp + df = stream_mod.readStream(resp.stream, addData) + df.addCallback(checkLength) + return df def test_download(self): """Tests a normal download.""" @@ -379,7 +386,7 @@ class TestClientManager(unittest.TestCase): newRequest("/rfc/rfc0801.txt", 3, 40824) # This one will probably be queued - self.pending_calls.append(reactor.callLater(1, newRequest, '/rfc/rfc0013.txt', 4, 1070)) + self.pending_calls.append(reactor.callLater(6, newRequest, '/rfc/rfc0013.txt', 4, 1070)) # Connection should still be open, but idle self.pending_calls.append(reactor.callLater(10, newRequest, '/rfc/rfc0022.txt', 5, 4606)) diff --git a/test.py b/test.py index aff8e2b..673d1bc 100755 --- a/test.py +++ b/test.py @@ -264,11 +264,20 @@ tests = {'1': ('Start a single bootstrap and downloader, test updating and downl (6, ['install', 'kde-icons-oxygen']), ]), - 'a': ('Test pipelining and caching, can also interrupt to test resuming.', - {1: {}}, - {1: {}, - 2: {}}, - [(1, ['update']), + 'a': ('Test pipelining and caching, can also interrupt or restart to test resuming.', + {1: {'clean': False}}, + {1: {'clean': False}, + 2: {'clean': False}}, + [(1, ['install', 'aboot-base', 'aap-doc', 'ada-reference-manual', + 'aspectj-doc', 'fop-doc', 'asis-doc', + 'bison-doc', 'crash-whitepaper', + 'bash-doc', 'apt-howto-common', 'autotools-dev', + 'aptitude-doc-en', 'asr-manpages', + 'atomix-data', 'alcovebook-sgml-doc', + 'afbackup-common', 'airstrike-common', + ]), + (1, ['update']), + (1, ['update']), (1, ['install', 'aboot-base', 'aap-doc', 'ada-reference-manual', 'aspectj-doc', 'fop-doc', 'asis-doc', 'bison-doc', 'crash-whitepaper', @@ -285,6 +294,15 @@ tests = {'1': ('Start a single bootstrap and downloader, test updating and downl 'atomix-data', 'alcovebook-sgml-doc', 'afbackup-common', 'airstrike-common', ]), + (2, ['install', 'aboot-base', 'aap-doc', 'ada-reference-manual', + 'aspectj-doc', 'fop-doc', 'asis-doc', + 'bison-doc', 'crash-whitepaper', + 'bash-doc', 'apt-howto-common', 'autotools-dev', + 'aptitude-doc-en', 'asr-manpages', + 'atomix-data', 'alcovebook-sgml-doc', + 'afbackup-common', 'airstrike-common', + ]), + (2, ['update']), (2, ['update']), (2, ['install', 'aboot-base', 'aap-doc', 'ada-reference-manual', 'aspectj-doc', 'fop-doc', 'asis-doc', -- 2.39.5