如何让uwsgi以任何失败子进程的返回码退出(How to get uwsgi to exit with return code of any failed sub

编程入门 行业动态 更新时间:2024-10-08 10:58:44
如何让uwsgi以任何失败子进程的返回码退出(How to get uwsgi to exit with return code of any failed sub-process)

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

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

注意:我对嘲笑这件事并不感兴趣 - 我需要测试这个工作。

我已经创建了一个Docker化的最小化,完整和可验证的例子来说明我的问题:

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将失败进程的退出代码转发给主服务器?

I'm writing some integration tests that involve a Python application running under uwsgi. To test an aspect of this, I am running an uwsgi spooler, which requires that the master process is running. If pytest has a failed test, it returns a non-zero exit code, which is great. Without the master process, the entire uwsgi process also returns this exit code, and so our continuous integration server responds appropriately. However, when the master process is running, it always exits with a zero exit code - regardless of failed tests.

I need it to pass on the first non-zero exit code of a subprocess if there is one.

Note: I'm not really interested in mocking this out - I need to test this working.

I've created a Dockerized Minimal, Complete, and Verifiable Example that illustrates my issue:

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

Given the above 2 files in a directory, the following shows the return code if I run this failing test under uwsgi without the master process:

$ 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

Note: you can see that the return code from this process (last line) is non-zero as required


Now, changing nothing other than running uwsgi with the master process, we get the following output:

$ 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

Note: this time the return code from this process (last line) is zero - even though the test failed

How can I get uwsgi to forward the exit code from a failing process to the master?

最满意答案

这工作,但感觉有点哈克 。 如果有人来,我会很乐意接受更好的答案。

我已经做了这项工作,增加了两个额外的文件(以及对Dockerfile的一个小更新):

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 test run_tests.py /srv/ CMD ['/bin/bash']

测试

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

run_tests.py

#!/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()

它的工作方式是我复制并调整了pytest程序到run_tests.py ,在那里它将测试的返回代码写入临时文件。 测试通过bash脚本运行: test ,运行uwsgi,运行测试,然后用测试返回代码退出脚本。

结果现在看起来像

$ docker build -t=test . $ docker run test /srv/test ... ============================= 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 $? 1

This works, but feels a little hacky. I'll happily accept a better answer if one comes along.

I've made this work with the addition of two additional files (and a small update to the Dockerfile):

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 test run_tests.py /srv/ CMD ['/bin/bash']

test:

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

run_tests.py:

#!/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()

The way it works is that I've copied and tweaked the pytest program into run_tests.py, where it writes out the return code of the tests to a temporary file. The tests are run via a bash script: test, that runs uwsgi, which runs the tests, then exits the script with the return code from the tests.

Results now look like:

$ docker build -t=test . $ docker run test /srv/test ... ============================= 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 $? 1

更多推荐

本文发布于:2023-07-09 10:04:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1085522.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:进程   exit   uwsgi   failed   code

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!