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 6, 2023
1 parent 7d232eb commit 2941f27
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 340 deletions.
Empty file.
19 changes: 16 additions & 3 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,10 +77,19 @@ 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
Expand All @@ -86,7 +99,7 @@ services:
oracle:
image: docker.io/gvenzl/oracle-xe:21-slim
profiles:
- alldb
- oracle
environment:
- ORACLE_PASSWORD=rucio
- ORACLE_ALLOW_REMOTE=true
Expand Down
2 changes: 1 addition & 1 deletion etc/docker/test/extra/alembic_mysql8.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 = mysql+pymysql://root:secret@mysql8/mysql
sqlalchemy.url = mysql+pymysql://rucio:rucio@mysql8:3308/rucio
version_table_schema = dev

# Logging configuration
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: 1 addition & 3 deletions etc/docker/test/extra/rucio_mysql8.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ account = root
request_retries = 3

[database]
default = mysql+pymysql://root:secret@mysql8/mysql
schema=dev
pool_recycle=3600
default = mysql+pymysql://rucio:rucio@mysql8:330/rucio
echo=0
pool_reset_on_return=rollback
pool_size = 20
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
143 changes: 80 additions & 63 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,69 @@ 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:
from tempfile import NamedTemporaryFile
with (NamedTemporaryFile() as compose_override_file):

project_name = os.urandom(8).hex()
compose_common_args = (
'-p', project_name,
'--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)
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,
},
)

# 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')
# Start docker compose
run('docker-compose', *compose_common_args, '--profile', rdbms, 'up', '-d')
# Running before_script.sh
run(
'./tools/test/before_script.sh',
env={
**os.environ,
**caseenv,
**namespace_env,
"CONTAINER_RUNTIME_ARGS": ' '.join(namespace_args),
"CON_RUCIO": f'{project_name}_rucio_1',
"CON_DB": f'{project_name}_{rdbms}_1',
},
)

# 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', f'{project_name}_rucio_1', './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, f'{project_name}_rucio_1', './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,12 +346,12 @@ def create_cnt(cnt_class: Callable) -> Container:
flush=True,
)
finally:
run('docker', *namespace_args, 'logs', rucio_container.cid, check=False)
run('docker', *namespace_args, 'logs', f'{project_name}_rucio_1', 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))
run('docker', *namespace_args, 'cp', f'{project_name}_rucio_1:/var/log', str(logs_dir))
except Exception:
print(
"** Error on retrieving logs for",
Expand All @@ -346,6 +362,7 @@ def create_cnt(cnt_class: Callable) -> Container:
file=sys.stderr,
flush=True,
)
run('docker-compose', *compose_common_args, 'down', check=False)
return False


Expand Down
Loading

0 comments on commit 2941f27

Please sign in to comment.