erplibre/test/test_odoo_rc.py

130 lines
4.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
"""Quel fichier de configuration Odoo lit, quand personne ne le dit.
Sans ODOO_RC, Odoo retombe sur `~/.odoorc` — un fichier PERSONNEL que
rien ne synchronise avec le `config.conf` du dépôt. Mesuré sur une vraie
migration : un `~/.odoorc` portant un mot de passe maître haché faisait
échouer « odoo_bin.sh db --drop » par AccessDenied, alors que
`db_restore.py` venait de lire « admin_passwd = admin » dans config.conf
et d'en conclure qu'aucun mot de passe n'était nécessaire.
Les deux avaient raison. Ils ne parlaient pas du même fichier — et rien,
nulle part, ne les confrontait. Le drop échouait, le clone butait ensuite
sur « database already exists », et la boucle de reprise faisait passer
les deux pour un accident. Huit fois par migration.
"""
import io
import os
import subprocess
import unittest
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LIB = os.path.join(REPO, "script", "lib_odoo_rc.sh")
class Base(unittest.TestCase):
def resoudre(self, racine, environ=None):
"""Ce que la résolution pose dans ODOO_RC, pour cette racine."""
env = dict(os.environ)
env.pop("ODOO_RC", None)
env.update(environ or {})
done = subprocess.run(
[
"bash",
"-c",
f'source {LIB!r}; odoo_rc_resolve "$1"; echo "${{ODOO_RC:-}}"',
"bash",
racine,
],
capture_output=True,
text=True,
env=env,
)
self.assertEqual(0, done.returncode, done.stderr)
return done.stdout.strip()
class TestWhichFileIsChosen(Base):
def setUp(self):
import shutil
import tempfile
self.dossier = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, self.dossier)
def config(self):
chemin = os.path.join(self.dossier, "config.conf")
with io.open(chemin, "w", encoding="utf-8") as handle:
handle.write("[options]\nadmin_passwd = admin\n")
return chemin
def test_the_repository_config_wins_over_the_personal_one(self):
# C'est tout le propos : ~/.odoorc n'est plus consulté.
self.assertEqual(self.config(), self.resoudre(self.dossier))
def test_an_explicit_choice_is_never_overridden(self):
# Odoo lit ODOO_RC avant ~/.odoorc, et « -c » avant ODOO_RC :
# écraser une valeur posée exprès retirerait ce choix.
self.config()
self.assertEqual(
"/ailleurs/odoo.conf",
self.resoudre(self.dossier, {"ODOO_RC": "/ailleurs/odoo.conf"}),
)
def test_without_a_repository_config_nothing_is_forced(self):
# Sur une machine sans config.conf ni /etc/odoo/odoo.conf, on
# laisse Odoo faire ce qu'il a toujours fait.
vide = self.resoudre(self.dossier)
self.assertIn(vide, ("", "/etc/odoo/odoo.conf"))
def test_it_never_fails_the_command_that_sourced_it(self):
# Elle est appelée au tout début d'odoo_bin.sh : y échouer
# empêcherait de lancer Odoo, pour une question de configuration.
done = subprocess.run(
["bash", "-c", f"source {LIB!r}; odoo_rc_resolve /inexistant"],
capture_output=True,
text=True,
env={k: v for k, v in os.environ.items() if k != "ODOO_RC"},
)
self.assertEqual(0, done.returncode, done.stderr)
class TestTheEntryPointUsesIt(unittest.TestCase):
def source(self, nom):
with io.open(os.path.join(REPO, nom), encoding="utf-8") as handle:
return handle.read()
def test_odoo_bin_resolves_before_running_odoo(self):
source = self.source("odoo_bin.sh")
self.assertIn("odoo_rc_resolve", source)
self.assertLess(
source.index("odoo_rc_resolve"), source.index("odoo-bin")
)
def test_the_order_matches_what_db_restore_checks(self):
# `db_restore.py` lit ./config.conf puis /etc/odoo/odoo.conf pour
# décider s'il faut un mot de passe maître. Si Odoo en lisait un
# autre, cette vérification ne vérifierait rien.
lib = self.source(os.path.join("script", "lib_odoo_rc.sh"))
restore = self.source(
os.path.join("script", "database", "db_restore.py")
)
for candidat in ("config.conf", "/etc/odoo/odoo.conf"):
self.assertIn(candidat, lib, candidat)
self.assertIn(candidat, restore, candidat)
self.assertLess(
lib.index("config.conf"), lib.index("/etc/odoo/odoo.conf")
)
self.assertLess(
restore.index("config.conf"),
restore.index("/etc/odoo/odoo.conf"),
)
if __name__ == "__main__":
unittest.main()