Add initial chunked encoding tests
This closed #179
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ae30cce2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ae30cce2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ae30cce2
Branch: refs/heads/master
Commit: ae30cce253d1cab45943ad0ec9ea68d7531733cf
Parents: eb5a3d3
Author: Thomas Jackson <jacksontj@apache.org>
Authored: Thu Mar 12 19:28:26 2015 -0700
Committer: Thomas Jackson <jacksontj@apache.org>
Committed: Mon Mar 16 11:32:48 2015 -0700
----------------------------------------------------------------------
ci/new_tsqa/tests/test_chunked.py | 148 +++++++++++++++++++++++++++++++++
1 file changed, 148 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ae30cce2/ci/new_tsqa/tests/test_chunked.py
----------------------------------------------------------------------
diff --git a/ci/new_tsqa/tests/test_chunked.py b/ci/new_tsqa/tests/test_chunked.py
new file mode 100644
index 0000000..8302869
--- /dev/null
+++ b/ci/new_tsqa/tests/test_chunked.py
@@ -0,0 +1,148 @@
+'''
+Test chunked request/responses
+'''
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import requests
+import time
+import logging
+import json
+import threading
+
+import helpers
+
+import tsqa.test_cases
+import tsqa.utils
+import tsqa.endpoint
+
+log = logging.getLogger(__name__)
+
+import SocketServer
+class ChunkedHandler(SocketServer.BaseRequestHandler):
+ """
+ A subclass of RequestHandler which return chunked encoding optionally
+
+ /parts/sleep_time/close
+ parts: number of parts to send
+ sleep_time: time between parts
+ close: bool wether to close properly
+ """
+
+ def handle(self):
+ # Receive the data in small chunks and retransmit it
+ while True:
+ data = self.request.recv(4096).strip()
+ if data:
+ log.info('sending data back to the client')
+ else:
+ log.info('Client disconnected')
+ break
+ inc_lines = data.splitlines()
+ uri = inc_lines[0].split()[1]
+ parts = 5 # how many things to send
+ sleep_time = 0.2 # how long to sleep between parts
+ close = True # whether to close properly
+ if uri[1:]: # if there is something besides /
+ uri_parts = uri[1:].split('/')
+ if len(uri_parts) >= 1:
+ parts = int(uri_parts[0])
+ if len(uri_parts) >= 2:
+ sleep_time = float(uri_parts[1])
+ if len(uri_parts) >= 3:
+ close = json.loads(uri_parts[2])
+
+ resp = ('HTTP/1.1 200 OK\r\n'
+ 'Transfer-Encoding: chunked\r\n'
+ '\r\n')
+ self.request.sendall(resp)
+ for x in xrange(0, parts):
+ self.request.sendall('{0}\r\n{1}\r\n'.format(len(str(x)), x))
+ time.sleep(sleep_time)
+ if close:
+ self.request.sendall('0\r\n\r\n')
+ else:
+ self.request.sendall('lkfjasd;lfjas;d')
+
+ time.sleep(2)
+ self.request.close()
+ return
+
+class TestChunked(helpers.EnvironmentCase):
+ @classmethod
+ def setUpEnv(cls, env):
+ '''
+ This function is responsible for setting up the environment for this fixture
+ This includes everything pre-daemon start
+ '''
+
+ # create a socket server
+ cls.port = tsqa.utils.bind_unused_port()[1]
+ server = SocketServer.TCPServer(('127.0.0.1', cls.port), ChunkedHandler)
+ t = threading.Thread(target=server.serve_forever)
+ t.daemon = True
+ t.start()
+ cls.configs['remap.config'].add_line('map / http://127.0.0.1:{0}/'.format(cls.port))
+
+ cls.configs['records.config']['CONFIG']['proxy.config.http.connect_attempts_timeout']
= 5
+ cls.configs['records.config']['CONFIG']['proxy.config.http.connect_attempts_max_retries']
= 0
+
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_in']
= 1
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_out']
= 0
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] =
0
+
+ def test_chunked_origin(self):
+ '''
+ Test that the origin does in fact support keepalive
+ '''
+ url = 'http://127.0.0.1:{0}/'.format(self.port)
+ self.assertEqual(requests.get(url).text, '01234')
+
+ url = 'http://127.0.0.1:{0}/2'.format(self.port)
+ self.assertEqual(requests.get(url).text, '01')
+
+ url = 'http://127.0.0.1:{0}/2/1'.format(self.port)
+ start = time.time()
+ self.assertEqual(requests.get(url).text, '01')
+ self.assertTrue(time.time() - start > 2)
+
+ def test_chunked_basic(self):
+ url = 'http://127.0.0.1:{0}'.format(self.port)
+ ret = requests.get(url, proxies=self.proxies)
+ self.assertEqual(ret.status_code, 200)
+ self.assertEqual(ret.text.strip(), '01234')
+
+ # TODO: fix keepalive with chunked responses
+ def test_chunked_keepalive(self):
+ url = 'http://127.0.0.1:{0}'.format(self.port)
+ ret = requests.get(url, proxies=self.proxies)
+ self.assertEqual(ret.status_code, 200)
+ self.assertEqual(ret.text.strip(), '01234')
+
+ # make sure that a second request works, and since we have keep-alive out
+ # disabled it should be a new connection
+ ret = requests.get(url, proxies=self.proxies)
+ self.assertEqual(ret.status_code, 200)
+ self.assertEqual(ret.text.strip(), '01234')
+
+ def test_chunked_bad_close(self):
+ url = 'http://127.0.0.1:{0}/5/0.1/false'.format(self.port)
+ with self.assertRaises(requests.exceptions.ConnectionError):
+ ret = requests.get(url, proxies=self.proxies, timeout=2)
+
+
|