You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ja...@apache.org on 2015/02/27 03:47:25 UTC
trafficserver git commit: TS-3312: Add tests based around this issue
Repository: trafficserver
Updated Branches:
refs/heads/master c61e7d2a3 -> 1f25a8846
TS-3312: Add tests based around this issue
This also merges the current tests to use mixins.
This closes #174
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/1f25a884
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/1f25a884
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/1f25a884
Branch: refs/heads/master
Commit: 1f25a8846c0cdf7cbd06b442c9fb1289026f439c
Parents: c61e7d2
Author: Derek Bruce <db...@gmail.com>
Authored: Wed Feb 25 14:42:16 2015 -0800
Committer: Thomas Jackson <ja...@apache.org>
Committed: Thu Feb 26 18:20:36 2015 -0800
----------------------------------------------------------------------
ci/new_tsqa/tests/test_keepalive.py | 291 +++++++++++++++++++++++--------
1 file changed, 221 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f25a884/ci/new_tsqa/tests/test_keepalive.py
----------------------------------------------------------------------
diff --git a/ci/new_tsqa/tests/test_keepalive.py b/ci/new_tsqa/tests/test_keepalive.py
index 7e598bd..c94d4d1 100644
--- a/ci/new_tsqa/tests/test_keepalive.py
+++ b/ci/new_tsqa/tests/test_keepalive.py
@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import os
+import uuid
import requests
import time
import logging
@@ -29,24 +29,26 @@ import tsqa.endpoint
log = logging.getLogger(__name__)
import SocketServer
+
+
class KeepaliveTCPHandler(SocketServer.BaseRequestHandler):
"""
- A subclass of RequestHandler which will count the number of requests
- per tcp session
+ A subclass of RequestHandler which will return a connection uuid
"""
def handle(self):
- num_requests = 0
# Receive the data in small chunks and retransmit it
+ start = time.time()
+ conn_id = uuid.uuid4().hex
while True:
- num_requests += 1
+ now = time.time() - start
data = self.request.recv(4096).strip()
if data:
- log.info('sending data back to the client')
+ log.debug('Sending data back to the client: {uid}'.format(uid=conn_id))
else:
- log.info('Client disconnected')
+ log.debug('Client disconnected: {timeout}seconds'.format(timeout=now))
break
- body = str(num_requests)
+ body = conn_id
resp = ('HTTP/1.1 200 OK\r\n'
'Content-Length: {content_length}\r\n'
'Content-Type: text/html; charset=UTF-8\r\n'
@@ -56,31 +58,17 @@ class KeepaliveTCPHandler(SocketServer.BaseRequestHandler):
self.request.sendall(resp)
-class TestKeepAliveInHTTP(tsqa.test_cases.DynamicHTTPEndpointCase, helpers.EnvironmentCase):
- @classmethod
- def setUpEnv(cls, env):
-
- def hello(request):
- return 'hello'
- cls.http_endpoint.add_handler('/exists/', hello)
-
- cls.configs['remap.config'].add_line('map /exists/ http://127.0.0.1:{0}/exists/'.format(cls.http_endpoint.address[1]))
-
- # only add server headers when there weren't any
- cls.configs['records.config']['CONFIG']['proxy.config.http.response_server_enabled'] = 2
- cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_in'] = 1
- cls.configs['records.config']['CONFIG']['share_server_session'] = 2
-
- # set only one ET_NET thread (so we don't have to worry about the per-thread pools causing issues)
- cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
- cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
+class KeepAliveInMixin(object):
+ """Mixin for keep alive in.
+ TODO: Allow protocol to be specified for ssl traffic
+ """
def _get_socket(self):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', int(self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])))
return s
- def test_working_path(self):
+ def _aux_working_path(self, protocol):
# connect tcp
s = self._get_socket()
@@ -96,7 +84,7 @@ class TestKeepAliveInHTTP(tsqa.test_cases.DynamicHTTPEndpointCase, helpers.Envir
self.assertIn('HTTP/1.1 200 OK', response)
self.assertIn('hello', response)
- def test_error_path(self):
+ def _aux_error_path(self, protocol):
# connect tcp
s = self._get_socket()
@@ -108,7 +96,7 @@ class TestKeepAliveInHTTP(tsqa.test_cases.DynamicHTTPEndpointCase, helpers.Envir
response = s.recv(4096)
self.assertIn('HTTP/1.1 404 Not Found on Accelerator', response)
- def test_error_path_post(self):
+ def _aux_error_path_post(self, protocol):
'''
Ensure that sending a request with a body doesn't break the keepalive session
'''
@@ -128,14 +116,112 @@ class TestKeepAliveInHTTP(tsqa.test_cases.DynamicHTTPEndpointCase, helpers.Envir
s.send(request)
response = s.recv(4096)
- self.assertIn('HTTP/1.1 404 Not Found on Accelerator', response)
+ # Check if client disconnected
+ if response:
+ self.assertIn('HTTP/1.1 404 Not Found on Accelerator', response)
-# TODO: test timeouts
-# https://issues.apache.org/jira/browse/TS-3312
-# https://issues.apache.org/jira/browse/TS-242
+class BasicTestsOutMixin(object):
+
+ def _aux_KA_origin(self, protocol):
+ '''
+ Test that the origin does in fact support keepalive
+ '''
+ conn_id = None
+ with requests.Session() as s:
+ url = '{0}://127.0.0.1:{1}/'.format(protocol, self.socket_server.port)
+ for x in xrange(1, 10):
+ ret = s.get(url, verify=False)
+ if not conn_id:
+ conn_id = ret.text.strip()
+ self.assertEqual(ret.status_code, 200)
+ self.assertEqual(ret.text.strip(), conn_id, "Client reports server closed connection")
-class TestKeepAliveOutHTTP(helpers.EnvironmentCase):
+ def _aux_KA_proxy(self, protocol):
+ '''
+ Test that keepalive works through ATS to that origin
+ '''
+ url = '{0}://127.0.0.1:{1}'.format(protocol,
+ self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])
+ conn_id = None
+ for x in xrange(1, 10):
+ ret = requests.get(url, verify=False)
+ if not conn_id:
+ conn_id = ret.text.strip()
+ self.assertEqual(ret.status_code, 200)
+ self.assertEqual(ret.text.strip(), conn_id, "Client reports server closed connection")
+
+class TimeoutOutMixin(object):
+
+ def _aux_KA_timeout_direct(self, protocol):
+ '''Tests that origin does not timeout using keepalive.'''
+ with requests.Session() as s:
+ url = '{0}://127.0.0.1:{1}/'.format(protocol, self.socket_server.port)
+ conn_id = None
+ for x in xrange(0, 3):
+ ret = s.get(url, verify=False)
+ if not conn_id:
+ conn_id = ret.text.strip()
+ self.assertEqual(ret.text.strip(), conn_id, "Client reports server closed connection")
+ time.sleep(3)
+
+ def _aux_KA_timeout_proxy(self, protocol):
+ '''Tests that keepalive timeout is honored through ATS to origin.'''
+ url = '{0}://127.0.0.1:{1}'.format(protocol,
+ self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])
+ conn_id = None
+ for x in xrange(0, 3):
+ ret = requests.get(url, verify=False)
+ if not conn_id:
+ conn_id = ret.text.strip()
+ self.assertEqual(ret.text.strip(), conn_id, "Client reports server closed connection")
+ time.sleep(3)
+
+
+class OriginMinMaxMixin(object):
+
+ def _aux_KA_min_origin(self, protocol):
+ '''Tests that origin_min_keep_alive_connections is honored.'''
+ url = '{0}://127.0.0.1:{1}'.format(protocol,
+ self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])
+ ret = requests.get(url, verify=False)
+ conn_id = ret.text.strip()
+ time.sleep(3)
+ ret = requests.get(url, verify=False)
+ self.assertEqual(ret.text.strip(), conn_id, "Client reports server closed connection")
+
+class TestKeepAliveInHTTP(tsqa.test_cases.DynamicHTTPEndpointCase, helpers.EnvironmentCase, KeepAliveInMixin):
+ @classmethod
+ def setUpEnv(cls, env):
+
+ def hello(request):
+ return 'hello'
+ cls.http_endpoint.add_handler('/exists/', hello)
+
+ cls.configs['remap.config'].add_line('map /exists/ http://127.0.0.1:{0}/exists/'.format(cls.http_endpoint.address[1]))
+
+ # only add server headers when there weren't any
+ cls.configs['records.config']['CONFIG']['proxy.config.http.response_server_enabled'] = 2
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_in'] = 1
+ cls.configs['records.config']['CONFIG']['share_server_session'] = 2
+
+ # set only one ET_NET thread (so we don't have to worry about the per-thread pools causing issues)
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
+
+ def test_working_path(self):
+ self._aux_working_path("http")
+
+ def test_error_path(self):
+ self._aux_error_path("http")
+
+ def test_error_path_post(self):
+ '''
+ Ensure that sending a request with a body doesn't break the keepalive session
+ '''
+ self._aux_error_path_post("http")
+
+class TestKeepAliveOriginConnOutHTTP(helpers.EnvironmentCase, OriginMinMaxMixin):
@classmethod
def setUpEnv(cls, env):
'''
@@ -146,7 +232,7 @@ class TestKeepAliveOutHTTP(helpers.EnvironmentCase):
cls.socket_server = tsqa.endpoint.SocketServerDaemon(KeepaliveTCPHandler)
cls.socket_server.start()
cls.socket_server.ready.wait()
- cls.configs['remap.config'].add_line('map / http://127.0.0.1:{0}/\n'.format(cls.socket_server.port))
+ cls.configs['remap.config'].add_line('map / http://127.0.0.1:{0}/'.format(cls.socket_server.port))
# only add server headers when there weren't any
cls.configs['records.config']['CONFIG']['proxy.config.http.response_server_enabled'] = 2
@@ -157,28 +243,97 @@ class TestKeepAliveOutHTTP(helpers.EnvironmentCase):
cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
- def test_KA_origin(self):
+ # Timeouts
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_no_activity_timeout_out'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.http.transaction_no_activity_timeout_out'] = 1
+
+ cls.configs['records.config']['CONFIG']['proxy.config.http.origin_min_keep_alive_connections'] = 1
+
+ def test_KA_min_origin(self):
+ '''Tests that origin_min_keep_alive_connections is honored via http.'''
+ self._aux_KA_min_origin("http")
+
+
+class TestKeepAliveOriginConnOutHTTPS(helpers.EnvironmentCase, OriginMinMaxMixin):
+ @classmethod
+ def setUpEnv(cls, env):
'''
- Test that the origin does in fact support keepalive
+ This function is responsible for setting up the environment for this fixture
+ This includes everything pre-daemon start
'''
- with requests.Session() as s:
- url = 'http://127.0.0.1:{0}/'.format(self.socket_server.port)
- for x in xrange(1, 10):
- ret = s.get(url)
- self.assertEqual(ret.status_code, 200)
- self.assertEqual(ret.text.strip(), str(x))
+ # create a socket server
+ cls.socket_server = tsqa.endpoint.SSLSocketServerDaemon(KeepaliveTCPHandler,
+ helpers.tests_file_path('cert.pem'),
+ helpers.tests_file_path('key.pem'))
+ cls.socket_server.start()
+ cls.socket_server.ready.wait()
+ cls.configs['remap.config'].add_line('map / https://127.0.0.1:{0}/\n'.format(cls.socket_server.port))
- def test_KA_proxy(self):
+ # only add server headers when there weren't any
+ cls.configs['records.config']['CONFIG']['proxy.config.http.response_server_enabled'] = 2
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_out'] = 1
+ cls.configs['records.config']['CONFIG']['share_server_session'] = 2
+
+ # set only one ET_NET thread (so we don't have to worry about the per-thread pools causing issues)
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
+ cls.configs['records.config']['CONFIG']['proxy.config.ssl.number.threads'] = -1
+
+ # Timeouts
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_no_activity_timeout_out'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.http.transaction_no_activity_timeout_out'] = 1
+
+ cls.configs['records.config']['CONFIG']['proxy.config.http.origin_min_keep_alive_connections'] = 1
+
+ def test_KA_min_origin(self):
+ '''Tests that origin_min_keep_alive_connections is honored via https.'''
+ self._aux_KA_min_origin("http")
+
+
+class TestKeepAliveOutHTTP(helpers.EnvironmentCase, BasicTestsOutMixin, TimeoutOutMixin):
+ @classmethod
+ def setUpEnv(cls, env):
'''
- Test that keepalive works through ATS to that origin
+ This function is responsible for setting up the environment for this fixture
+ This includes everything pre-daemon start
'''
- url = 'http://127.0.0.1:{0}'.format(self.socket_server.port)
- for x in xrange(1, 10):
- ret = requests.get(url, proxies=self.proxies)
- self.assertEqual(ret.status_code, 200)
- self.assertEqual(ret.text.strip(), str(x))
+ # create a socket server
+ cls.socket_server = tsqa.endpoint.SocketServerDaemon(KeepaliveTCPHandler)
+ cls.socket_server.start()
+ cls.socket_server.ready.wait()
+ cls.configs['remap.config'].add_line('map / http://127.0.0.1:{0}/'.format(cls.socket_server.port))
+
+ # only add server headers when there weren't any
+ cls.configs['records.config']['CONFIG']['proxy.config.http.response_server_enabled'] = 2
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_enabled_out'] = 1
+ cls.configs['records.config']['CONFIG']['share_server_session'] = 2
+
+ # set only one ET_NET thread (so we don't have to worry about the per-thread pools causing issues)
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
+ cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
+
+ # Timeouts
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_no_activity_timeout_out'] = 10
+ cls.configs['records.config']['CONFIG']['proxy.config.http.transaction_no_activity_timeout_out'] = 2
+
+ def test_KA_origin(self):
+ '''Test that the origin does in fact support keepalive via http.'''
+ self._aux_KA_origin("http")
+
+ def test_KA_proxy(self):
+ '''Tests that keepalive works through ATS to origin via http.'''
+ self._aux_KA_proxy("http")
+
+ def test_KA_timeout_direct(self):
+ '''Tests that origin does not timeout using keepalive via http.'''
+ self._aux_KA_timeout_direct("http")
-class TestKeepAliveOutHTTPS(helpers.EnvironmentCase):
+ def test_KA_timeout_proxy(self):
+ '''Tests that keepalive timeout is honored through ATS to origin via http.'''
+ self._aux_KA_timeout_proxy("http")
+
+
+class TestKeepAliveOutHTTPS(helpers.EnvironmentCase, BasicTestsOutMixin, TimeoutOutMixin):
@classmethod
def setUpEnv(cls, env):
'''
@@ -189,7 +344,6 @@ class TestKeepAliveOutHTTPS(helpers.EnvironmentCase):
cls.socket_server = tsqa.endpoint.SSLSocketServerDaemon(KeepaliveTCPHandler,
helpers.tests_file_path('cert.pem'),
helpers.tests_file_path('key.pem'))
-
cls.socket_server.start()
cls.socket_server.ready.wait()
cls.configs['remap.config'].add_line('map / https://127.0.0.1:{0}/\n'.format(cls.socket_server.port))
@@ -202,27 +356,24 @@ class TestKeepAliveOutHTTPS(helpers.EnvironmentCase):
# set only one ET_NET thread (so we don't have to worry about the per-thread pools causing issues)
cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.limit'] = 1
cls.configs['records.config']['CONFIG']['proxy.config.exec_thread.autoconfig'] = 0
-
cls.configs['records.config']['CONFIG']['proxy.config.ssl.number.threads'] = -1
+ # Timeouts
+ cls.configs['records.config']['CONFIG']['proxy.config.http.keep_alive_no_activity_timeout_out'] = 10
+ cls.configs['records.config']['CONFIG']['proxy.config.http.transaction_no_activity_timeout_out'] = 2
def test_KA_origin(self):
- '''
- Test that the origin does in fact support keepalive
- '''
- with requests.Session() as s:
- url = 'https://127.0.0.1:{0}/'.format(self.socket_server.port)
- for x in xrange(1, 10):
- ret = s.get(url, verify=False)
- self.assertEqual(ret.status_code, 200)
- self.assertEqual(ret.text.strip(), str(x))
+ '''Test that the origin does in fact support keepalive via https.'''
+ self._aux_KA_origin("https")
def test_KA_proxy(self):
- '''
- Test that keepalive works through ATS to that origin
- '''
- url = 'http://127.0.0.1:{0}'.format(self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])
- for x in xrange(1, 10):
- ret = requests.get(url)
- self.assertEqual(ret.status_code, 200)
- self.assertEqual(ret.text.strip(), str(x))
+ '''Tests that keepalive works through ATS to origin via https.'''
+ self._aux_KA_proxy("http")
+
+ def test_KA_timeout_direct(self):
+ '''Tests that origin does not timeout using keepalive via https.'''
+ self._aux_KA_timeout_direct("https")
+
+ def test_KA_timeout_proxy(self):
+ '''Tests that keepalive timeout is honored through ATS to origin via https.'''
+ self._aux_KA_timeout_proxy("http")