Fix assets file naming to work across both *nix and windows (#223)

* Fix assets file naming to work across both *nix and windows

Fixes #214
Fixes #213

* Better replacement strategy for test id

* Update markers
This commit is contained in:
Jim Brännlund 2019-08-06 13:57:05 +02:00 committed by GitHub
parent 6abbbff3e4
commit 9dd249f200
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 41 deletions

View File

@ -14,8 +14,8 @@ import pkg_resources
import sys
import time
import bisect
import hashlib
import warnings
import re
try:
from ansi2html import Ansi2HTMLConverter, style
@ -167,21 +167,17 @@ class HTMLReport(object):
def create_asset(
self, content, extra_index, test_index, file_extension, mode="w"
):
hash_key = "".join([self.test_id, str(extra_index), str(test_index)])
hash_generator = hashlib.md5()
hash_generator.update(hash_key.encode("utf-8"))
hex_digest = hash_generator.hexdigest()
# 255 is the common max filename length on various filesystems,
# we subtract hash length, file extension length and 2 more
# characters for the underscore and dot
max_length = 255 - len(hex_digest) - len(file_extension) - 2
asset_file_name = "{0}_{1}.{2}".format(
hash_key[:max_length], hex_digest, file_extension
)
# 255 is the common max filename length on various filesystems
asset_file_name = "{}_{}_{}.{}".format(
re.sub(r"[^\w\.]", "_", self.test_id),
str(extra_index),
str(test_index),
file_extension,
)[-255:]
asset_path = os.path.join(
os.path.dirname(self.logfile), "assets", asset_file_name
)
if not os.path.exists(os.path.dirname(asset_path)):
os.makedirs(os.path.dirname(asset_path))
@ -217,9 +213,9 @@ class HTMLReport(object):
html_div = html.img(src=src)
else:
if PY3:
content = b64decode(content.encode("utf-8"))
else:
content = b64decode(content)
content = content.encode("utf-8")
content = b64decode(content)
href = src = self.create_asset(
content, extra_index, test_index, extra.get("extension"), "wb"
)

View File

@ -10,7 +10,6 @@ import sys
import pkg_resources
import random
import re
import hashlib
import pytest
@ -468,13 +467,8 @@ class TestHTML:
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
hash_key = "test_extra_text_separated.py::" "test_pass00"
hash_generator = hashlib.md5()
hash_generator.update(hash_key.encode("utf-8"))
assert result.ret == 0
src = "{0}/{1}".format(
"assets", "{0}_{1}.txt".format(hash_key, hash_generator.hexdigest())
)
src = "assets/test_extra_text_separated.py__test_pass_0_0.txt"
link = '<a class="text" href="{0}" target="_blank">'.format(src)
assert link in html
assert os.path.exists(src)
@ -501,13 +495,9 @@ class TestHTML:
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
hash_key = "test_extra_image_separated.py::test_pass00"
hash_generator = hashlib.md5()
hash_generator.update(hash_key.encode("utf-8"))
assert result.ret == 0
src = "{0}/{1}".format(
"assets",
"{0}_{1}.{2}".format(hash_key, hash_generator.hexdigest(), file_extension),
src = "assets/test_extra_image_separated.py__test_pass_0_0.{}".format(
file_extension
)
link = '<a class="image" href="{0}" target="_blank">'.format(src)
assert link in html
@ -543,12 +533,8 @@ class TestHTML:
result, html = run(testdir)
for i in range(1, 4):
hash_key = "test_extra_image_separated_rerun.py::" "test_fail0{0}".format(i)
hash_generator = hashlib.md5()
hash_generator.update(hash_key.encode("utf-8"))
src = "assets/{0}_{1}.{2}".format(
hash_key, hash_generator.hexdigest(), file_extension
)
asset_name = "test_extra_image_separated_rerun.py__test_fail"
src = "assets/{}_0_{}.{}".format(asset_name, i, file_extension)
link = '<a class="image" href="{0}" target="_blank">'.format(src)
assert result.ret
assert link in html
@ -602,16 +588,36 @@ class TestHTML:
)
)
result, html = run(testdir)
hash_key = "test_very_long_test_name.py::{}00".format(test_name)
hash_generator = hashlib.md5()
hash_generator.update(hash_key.encode("utf-8"))
src = "assets/{0}_{1}.png".format(hash_key[:218], hash_generator.hexdigest())
file_name = "test_very_long_test_name.py__{}_0_0.png".format(test_name)[-255:]
src = "assets/" + file_name
link = '<a class="image" href="{0}" target="_blank">'.format(src)
assert result.ret
assert link in html
assert os.path.exists(src)
def test_no_invalid_characters_in_filename(self, testdir):
testdir.makeconftest(
"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
report.extra = [extras.image('image.png')]
"""
)
testdir.makepyfile(
"""
def test_fail():
assert False
"""
)
run(testdir)
for filename in os.listdir("assets"):
assert re.search(r'[:\\<>\*\?\|"}{}~]', filename) is None
def test_no_environment(self, testdir):
testdir.makeconftest(
"""

View File

@ -7,12 +7,13 @@
envlist = py{27,36,37,py,py3}{,-ansi2html}, flake8, black
[testenv]
commands = pytest -v -r a {posargs}
setenv = PYTHONDONTWRITEBYTECODE=1
deps =
pytest-xdist
pytest-rerunfailures
pytest-mock
py{27,36,py,py3}-ansi2html: ansi2html
commands = pytest -v -r a {posargs}
[testenv:flake8]
skip_install = true