tests: Use JSON for webserver_sub logging.
This simplifies logging output and parsing.
This commit is contained in:
parent
b8467b8fef
commit
7eb6f658eb
@ -19,6 +19,7 @@
|
||||
|
||||
"""Test the httpbin webserver used for tests."""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
@ -51,17 +52,13 @@ def test_httpbin(httpbin, qtbot, path, content, expected):
|
||||
|
||||
|
||||
@pytest.mark.parametrize('line, verb, path, equal', [
|
||||
('127.0.0.1 - - [01/Jan/1990 00:00:00] "GET / HTTP/1.1" 200 -',
|
||||
'GET', '/', True),
|
||||
('127.0.0.1 - - [01/Jan/1990 00:00:00] "GET /foo/ HTTP/1.1" 200 -',
|
||||
'GET', '/foo', True),
|
||||
({'verb': 'GET', 'path': '/', 'status': 200}, 'GET', '/', True),
|
||||
({'verb': 'GET', 'path': '/foo/', 'status': 200}, 'GET', '/foo', True),
|
||||
|
||||
('127.0.0.1 - - [01/Jan/1990 00:00:00] "GET / HTTP/1.1" 200 -',
|
||||
'GET', '/foo', False),
|
||||
('127.0.0.1 - - [01/Jan/1990 00:00:00] "GET / HTTP/1.1" 200 -',
|
||||
'POST', '/foo', False),
|
||||
({'verb': 'GET', 'path': '/', 'status': 200}, 'GET', '/foo', False),
|
||||
({'verb': 'POST', 'path': '/', 'status': 200}, 'GET', '/', False),
|
||||
])
|
||||
def test_expected_request(httpbin, line, verb, path, equal):
|
||||
expected = httpbin.ExpectedRequest(verb, path)
|
||||
request = httpbin.Request(line)
|
||||
request = httpbin.Request(json.dumps(line))
|
||||
assert (expected == request) == equal
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import socket
|
||||
import os.path
|
||||
|
||||
@ -38,45 +39,25 @@ class Request(testprocess.Line):
|
||||
"""A parsed line from the httpbin/flask log output.
|
||||
|
||||
Attributes:
|
||||
timestamp/verb/path/status: Parsed from the log output.
|
||||
|
||||
Class attributes:
|
||||
LOG_RE: Used to parse the CLF log which httpbin outputs.
|
||||
verb/path/status: Parsed from the log output.
|
||||
"""
|
||||
|
||||
LOG_RE = re.compile(r"""
|
||||
(?P<host>[^ ]*)
|
||||
\ ([^ ]*) # ignored
|
||||
\ (?P<user>[^ ]*)
|
||||
\ \[(?P<date>[^]]*)\]
|
||||
\ "(?P<request>
|
||||
(?P<verb>[^ ]*)
|
||||
\ (?P<path>[^ ]*)
|
||||
\ (?P<protocol>[^ ]*)
|
||||
)"
|
||||
\ (?P<status>[^ ]*)
|
||||
\ (?P<size>[^ ]*)
|
||||
""", re.VERBOSE)
|
||||
|
||||
def __init__(self, data):
|
||||
super().__init__(data)
|
||||
match = self.LOG_RE.match(data)
|
||||
if match is None:
|
||||
try:
|
||||
parsed = json.loads(data)
|
||||
except ValueError:
|
||||
raise testprocess.InvalidLine(data)
|
||||
|
||||
assert match.group('host') == '127.0.0.1'
|
||||
assert match.group('user') == '-'
|
||||
self.timestamp = match.group('date')
|
||||
self.verb = match.group('verb')
|
||||
assert isinstance(parsed, dict)
|
||||
assert set(parsed.keys()) == {'path', 'verb', 'status'}
|
||||
|
||||
# FIXME do we need to allow other options?
|
||||
assert match.group('protocol') == 'HTTP/1.1'
|
||||
assert self.verb == 'GET'
|
||||
self.verb = parsed['verb']
|
||||
|
||||
path = match.group('path')
|
||||
path = parsed['path']
|
||||
self.path = '/' if path == '/' else path.rstrip('/')
|
||||
|
||||
self.status = int(match.group('status'))
|
||||
self.status = parsed['status']
|
||||
|
||||
missing_paths = ['/favicon.ico', '/does-not-exist']
|
||||
|
||||
@ -85,8 +66,6 @@ class Request(testprocess.Line):
|
||||
else:
|
||||
assert self.status < 400
|
||||
|
||||
assert match.group('size') == '-'
|
||||
|
||||
def __eq__(self, other):
|
||||
return NotImplemented
|
||||
|
||||
|
@ -23,6 +23,7 @@ This script gets called as a QProcess from integration/conftest.py.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import signal
|
||||
import os
|
||||
@ -87,14 +88,12 @@ def redirect_later_continue():
|
||||
def log_request(response):
|
||||
"""Log a webserver request."""
|
||||
request = flask.request
|
||||
template = '127.0.0.1 - - [{date}] "{verb} {path} {http}" {status} -'
|
||||
print(template.format(
|
||||
date=datetime.now().strftime('%d/%b/%Y %H:%M:%S'),
|
||||
verb=request.method,
|
||||
path=request.full_path if request.query_string else request.path,
|
||||
http=request.environ['SERVER_PROTOCOL'],
|
||||
status=response.status_code,
|
||||
), file=sys.stderr, flush=True)
|
||||
data = {
|
||||
'verb': request.method,
|
||||
'path': request.full_path if request.query_string else request.path,
|
||||
'status': response.status_code,
|
||||
}
|
||||
print(json.dumps(data), file=sys.stderr, flush=True)
|
||||
return response
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user