2017-09-20 9 views
1

Ich benutze Pytest, aber ich hätte gerne einen Dekorator, der eine maximale Speicherauslastung pro Test einstellen könnte. Ähnlich wie bei diesem question die mit beantwortet wurde,Wie pytest Platz Speichergrenzen für Tests?

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

Ich möchte,

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

EDIT:

Ich habe versucht,

>>> 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 

Welche fangen nicht die Speicherzuweisung in der Funktion.

Antwort

1

Nachdem ich gelernt habe, wie limit the memory used und zu sehen, wie viel memory is currently used, schrieb ich einen Dekorator, der aus, wenn das Speicherinkrement zu hoch ist. Es ist ein bisschen buggy mit der Festlegung der Grenzen, aber es funktioniert gut genug für mich.

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") 

Zumindest läuft auf meinem Computer Code und endet ohne einen Fehler.

+0

Das sieht super aus. Könnten Sie näher auf "ein bisschen Buggy mit dem Festlegen der Grenzen" näher eingehen? –

+1

Beachten Sie, dass der Dekorator '@memory_limit (int (16e8))' 'sagt, aber der try/except-Block fehlschlägt für' allocate (int (3e8)) '. "Ein bisschen buggy" bedeutete, dass ich keine offensichtliche Beziehung zwischen den beiden Zahlen finden konnte, aber für meine Zwecke war ein ungefähres Ergebnis in Ordnung. –

Verwandte Themen