#!/usr/bin/python

"""Test xz_mod.py, which attempts to figure in a somewhat blithe way which xz adapter to use."""

from __future__ import with_statement

import gc
import os
import sys
import subprocess

import xz_mod
import python2x3


def how_large_am_i():
    '''Check how large this process is'''
    # Note: For now at least, this is Linux-specific
    my_pid = os.getpid()
    process = subprocess.Popen('ps -p %d -o vsz=' % my_pid, shell=True, stdout=subprocess.PIPE)
    gc.collect()
    size = int(process.stdout.readline().strip())
    retval = process.wait()
    if retval is not None and retval != 0:
        sys.stderr.write('%s: running ps subcommand failed\n' % sys.argv[0])
        sys.exit(1)
    return size


def small_tests():
    '''main function'''
    all_good = True
    with open('/etc/protocols', 'rb') as protocols_file:
        protocols = protocols_file.read()
    for string in ['Rush Rocks', 'flurfl', protocols]:
        b_string = python2x3.string_to_binary(string)
        compressed = xz_mod.compress(b_string)
        decompressed = xz_mod.decompress(compressed)
        if b_string != decompressed:
            all_good = False
            sys.stderr.write('%s: Bad round trip: "%s", "%s"\n' % (sys.argv[0], string[:40], decompressed[:40]))
            if 1 == 2:
                # This facilitates debugging, but normally we want info about all 3, not just the first to fail
                with open('1', 'wb') as one:
                    one.write(b_string)
                with open('2', 'wb') as two:
                    two.write(decompressed)
                sys.exit(1)
    return all_good


def memleak_test():
    '''Test for a memory leak in decompression'''
    all_good = True
    string = 'To be multiplied, many times over' * int(1e2)
    b_string = python2x3.string_to_binary(string)

    maximum_tolerable_size = 512 * 2**30

    size = how_large_am_i()
    if size > maximum_tolerable_size:
        sys.stderr.write('%s: Preexisting memory leak?  %d\n' % (sys.argv[0], size))
        all_good = False
        return all_good

    for repno in range(10000):
        compressed = xz_mod.compress(b_string)
        decompressed = xz_mod.decompress(compressed)
        if b_string != decompressed:
            sys.stderr.write('%s: Bad memleak round trip\n' % sys.argv[0])
            all_good = False
        size = how_large_am_i()
        if size > maximum_tolerable_size:
            sys.stderr.write('%s: Memory leak detected - my virtual size is %d Kilobytes\n' % (sys.argv[0], size))
            all_good = False
            break
        else:
            tuple_ = (sys.argv[0], repno, size, len(b_string), len(compressed))
            sys.stdout.write('%s: Repetition %d, size is now %dK (%d, %d)\n' % tuple_)
    return all_good


def main():
    '''Main function'''
    all_good = True
    all_good &= small_tests()
    # all_good &= memleak_test()
    if not all_good:
        sys.stderr.write('%s: One or more tests failed\n' % sys.argv[0])
        sys.exit(1)


main()