Fix an HTTP download bug that caused HEAD requests to not pipeline.
authorCameron Dale <camrdale@gmail.com>
Mon, 21 Apr 2008 02:39:33 +0000 (19:39 -0700)
committerCameron Dale <camrdale@gmail.com>
Mon, 21 Apr 2008 02:39:33 +0000 (19:39 -0700)
Also improve the testing for this.

apt_p2p/HTTPDownloader.py
test.py

index 97346db..1831cea 100644 (file)
@@ -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 (executable)
--- 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',