feat: keep SAB jobs leased until Arr import
This commit is contained in:
parent
6694b48420
commit
0ce5a817a2
1 changed files with 107 additions and 0 deletions
107
usenet-scripts/test_movetdarr.py
Normal file
107
usenet-scripts/test_movetdarr.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import threading
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPT = Path(__file__).with_name("movetdarr.sh")
|
||||
actions = []
|
||||
status_polls = 0
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
global status_polls
|
||||
data = json.loads(self.rfile.read(int(self.headers.get("Content-Length", "0"))))
|
||||
actions.append(data)
|
||||
action = data.get("action")
|
||||
if action == "start":
|
||||
result = {"ok": True, "jobId": "test-job-1234", "state": "registered"}
|
||||
elif action == "moved":
|
||||
result = {"ok": True, "jobId": "test-job-1234", "state": "processing"}
|
||||
elif action == "status":
|
||||
status_polls += 1
|
||||
result = {"ok": True, "jobId": "test-job-1234", "state": "success" if status_polls >= 2 else "processing"}
|
||||
else:
|
||||
result = {"ok": True, "jobId": "test-job-1234", "state": "failed"}
|
||||
body = json.dumps(result).encode()
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
|
||||
def log_message(self, *_args):
|
||||
pass
|
||||
|
||||
|
||||
def run_case(root, category="serien4k", status="0", name="Show.S01E01", target_video=False):
|
||||
src_root = root / "source"
|
||||
dst_root = root / "dest"
|
||||
source = src_root / category / name
|
||||
source.mkdir(parents=True)
|
||||
(source / "episode.mkv").write_bytes(b"video")
|
||||
target = dst_root / category / name
|
||||
if target_video:
|
||||
target.mkdir(parents=True)
|
||||
(target / "existing.mkv").write_bytes(b"existing")
|
||||
env = os.environ | {
|
||||
"SOURCE_ROOT": str(src_root),
|
||||
"DEST_ROOT": str(dst_root),
|
||||
"LOGFILE": str(root / "postprocess.log"),
|
||||
"HANDOFF_URL": f"http://127.0.0.1:{server.server_port}/media/handoff",
|
||||
"POLL_SECONDS": "0",
|
||||
"MAX_POLLS": "3",
|
||||
}
|
||||
result = subprocess.run(
|
||||
["bash", str(SCRIPT), str(source), name + ".nzb", name, "", category, "", status],
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=20,
|
||||
)
|
||||
return result, source, target
|
||||
|
||||
|
||||
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
|
||||
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
thread.start()
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
actions.clear()
|
||||
status_polls = 0
|
||||
result, source, target = run_case(Path(td))
|
||||
assert result.returncode == 0, (result.stdout, result.stderr)
|
||||
assert not source.exists() and (target / "episode.mkv").exists()
|
||||
assert [a["action"] for a in actions] == ["start", "moved", "status", "status"]
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
actions.clear()
|
||||
status_polls = 0
|
||||
result, source, _ = run_case(Path(td), category="other")
|
||||
assert result.returncode == 1 and source.exists() and actions == []
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
actions.clear()
|
||||
status_polls = 0
|
||||
result, source, target = run_case(Path(td), target_video=True)
|
||||
assert result.returncode == 2 and source.exists() and (target / "existing.mkv").exists()
|
||||
assert [a["action"] for a in actions] == ["start", "fail"]
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
actions.clear()
|
||||
status_polls = 0
|
||||
root = Path(td)
|
||||
stale = root / "dest" / "video" / "Movie.2026"
|
||||
stale.mkdir(parents=True)
|
||||
(stale / "leftover.nfo").write_text("stale")
|
||||
result, source, target = run_case(root, category="video", name="Movie.2026")
|
||||
assert result.returncode == 0 and not source.exists()
|
||||
assert not (target / "leftover.nfo").exists() and (target / "episode.mkv").exists()
|
||||
|
||||
print("PASS: success lease, category fail-closed, no-overwrite, stale-directory cleanup")
|
||||
finally:
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
Loading…
Add table
Add a link
Reference in a new issue