-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Infrastructure for memory usage tests (#299)
* added MemoryThreshold context manager * added unit test for memory usage of median computation
- Loading branch information
Showing
4 changed files
with
106 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add infrastructure for testing memory usage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import tracemalloc | ||
|
||
MEMORY_UNIT_CONVERSION = {"B": 1, "KB": 1024, "MB": 1024 ** 2, "GB": 1024 ** 3, "TB": 1024 ** 4} | ||
|
||
class MemoryThresholdExceeded(Exception): | ||
pass | ||
|
||
|
||
class MemoryThreshold: | ||
""" | ||
Context manager to check peak memory usage against an expected threshold. | ||
example usage: | ||
with MemoryThreshold(expected_usage): | ||
# code that should not exceed expected | ||
If the code in the with statement uses more than the expected_usage | ||
memory a ``MemoryThresholdExceeded`` exception | ||
will be raised. | ||
Note that this class does not prevent allocations beyond the threshold | ||
and only checks the actual peak allocations to the threshold at the | ||
end of the with statement. | ||
""" | ||
|
||
def __init__(self, expected_usage): | ||
""" | ||
Parameters | ||
---------- | ||
expected_usage : str | ||
Expected peak memory usage expressed as a whitespace-separated string | ||
with a number and a memory unit (e.g. "100 KB"). | ||
Supported units are "B", "KB", "MB", "GB", "TB". | ||
""" | ||
expected, self.units = expected_usage.upper().split() | ||
self.expected_usage_bytes = float(expected) * MEMORY_UNIT_CONVERSION[self.units] | ||
|
||
def __enter__(self): | ||
tracemalloc.start() | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_value, traceback): | ||
_, peak = tracemalloc.get_traced_memory() | ||
tracemalloc.stop() | ||
|
||
if peak > self.expected_usage_bytes: | ||
scaling = MEMORY_UNIT_CONVERSION[self.units] | ||
msg = ("Peak memory usage exceeded expected usage: " | ||
f"{peak / scaling:.2f} {self.units} > " | ||
f"{self.expected_usage_bytes / scaling:.2f} {self.units} ") | ||
raise MemoryThresholdExceeded(msg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
"""Tests of custom testing infrastructure""" | ||
|
||
import pytest | ||
import numpy as np | ||
from stcal.testing_helpers import MemoryThreshold, MemoryThresholdExceeded | ||
|
||
|
||
def test_memory_threshold(): | ||
with MemoryThreshold("10 KB"): | ||
buff = np.ones(1000, dtype=np.uint8) | ||
|
||
|
||
def test_memory_threshold_exceeded(): | ||
with pytest.raises(MemoryThresholdExceeded): | ||
with MemoryThreshold("500. B"): | ||
buff = np.ones(10000, dtype=np.uint8) |