有没有办法用pytest来testing沙箱,特别是文件系统的访问?

我有兴趣使用pytest在像docker这样的沙箱中执行可能不受信任的testing,类似于持续集成服务所做的。

我知道,为了正确的沙箱化一个python进程,你需要操作系统级别的隔离,就像在一次性的chroot /容器中运行testing一样,但是在我的用例中,我不需要防止有意识的恶意代码,只能从配对的危险行为“随机”function与参数。 所以较不严格的沙盒仍然可以接受。 但我没有find任何插件,使任何forms的沙箱​​。

在pytest中,沙盒testing执行的最佳方式是什么?

更新 :这个问题不是关于python sandboxing的一般情况,因为testing的代码是由pytest运行的,我不能改变它被执行的方式来使用execast或其他。 另外使用pypy-sandbox不是一个不幸的select,因为它是PyPy特性页面的 “仅限原型”。

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

 py.test --tx ssh=OTHERUSER@localhost --dist=each 

这让我意识到 ,对于我的CI类用例:

拥有一个“一次性”环境与隔离环境同样重要,因此每个testing或每个会话都从相同的初始状态运行,并且不受可能由testuser (/ home / testuser,/ tmp,/ var / tmp等)。

因此,testuser + xdist接近解决scheme,但不是那里。

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

经过相当多的研究,我没有find任何现成的pytest运行OS级别隔离和一次性环境的项目testing的方法。 许多方法都是可能的,有优点和缺点,但其中大多数有更多我感到舒适的移动部件。

我所devise的绝对最小化(但是有见地的)方法如下:

  • build立一个Python泊坞窗图像:
    • 一个专门的非root用户: pytest
    • 来自requirements.txt所有项目依赖关系
    • 该项目安装在开发模式
  • 在一个将主机上的项目文件夹作为pytest用户主目录的容器中运行py.test

要实现该方法,请将以下Dockerfile添加到您要在requirements.txtsetup.py文件旁边testing的项目的顶层文件夹中:

 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"] 

用以下方法构build图像一次:

 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。

现在,您应该能够使用操作系统级别的隔离来开发和testing您的项目。

更新:如果您也在主机上运行testing,则可能需要删除容器内不可写入的python和pytestcaching。 在主机上运行:

 rm -rf .cache/ && find . -name __pycache__ | xargs rm -rf 

说实话,这对Docker等东西来说似乎是一个很好的用例。 当然,你没有完全使用Python来完全处理它,但是你可以滥用主机操作系统来满足你的心愿,而不必担心长期的损害。 另外,与许多CI解决scheme不同,它可以在您的开发机器上舒适地运行。

还要注意,不pipe你的代码是否是有意的恶意代码,这种隔离措施对于防止这样的事故仍然是有益的,例如:

 rm -rf /usr/local/share/ myapp