test(docker): Add compose setup for integration testing
ref: #947 #152 #774
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,3 +24,5 @@ log/
|
|||||||
# Integration testing
|
# Integration testing
|
||||||
app/artifacts/
|
app/artifacts/
|
||||||
app/pyproject.toml
|
app/pyproject.toml
|
||||||
|
app/histogram_**
|
||||||
|
app/counter_**
|
||||||
|
64
makefile
64
makefile
@ -69,6 +69,70 @@ lint: markdown-mkdocs-lint
|
|||||||
test:
|
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
|
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:
|
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
|
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
89
test/docker-compose.yaml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
x-app: ¢urion
|
||||||
|
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
2
test/docker/centurion.sql
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
CREATE DATABASE itsm;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE itsm TO admin;
|
79
test/docker/settings.py
Executable file
79
test/docker/settings.py
Executable 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
0
test/page_speed.js
Normal file → Executable file
0
test/parameterizedData.json
Normal file → Executable file
0
test/parameterizedData.json
Normal file → Executable file
70
test/setup-integration.sh
Executable file
70
test/setup-integration.sh
Executable 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
|
||||||
|
"
|
Reference in New Issue
Block a user