Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: improve experience with dockerized tests and runtime execution #12

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.pyc
.cache/
.cache/
.idea/
db/
49 changes: 49 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
FROM python:3.8.16-alpine3.17 AS builder

# https://stackoverflow.com/questions/59554493/unable-to-fire-a-docker-build-for-django-and-mysql/59554601#59554601
RUN apk add musl-dev python3-dev mariadb-dev gcc build-base bash

WORKDIR /viasat/minitwit

COPY requirements.txt .

RUN pip install -r requirements.txt

ENV FLASK_APP=minitwit.py
ENV LC_ALL=en_US.utf-8
ENV LANG=en_US.utf-8

COPY ./static /viasat/minitwit/static
COPY ./templates /viasat/minitwit/templates

COPY *.py /viasat/minitwit
COPY *.sql /viasat/minitwit

####
#### tester image that installs the dev dependencies and executes the test cases during build
#### and during a container execution! The build will fail if any test case fails.
#### The test image is good for inspection of test environments and ca be used in CI/CD envs.
####
FROM builder AS tester

# Only copy the development tools from the requirements for tests
COPY requirements-dev.txt .
RUN pip install -r requirements-dev.txt

# All the requirements are installed and so the test cases can be executed
CMD ["pytest", "test_minitwit.py"]

###
### Runtime environment containing only the runtime dependencies.
### Note that this image does NOT have anything for testing!
###
FROM builder AS runtime

# All the other resources are there, so let's add the run-app as it's part of the runtime
# Note that the builder runtime defines the WORKDIR already so we can COPY to .
COPY run-app .
COPY init-db .

RUN rm -rf requirements* test_minitwit.py

ENTRYPOINT ["bash", "/viasat/minitwit/run-app"]
39 changes: 0 additions & 39 deletions README

This file was deleted.

265 changes: 265 additions & 0 deletions README.md

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: "3.8"

services:

####
#### Executes the test cases locally within a test image and prepares the container for execution.
####
#### docker compose build minitwit-test
####
minitwit-test:
image: viasat/minitwit-test
platform: linux/amd64
build:
context: .
target: tester

####
#### Runs the runtime server locally with the port mapping local:container
####
#### docker compose up --build minitwit-runtime
####
minitwit-runtime:
image: viasat/minitwit
platform: linux/amd64
build:
context: .
target: runtime
ports:
- 4000:5000
volumes:
- ./db:/var/minitwit
7 changes: 7 additions & 0 deletions init-db
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ export FLASK_APP=minitwit.py
export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8

DB_DIR=${DB_DIR:-/var/minitwit}

# Initialize the path where the db is
if [ ! -d ${DB_DIR} ]; then
mkdir -p ${DB_DIR}
fi

flask initdb
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest==5.3.2
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Flask>=2.2
pytest==5.3.2
SQLAlchemy >= 1.3.0, < 2.0
boto3>=1.26
mysqlclient>=2.1
Expand Down
7 changes: 7 additions & 0 deletions run-app
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ export FLASK_APP=minitwit.py
export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8

export DB_DIR=${DB_DIR:-/var/minitwit}

if [ ! -f ${DB_DIR}/minitwit.db ] || [ -n "${INIT_DB}" ]; then
echo "Initializing database at ${DB_DIR}/minitwit.db"
./init-db
fi

flask run --host=0.0.0.0 --with-threads --no-debugger --no-reload
9 changes: 8 additions & 1 deletion test_minitwit.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ def client(request):
minitwit.app.config['DATABASE'] = 'sqlite:///' + minitwit.app.config['DATABASE']
client = minitwit.app.test_client()
with minitwit.app.app_context():
minitwit.init_db()
# Required to not fail the tests at /var/minitwit/minitwit.db
# sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
db_dir = "/var/minitwit"
if not os.path.exists(db_dir):
os.makedirs(db_dir)

# Note that this is the same as the production db /var/minitwit/minitwit.db
minitwit.init_db()

def teardown():
"""Get rid of the database again after each test."""
Expand Down