2017-09-20 71 views
1

我正在使用pytest,但我希望有一個裝飾器可以設置每個測試的最大內存使用量。與此相似question其得到的回答是,如何在測試中使用pytest地方內存限制?

@pytest.mark.timeout(300) 
def test_foo(): 
    pass 

我想,

@pytest.mark.maxmem(300) 
def test_foo(): 
    pass 

編輯:

我試過,

>>> import os, psutil 
>>> import numpy as np 
>>> process = psutil.Process(os.getpid()) 
>>> process.memory_info().rss/1e9 
0.01978368 
>>> def f(): 
...  x = np.arange(int(1e9)) 
... 
>>> process.memory_info().rss/1e9 
0.01982464 
>>> f() 
>>> process.memory_info().rss/1e9 
0.019832832 

這並不趕上內存分配在函數中。

回答

1

學習如何limit the memory used並看到多少memory is currently used,我寫了一個裝飾器,如果內存增量太高,錯誤。設置限制是有點bug的,但它對我來說已經足夠好了。

import resource, os, psutil 
import numpy 

def memory_limit(max_mem): 
    def decorator(f): 
     def wrapper(*args, **kwargs): 
      process = psutil.Process(os.getpid()) 
      prev_limits = resource.getrlimit(resource.RLIMIT_AS) 
      resource.setrlimit(resource.RLIMIT_AS, (process.memory_info().rss + max_mem, -1)) 
      result = f(*args, **kwargs) 
      resource.setrlimit(resource.RLIMIT_AS, prev_limits) 
      return result 
     return wrapper 
    return decorator 


@memory_limit(int(16e8)) 
def allocate(N): 
    return numpy.arange(N, dtype='u8') 

a = [allocate(int(1e8)) for i in range(10)] 

try: 
    allocate(int(3e8)) 
except: 
    exit(0) 
raise Exception("Should have failed") 

至少在我的機器上的代碼運行和退出沒有錯誤。

+0

這看起來很棒。你能否詳細說明「設置限制有點小錯誤」? –

+1

請注意,修飾符說'@memory_limit(int(16e8))',但try/except塊失敗'allocate(int(3e8))'。 「有點馬車」意味着我無法找到這兩個數字之間的明顯關係,但爲了我的目的,近似沒有問題。 –