Repository: trafficserver-qa Updated Branches: refs/heads/master 5a74e467c -> 9e99c096d
Add HTTPBinCase (http://httpbin.org/) This embeds the httpbin wsgi app into the tracking information that we have for the DynamicHTTPEndpoint. For most cases this will be preferable-- since it requires less setup. Project: http://git-wip-us.apache.org/repos/asf/trafficserver-qa/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver-qa/commit/9e99c096 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver-qa/tree/9e99c096 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver-qa/diff/9e99c096 Branch: refs/heads/master Commit: 9e99c096d7147b4253f3ba210b079d3ea265573b Parents: 5a74e46 Author: Thomas Jackson <[email protected]> Authored: Tue Apr 7 16:55:32 2015 -0700 Committer: Thomas Jackson <[email protected]> Committed: Tue Apr 7 16:58:23 2015 -0700 ---------------------------------------------------------------------- setup.py | 2 +- tests/test_httpbincase.py | 19 ++++++++++ tsqa/endpoint.py | 78 ++++++++++++++++++++++++++++++++++++++++++ tsqa/test_cases.py | 37 ++++++++++++++++++-- 4 files changed, 133 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver-qa/blob/9e99c096/setup.py ---------------------------------------------------------------------- diff --git a/setup.py b/setup.py index dbe02e0..c67df59 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ config = { #'download_url': 'Where to download it.', 'author_email': '[email protected]', 'version': '0.1', - 'install_requires': ['nose', 'unittest2', 'requests', 'flask'], + 'install_requires': ['nose', 'unittest2', 'requests', 'flask', 'httpbin'], 'packages': ['tsqa'], 'scripts': [], 'name': 'tsqa' http://git-wip-us.apache.org/repos/asf/trafficserver-qa/blob/9e99c096/tests/test_httpbincase.py ---------------------------------------------------------------------- diff --git a/tests/test_httpbincase.py b/tests/test_httpbincase.py new file mode 100644 index 0000000..22318ac --- /dev/null +++ b/tests/test_httpbincase.py @@ -0,0 +1,19 @@ +''' +''' +import helpers + +import tsqa.utils +unittest = tsqa.utils.import_unittest() +import tsqa.test_cases + +import requests + +class TestBasic(tsqa.test_cases.HTTPBinCase): + def test_endpoint_url(self): + self.assertEqual(self.endpoint_url(), 'http://127.0.0.1:{0}'.format(self.http_endpoint.address[1])) + + self.assertEqual(self.endpoint_url('/foo'), 'http://127.0.0.1:{0}/foo'.format(self.http_endpoint.address[1])) + + def test_basic(self): + ret = requests.get(self.endpoint_url('/ip')) + self.assertEqual(ret.json()['origin'], '127.0.0.1') http://git-wip-us.apache.org/repos/asf/trafficserver-qa/blob/9e99c096/tsqa/endpoint.py ---------------------------------------------------------------------- diff --git a/tsqa/endpoint.py b/tsqa/endpoint.py index 99e3d38..99888bb 100644 --- a/tsqa/endpoint.py +++ b/tsqa/endpoint.py @@ -216,6 +216,84 @@ class DynamicHTTPEndpoint(threading.Thread): self.server.serve_forever() +class TrackingWSGIServer(threading.Thread): + ''' + A threaded webserver which will wrap any wsgi app and track request/response + headers to the origin + + # create the thread object + http_endpoint = tsqa.endpoint.TrackingWSGIServer(app) + # start the thread + http_endpoint.start() + # wait for the webserver to listen + http_endpoint.ready.wait() + ''' + TRACKING_HEADER = '__cool_test_header__' # TODO: better name? + + @property + def address(self): + ''' + Return a tuple of (ip, port) that this thread is listening on. + ''' + return (self.server.server_address, self.server.server_port) + + def __init__(self, app, port=0): + threading.Thread.__init__(self) + # dict to store request data in + self.tracked_requests = {} + + self.daemon = True + self.port = port + self.ready = threading.Event() + + self.app = app + self.app.debug = True + + @self.app.before_request + def save_request(): + ''' + If the tracking header is set, save the request + ''' + if flask.request.headers.get(self.TRACKING_HEADER): + self.tracked_requests[flask.request.headers[self.TRACKING_HEADER]] = {'request': request.copy()} + + + @self.app.after_request + def save_response(response): + ''' + If the tracking header is set, save the response + ''' + if flask.request.headers.get(self.TRACKING_HEADER): + self.tracked_requests[flask.request.headers[self.TRACKING_HEADER]]['response'] = response + + return response + + def get_tracking_key(self): + ''' + Return a new key for tracking a request by key + ''' + key = str(len(self.tracked_requests)) + self.tracked_requests[key] = {} + return key + + def get_tracking_by_key(self, key): + ''' + Return tracking data by key + ''' + if key not in self.tracked_requests: + raise Exception() + return self.tracked_requests[key] + + def run(self): + self.server = make_server('', + self.port, + self.app.wsgi_app) + # mark it as ready + self.ready.set() + # serve it + self.server.serve_forever() + + class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): pass http://git-wip-us.apache.org/repos/asf/trafficserver-qa/blob/9e99c096/tsqa/test_cases.py ---------------------------------------------------------------------- diff --git a/tsqa/test_cases.py b/tsqa/test_cases.py index ab68fcd..b314c5f 100644 --- a/tsqa/test_cases.py +++ b/tsqa/test_cases.py @@ -17,8 +17,10 @@ Some base test cases that do environment handling for you # See the License for the specific language governing permissions and # limitations under the License. - import logging +import os + +import httpbin import tsqa.endpoint import tsqa.environment @@ -26,7 +28,7 @@ import tsqa.configs import tsqa.utils unittest = tsqa.utils.import_unittest() -import os + # Base environment case class EnvironmentCase(unittest.TestCase): @@ -158,3 +160,34 @@ class DynamicHTTPEndpointCase(unittest.TestCase): return 'http://127.0.0.1:{0}{1}'.format(self.http_endpoint.address[1], path) + +class HTTPBinCase(unittest.TestCase): + ''' + This class will set up httpbin which is local to this class + ''' + @classmethod + def setUpClass(cls): + # get a logger + cls.log = logging.getLogger(__name__) + + cls.http_endpoint = tsqa.endpoint.TrackingWSGIServer(httpbin.app) + cls.http_endpoint.start() + + cls.http_endpoint.ready.wait() + + # create local requester object + cls.track_requests = tsqa.endpoint.TrackingRequests(cls.http_endpoint) + + # Do this last, so we can get our stuff registered + # call parent constructor + super(HTTPBinCase, cls).setUpClass() + + def endpoint_url(self, path=''): + ''' + Get the url for the local dynamic endpoint given a path + ''' + if path and not path.startswith('/'): + path = '/' + path + return 'http://127.0.0.1:{0}{1}'.format(self.http_endpoint.address[1], + path) +
