2026-03-11 22:50:02 -04:00
|
|
|
#!/usr/bin/env python3
|
2026-03-11 23:15:07 -04:00
|
|
|
# © 2026 TechnoLibre (http://www.technolibre.ca)
|
2026-03-11 22:50:02 -04:00
|
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import tempfile
|
|
|
|
|
import unittest
|
|
|
|
|
from types import SimpleNamespace
|
|
|
|
|
|
2026-09-03 23:42:34 -04:00
|
|
|
from script.docker.docker_update_version import edit_docker_prod, edit_text
|
2026-03-11 22:50:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestEditText(unittest.TestCase):
|
|
|
|
|
"""Test docker-compose.yml image version update."""
|
|
|
|
|
|
|
|
|
|
def _write_compose(self, content):
|
2026-09-03 23:42:34 -04:00
|
|
|
f = tempfile.NamedTemporaryFile(mode="w", suffix=".yml", delete=False)
|
2026-03-11 22:50:02 -04:00
|
|
|
f.write(content)
|
|
|
|
|
f.close()
|
|
|
|
|
return f.name
|
|
|
|
|
|
|
|
|
|
def test_updates_image_after_erplibre(self):
|
|
|
|
|
path = self._write_compose(
|
2026-09-03 23:42:34 -04:00
|
|
|
"services:\n" " ERPLibre:\n" " image: old:1.0\n" " ports:\n"
|
2026-03-11 22:50:02 -04:00
|
|
|
)
|
|
|
|
|
config = SimpleNamespace(
|
|
|
|
|
docker_compose_file=path,
|
|
|
|
|
prod_version="myrepo:2.0",
|
|
|
|
|
)
|
|
|
|
|
edit_text(config)
|
|
|
|
|
with open(path) as f:
|
|
|
|
|
content = f.read()
|
|
|
|
|
self.assertIn("image: myrepo:2.0", content)
|
|
|
|
|
self.assertNotIn("old:1.0", content)
|
|
|
|
|
os.unlink(path)
|
|
|
|
|
|
|
|
|
|
def test_preserves_other_lines(self):
|
|
|
|
|
path = self._write_compose(
|
|
|
|
|
"version: '3'\n"
|
|
|
|
|
"services:\n"
|
|
|
|
|
" ERPLibre:\n"
|
|
|
|
|
" image: old:1.0\n"
|
|
|
|
|
" postgres:\n"
|
|
|
|
|
" image: postgres:14\n"
|
|
|
|
|
)
|
|
|
|
|
config = SimpleNamespace(
|
|
|
|
|
docker_compose_file=path,
|
|
|
|
|
prod_version="new:3.0",
|
|
|
|
|
)
|
|
|
|
|
edit_text(config)
|
|
|
|
|
with open(path) as f:
|
|
|
|
|
content = f.read()
|
|
|
|
|
self.assertIn("version: '3'", content)
|
|
|
|
|
self.assertIn("postgres:14", content)
|
|
|
|
|
os.unlink(path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestEditDockerProd(unittest.TestCase):
|
|
|
|
|
"""Test Dockerfile.prod FROM line update."""
|
|
|
|
|
|
|
|
|
|
def _write_dockerfile(self, content):
|
2026-09-03 23:42:34 -04:00
|
|
|
f = tempfile.NamedTemporaryFile(mode="w", suffix=".pkg", delete=False)
|
2026-03-11 22:50:02 -04:00
|
|
|
f.write(content)
|
|
|
|
|
f.close()
|
|
|
|
|
return f.name
|
|
|
|
|
|
|
|
|
|
def test_updates_from_line(self):
|
2026-09-03 23:42:34 -04:00
|
|
|
path = self._write_dockerfile("FROM base:old\nRUN apt-get update\n")
|
2026-03-11 22:50:02 -04:00
|
|
|
config = SimpleNamespace(
|
|
|
|
|
docker_compose_file="unused",
|
|
|
|
|
docker_prod=path,
|
|
|
|
|
base_version="base:new",
|
|
|
|
|
)
|
|
|
|
|
edit_docker_prod(config)
|
|
|
|
|
with open(path) as f:
|
|
|
|
|
content = f.read()
|
|
|
|
|
self.assertIn("FROM base:new", content)
|
|
|
|
|
self.assertNotIn("FROM base:old", content)
|
|
|
|
|
os.unlink(path)
|
|
|
|
|
|
|
|
|
|
def test_preserves_run_lines(self):
|
|
|
|
|
path = self._write_dockerfile(
|
|
|
|
|
"FROM base:old\nRUN echo hello\nCOPY . /app\n"
|
|
|
|
|
)
|
|
|
|
|
config = SimpleNamespace(
|
|
|
|
|
docker_compose_file="unused",
|
|
|
|
|
docker_prod=path,
|
|
|
|
|
base_version="base:v2",
|
|
|
|
|
)
|
|
|
|
|
edit_docker_prod(config)
|
|
|
|
|
with open(path) as f:
|
|
|
|
|
content = f.read()
|
|
|
|
|
self.assertIn("RUN echo hello", content)
|
|
|
|
|
self.assertIn("COPY . /app", content)
|
|
|
|
|
os.unlink(path)
|
|
|
|
|
|
|
|
|
|
def test_multiple_from_lines(self):
|
|
|
|
|
path = self._write_dockerfile(
|
|
|
|
|
"FROM base:old\nRUN build\nFROM base:old\nRUN run\n"
|
|
|
|
|
)
|
|
|
|
|
config = SimpleNamespace(
|
|
|
|
|
docker_compose_file="unused",
|
|
|
|
|
docker_prod=path,
|
|
|
|
|
base_version="base:v3",
|
|
|
|
|
)
|
|
|
|
|
edit_docker_prod(config)
|
|
|
|
|
with open(path) as f:
|
|
|
|
|
lines = f.readlines()
|
|
|
|
|
from_lines = [l for l in lines if l.startswith("FROM")]
|
|
|
|
|
for line in from_lines:
|
|
|
|
|
self.assertIn("base:v3", line)
|
|
|
|
|
os.unlink(path)
|
[FIX] tests : balayer test/test_*.py et refuser un fichier muet
Le lanceur ne prenait que sept préfixes de noms, « le reste demandant une
base de données » : les 3703 tests du répertoire passent avec PostgreSQL
injoignable, et la suite n'en exécutait que 1131. Il balaie test/test_*.py.
Deux formes rendent un fichier muet sans erreur : unittest.main() posé en
plein milieu, qui sort avant que la seconde moitié soit définie (quatre
fichiers, 87 tests), et l'absence de bloc __main__, qui compte zéro (huit
fichiers, 174 tests). Une garde refuse ces deux formes et le retour d'une
liste de préfixes.
--- EN ---
The runner took seven filename prefixes only, "the rest needing a
database": all 3703 tests in the directory pass with PostgreSQL
unreachable, and the suite ran 1131 of them. It now globs test/test_*.py.
Two shapes make a file silent without error: unittest.main() placed
mid-file, which exits before the second half is defined (four files, 87
tests), and no __main__ block at all, which counts zero (eight files, 174
tests). A guard now refuses both shapes and the return of a prefix list.
Assisted-by: Claude Opus 5
(cherry picked from commit db71b333cc08ae0fce4ddaaf037357648b10236b)
2026-08-26 07:46:14 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
unittest.main()
|