aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pyrsistent/py3/tests/memory_profiling.py
blob: 69036520cdcfe1543d244b5950f2d7a66868264b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"""
Script to try do detect any memory leaks that may be lurking in the C implementation of the PVector.
"""
import inspect
import sys
import time
import memory_profiler
import vector_test
from pyrsistent import pvector

try:
    import pvectorc
except ImportError:
    print("No C implementation of PVector available, terminating")
    sys.exit()


PROFILING_DURATION = 2.0


def run_function(fn):
    stop = time.time() + PROFILING_DURATION
    while time.time() < stop:
        fn(pvector)


def detect_memory_leak(samples):
    # Do not allow a memory usage difference larger than 5% between the beginning and the end.
    # Skip the first samples to get rid of the build up period and the last sample since it seems
    # a little less precise
    return abs(1 - (sum(samples[5:8]) / sum(samples[-4:-1]))) > 0.05


def profile_tests():
    test_functions = [fn for fn in inspect.getmembers(vector_test, inspect.isfunction)
                      if fn[0].startswith('test_')]

    for name, fn in test_functions:
        # There are a couple of tests that are not run for the C implementation, skip those
        fn_args = inspect.getfullargspec(fn)[0]
        if 'pvector' in fn_args:
            print('Executing %s' % name)
            result = memory_profiler.memory_usage((run_function, (fn,), {}), interval=.1)
            assert not detect_memory_leak(result), (name, result)


if __name__ == "__main__":
    profile_tests()