Use expected pattern to compare textual stdout/stderr

This commit is contained in:
Fabrice Reix 2022-06-29 11:40:54 +02:00
parent 67ef7c75a7
commit 15582c03f6
No known key found for this signature in database
GPG Key ID: BF5213154B2E7155
3 changed files with 63 additions and 6 deletions

View File

@ -7,7 +7,7 @@ import subprocess
import os import os
import platform import platform
import check_json_output import check_json_output
import tempfile import re
def decode_string(encoded): def decode_string(encoded):
@ -93,11 +93,35 @@ def test(hurl_file):
if os.path.exists(f): if os.path.exists(f):
expected = open(f, "rb").read() expected = open(f, "rb").read()
actual = result.stdout actual = result.stdout
if expected != actual: if actual != expected:
print(">>> error in stdout") print(">>> error in stdout")
print(f"actual: <{actual}>\nexpected: <{expected}>") print(f"actual: <{actual}>\nexpected: <{expected}>")
sys.exit(1) sys.exit(1)
# stdout with textual pattern / line per line
f = hurl_file.replace(".hurl", ".out.pattern")
if os.path.exists(f):
expected = open(f, "r").read()
actual = decode_string(result.stdout)
expected_lines = expected.split("\n")
expected_pattern_lines = [parse_pattern(line) for line in expected_lines]
actual_lines = actual.split("\n")
if len(actual_lines) != len(expected_pattern_lines):
print(">>> error in stderr / mismatch in number of lines")
print(
"actual: %d lines\nexpected: %d lines"
% (len(actual_lines), len(expected_lines))
)
sys.exit(1)
for i in range(len(expected_pattern_lines)):
if not re.match(expected_pattern_lines[i], actual_lines[i]):
print(f">>> error in stdout in line {i+1}")
print(f"actual: <{actual_lines[i]}>")
print(
f"expected: <{expected_lines[i]}> (translated to regex <{expected_pattern_lines[i]}>)"
)
sys.exit(1)
# stdout (json) # stdout (json)
if os.path.exists(json_output_file): if os.path.exists(json_output_file):
expected = open(json_output_file).read() expected = open(json_output_file).read()
@ -109,7 +133,7 @@ def test(hurl_file):
if os.path.exists(f): if os.path.exists(f):
expected = open(f).read().strip() expected = open(f).read().strip()
actual = decode_string(result.stderr).strip() actual = decode_string(result.stderr).strip()
if expected != actual: if actual != expected:
print(">>> error in stderr") print(">>> error in stderr")
print(f"actual: <{actual}>\nexpected: <{expected}>") print(f"actual: <{actual}>\nexpected: <{expected}>")
sys.exit(1) sys.exit(1)
@ -123,6 +147,30 @@ def test(hurl_file):
print(f"actual: <{actual}>\nexpected: <{expected}>") print(f"actual: <{actual}>\nexpected: <{expected}>")
sys.exit(1) sys.exit(1)
# stderr with textual pattern / line per line
f = hurl_file.replace(".hurl", ".err.pattern")
if os.path.exists(f):
expected = open(f, "r").read()
actual = decode_string(result.stderr)
expected_lines = expected.split("\n")
expected_pattern_lines = [parse_pattern(line) for line in expected_lines]
actual_lines = re.split(r"\r?\n", actual)
if len(actual_lines) != len(expected_pattern_lines):
print(">>> error in stderr / mismatch in number of lines")
print(
"actual: %d lines\nexpected: %d lines"
% (len(actual_lines), len(expected_lines))
)
sys.exit(1)
for i in range(len(expected_pattern_lines)):
if not re.match(expected_pattern_lines[i], actual_lines[i]):
print(f">>> error in stderr in line {i+1}")
print(f"actual: <{actual_lines[i]}>")
print(
f"expected: <{expected_lines[i]}> (translated to regex <{expected_pattern_lines[i]}>)"
)
sys.exit(1)
# curl output # curl output
if os.path.exists(curl_file): if os.path.exists(curl_file):
expected_commands = [] expected_commands = []
@ -151,6 +199,16 @@ def test(hurl_file):
sys.exit(1) sys.exit(1)
def parse_pattern(s):
# Escape regex metacharacters
for c in [".", "(", ")", "[", "]", "^", "$", "*", "+", "?"]:
s = s.replace(c, "\\" + c)
s = re.sub("~+", ".*", s)
s = "^" + s + "$"
return s
def main(): def main():
for hurl_file in sys.argv[1:]: for hurl_file in sys.argv[1:]:
test(hurl_file) test(hurl_file)

View File

@ -1,7 +1,7 @@
HTTP/1.0 200 HTTP/1.0 200
Date: DATE
Content-Type: text/html; charset=utf-8 Content-Type: text/html; charset=utf-8
Content-Length: 5 Content-Length: 5
Server: Flask Server Server: Flask Server
Date: ~~~
Hello Hello

View File

@ -4,5 +4,4 @@ from flask import Response
@app.route("/include") @app.route("/include")
def include(): def include():
headers = {"Date": "DATE"} return Response("Hello")
return Response("Hello", headers=headers)