This requires that there is an xz binary installed, and accessible, obviously.
v4: - add this patch Signed-off-by: Dylan Baker <[email protected]> --- framework/backends/compression.py | 82 ++++++++++++++++++++++++++++- framework/tests/compressed_backend_tests.py | 17 ++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/framework/backends/compression.py b/framework/backends/compression.py index 153dc94..ef97c95 100644 --- a/framework/backends/compression.py +++ b/framework/backends/compression.py @@ -43,15 +43,17 @@ they're passing unicode and not bytes. from __future__ import print_function, absolute_import, division import bz2 +import errno import functools import gzip import os +import subprocess from framework import exceptions from framework.core import PIGLIT_CONFIG -# TODO: in python3 the bz2 module has an open function +# TODO: in python3 the bz2 module has an open function COMPRESSION_SUFFIXES = ['.gz', '.bz2'] DEFAULT = 'bz2' @@ -68,6 +70,84 @@ DECOMPRESSORS = { 'none': functools.partial(open, mode='r'), } +# TODO: in python3 there is builtin xz support, and doesn't need this madness +# If there is an xz binary then try calling out to that +try: + with open(os.devnull, 'w') as d: + subprocess.check_call(['xz'], stderr=d) +except subprocess.CalledProcessError as e: + if e.returncode == 1: + import contextlib + try: + import cStringIO as StringIO + except ImportError: + import StringIO + + @contextlib.contextmanager + def _compress_xz(filename): + """Emulates an open function in write mode for xz. + + Python 2.x doesn't support xz, but it's dang useful. This function calls + out to the shell and tries to use xz from the environment to get xz + compression. + + This obviously won't work without a working xz binary. + + This function tries to emulate the default values of the lzma module in + python3 as much as possible + + """ + if filename.endswith('.xz'): + filename = filename[:-2] + + with open(filename, 'w') as f: + yield f + + try: + subprocess.check_call(['xz', '--compress', '-9', filename]) + except OSError as e: + if e.errno == errno.ENOENT: + raise exceptions.PiglitFatalError('No xz binary available') + raise + + @contextlib.contextmanager + def _decompress_xz(filename): + """Eumlates an option function in read mode for xz. + + See the comment in _compress_xz for more information. + + This module tries to emulate the lzma module as much as possible + + """ + if not filename.endswith('.xz'): + filename = '{}.xz'.format(filename) + + print('decompress: ' + filename) + + try: + string = subprocess.check_output( + ['xz', '--decompress', '--stdout', filename]) + except OSError as e: + if e.errno == errno.ENOENT: + raise exceptions.PiglitFatalError('No xz binary available') + raise + + # We need a file-like object, so the contents must be placed in a StringIO + # object. + io = StringIO.StringIO() + io.write(string) + io.seek(0) + + yield io + + io.close() + + COMPRESSORS['xz'] = _compress_xz + DECOMPRESSORS['xz'] = _decompress_xz + COMPRESSION_SUFFIXES += ['.xz'] +except OSError: + pass + def _set_mode(): """Set the compression mode. diff --git a/framework/tests/compressed_backend_tests.py b/framework/tests/compressed_backend_tests.py index 7af633d..2353c7b 100644 --- a/framework/tests/compressed_backend_tests.py +++ b/framework/tests/compressed_backend_tests.py @@ -218,3 +218,20 @@ def test_decompress_bz2(): def test_bz2_output(): """framework.backends: when using bz2 compression a bz2 file is created""" nt.eq_(_test_extension(), '.bz2') + + [email protected]_error +def test_compress_xz(): + """framework.backends.compression: can compress to 'xz'""" + _test_compressor('xz') + + +def test_decompress_xz(): + """framework.backends.compression: can decompress from 'xz'""" + _test_decompressor('xz') + + +@_set_compression_mode('xz') +def test_xz_output(): + """framework.backends: when using xz compression a xz file is created""" + nt.eq_(_test_extension(), '.xz') -- 2.4.5 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
