mirror of
https://gitlab.com/bzip2/bzip2.git
synced 2025-08-09 13:22:45 +03:00
The tests may fail if the BZIP or BZIP2 environment variables are set. To reproduce the issue, run: BZIP2="--derp" ctest -V This commit discards those variables before running the tests. Resolves: https://gitlab.com/bzip2/bzip2/-/issues/31 Fix courtesy of Michael Orlitzky
160 lines
4.2 KiB
Python
160 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--mode', choices={'compress', 'decompress'})
|
|
parser.add_argument('bzip2')
|
|
parser.add_argument('bzip_arg')
|
|
parser.add_argument('input')
|
|
parser.add_argument('reference', nargs='?')
|
|
args = parser.parse_args()
|
|
|
|
if args.mode == 'compress':
|
|
test_compress(args)
|
|
else:
|
|
test_decompress(args)
|
|
|
|
def get_slice(data, line_no, size):
|
|
if len(data) / size > line_no:
|
|
return data[line_no:line_no + size]
|
|
elif len(data) / size == line_no:
|
|
return data[line_no:line_no + len(data) % size]
|
|
else:
|
|
return []
|
|
|
|
def print_binary(data, size):
|
|
'''
|
|
Print hex
|
|
'''
|
|
lines = int(len(data) / size)
|
|
|
|
def render_slice(to_print, size):
|
|
line = ''
|
|
for byte in range(0, size):
|
|
if byte == size / 2:
|
|
line += ' '
|
|
if byte < len(to_print):
|
|
line += '{:02x}'.format(to_print[byte])
|
|
else:
|
|
line += ' '
|
|
return line
|
|
|
|
for line in range(0, lines):
|
|
print(render_slice(get_slice(data, line, size), size))
|
|
print('')
|
|
|
|
def print_binary_compare(actual, expected, size):
|
|
'''
|
|
Print hex comparison of two buffers
|
|
'''
|
|
a_lines = int(len(actual) / size)
|
|
e_lines = int(len(expected) / size)
|
|
lines = max(a_lines, e_lines)
|
|
|
|
def render_slice(to_print, to_compare):
|
|
line = ''
|
|
for byte in range(0, size):
|
|
if byte == size / 2:
|
|
line += ' '
|
|
if byte < len(to_print):
|
|
if byte >= len(to_compare) or to_print[byte] != to_compare[byte]:
|
|
line += '\x1b[1;33m{:02x}\x1b[0m'.format(to_print[byte]) # bold yellow
|
|
else:
|
|
line += '{:02x}'.format(to_print[byte]) # plain
|
|
else:
|
|
line += ' '
|
|
return line
|
|
|
|
for line in range(0, lines):
|
|
a_line = get_slice(actual, line, size)
|
|
e_line = get_slice(expected, line, size)
|
|
text_line = '{} {}'.format(
|
|
render_slice(a_line, e_line),
|
|
render_slice(e_line, a_line)
|
|
)
|
|
print(text_line)
|
|
print('')
|
|
|
|
|
|
def test_compress(args: argparse.Namespace) -> None:
|
|
with open(args.reference, 'rb') as f:
|
|
expected = f.read()
|
|
|
|
with open(args.input, 'rb') as f:
|
|
input_ = f.read()
|
|
|
|
command = '{bzip2} {arg}'.format(
|
|
bzip2=args.bzip2,
|
|
arg=args.bzip_arg
|
|
)
|
|
|
|
print('\nRunning: {}\n with {} bytes of input from {}\n'.format(command, len(input_), args.input))
|
|
|
|
p = subprocess.run(
|
|
command.split(' '),
|
|
stdout=subprocess.PIPE,
|
|
input=input_)
|
|
if p.returncode != 0:
|
|
print('bzip2 failed to run')
|
|
sys.exit(1)
|
|
|
|
actual = p.stdout
|
|
if actual != expected:
|
|
print('comparison of actual and expected output failed')
|
|
print(' actual:' + ' ' * 60 + 'expected:')
|
|
print_binary_compare(actual, expected, 32)
|
|
sys.exit(1)
|
|
|
|
|
|
def test_decompress(args: argparse.Namespace) -> None:
|
|
with open(args.input, 'rb') as f:
|
|
input_ = f.read()
|
|
|
|
p = subprocess.run(
|
|
[args.bzip2, args.bzip_arg],
|
|
stdout=subprocess.PIPE,
|
|
input=input_)
|
|
if p.returncode != 0:
|
|
print('bzip2 failed to compress')
|
|
sys.exit(1)
|
|
compressed = p.stdout
|
|
dargs = '-d' if args.bzip_arg != '-3' else '-ds'
|
|
|
|
command = '{bzip2} {arg}'.format(
|
|
bzip2=args.bzip2,
|
|
arg=dargs
|
|
)
|
|
|
|
print('\nRunning: {}\n with {} bytes of input from {}\n'.format(command, len(input_), args.input))
|
|
|
|
p = subprocess.run(
|
|
command.split(' '),
|
|
stdout=subprocess.PIPE,
|
|
input=compressed,
|
|
)
|
|
if p.returncode != 0:
|
|
print('bzip2 failed to decompress')
|
|
sys.exit(1)
|
|
|
|
actual = p.stdout
|
|
if input_ != actual:
|
|
print('comparison of actual and expected output failed')
|
|
print(' actual:' + ' ' * 60 + 'input:')
|
|
print_binary_compare(actual, input_, 32)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
# Prevent OS environment variables from affecting the test suite.
|
|
os.environ.pop('BZIP', None)
|
|
os.environ.pop('BZIP2', None)
|
|
|
|
main()
|