coverage gunicorn <params>
funktioniert nicht, weil Gunicorn Arbeitsprozesse erstellt, und das Modul coverage
kann nicht über Gabeln (im Grunde, Erstellung neuer Prozesse) funktionieren. Sie können the coverage API, obwohl verwenden, zum Beispiel in dem Python-Modul, die WSGI-Anwendung enthält:
# wsgi_with_coverage.py
import atexit
import sys
import coverage
cov = coverage.coverage()
cov.start()
from wsgi import application # adjust to python module containing your wsgi application
def save_coverage():
print >> sys.stderr, "saving coverage"
cov.stop()
cov.save()
atexit.register(save_coverage)
Dann gunicorn -w 1 wsgi_with_coverage:application <other params>
laufen.
Das Problem ist, die atexit
Funktionen werden nicht aufgerufen, wenn Sie den Gunicorn-Prozess zum Beispiel über STRG + C beenden. Aber sie sind aufgerufen SIGHUP
, wenn Sie also kill -HUP $(cat <gunicorn_pidfile_here>)
tun, sollten die Coverage-Daten gespeichert werden (standardmäßig auf ".coverage" im aktuellen Verzeichnis).
Eine mögliche Einschränkung ist, dass dies nicht mit mehr als einem Gunicorn-Arbeiter funktioniert, weil sie alle die ".coverage" -Datei überschreiben würden. Wenn Sie unbedingt mehr als einen Worker benötigen, können Sie unter ".coverage-%d" % os.getpid()
(geben Sie den Dateinamen via the data_file
parameter to the coverage
constructor) und the combine()
method verwenden, um die einzelnen Messungen zusammenzuführen.
Dies sollte auch auf anderen WSGI-Servern funktionieren, je nachdem, ob sie ihren Worker-Prozessen ermöglichen, über die Methode atexit
zu bereinigen.
Die SIGHUP Beratung ist nicht so gut :). Gunicorn lädt die Arbeitsprozesse beim Abrufen von SIGHUP erneut. Das heißt, die erfassten Coverage-Daten werden nicht genau gespeichert, sondern mit den Daten überschrieben, die nur beim Laden auftreten. Das Senden von SIGTER dagegen löst den atexit-Handler ordnungsgemäß aus und schließt Gunicorn sauber ab. –