Skip to content

Commit

Permalink
Tests: use docker-compose in autotests
Browse files Browse the repository at this point in the history
Remove the home-made suites.py which was manually starting the same
docker containers, but with a slightly different configuration.
The difference in configuration was not justified in any way.
  • Loading branch information
Radu Carpa committed Oct 9, 2023
1 parent 7d232eb commit 97d5c4f
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 356 deletions.
Empty file.
2 changes: 1 addition & 1 deletion etc/docker/dev/docker-compose.ports.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ services:
activemq:
ports:
- "127.0.0.1:61613:61613"
ruciomy8:
mysql8:
ports:
- "127.0.0.1:3308:3308"
oracle:
Expand Down
24 changes: 20 additions & 4 deletions etc/docker/dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ services:
rucioclient:
image: docker.io/rucio/rucio-dev:latest-alma9
command: ["sleep", "infinity"]
profiles:
- client
volumes:
- ../../certs/rucio_ca.pem:/etc/grid-security/certificates/5fca1cb1.0:z
- ../../certs/hostcert_rucio.pem:/etc/grid-security/hostcert.pem:z
- ../../certs/hostcert_rucio.key.pem:/etc/grid-security/hostkey.pem:z
- ../../certs/rucio_ca.pem:/opt/rucio/etc/rucio_ca.pem:z
- ../../certs/ruciouser.pem:/opt/rucio/etc/usercert.pem:z
- ../../certs/ruciouser.key.pem:/opt/rucio/etc/userkey.pem:z
- ../../certs/ruciouser.certkey.pem:/opt/rucio/etc/usercertkey.pem:z
Expand All @@ -26,6 +29,7 @@ services:
- ../../certs/rucio_ca.pem:/etc/grid-security/certificates/5fca1cb1.0:z
- ../../certs/hostcert_rucio.pem:/etc/grid-security/hostcert.pem:z
- ../../certs/hostcert_rucio.key.pem:/etc/grid-security/hostkey.pem:z
- ../../certs/rucio_ca.pem:/opt/rucio/etc/rucio_ca.pem:z
- ../../certs/ruciouser.pem:/opt/rucio/etc/usercert.pem:z
- ../../certs/ruciouser.key.pem:/opt/rucio/etc/userkey.pem:z
- ../../certs/ruciouser.certkey.pem:/opt/rucio/etc/usercertkey.pem:z
Expand Down Expand Up @@ -73,20 +77,32 @@ services:
- ACTIVEMQ_CONFIG_SCHEDULERENABLED=true
- ACTIVEMQ_USERS_hermes=supersecret
- ACTIVEMQ_CONFIG_QUEUES_events=/queue/events'
ruciomy8:
postgres14:
image: docker.io/postgres:14
profiles:
- postgres14
environment:
- POSTGRES_USER=rucio
- POSTGRES_DB=rucio
- POSTGRES_PASSWORD=rucio
command: ["-c", "fsync=off","-c", "synchronous_commit=off","-c", "full_page_writes=off"]
mysql8:
image: docker.io/mysql:8
profiles:
- alldb
- mysql8
environment:
- MYSQL_USER=rucio
- MYSQL_PASSWORD=rucio
- MYSQL_ROOT_PASSWORD=rucio
- MYSQL_DATABASE=rucio
- MYSQL_TCP_PORT=3308
command:
- "--default-authentication-plugin=mysql_native_password"
- "--character-set-server=latin1"
oracle:
image: docker.io/gvenzl/oracle-xe:21-slim
image: docker.io/gvenzl/oracle-xe:18.4.0
profiles:
- alldb
- oracle
environment:
- ORACLE_PASSWORD=rucio
- ORACLE_ALLOW_REMOTE=true
Expand Down
4 changes: 2 additions & 2 deletions etc/docker/test/extra/alembic_mysql8.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ script_location = lib/rucio/db/sqla/migrate_repo/
# the 'revision' command, regardless of autogenerate
# revision_environment = false

sqlalchemy.url = mysql+pymysql://root:secret@mysql8/mysql
version_table_schema = dev
sqlalchemy.url = mysql+pymysql://rucio:rucio@mysql8:3308/rucio
version_table_schema = rucio

# Logging configuration
[loggers]
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/alembic_oracle.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ script_location = lib/rucio/db/sqla/migrate_repo/
# the 'revision' command, regardless of autogenerate
# revision_environment = false

sqlalchemy.url = oracle://system:oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))
sqlalchemy.url = oracle://system:rucio@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))
version_table_schema = SYSTEM

# Logging configuration
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/alembic_postgres14.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ script_location = lib/rucio/db/sqla/migrate_repo/
# the 'revision' command, regardless of autogenerate
# revision_environment = false

sqlalchemy.url = postgresql://postgres:secret@postgres14/postgres
sqlalchemy.url = postgresql://rucio:rucio@postgres14/rucio
version_table_schema = dev

# Logging configuration
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/rucio_multi_vo_ts2_postgres14.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ request_retries = 3
vo = testvo2

[database]
default = postgresql://postgres:secret@postgres14/postgres
default = postgresql://rucio:rucio@postgres14/rucio
schema = dev
pool_recycle=3600
echo=0
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/rucio_multi_vo_tst_postgres14.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ request_retries = 3
vo = testvo1

[database]
default = postgresql://postgres:secret@postgres14/postgres
default = postgresql://rucio:rucio@postgres14/rucio
schema = dev
pool_recycle=3600
echo=0
Expand Down
4 changes: 2 additions & 2 deletions etc/docker/test/extra/rucio_mysql8.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ account = root
request_retries = 3

[database]
default = mysql+pymysql://root:secret@mysql8/mysql
schema=dev
default = mysql+pymysql://rucio:rucio@mysql8:3308/rucio
schema=rucio
pool_recycle=3600
echo=0
pool_reset_on_return=rollback
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/rucio_oracle.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ account = root
request_retries = 3

[database]
default = oracle://system:oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))
default = oracle://system:rucio@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))
schema=system
pool_recycle=3600
echo=0
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/rucio_postgres14.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ account = root
request_retries = 3

[database]
default = postgresql://postgres:secret@postgres14/postgres
default = postgresql://rucio:rucio@postgres14/rucio
schema=dev
pool_recycle=3600
echo=0
Expand Down
2 changes: 1 addition & 1 deletion tools/test/before_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ elif [ $RDBMS == "mysql8" ]; then
date
for i in {1..30}; do
sleep 4
cont=$(bash -c 'ping=`docker '"$CONTAINER_RUNTIME_ARGS"' exec '"$CON_DB"' mysqladmin --user=root --password=secret ping`; echo $ping 1>&2; echo $ping | grep "mysqld is alive" 1>&2; echo $?')
cont=$(bash -c 'ping=`docker '"$CONTAINER_RUNTIME_ARGS"' exec '"$CON_DB"' mysqladmin --user=rucio --password=rucio ping`; echo $ping 1>&2; echo $ping | grep "mysqld is alive" 1>&2; echo $?')
[ "$cont" -eq "0" ] && break
done
date
Expand Down
177 changes: 100 additions & 77 deletions tools/test/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.

import json
import io
import itertools
import multiprocessing
import os
import pathlib
Expand All @@ -24,11 +26,32 @@
import time
import traceback
import uuid
from collections.abc import Callable
from datetime import datetime
from typing import Optional
from textwrap import dedent
from typing import Optional, Union, NoReturn

from suites import run, Container, rdbms_container, services, CumulativeContextManager, service_hostnames, env_args
import yaml


def run(*args, check=True, return_stdout=False, env=None) -> Union[NoReturn, io.TextIOBase]:
kwargs = {'check': check, 'stdout': sys.stderr, 'stderr': subprocess.STDOUT}
if env is not None:
kwargs['env'] = env
if return_stdout:
kwargs['stderr'] = sys.stderr
kwargs['stdout'] = subprocess.PIPE
args = [str(a) for a in args]
print("** Running", " ".join(map(lambda a: repr(a) if ' ' in a else a, args)), kwargs, file=sys.stderr, flush=True)
proc = subprocess.run(args, **kwargs)
if return_stdout:
return proc.stdout


def env_args(caseenv):
environment_args = list(itertools.chain(*map(lambda x: ('--env', f'{x[0]}={x[1]}'), caseenv.items())))
environment_args.append('--env')
environment_args.append('GITHUB_ACTIONS')
return environment_args


def matches(small: dict, group: dict):
Expand Down Expand Up @@ -177,8 +200,6 @@ def run_case(caseenv, image, use_podman, use_namespace, use_httpd, copy_rucio_lo
success = run_with_httpd(
caseenv=caseenv,
image=image,
use_podman=use_podman,
pod=pod,
namespace_args=namespace_args,
namespace_env=namespace_env,
copy_rucio_logs=copy_rucio_logs,
Expand Down Expand Up @@ -254,74 +275,74 @@ def run_test_directly(
def run_with_httpd(
caseenv: dict[str, str],
image: str,
use_podman: bool,
pod: str,
namespace_args: list[str],
namespace_env: dict[str, str],
copy_rucio_logs: bool,
logs_dir: pathlib.Path,
tests: list[str],
) -> bool:
pod_net_arg = ['--pod', pod] if use_podman else []
# Running rucio container from given image
with Container(image, runtime_args=namespace_args, run_args=pod_net_arg, environment=caseenv) as rucio_container:
try:
network_arg = ('--network', 'container:' + rucio_container.cid)
container_run_args = pod_net_arg if use_podman else network_arg
additional_containers = []

def create_cnt(cnt_class: Callable) -> Container:
return cnt_class(
runtime_args=namespace_args,
run_args=container_run_args,
)

db_container = None
rdbms = caseenv.get('RDBMS', '')
if rdbms:
service_key = caseenv.get('SERVICES', 'default')
db_container_class = rdbms_container.get(rdbms, None)
if db_container_class:
db_container = create_cnt(db_container_class)
additional_containers.append(db_container)
additional_containers += list(map(create_cnt, services[service_key]))

with CumulativeContextManager(*additional_containers):
db_env = dict()
if db_container:
db_env['CON_DB'] = db_container.cid

# Running before_script.sh
run(
'./tools/test/before_script.sh',
env={
**os.environ,
**caseenv,
**namespace_env,
**db_env,
"CONTAINER_RUNTIME_ARGS": ' '.join(namespace_args),
"CON_RUCIO": rucio_container.cid,
},
)
from tempfile import NamedTemporaryFile
with (NamedTemporaryFile() as compose_override_file):

# register service hostnames
run('docker', *namespace_args, 'exec', rucio_container.cid, '/bin/sh', '-c', f'echo "127.0.0.1 {" ".join(service_hostnames)}" | tee -a /etc/hosts')
compose_common_args = (
'-p', os.urandom(8).hex(),
'--file', 'etc/docker/dev/docker-compose.yml',
'--file', compose_override_file.name,
)
compose_override_content = yaml.dump({
'services': {
'rucio': {
'image': image,
'volumes': ['../../../:/usr/local/src/rucio/:Z'],
'environment': [f'{k}={v}' for k, v in caseenv.items()],
},
'ruciodb': {
'profiles': ['donotstart'],
}
}
})
with open(compose_override_file.name, 'w') as f:
f.write(dedent(compose_override_content))
rdbms = caseenv.get('RDBMS', '')
print("Overriding docker-compose configuration with: \n", compose_override_content)
containers = {}
try:
# Start docker compose
run('docker-compose', *compose_common_args, '--profile', rdbms, 'up', '-d')

# Retrieve container names from docker compose
_containers = run('docker-compose', *compose_common_args, 'ps', '--format', 'json', return_stdout=True)
containers = {c['Service']: c['Name'] for c in json.loads(_containers)}

# Running before_script.sh
run(
'./tools/test/before_script.sh',
env={
**os.environ,
**caseenv,
**namespace_env,
"CONTAINER_RUNTIME_ARGS": ' '.join(namespace_args),
"CON_RUCIO": containers['rucio'],
"CON_DB": containers[rdbms],
},
)

# Running install_script.sh
run('docker', *namespace_args, 'exec', rucio_container.cid, './tools/test/install_script.sh')
# Running install_script.sh
run('docker', *namespace_args, 'exec', containers['rucio'], './tools/test/install_script.sh')

# Running test.sh
if tests:
tests_env = ('--env', 'TESTS=' + ' '.join(tests))
tests_arg = ('-p', )
else:
tests_env = ()
tests_arg = ()
# Running test.sh
if tests:
tests_env = ('--env', 'TESTS=' + ' '.join(tests))
tests_arg = ('-p', )
else:
tests_env = ()
tests_arg = ()

run('docker', *namespace_args, 'exec', *tests_env, rucio_container.cid, './tools/test/test.sh', *tests_arg)
run('docker', *namespace_args, 'exec', *tests_env, containers['rucio'], './tools/test/test.sh', *tests_arg)

# if everything went through without an exception, mark this case as a success
return True
# if everything went through without an exception, mark this case as a success
return True
except subprocess.CalledProcessError as error:
print(
f"** Process '{error.cmd}' exited with code {error.returncode}",
Expand All @@ -330,22 +351,24 @@ def create_cnt(cnt_class: Callable) -> Container:
flush=True,
)
finally:
run('docker', *namespace_args, 'logs', rucio_container.cid, check=False)
if copy_rucio_logs:
try:
if logs_dir.exists():
shutil.rmtree(logs_dir)
run('docker', *namespace_args, 'cp', f'{rucio_container.cid}:/var/log', str(logs_dir))
except Exception:
print(
"** Error on retrieving logs for",
{**caseenv, "IMAGE": image},
'\n',
traceback.format_exc(),
'\n**',
file=sys.stderr,
flush=True,
)
if 'rucio' in containers:
run('docker', *namespace_args, 'logs', containers['rucio'], check=False)
if copy_rucio_logs:
try:
if logs_dir.exists():
shutil.rmtree(logs_dir)
run('docker', *namespace_args, 'cp', f'{containers["rucio"]}:/var/log', str(logs_dir))
except Exception:
print(
"** Error on retrieving logs for",
{**caseenv, "IMAGE": image},
'\n',
traceback.format_exc(),
'\n**',
file=sys.stderr,
flush=True,
)
run('docker-compose', *compose_common_args, 'down', check=False)
return False


Expand Down
Loading

0 comments on commit 97d5c4f

Please sign in to comment.