My goal is to write a unit test that builds a docker container and tries to execute a request to the newly built container.
The test first builds an docker image, then runs the image and finally tries to execute a request to the newly created container. Currently running the test using py.test
gives me
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
whereas running the same code in ipython works just fine.
Expected behavior: py.test
gives a successful result.
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
My docker file looks as follows,
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
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())
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
bind = '0.0.0.0:8000'
The right test looks like,
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