当单元测试请求 docker 内置于 python 的容器时,连接中止
Connection aborted when unit test to request to docker container built in python
我的目标是编写一个构建 docker 容器并尝试对新建容器执行请求的单元测试。
测试首先构建一个docker镜像,然后运行镜像,最后尝试对新创建的容器执行请求。目前 运行 使用 py.test
的测试给了我
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
而 运行 ipython 中的相同代码工作得很好。
预期行为: py.test
给出了成功的结果。
测试
import pytest
import docker
import requests
@pytest.fixture(scope='module')
def docker_env():
return docker.from_env()
@pytest.fixture(scope='module')
def docker_image(docker_env):
client = docker_env
image = client.images.build(path = ".", tag = "python-test:latest")
yield image, client
client.images.remove("python-test:latest")
def test_port(docker_image):
image, client = docker_image
client.containers.run("python-test:latest",
entrypoint="/opt/conda/envs/python-docker-test/bin/gunicorn --config /usr/src/app/gunicorn.conf.py app:api",
detach=True,
ports={'8000/tcp': ('127.0.0.1', 8000)})
resp = requests.get("http://127.0.0.1:8000/hello")
assert resp.status == 200
# Expect success, currently getting an error
Docker 文件
我的 docker 文件如下所示,
FROM phusion/baseimage:0.9.22
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1 \
git mercurial subversion
RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.3.30-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh
ENV PATH /opt/conda/bin:$PATH
WORKDIR /usr/src/app
COPY . .
RUN conda env create -f environment.yml
EXPOSE 8000
SHELL ["/bin/bash", "-c"]
ENTRYPOINT source activate python-docker-test && /opt/conda/envs/python-docker-test/bin/gunicorn \
--config /usr/src/app/gunicorn.conf.py app:api
app.py
import falcon
class TestServer:
def on_get(self, req, resp):
resp.content_type = "text/text"
resp.body = "hello world"
resp.status = falcon.HTTP_OK
api = falcon.API()
api.add_route("/hello", TestServer())
environment.yml
name: python-docker-test
channels:
- anaconda
- conda-forge
dependencies:
- python==3.6
- gunicorn==19.7.1
- pytest==3.2.5
- gunicorn==19.7.1
- ipython
- falcon==1.3.0
- pip==9.0.1
- pip:
- docker==2.7.0
Gunicorn.conf.py
bind = '0.0.0.0:8000'
系统规格
- 服务器版本:17.12.0-ce
- uname: 17.3.0 达尔文内核版本 17.3.0
正确的测试看起来像,
def test_port(docker_image):
image, client = docker_image
import time
container = client.containers.run("python-test:latest",
detach=True,
ports={'8000/tcp': ('127.0.0.1', 8000)})
time.sleep(1)
resp = requests.get("http://127.0.0.1:8000/hello")
container.kill()
assert resp.status_code == 200
我的目标是编写一个构建 docker 容器并尝试对新建容器执行请求的单元测试。
测试首先构建一个docker镜像,然后运行镜像,最后尝试对新创建的容器执行请求。目前 运行 使用 py.test
的测试给了我
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
而 运行 ipython 中的相同代码工作得很好。
预期行为: py.test
给出了成功的结果。
测试
import pytest
import docker
import requests
@pytest.fixture(scope='module')
def docker_env():
return docker.from_env()
@pytest.fixture(scope='module')
def docker_image(docker_env):
client = docker_env
image = client.images.build(path = ".", tag = "python-test:latest")
yield image, client
client.images.remove("python-test:latest")
def test_port(docker_image):
image, client = docker_image
client.containers.run("python-test:latest",
entrypoint="/opt/conda/envs/python-docker-test/bin/gunicorn --config /usr/src/app/gunicorn.conf.py app:api",
detach=True,
ports={'8000/tcp': ('127.0.0.1', 8000)})
resp = requests.get("http://127.0.0.1:8000/hello")
assert resp.status == 200
# Expect success, currently getting an error
Docker 文件
我的 docker 文件如下所示,
FROM phusion/baseimage:0.9.22
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1 \
git mercurial subversion
RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.3.30-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh
ENV PATH /opt/conda/bin:$PATH
WORKDIR /usr/src/app
COPY . .
RUN conda env create -f environment.yml
EXPOSE 8000
SHELL ["/bin/bash", "-c"]
ENTRYPOINT source activate python-docker-test && /opt/conda/envs/python-docker-test/bin/gunicorn \
--config /usr/src/app/gunicorn.conf.py app:api
app.py
import falcon
class TestServer:
def on_get(self, req, resp):
resp.content_type = "text/text"
resp.body = "hello world"
resp.status = falcon.HTTP_OK
api = falcon.API()
api.add_route("/hello", TestServer())
environment.yml
name: python-docker-test
channels:
- anaconda
- conda-forge
dependencies:
- python==3.6
- gunicorn==19.7.1
- pytest==3.2.5
- gunicorn==19.7.1
- ipython
- falcon==1.3.0
- pip==9.0.1
- pip:
- docker==2.7.0
Gunicorn.conf.py
bind = '0.0.0.0:8000'
系统规格
- 服务器版本:17.12.0-ce
- uname: 17.3.0 达尔文内核版本 17.3.0
正确的测试看起来像,
def test_port(docker_image):
image, client = docker_image
import time
container = client.containers.run("python-test:latest",
detach=True,
ports={'8000/tcp': ('127.0.0.1', 8000)})
time.sleep(1)
resp = requests.get("http://127.0.0.1:8000/hello")
container.kill()
assert resp.status_code == 200