Skip to content

Commit

Permalink
♻️ Refactor tests to use env vars, Travis matrix, and push dated tags (
Browse files Browse the repository at this point in the history
  • Loading branch information
tiangolo authored Oct 15, 2019
1 parent af3a15c commit 70cf48f
Show file tree
Hide file tree
Showing 18 changed files with 214 additions and 392 deletions.
23 changes: 18 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,24 @@ install:
services:
- docker

env:
- NAME='latest' BUILD_PATH='python3.7' TEST_STR1='Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 3.7'
- NAME='python3.7' BUILD_PATH='python3.7' TEST_STR1='Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 3.7'
- NAME='python3.6' BUILD_PATH='python3.6' TEST_STR1='Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 3.6'
- NAME='python2.7' BUILD_PATH='python2.7' TEST_STR1='Hello World from a default Python 2.7 app in a Docker container, with Meinheld and Gunicorn (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 2.7'
- NAME='python3.7-alpine3.8' BUILD_PATH='python3.7-alpine3.8' TEST_STR1='Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 3.7'
- NAME='python3.6-alpine3.8' BUILD_PATH='python3.6-alpine3.8' TEST_STR1='Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)' TEST_STR2='Test app. From Meinheld with Gunicorn. Using Python 3.6'

script:
- bash scripts/test.sh

deploy:
provider: script
script: bash scripts/build-push.sh
on:
branch: master
jobs:
include:
- script: bash scripts/test.sh
- stage: deploy
script: skip
deploy:
provider: script
script: bash scripts/build-push-all.sh
on:
branch: master
20 changes: 0 additions & 20 deletions docker-compose.build.yml

This file was deleted.

7 changes: 7 additions & 0 deletions scripts/build-push-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -e

echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

BUILD_PUSH=1 python scripts/process_all.py
10 changes: 7 additions & 3 deletions scripts/build-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

set -e

echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
use_tag="tiangolo/meinheld-gunicorn:$NAME"
use_dated_tag="${use_tag}-$(date -I)"

docker-compose -f docker-compose.build.yml build
docker build -t "$use_tag" "$BUILD_PATH"

docker-compose -f docker-compose.build.yml push
docker tag "$use_tag" "$use_dated_tag"

docker push "$use_tag"
docker push "$use_dated_tag"
84 changes: 84 additions & 0 deletions scripts/process_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import os
import subprocess
import sys

environments = [
{
"NAME": "latest",
"BUILD_PATH": "python3.7",
"TEST_STR1": "Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 3.7",
},
{
"NAME": "python3.7",
"BUILD_PATH": "python3.7",
"TEST_STR1": "Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 3.7",
},
{
"NAME": "python3.6",
"BUILD_PATH": "python3.6",
"TEST_STR1": "Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 3.6",
},
{
"NAME": "python2.7",
"BUILD_PATH": "python2.7",
"TEST_STR1": "Hello World from a default Python 2.7 app in a Docker container, with Meinheld and Gunicorn (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 2.7",
},
{
"NAME": "python3.7-alpine3.8",
"BUILD_PATH": "python3.7-alpine3.8",
"TEST_STR1": "Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 3.7",
},
{
"NAME": "python3.6-alpine3.8",
"BUILD_PATH": "python3.6-alpine3.8",
"TEST_STR1": "Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
"TEST_STR2": "Test app. From Meinheld with Gunicorn. Using Python 3.6",
},
]

start_with = os.environ.get("START_WITH")
build_push = os.environ.get("BUILD_PUSH")


def process_tag(*, env: dict):
use_env = {**os.environ, **env}
script = "scripts/test.sh"
if build_push:
script = "scripts/build-push.sh"
return_code = subprocess.call(["bash", script], env=use_env)
if return_code != 0:
sys.exit(return_code)


def print_version_envs():
env_lines = []
for env in environments:
env_vars = []
for key, value in env.items():
env_vars.append(f"{key}='{value}'")
env_lines.append(" ".join(env_vars))
for line in env_lines:
print(line)


def main():
start_at = 0
if start_with:
start_at = [
i for i, env in enumerate((environments)) if env["NAME"] == start_with
][0]
for i, env in enumerate(environments[start_at:]):
print(f"Processing tag: {env['NAME']}")
process_tag(env=env)


if __name__ == "__main__":
if len(sys.argv) > 1:
print_version_envs()
else:
main()
4 changes: 4 additions & 0 deletions scripts/test-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -e

python scripts/process_all.py
4 changes: 3 additions & 1 deletion scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
set -e

docker-compose -f docker-compose.build.yml build
use_tag="tiangolo/meinheld-gunicorn:$NAME"

docker build -t "$use_tag" "$BUILD_PATH"
pytest tests
40 changes: 8 additions & 32 deletions tests/test_01_main/test_defaults.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import time

import docker
Expand Down Expand Up @@ -27,46 +28,21 @@ def verify_container(container, response_text):
assert response.text == response_text


@pytest.mark.parametrize(
"image,response_text",
[
(
"tiangolo/meinheld-gunicorn:python2.7",
"Hello World from a default Python 2.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6-alpine3.8",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7-alpine3.8",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:latest",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
],
)
def test_defaults(image, response_text):
def test_defaults():
name = os.getenv("NAME")
image = f"tiangolo/meinheld-gunicorn:{name}"
response_text = os.getenv("TEST_STR1")
sleep_time = int(os.getenv("SLEEP_TIME", 1))
remove_previous_container(client)
container = client.containers.run(
image, name=CONTAINER_NAME, ports={"80": "8000"}, detach=True
)
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
# Test that everything works after restarting too
container.start()
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
container.remove()
40 changes: 8 additions & 32 deletions tests/test_01_main/test_env_vars_1.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import time

import docker
Expand Down Expand Up @@ -26,36 +27,11 @@ def verify_container(container, response_text):
assert response.text == response_text


@pytest.mark.parametrize(
"image,response_text",
[
(
"tiangolo/meinheld-gunicorn:python2.7",
"Hello World from a default Python 2.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6-alpine3.8",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7-alpine3.8",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:latest",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
],
)
def test_env_vars_1(image, response_text):
def test_env_vars_1():
name = os.getenv("NAME")
image = f"tiangolo/meinheld-gunicorn:{name}"
response_text = os.getenv("TEST_STR1")
sleep_time = int(os.getenv("SLEEP_TIME", 1))
remove_previous_container(client)
container = client.containers.run(
image,
Expand All @@ -64,12 +40,12 @@ def test_env_vars_1(image, response_text):
ports={"8000": "8000"},
detach=True,
)
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
# Test that everything works after restarting too
container.start()
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
container.remove()
21 changes: 7 additions & 14 deletions tests/test_01_main/test_env_vars_2.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import time

import docker
Expand Down Expand Up @@ -31,18 +32,10 @@ def verify_container(container):
)


@pytest.mark.parametrize(
"image",
[
("tiangolo/meinheld-gunicorn:python2.7"),
("tiangolo/meinheld-gunicorn:python3.6"),
("tiangolo/meinheld-gunicorn:python3.7"),
("tiangolo/meinheld-gunicorn:latest"),
("tiangolo/meinheld-gunicorn:python3.6-alpine3.8"),
("tiangolo/meinheld-gunicorn:python3.7-alpine3.8"),
],
)
def test_env_vars_2(image):
def test_env_vars_2():
name = os.getenv("NAME")
image = f"tiangolo/meinheld-gunicorn:{name}"
sleep_time = int(os.getenv("SLEEP_TIME", 1))
remove_previous_container(client)
container = client.containers.run(
image,
Expand All @@ -51,12 +44,12 @@ def test_env_vars_2(image):
ports={"80": "8000"},
detach=True,
)
time.sleep(1)
time.sleep(sleep_time)
verify_container(container)
container.stop()
# Test that everything works after restarting too
container.start()
time.sleep(1)
time.sleep(sleep_time)
verify_container(container)
container.stop()
container.remove()
40 changes: 8 additions & 32 deletions tests/test_01_main/test_env_vars_3.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import time

import docker
Expand All @@ -24,36 +25,11 @@ def verify_container(container, response_text):
assert response.text == response_text


@pytest.mark.parametrize(
"image,response_text",
[
(
"tiangolo/meinheld-gunicorn:python2.7",
"Hello World from a default Python 2.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.6-alpine3.8",
"Hello World from a default Python 3.6 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
(
"tiangolo/meinheld-gunicorn:python3.7-alpine3.8",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn on Alpine (default)",
),
(
"tiangolo/meinheld-gunicorn:latest",
"Hello World from a default Python 3.7 app in a Docker container, with Meinheld and Gunicorn (default)",
),
],
)
def test_env_bind(image, response_text):
def test_env_bind():
name = os.getenv("NAME")
image = f"tiangolo/meinheld-gunicorn:{name}"
response_text = os.getenv("TEST_STR1")
sleep_time = int(os.getenv("SLEEP_TIME", 1))
remove_previous_container(client)
container = client.containers.run(
image,
Expand All @@ -62,12 +38,12 @@ def test_env_bind(image, response_text):
ports={"8080": "8000"},
detach=True,
)
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
# Test that everything works after restarting too
container.start()
time.sleep(1)
time.sleep(sleep_time)
verify_container(container, response_text)
container.stop()
container.remove()
Loading

0 comments on commit 70cf48f

Please sign in to comment.