如何让uwsgi退出任何失败的子进程的返回代码

时间:2018-01-12 20:25:01

标签: python docker pytest uwsgi

我正在编写一些涉及在uwsgi下运行的Python应用程序的集成测试 为了测试这方面的一个方面,我正在运行一个uwsgi假脱机程序,这需要master进程正在运行。
如果pytest测试失败,则返回非零退出代码,这很好 如果没有主进程,整个uwsgi进程也会返回此退出代码,因此我们的持续集成服务器会做出适当的响应 但是,当主进程正在运行时,它始终以零退出代码退出 - 无论测试失败。

我需要它传递子进程的第一个非零退出代码(如果有的话)。

注意:我真的不想嘲笑这个 - 我需要对此进行测试。

我创建了一个Dockerized Minimal, Complete, and Verifiable Example来说明我的问题:

Dockerfile:

FROM python:3.6.4-slim-stretch

WORKDIR /srv

RUN apt-get update \
    && apt-get install -y build-essential \
    && pip install uwsgi pytest

COPY test_app.py /srv/

CMD ['/bin/bash']

test_app.py:

import pytest

def test_this():
    assert 1==0

鉴于目录中的上述2个文件,如果我在没有主进程的情况下在uwsgi 下运行此失败测试,​​则显示返回代码

$ docker build -t=test .
$ docker run test uwsgi --chdir /srv --pyrun /usr/local/bin/pytest
...
============================= test session starts ==============================
platform linux -- Python 3.6.4, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /srv, inifile:
collected 1 item

test_app.py F                                                            [100%]

=================================== FAILURES ===================================
__________________________________ test_this ___________________________________

    def test_this():
>       assert 1==0
E       assert 1 == 0

test_app.py:4: AssertionError
=========================== 1 failed in 0.05 seconds ===========================
$ echo $?
1

注意:您可以看到此流程的返回代码(最后一行)根据需要为非零

现在,除了使用主进程运行uwsgi之外什么都不做,我们得到以下输出:

$ docker run test uwsgi --set master=true --chdir /srv --pyrun /usr/local/bin/pytest
...
============================= test session starts ==============================
platform linux -- Python 3.6.4, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /srv, inifile:
collected 1 item

test_app.py F                                                            [100%]

=================================== FAILURES ===================================
__________________________________ test_this ___________________________________

    def test_this():
>       assert 1==0
E       assert 1 == 0

test_app.py:4: AssertionError
=========================== 1 failed in 0.05 seconds ===========================
worker 1 buried after 0 seconds
goodbye to uWSGI.
$ echo $?
0

注意:这次来自此过程的返回码(最后一行)为零 - 即使测试失败

如何让uwsgi将退出代码从失败的流程转发给主人?

1 个答案:

答案 0 :(得分:0)

这有效,但感觉有点 hacky 。如果有人出现,我会很乐意接受更好的答案。

我通过添加两个额外的文件(以及对Dockerfile的一个小更新)来完成这项工作:

<强> Dockerfile

results

<强>测试

FROM python:3.6.4-slim-stretch

WORKDIR /srv

RUN apt-get update \
    && apt-get install -y build-essential \
    && pip install uwsgi pytest

COPY test_app.py test run_tests.py /srv/

CMD ['/bin/bash']

<强> run_tests.py

#!/bin/bash
uwsgi --set master=true --chdir /srv --pyrun /srv/run_tests.py
exit $(cat /tmp/test_results)

它的工作方式是我将pytest程序复制并调整到#!/usr/bin/python import re import subprocess import sys from pytest import main def write_result(retcode): path = r'/tmp/test_results' with open(path, 'w') as f: f.write(str(retcode)) def run(): sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) retcode = 1 try: retcode = main() finally: write_result(retcode) sys.exit(retcode) if __name__ == '__main__': run() ,在那里它将测试的返回代码写入临时文件。测试通过bash脚本运行:run_tests.py,运行uwsgi,运行测试,然后使用测试的返回代码退出脚本。

结果现在看起来像

test