Harden upstream ImapTest adapter

This commit is contained in:
Mario Fetka
2026-07-29 10:33:10 +02:00
parent 4341e004f9
commit d0cf38c8a6
3 changed files with 38 additions and 9 deletions
+3 -1
View File
@@ -66,7 +66,9 @@ one-off files in `/tmp`:
tracking. POP mode seeds three identifiable messages through Bongo IMAPS,
runs ImapTest's POP3 profile with message retention, and verifies and removes
all three fixtures afterward. Credentials are passed through a mode-0600
temporary user file instead of the process command line. See
temporary user file instead of the process command line. A scripted group
can be isolated with repeatable `--test-group NAME`; raw protocol logging is
deliberately disabled because it can expose the decoded login. See
`docs/upstream-test-suites.md` for the limits of upstream-suite reuse.
- `smtp4dev-fixture.py` manages two authenticated, loopback-only external SMTP
provider fixtures for STARTTLS and implicit TLS plus a TLS-required,
+31 -8
View File
@@ -89,9 +89,16 @@ def find_source(explicit: str | None) -> Path:
return source
def selected_tests(source: Path, suite: str) -> tuple[Path, ...]:
def selected_tests(
source: Path, suite: str, explicit: tuple[str, ...] = ()
) -> tuple[Path, ...]:
source_tests = source / "src" / "tests"
if suite == "core":
if explicit:
for name in explicit:
if not name or Path(name).name != name or name.endswith(".mbox"):
raise UpstreamTestError(f"invalid upstream test group: {name!r}")
names = explicit
elif suite == "core":
names = CORE_TESTS
elif suite == "search":
names = SEARCH_TESTS
@@ -113,9 +120,14 @@ def selected_tests(source: Path, suite: str) -> tuple[Path, ...]:
return paths
def stage_tests(source: Path, suite: str, destination: Path) -> int:
def stage_tests(
source: Path,
suite: str,
destination: Path,
explicit: tuple[str, ...] = (),
) -> int:
source_tests = source / "src" / "tests"
paths = selected_tests(source, suite)
paths = selected_tests(source, suite, explicit)
shutil.copy2(source_tests / "default.mbox", destination / "default.mbox")
for path in paths:
shutil.copy2(path, destination / path.name)
@@ -142,7 +154,6 @@ def common_arguments(args: argparse.Namespace, userfile: Path) -> list[str]:
f"port={args.port}",
f"userfile={userfile}",
"ssl=any-cert" if not args.ca_file else "ssl",
"disconnect_quit",
]
if args.ca_file:
command.append(f"ssl_ca_file={Path(args.ca_file).resolve()}")
@@ -180,13 +191,15 @@ def scripted(args: argparse.Namespace) -> None:
directory = Path(raw)
staged = directory / "tests"
staged.mkdir()
count = stage_tests(source, args.suite, staged)
explicit = tuple(args.test_group)
count = stage_tests(source, args.suite, staged, explicit)
userfile = credentials_file(directory, args.username, args.password)
command = common_arguments(args, userfile)
command.extend((f"box={args.mailbox}", f"test={staged}", "rawlog"))
command.extend((f"box={args.mailbox}", f"test={staged}"))
run(command, args.timeout, directory)
label = ", ".join(explicit) if explicit else f"{args.suite} suite"
print(
f"PASS: Dovecot ImapTest {args.suite} suite "
f"PASS: Dovecot ImapTest {label} "
f"({count} scripted test groups)"
)
@@ -208,6 +221,7 @@ def stress(args: argparse.Namespace) -> None:
"random",
"own_msgs",
"own_flags",
"disconnect_quit",
"stalled_disconnect_timeout=15",
)
)
@@ -384,6 +398,15 @@ def parser() -> argparse.ArgumentParser:
result.add_argument("--ca-file", default=os.environ.get("BONGO_TEST_CA_FILE"))
result.add_argument("--imap4rev2", action="store_true")
result.add_argument("--suite", choices=("core", "search", "all"), default="core")
result.add_argument(
"--test-group",
action="append",
default=[],
help=(
"run one named upstream scripted group; may be repeated and "
"overrides --suite"
),
)
result.add_argument("--clients", type=int, default=4)
result.add_argument("--seconds", type=int, default=30)
result.add_argument("--checkpoint", type=int, default=5)
+4
View File
@@ -47,6 +47,10 @@ export BONGO_TEST_PASSWORD='a-disposable-password-of-at-least-12-characters'
The complete upstream suite can be selected with `--suite all`. Missing
optional capabilities are reported as skips by ImapTest; a failure in the
base protocol or an advertised extension fails the Bongo test.
For diagnosis, `--test-group append` selects one named upstream file and may
be repeated. The adapter does not enable ImapTest's raw logging because a raw
IMAP trace can contain the decoded test password; the captured test summary
is the release artifact.
The upstream scripted corpus uses IMAP4rev1 response rules, including
`RECENT`. It must not be combined with `--imap4rev2`. Bongo's dedicated live