test(docker): Add compose setup for integration testing

ref: #947 #152 #774
This commit is contained in:
2025-08-12 13:01:58 +09:30
parent e1f8ba0c2b
commit ecc16e6cbf
8 changed files with 306 additions and 0 deletions

2
.gitignore vendored
View File

@ -24,3 +24,5 @@ log/
# Integration testing
app/artifacts/
app/pyproject.toml
app/histogram_**
app/counter_**

View File

@ -69,6 +69,70 @@ lint: markdown-mkdocs-lint
test:
pytest --cov-report xml:artifacts/coverage_unit_functional.xml --cov-report html:artifacts/coverage/unit_functional/ --junit-xml=artifacts/unit_functional.JUnit.xml app/**/tests/unit app/**/tests/functional
test-integration:
export exit_code=0;
cp pyproject.toml app/;
sed -i 's|^source = \[ "./app" \]|source = [ "." ]|' app/pyproject.toml;
cd test;
if docker-compose up -d; then
docker ps -a;
chmod +x setup-integration.sh;
if ./setup-integration.sh; then
cd ..;
ls -laR test/;
docker exec -i centurion-erp supervisorctl stop gunicorn;
docker exec -i centurion-erp sh -c 'rm -rf /app/artifacts/* /app/artifacts/.[!.]*';
docker exec -i centurion-erp supervisorctl start gunicorn;
sleep 30;
docker ps -a;
curl --trace-ascii - http://localhost:8003/api;
echo '--------------------------------------------------------------------';
curl --trace-ascii - http://127.0.0.1:8003/api;
if [ "0${GITHUB_SHA}"!="0" ]; then
sudo chmod 777 -R ./test
fi;
docker logs centurion-erp;
pytest --override-ini addopts= --no-migrations --tb=long --verbosity=2 --full-trace --showlocals --junit-xml=integration.JUnit.xml app/*/tests/integration;
docker exec -i centurion-erp supervisorctl restart gunicorn;
docker exec -i centurion-erp sh -c 'coverage combine; coverage report --skip-covered; coverage html -d artifacts/html/;';
docker logs centurion-erp-init > ./test/volumes/log/docker-log-centurion-erp-init.log;
docker logs centurion-erp> ./test/volumes/log/docker-log-centurion-erp.log;
docker logs postgres > ./test/volumes/log/docker-log-postgres.log;
docker logs rabbitmq > ./test/volumes/log/docker-log-rabbitmq.log;
cd test;
else
echo 'Error: could not setup containers for testing';
export exit_code=10;
fi;
else
echo 'Error: Failed to launch containers';
export exit_code=20;
fi;
cd test;
docker-compose down -v;
cd ..;
exit ${exit_code};
test-functional:
pytest --cov-report xml:artifacts/coverage_functional.xml --cov-report html:artifacts/coverage/functional/ --junit-xml=artifacts/functional.JUnit.xml app/**/tests/functional

89
test/docker-compose.yaml Normal file
View File

@ -0,0 +1,89 @@
---
x-app: &centurion
image: ${CENTURION_IMAGE:-ghcr.io/nofusscomputing/centurion-erp}:${CENTURION_IMAGE_TAG:-dev}
volumes:
- ./docker/settings.py:/etc/itsm/settings.py:ro
services:
postgres:
image: ${CENTURION_POSTGRES_IMAGE:-postgres}:${CENTURION_POSTGRES_IMAGE_TAG:-13.21}-alpine # 14.18-alpine, 15.13-alpine, 16.9-alpine, 17.5-alpine
container_name: postgres
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin
expose:
- 5432
volumes:
- ./docker/centurion.sql:/docker-entrypoint-initdb.d/centurion.sql:ro
rabbitmq:
image: ${CENTURION_RABBITMQ_IMAGE:-rabbitmq}:${CENTURION_RABBITMQ_IMAGE_TAG:-4.0.9}-management-alpine # 4.1.3-management-alpine
container_name: rabbitmq
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin
- RABBITMQ_DEFAULT_VHOST=itsm
expose:
- 5672
ports:
# - "5672:5672"
- "15672:15672"
centurion-init:
<<: *centurion
container_name: centurion-erp-init
restart: "no"
entrypoint: ""
command: sh -c 'sleep 15; python manage.py migrate'
depends_on:
- postgres
- rabbitmq
centurion:
<<: *centurion
container_name: centurion-erp
restart: always
hostname: centurion-erp
volumes:
- ./volumes/log:/var/log:rw
- ./docker/settings.py:/etc/itsm/settings.py:ro
- ./volumes/data:/data:rw
- ./volumes/artifacts:/app/artifacts:rw
ports:
- "8003:8000"
depends_on:
- postgres
- rabbitmq
worker:
<<: *centurion
container_name: centurion-worker
restart: always
environment:
- IS_WORKER=true
hostname: centurion-worker
depends_on:
- postgres
- rabbitmq
- centurion
centurion-ui:
image: ${CENTURION_UI_IMAGE:-ghcr.io/nofusscomputing/centurion-erp-ui}:${CENTURION_UI_IMAGE_TAG:-dev}
container_name: centurion-ui
restart: always
environment:
- API_URL=http://127.0.0.1:8003/api/v2
hostname: centurion-ui
ports:
- "3000:80"
depends_on:
- centurion

2
test/docker/centurion.sql Executable file
View File

@ -0,0 +1,2 @@
CREATE DATABASE itsm;
GRANT ALL PRIVILEGES ON DATABASE itsm TO admin;

79
test/docker/settings.py Executable file
View File

@ -0,0 +1,79 @@
# ITSM Docker Settings
# If metrics enabled, see https://nofusscomputing.com/projects/centurion_erp/administration/monitoring/#django-exporter-setup)
# to configure the database metrics.
API_TEST = True
AUTH_PASSWORD_VALIDATORS = []
CELERY_BROKER_URL = 'amqp://admin:admin@rabbitmq:5672/itsm' # 'amqp://' is the connection protocol
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = (
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
)
CORS_ALLOWED_ORIGINS = [
"http://127.0.0.1:3000",
"http://localhost:3000",
"http://127.0.0.1:8003",
"http://localhost:8003",
"http://127.0.0.1",
]
CORS_EXPOSE_HEADERS = ['Content-Type', 'X-CSRFToken']
CSRF_COOKIE_SECURE = False
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'itsm',
'USER': 'admin',
'PASSWORD': 'admin',
'HOST': 'postgres',
'PORT': '5432',
}
}
DEBUG = True
FEATURE_FLAGGING_ENABLED = True # Turn Feature Flagging on/off
FEATURE_FLAG_OVERRIDES = [] # Feature Flag Overrides. Takes preceedence over downloaded feature flags.
LOG_FILES = { # Location where log files will be created
"centurion": "/var/log/centurion.log",
"weblog": "/var/log/weblog.log",
"rest_api": "/var/log/rest_api.log",
"catch_all":"/var/log/catch-all.log"
}
METRICS_ENABLED = True
SECRET_KEY = 'django-insecure-b*41-$afq0yl)1e#qpz^-nbt-opvjwb#avv++b9rfdxa@b55sk'
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = False
SESSION_COOKIE_SECURE = False
SITE_URL = 'http://127.0.0.1:8003'
TRUSTED_ORIGINS = [
"http://127.0.0.1:3000",
"http://localhost:3000",
"http://127.0.0.1:8003",
"http://localhost:8003",
"http://127.0.0.1",
]
USE_X_FORWARDED_HOST = True

0
test/page_speed.js Normal file → Executable file
View File

0
test/parameterizedData.json Normal file → Executable file
View File

70
test/setup-integration.sh Executable file
View File

@ -0,0 +1,70 @@
#!/bin/sh
set -e
docker exec -i centurion-erp pip install -r /requirements_test.txt
docker exec -i centurion-erp supervisorctl restart gunicorn
CONTAINER_NAME="centurion-erp-init"
TIMEOUT=400
INTERVAL=5
ELAPSED=0
STATUS=""
while [ "$STATUS" != "exited" ] && [ "$STATUS" != "dead" ]; do
STATUS=$(docker inspect --format '{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null || echo "not_found")
if [ "$STATUS" = "not_found" ]; then
docker ps -a
echo "Container $CONTAINER_NAME was not found."
exit 2
fi
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "Timeout reached. Container $CONTAINER_NAME still running (status: $STATUS)."
exit 3
fi
echo "Waiting for container $CONTAINER_NAME to complete... Current status: $STATUS"
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
done
echo "Container $CONTAINER_NAME has completed."
CONTAINER_NAME="centurion-erp"
TIMEOUT=90
INTERVAL=5
ELAPSED=0
STATUS=""
while [ "$STATUS" != "healthy" ]; do
STATUS=$(docker inspect --format '{{.State.Health.Status}}' "$CONTAINER_NAME" 2>/dev/null || echo "none")
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "Timeout reached. Container $CONTAINER_NAME is not healthy."
exit 4
fi
echo "Waiting for container $CONTAINER_NAME to be healthy... Current status: $STATUS"
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
done
docker exec -i centurion-erp python manage.py createsuperuser --username admin --email admin@localhost --noinput
docker exec -i centurion-erp apk add expect
docker exec -i centurion-erp expect -c "
spawn python manage.py changepassword admin
expect \"Password:\"
send \"admin\r\"
expect \"Password (again):\"
send \"admin\r\"
expect eof
"