-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Very large test suites take *far* too much RAM #619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Original comment by Alex Gaynor (BitBucket: alex_gaynor, GitHub: alex_gaynor): Link to the repo: https://github.com/pyca/cryptography can easily be run with |
Original comment by Alex Gaynor (BitBucket: alex_gaynor, GitHub: alex_gaynor): Eep, email just showed up this morning! I haven't tried yet, it works on py3k so I'd probably start with https://docs.python.org/3/library/tracemalloc.html |
Is this because Python is creating a first class object for every test function? |
Yes, it does at the very least create a In general pytest has been optimized for efficiency rather than memory usage (there's a lot of caches for example). |
sorry for resurrecting this issue but I'm trying to find an alternative way to reduce the memory usage of parametrizations: import numpy as np
import pytest
one = range(5)
two = range(30)
three = range(9000)
four = [np.zeros([50, 2000, 2000]), np.ones([50, 2000, 2000]),
np.zeros([50, 2000, 2000])+2, np.zeros([50, 2000, 2000])+3]
@pytest.mark.parametrize("A", four)
@pytest.mark.parametrize("B", three)
@pytest.mark.parametrize("C", two)
@pytest.mark.parametrize("D", one)
def test_highmem(A, B, C, D):
assert all(A)
assert B == C == D This quad-loop code is coping the numpy arrays in every test, skyrocketing memory usage. Is there a special function call to avoid copies? Any other idea different than coding for loops inside a single test and printing the success of each in the test? My use case scenario is a similar one to the above, but A is a list of objects where coverage should be complete [ 100%]. These objects are "read-only" in the sense they do not mutate during the test. PS: All of the above is also supposedly to run under pytest-xdist to minimize pytest runtime. |
A large portion of this problem is that pytest retains references to the stack for the purposes of error reporting. I couldn't find a way to disable. --tb=no and --assert=plain still causes a failure to garbage collect stuff. |
@earonesty you are correct that pytest will retain a reference to the stack (actually to the exception object) for error reporting. For passing tests it should not retain anything thought.
I would like to point out to |
For this reason, I have a whole set of memory-clearing and |
Some questsions:
|
|
Just tackled this bug. Making a session with 3k tests will result with ram usage being expended without garbage collection.
Is there any solution/ progress with this bug? |
Not at the moment, we would need a access to a repository which reproduces the problem. TBH I don't think there's a bug in pytest per-se, but there must be some fixture/parametrization which is wrongly causing pytest to consume too much RAM. At work we have complex fixtures at all scopes, parametrization, many test suites where 3k+ tests are usual, and we don't have any of the problems reported here, that's why I don't think it is necessarily a bug in pytest itself. |
fyi: this repo does not reproduce the problem. it has a very simple "6 tests" https://github.com/AtakamaLLC/pysecbytes. running with pytest works, which means memory is freed and this problem is definitely not intrinsic to pytest, but is more likely, as you said and interaction with a specific use of pytest. if i can modify this fairly minimal test suite to make it fail in pytest (memory leaked), but succeed in nose (memory freed), then it's a way to isolate the real issue |
We have an issue with a single test case, undecorated, blowing up x100 memory usage when run under pytest. This may not be your usual test case - it is a load test which generates 100 concurrent calls each to two systems, runs for an extended period, and reviews the call metrics. So 200 threads for, say, an hour each. Baseline memory footprint is just under 1GB. When run with pytest this grows to over 100GB - which is why it kept failing in our automated test framework. (1GB baseline is excessive to start with!) pytest 3.3.2 on python 3.8 (python version dictated by the framework), on Linux (RHEL 7). |
Pytest 3 is so phenomenally outdated that we can't do support for it, please get help from your vendor |
Hello, I hope this is relevant. We have similar issue with our project. We have a rather large test suite and when more tests fail (which is common), we run out of memory very quickly. We believe this is because pytest stores variables for failed test cases, which is generally desired behavior, this however causes issues for us, as even 120 GB RAM is not really enough to run the whole test suite. Is there any way we could run the test suite without having states of failed test cases stored? Really, we'd like to be able to run the test suite with failed test cases treated the same as passed test cases - without storing the failing state. We're running on python 3.11 and pytest 7.4.0. Most of the tests are parametrized, if it's relevant. |
Originally reported by: Alex Gaynor (BitBucket: alex_gaynor, GitHub: alex_gaynor)
The cryptography test suite on OS X -- which is 149150 test functions (almost entirely generated with
@pytest.mark.parametrize
) -- results in a CPython 2.7 process which, after collection, takes 1.26GB or so.This is about 8KB per test. This seems like way too much, it would be fantastic to bring this significantly down.
The text was updated successfully, but these errors were encountered: