mirror of
https://github.com/Sea-Haven-Industries/procurement-ingest.git
synced 2026-10-07 16:08:54 +00:00
Reject --all combined with --prefix/--since in reprocess.py
--all is a distinct mode (the demoted full-prefix sweep), but the args.all branch unconditionally set prefix=inbound/ and since=None, so passing it alongside a narrower selector silently discarded that selector. `--all --since 2026-07-01` swept the entire corpus instead of the bounded window, triggering every documented --all hazard (Bedrock re-bill, metric double- count, merged-field regression) on objects the operator never targeted -- contradicting the tool's safety goal. Add the missing mutual-exclusion guard alongside the existing --key one, and pin --all+--prefix, --all+--since, and all three together as argparse rejections.
This commit is contained in:
parent
7765111781
commit
88805d906d
2 changed files with 58 additions and 0 deletions
|
|
@ -171,6 +171,13 @@ def main():
|
|||
# --key is mutually exclusive with the listing selectors and with --all.
|
||||
if args.key and (args.prefix or args.since or args.all):
|
||||
parser.error("--key cannot be combined with --prefix, --since, or --all")
|
||||
# --all is a distinct MODE (the demoted full-prefix sweep), not a modifier:
|
||||
# reject it alongside the targeting selectors. Without this, the args.all
|
||||
# clobber branch below would silently discard a narrower --prefix/--since
|
||||
# (e.g. `--all --since 2026-07-01` would sweep the ENTIRE corpus, not the
|
||||
# bounded window) and trigger every --all hazard on unintended objects.
|
||||
if args.all and (args.prefix or args.since):
|
||||
parser.error("--all cannot be combined with --prefix or --since")
|
||||
|
||||
account_id = boto3.client("sts").get_caller_identity()["Account"]
|
||||
function_name = PIPELINES[args.pipeline]["function"]
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ replay single-decode-correct if a future handler ever adds unquote_plus.
|
|||
import importlib.util
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# reprocess.py builds its boto3 clients inside main()/functions, so importing
|
||||
# it is side-effect-free (no AWS calls, no clients at module scope). Set dummy
|
||||
|
|
@ -71,3 +74,51 @@ def test_build_s3_event_shape_and_raw_key():
|
|||
assert "+" in emitted
|
||||
# '%41' NOT decoded to 'A':
|
||||
assert "%41" in emitted and "A .eml" not in emitted
|
||||
|
||||
|
||||
# --- Selector mutual-exclusion: --all is a MODE, not a modifier ---------------
|
||||
# reprocess.main() reaches its first AWS call (sts get_caller_identity) only
|
||||
# AFTER the argparse mutual-exclusion gate, so an invalid selector combination
|
||||
# raises SystemExit(2) with no AWS access needed. This pins that `--all` cannot
|
||||
# be silently combined with a narrower --prefix/--since (which the args.all
|
||||
# clobber branch would otherwise discard -> unintended whole-corpus sweep).
|
||||
def _expect_argparse_reject(monkeypatch, capsys, argv):
|
||||
monkeypatch.setattr(sys, "argv", ["reprocess.py", *argv])
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
reprocess.main()
|
||||
assert exc.value.code == 2 # argparse error exit code
|
||||
return capsys.readouterr().err
|
||||
|
||||
|
||||
def test_all_rejects_prefix(monkeypatch, capsys):
|
||||
err = _expect_argparse_reject(
|
||||
monkeypatch,
|
||||
capsys,
|
||||
["--pipeline", "po", "--all", "--prefix", "inbound/2026/07/"],
|
||||
)
|
||||
assert "--all cannot be combined with --prefix or --since" in err
|
||||
|
||||
|
||||
def test_all_rejects_since(monkeypatch, capsys):
|
||||
err = _expect_argparse_reject(
|
||||
monkeypatch,
|
||||
capsys,
|
||||
["--pipeline", "po", "--all", "--since", "2026-07-01T00:00:00Z"],
|
||||
)
|
||||
assert "--all cannot be combined with --prefix or --since" in err
|
||||
|
||||
|
||||
def test_all_rejects_prefix_and_since_together(monkeypatch, capsys):
|
||||
_expect_argparse_reject(
|
||||
monkeypatch,
|
||||
capsys,
|
||||
[
|
||||
"--pipeline",
|
||||
"po",
|
||||
"--all",
|
||||
"--prefix",
|
||||
"inbound/2026/",
|
||||
"--since",
|
||||
"2026-07-01T00:00:00Z",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue