Skip to content

Commit 9bb781f

Browse files
committed
feat(lftest): add run_mariadb() helper and MARIADB_LTS_IMAGES constant
Shared context manager that hides the boilerplate the Linuxfabrik mysql-* check plugins need for container-based integration tests: start a sclorg-shaped or upstream MariaDB container, wait for the TCP listener, yield a temporary [client] .my.cnf pointing at the exposed host port, and clean up on exit. Knows about both image families (sclorg needs `run-mysqld --port=3306` to bring up the TCP listener, upstream uses the default entrypoint) and auto-detects the `mariadb` vs `mysql` client binary for the optional seed step. Ships alongside the helper a single MARIADB_LTS_IMAGES list of the current supported MariaDB LTS releases (10.6, 10.11, 11.4, 11.8) spanning the Red Hat family via sclorg and Debian-based via the upstream image, so the 16 mysql-* container tests in monitoring- plugins iterate over a single canonical matrix and adding or retiring a release is a single-line change.
1 parent 5930f2d commit 9bb781f

1 file changed

Lines changed: 138 additions & 1 deletion

File tree

lftest.py

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,33 @@
1313
import contextlib
1414
import os
1515
import re
16+
import tempfile
1617

1718
from . import base, disk, shell
1819

1920
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
20-
__version__ = '2026041303'
21+
__version__ = '2026041305'
22+
23+
24+
# Shared IMAGES matrix for mysql-* container tests. Covers the
25+
# currently supported MariaDB LTS releases across the Red Hat family
26+
# (sclorg quay.io images) and the upstream Debian-based image:
27+
#
28+
# - 10.6: oldest still-supported LTS (EOL 2026-07), upstream only
29+
# - 10.11: current workhorse LTS (EOL 2028-02), sclorg c10s
30+
# - 11.4: newer LTS (EOL 2029-05), upstream only - sclorg does not
31+
# publish a 11.4 image
32+
# - 11.8: newest LTS (EOL 2030-06), sclorg c10s
33+
#
34+
# All 16 mysql-* container tests in the repo iterate over this list
35+
# so adding a new LTS release (or retiring one that reaches EOL) is
36+
# a single-line change across the whole test suite.
37+
MARIADB_LTS_IMAGES = [
38+
('docker.io/library/mariadb:10.6', 'MariaDB 10.6'),
39+
('quay.io/sclorg/mariadb-1011-c10s', 'MariaDB 10.11 sclorg'),
40+
('docker.io/library/mariadb:11.4', 'MariaDB 11.4'),
41+
('quay.io/sclorg/mariadb-118-c10s', 'MariaDB 11.8 sclorg'),
42+
]
2143

2244

2345
def run(test_instance, plugin, testcase):
@@ -319,6 +341,121 @@ def run_container(
319341
c.stop()
320342

321343

344+
@contextlib.contextmanager
345+
def run_mariadb(image, *, extra_args=None, seed=None):
346+
"""Start a MariaDB container and yield (container, defaults_file).
347+
348+
Thin convenience wrapper around :func:`run_container` for the
349+
Linuxfabrik mysql-* check plugins. Hides the image-family
350+
boilerplate (env vars, TCP port exposure, start command, log
351+
marker to wait on) and writes a temporary `[client]` `.cnf` file
352+
pointing at the exposed host port so the caller can run a plugin
353+
with `--defaults-file=...` without manual tempfile management.
354+
355+
Supports two image families:
356+
357+
- **Red Hat family via sclorg** (`quay.io/sclorg/mariadb-*`).
358+
The sclorg entrypoint disables the TCP listener by default and
359+
binds only the unix socket, so the helper forces
360+
`run-mysqld --port=3306`.
361+
- **Upstream** (`docker.io/library/mariadb:*`). Uses the default
362+
`docker-entrypoint.sh` which already enables TCP on 3306; the
363+
helper only overrides the command when `extra_args` are given,
364+
in which case it appends them to `mariadbd`.
365+
366+
The `MYSQL_*` env var names work for both families (the upstream
367+
image accepts them as aliases for `MARIADB_*`). The log marker
368+
`port: 3306` appears in both startup banners once the TCP listener
369+
is bound, so the same wait works for both.
370+
371+
### Parameters
372+
- **image** (`str`): MariaDB image reference, e.g.
373+
`'quay.io/sclorg/mariadb-1011-c10s'` or
374+
`'docker.io/library/mariadb:11.8'`.
375+
- **extra_args** (`str`, optional): Extra `mariadbd` flags appended
376+
to the startup command, e.g.
377+
`'--innodb-buffer-pool-size=33554432'` to pin the buffer pool to
378+
a deterministic size.
379+
- **seed** (`str`, optional): SQL statement executed once via
380+
`container.exec` right after the container is ready. Used to
381+
seed happy-path state (e.g. creating an empty InnoDB table so
382+
storage-engine checks see the engine "in use"). The helper
383+
auto-detects whether the image ships the `mariadb` client (11.x
384+
upstream dropped the `mysql` alias) or only `mysql` (older
385+
sclorg images) and picks whichever is available.
386+
387+
### Yields
388+
- **tuple** (`DockerContainer`, `str`):
389+
- The running container (so callers can still reach
390+
`container.exec()`, `get_container_host_ip()` etc.).
391+
- Absolute path to a temporary `[client]` `.cnf` file that is
392+
deleted when the context manager exits.
393+
394+
### Example
395+
>>> with lib.lftest.run_mariadb(
396+
... 'docker.io/library/mariadb:11.8',
397+
... extra_args='--innodb-buffer-pool-size=33554432',
398+
... ) as (container, defaults_file):
399+
... result = subprocess.run(
400+
... ['python3', '../mysql-traffic', f'--defaults-file={defaults_file}'],
401+
... capture_output=True, text=True,
402+
... )
403+
"""
404+
is_sclorg = 'sclorg/' in image
405+
406+
if is_sclorg:
407+
cmd = 'run-mysqld --port=3306'
408+
if extra_args:
409+
cmd = f'{cmd} {extra_args}'
410+
else:
411+
cmd = f'mariadbd {extra_args}' if extra_args else None
412+
413+
with run_container(
414+
image,
415+
env={
416+
'MYSQL_ROOT_PASSWORD': 'test',
417+
'MYSQL_USER': 'test',
418+
'MYSQL_PASSWORD': 'test',
419+
'MYSQL_DATABASE': 'test',
420+
},
421+
ports=[3306],
422+
command=cmd,
423+
wait_log='port: 3306',
424+
wait_log_timeout=180,
425+
) as container:
426+
if seed:
427+
# 11.x upstream dropped the `mysql` client symlink in favor
428+
# of `mariadb`; sclorg c10s ships both. Prefer `mariadb`,
429+
# fall back to `mysql` so both families work.
430+
container.exec([
431+
'sh', '-c',
432+
'if command -v mariadb >/dev/null 2>&1; then CLIENT=mariadb; '
433+
'else CLIENT=mysql; fi; '
434+
f'"$CLIENT" -utest -ptest test -e "{seed}"',
435+
])
436+
437+
host = container.get_container_host_ip()
438+
port = container.get_exposed_port(3306)
439+
440+
fd, defaults_file = tempfile.mkstemp(suffix='.cnf')
441+
try:
442+
with os.fdopen(fd, 'w') as f:
443+
f.write(
444+
f'[client]\n'
445+
f'host={host}\n'
446+
f'port={port}\n'
447+
f'user=test\n'
448+
f'password=test\n'
449+
f'database=test\n'
450+
)
451+
yield container, defaults_file
452+
finally:
453+
try:
454+
os.unlink(defaults_file)
455+
except OSError:
456+
pass
457+
458+
322459
def test(args):
323460
"""
324461
Returns the content of two files and the provided return code. The first file represents STDOUT,

0 commit comments

Comments
 (0)