Harden upstream ImapTest adapter
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user