我有兴趣在某种类型的沙盒中使用pytest执行可能不受信任的测试,例如docker,类似于持续集成服务。
我理解为了正确沙箱化一个python进程你需要操作系统级隔离,比如在一次性chroot /容器中运行测试,但在我的用例中我不需要防止故意恶意代码,只有从配对的危险行为"随机"带参数的函数。因此,较不严格的沙箱仍然可以接受。但我没有找到任何能够支持任何形式沙盒的插件。
在pytest中沙盒测试执行的最佳方法是什么?
更新:此问题与python sandboxing in general无关,因为测试'代码由pytest运行,我无法改变执行方式以使用exec
或ast
或其他任何内容。不幸的是,使用pypy-sandbox并不是一个选择,因为它只是一个原型"根据{{3}}。
更新2 :用于用户级隔离的pytest-dev邮件列表PyPy feature page上的Hoger Krekel:
py.test --tx ssh=OTHERUSER@localhost --dist=each
suggests using a dedicated testuser via pytest-xdist我的CI用例:
拥有"一次性"环境与孤立一样重要 一,所以每个测试或每个会话都从同一个初始运行 状态,它不受旧会话可能留下的影响 在 testuser 可写的文件夹上(/ home / testuser,/ tmp,/ var / tmp, 等)。
所以testuser + xdist接近一个解决方案,但不是那么。
仅针对上下文我需要隔离才能运行made me realise。
答案 0 :(得分:7)
经过相当多的研究后,我没有找到任何现成的方法让pytest在操作系统级隔离和一次性环境中运行项目测试。许多方法都是可能的,并且有优点和缺点,但是大多数方法都有更多我觉得舒服的活动部件。
我设计的绝对最小(但固执己见)的方法如下:
pytest
requirements.txt
pytest
user 要实施此方法,请将以下Dockerfile
添加到要在requirements.txt
和setup.py
文件旁边测试的项目的顶部文件夹中:
FROM python:3
# setup pytest user
RUN adduser --disabled-password --gecos "" --uid 7357 pytest
COPY ./ /home/pytest
WORKDIR /home/pytest
# setup the python and pytest environments
RUN pip install --upgrade pip setuptools pytest
RUN pip install --upgrade -r requirements.txt
RUN python setup.py develop
# setup entry point
USER pytest
ENTRYPOINT ["py.test"]
使用以下方法构建图像:
docker build -t pytest .
在容器内运行py.test,将项目文件夹作为卷放在/ home / pytest上,并使用:
docker run --rm -it -v `pwd`:/home/pytest pytest [USUAL_PYTEST_OPTIONS]
请注意,-v
将卷安装为uid 1000,因此pytest用户无法写入主机文件,而uid强制为7357。
现在,您应该能够使用操作系统级隔离开发和测试项目。
更新:如果您还在主机上运行测试,则可能需要删除容器内无法写入的python和pytest缓存。在主机上运行:
rm -rf .cache/ && find . -name __pycache__ | xargs rm -rf
答案 1 :(得分:2)
老实说,对于像docker这样的东西来说,这似乎是一个很好的用例。当然,你只是不使用python完全干净地处理它,但你可以滥用主机操作系统,而不必担心长期损坏。此外,与许多CI解决方案不同,它可以在您的开发机器上轻松运行。
另请注意,无论您的代码是否有意恶意,具有这种隔离效果仍然有助于防止以下事故:
rm -rf /usr/local/share/ myapp