有没有办法用pytest进行沙箱测试执行,尤其是文件系统访问?

ale*_*ici 4 python testing unit-testing pytest docker

我有兴趣在某种沙盒中使用pytest执行可能不受信任的测试,比如docker,类似于持续集成服务.

我理解为了正确沙箱化一个python进程你需要操作系统级别的隔离,比如在一次性chroot /容器中运行测试,但在我的用例中,我不需要防止故意恶意代码,只是来自配对的危险行为带参数的"随机"函数.因此,较不严格的沙箱仍然可以接受.但我没有找到任何能够实现任何形式沙盒的插件.

沙盘测试在pytest中执行的最佳方法是什么?

更新:这个问题是不是在一般的蟒蛇沙盒作为测试代码由pytest运行,我不能改变它执行使用方式execast或什么的.不幸的是,使用pypy-sandbox也不是一个选项,因为根据PyPy功能页面它只是"原型" .

更新2:pytest-dev邮件列表中的Hoger Krekel 建议使用专用的testuser通过pytest-xdist进行用户级隔离:

py.test --tx ssh=OTHERUSER@localhost --dist=each
Run Code Online (Sandbox Code Playgroud)

让我意识到我的CI用例:

具有"一次性"环境与具有隔离的环境一样重要,因此每个测试或每个会话都从相同的初始状态运行,并且不会受到testuser可写入的文件夹上旧的会话可能留下的影响(/ home/testuser,/ tmp,/ var/tmp等).

因此testuser + xdist接近于解决方案,但并不完全存在.

只是为了上下文我需要隔离来运行pytest-nodev.

ale*_*ici 7

经过相当多的研究后,我没有找到任何现成的方法让pytest在操作系统级隔离和一次性环境中运行项目测试.许多方法都是可能的,并且有优点和缺点,但是大多数方法都有更多我觉得舒服的活动部件.

我设计的绝对最小(但固执己见)的方法如下:

  • 使用以下命令构建python docker镜像:
    • 专用的非root用户: pytest
    • 来自的所有项目依赖项 requirements.txt
    • 项目安装在开发模式下
  • 在一个容器中运行py.test,该容器将主机上的项目文件夹安装为pytest用户的主目录

要实现该方法,请将以下内容添加Dockerfile到要在requirements.txtsetup.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"]
Run Code Online (Sandbox Code Playgroud)

使用以下内容构建图像:

docker build -t pytest .
Run Code Online (Sandbox Code Playgroud)

在容器内运行py.test,将项目文件夹作为卷放在/ home/pytest上,使用:

docker run --rm -it -v `pwd`:/home/pytest pytest [USUAL_PYTEST_OPTIONS]
Run Code Online (Sandbox Code Playgroud)

请注意,-v将卷安装为uid 1000,因此pytest用户无法写入主机文件,并且uid强制为7357.

现在,您应该能够使用操作系统级隔离开发和测试项目.

更新:如果您还在主机上运行测试,则可能需要删除容器内无法写入的python和pytest缓存.在主机上运行:

rm -rf .cache/ && find . -name __pycache__  | xargs rm -rf
Run Code Online (Sandbox Code Playgroud)

  • 您在问题中描述的用例实际上是一段时间以来我对 Docker 最常见的用途。这个答案涵盖了使这种方法起作用的大部分细节。+1我目前正在努力解决的一件事是如何为每个单独的测试*生成一个 Docker 容器以获得测试和操作系统级别的隔离,以及与 pytest-xdist 插件等并行化的能力。 .. (2认同)
  • 据我所知,这种用例只能由专用插件支持,但我没有找到类似的东西。最接近的是 https://github.com/nvbn/pytest-docker-pexpect,它可以让您编写显式的图像生成。将核心功能编写为 pytest 插件应该不难,但是在插件本身中集成图像设置和维护看起来非常棘手。 (2认同)