有没有办法用pytest来testing沙箱,特别是文件系统的访问?
我有兴趣使用pytest在像docker这样的沙箱中执行可能不受信任的testing,类似于持续集成服务所做的。
我知道,为了正确的沙箱化一个python进程,你需要操作系统级别的隔离,就像在一次性的chroot /容器中运行testing一样,但是在我的用例中,我不需要防止有意识的恶意代码,只能从配对的危险行为“随机”function与参数。 所以较不严格的沙盒仍然可以接受。 但我没有find任何插件,使任何forms的沙箱。
在pytest中,沙盒testing执行的最佳方式是什么?
更新 :这个问题不是关于python sandboxing的一般情况,因为testing的代码是由pytest运行的,我不能改变它被执行的方式来使用exec
或ast
或其他。 另外使用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
所有项目依赖关系 - 该项目安装在开发模式
- 一个专门的非root用户:
- 在一个将主机上的项目文件夹作为
pytest
用户主目录的容器中运行py.test
要实现该方法,请将以下Dockerfile
添加到您要在requirements.txt
和setup.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