import json import logging import os import sys import threading from pathlib import Path from unittest.mock import MagicMock, patch import boto3 from src.app import make_worker from src.worker.task_protection import TaskProtectionResult def _read_body(arg: str) -> str: return arg if arg.lstrip().startswith("{") else Path(arg).read_text() def main() -> None: if len(sys.argv) != 2: sys.exit("usage: handle_task '' | ") body = _read_body(sys.argv[1]) os.environ.setdefault("ENVIRONMENT", "dev") os.environ.setdefault("MESSAGE_PROCESSING_TIMEOUT_MINUTES", "30") os.environ.setdefault("HEARTBEAT_INTERVAL_SECONDS", "60") sqs = boto3.client("sqs") queue_url = sqs.create_queue(QueueName="dev-handle-task")["QueueUrl"] os.environ["SQS_QUEUE_URL"] = queue_url sqs.send_message(QueueUrl=queue_url, MessageBody=body) sfn = MagicMock() shutdown = threading.Event() def disable_and_shutdown() -> bool: shutdown.set() return True logging.basicConfig(level=logging.INFO) with ( patch("src.worker.worker.task_protection.enable", return_value=TaskProtectionResult.ENABLED), patch("src.worker.worker.task_protection.disable", side_effect=disable_and_shutdown), patch("src.worker.worker.step_functions.send_task_success", sfn.send_task_success), patch("src.worker.worker.step_functions.send_task_failure", sfn.send_task_failure), patch("src.worker.worker.step_functions.send_task_heartbeat", sfn.send_task_heartbeat), ): make_worker().process_messages(shutdown) print() if sfn.send_task_success.called: print("→ send_task_success:") print(json.dumps(sfn.send_task_success.call_args.kwargs, indent=2, default=str)) elif sfn.send_task_failure.called: print("→ send_task_failure:") print(json.dumps(sfn.send_task_failure.call_args.kwargs, indent=2, default=str)) else: print("(no SFN call — silent abort or malformed message with no token)") if __name__ == "__main__": main()