git-subtree-dir: fiscal git-subtree-mainline:d95165fc8fgit-subtree-split:102ba84500
72 lines
3.0 KiB
Python
72 lines
3.0 KiB
Python
"""Setup.exe's Firebird discovery: read-only SGV detection, auto-select only when unambiguous."""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parents[1] / "installer"))
|
|
import firebird_discovery as fbd # noqa: E402
|
|
|
|
|
|
class FakeConn:
|
|
def __init__(self, tables): self.tables = tables; self.closed = False; self.sql = []
|
|
def cursor(self):
|
|
outer = self
|
|
class C:
|
|
def execute(self, sql): outer.sql.append(sql)
|
|
def fetchall(self): return [(t,) for t in outer.tables]
|
|
return C()
|
|
def close(self): self.closed = True
|
|
|
|
|
|
def make_connect(spec):
|
|
"""spec: path -> tables | 'AUTH' | Exception"""
|
|
def connect(path, user, password):
|
|
value = spec[path]
|
|
if value == "AUTH" and (user, password) != ("SYSDBA", "masterkey"):
|
|
raise Exception("Your user name and password are not defined")
|
|
if value == "BROKEN": raise OSError("cannot open")
|
|
return FakeConn(["C000025", "C000004"] if value == "AUTH" else value)
|
|
return connect
|
|
|
|
|
|
def run(spec, credentials=fbd.DEFAULT_CREDENTIALS):
|
|
return fbd.discover(roots=["X"], finder=lambda roots: list(spec), connect=make_connect(spec), credentials=credentials)
|
|
|
|
|
|
def test_exactly_one_sgv_database_is_selected_automatically():
|
|
found = run({r"D:\SGV\loja.fdb": ["C000025", "C000004", "OTHER"], r"D:\other\x.fdb": ["FOO"]})
|
|
assert found.state == "SELECTED" and found.selected.path == r"D:\SGV\loja.fdb" and found.selected.user == "SYSDBA"
|
|
|
|
|
|
def test_several_compatible_databases_are_never_chosen_silently():
|
|
found = run({r"D:\a.fdb": ["C000025", "C000004"], r"D:\b.fdb": ["C000025", "C000004"]})
|
|
assert found.state == "AMBIGUOUS" and len(found.compatible) == 2 and found.selected is None
|
|
|
|
|
|
def test_database_needs_both_c000025_and_c000004():
|
|
assert run({r"D:\a.fdb": ["C000025"]}).state == "NONE"
|
|
|
|
|
|
def test_unknown_credentials_ask_the_operator_inside_the_installer():
|
|
found = run({r"D:\a.fdb": "AUTH"}, credentials=(("SYSDBA", "wrong"),))
|
|
assert found.state == "AUTH_REQUIRED" and found.auth_failed[0].path == r"D:\a.fdb"
|
|
|
|
|
|
def test_probe_is_read_only_and_closes_the_connection():
|
|
conn = FakeConn(["C000025", "C000004"])
|
|
cand = fbd.probe("x.fdb", "SYSDBA", "masterkey", connect=lambda *a: conn)
|
|
assert cand.status == "OK" and conn.closed and all(sql.lstrip().upper().startswith("SELECT") for sql in conn.sql)
|
|
|
|
|
|
def test_broken_file_is_reported_not_raised():
|
|
assert fbd.probe("x.fdb", "u", "p", connect=lambda *a: (_ for _ in ()).throw(OSError("boom"))).status == "ERROR"
|
|
|
|
|
|
def test_finder_skips_system_dirs_security_db_and_tiny_files(tmp_path):
|
|
big = b"0" * (fbd.MIN_BYTES + 1)
|
|
(tmp_path / "SGV").mkdir(); (tmp_path / "SGV" / "loja.FDB").write_bytes(big)
|
|
(tmp_path / "SGV" / "security2.fdb").write_bytes(big)
|
|
(tmp_path / "SGV" / "tiny.fdb").write_bytes(b"0")
|
|
(tmp_path / "Windows").mkdir(); (tmp_path / "Windows" / "sys.fdb").write_bytes(big)
|
|
found = fbd.find_fdb_files([str(tmp_path)])
|
|
assert [Path(p).name for p in found] == ["loja.FDB"]
|