jellyfin-qbittorrent-monitor: don't use mock qbittorrent
This commit is contained in:
@@ -1,45 +1,10 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Mock qBittorrent - simple enough to keep mocked
|
||||
mockQBittorrent = pkgs.writers.writePython3Bin "mock-qbt" { flakeIgnore = [ "E501" ]; } ''
|
||||
import http.server
|
||||
import socketserver
|
||||
|
||||
|
||||
class Handler(http.server.BaseHTTPRequestHandler):
|
||||
def log_message(self, fmt, *args):
|
||||
print(f"qbt: {fmt % args}")
|
||||
|
||||
def do_GET(self):
|
||||
if self.path == "/api/v2/transfer/speedLimitsMode":
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/plain")
|
||||
self.end_headers()
|
||||
self.wfile.write(("1" if getattr(self.server, "alt_speed", False) else "0").encode())
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def do_POST(self):
|
||||
if self.path == "/api/v2/transfer/toggleSpeedLimitsMode":
|
||||
self.server.alt_speed = not getattr(self.server, "alt_speed", False)
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
|
||||
socketserver.TCPServer.allow_reuse_address = True
|
||||
with socketserver.TCPServer(("0.0.0.0", 8080), Handler) as s:
|
||||
print("Mock qBittorrent on port 8080")
|
||||
s.serve_forever()
|
||||
'';
|
||||
|
||||
payloads = {
|
||||
auth = pkgs.writeText "auth.json" (builtins.toJSON { Username = "jellyfin"; });
|
||||
empty = pkgs.writeText "empty.json" (builtins.toJSON { });
|
||||
@@ -49,8 +14,48 @@ pkgs.testers.runNixOSTest {
|
||||
name = "jellyfin-qbittorrent-monitor";
|
||||
|
||||
nodes = {
|
||||
server = {
|
||||
server =
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.vpn-confinement.nixosModules.default
|
||||
];
|
||||
|
||||
services.jellyfin.enable = true;
|
||||
|
||||
# Real qBittorrent service
|
||||
services.qbittorrent = {
|
||||
enable = true;
|
||||
webuiPort = 8080;
|
||||
openFirewall = true;
|
||||
|
||||
serverConfig.LegalNotice.Accepted = true;
|
||||
|
||||
serverConfig.Preferences = {
|
||||
WebUI = {
|
||||
# Disable authentication for testing
|
||||
AuthSubnetWhitelist = "0.0.0.0/0,::/0";
|
||||
AuthSubnetWhitelistEnabled = true;
|
||||
LocalHostAuth = false;
|
||||
};
|
||||
|
||||
Downloads = {
|
||||
SavePath = "/var/lib/qbittorrent/downloads";
|
||||
TempPath = "/var/lib/qbittorrent/incomplete";
|
||||
};
|
||||
};
|
||||
|
||||
serverConfig.BitTorrent.Session = {
|
||||
# Normal speed - unlimited
|
||||
GlobalUPSpeedLimit = 0;
|
||||
GlobalDLSpeedLimit = 0;
|
||||
|
||||
# Alternate speed limits for when Jellyfin is streaming
|
||||
AlternativeGlobalUPSpeedLimit = 100;
|
||||
AlternativeGlobalDLSpeedLimit = 100;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
ffmpeg
|
||||
@@ -72,10 +77,12 @@ pkgs.testers.runNixOSTest {
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
systemd.services.mock-qbittorrent = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.ExecStart = lib.getExe mockQBittorrent;
|
||||
};
|
||||
|
||||
# Create directories for qBittorrent
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/qbittorrent/downloads 0755 qbittorrent qbittorrent"
|
||||
"d /var/lib/qbittorrent/incomplete 0755 qbittorrent qbittorrent"
|
||||
];
|
||||
};
|
||||
|
||||
# Public test IP (RFC 5737 TEST-NET-3) so Jellyfin sees it as external
|
||||
@@ -123,9 +130,12 @@ pkgs.testers.runNixOSTest {
|
||||
server.wait_for_unit("jellyfin.service")
|
||||
server.wait_for_open_port(8096)
|
||||
server.wait_until_succeeds("curl -sf http://localhost:8096/health | grep -q Healthy", timeout=60)
|
||||
server.wait_for_unit("mock-qbittorrent.service")
|
||||
server.wait_for_unit("qbittorrent.service")
|
||||
server.wait_for_open_port(8080)
|
||||
|
||||
# Wait for qBittorrent WebUI to be responsive
|
||||
server.wait_until_succeeds("curl -sf http://localhost:8080/api/v2/app/version", timeout=30)
|
||||
|
||||
with subtest("Complete Jellyfin setup wizard"):
|
||||
server.wait_until_succeeds(api_get("/Startup/Configuration"))
|
||||
server.succeed(api_get("/Startup/FirstUser"))
|
||||
@@ -169,13 +179,13 @@ pkgs.testers.runNixOSTest {
|
||||
python = "${pkgs.python3.withPackages (ps: [ ps.requests ])}/bin/python"
|
||||
monitor = "${../services/jellyfin-qbittorrent-monitor.py}"
|
||||
server.succeed(f"""
|
||||
systemd-run --unit=monitor-test \\
|
||||
--setenv=JELLYFIN_URL=http://localhost:8096 \\
|
||||
--setenv=JELLYFIN_API_KEY={token} \\
|
||||
--setenv=QBITTORRENT_URL=http://localhost:8080 \\
|
||||
--setenv=CHECK_INTERVAL=1 \\
|
||||
--setenv=STREAMING_START_DELAY=1 \\
|
||||
--setenv=STREAMING_STOP_DELAY=1 \\
|
||||
systemd-run --unit=monitor-test \
|
||||
--setenv=JELLYFIN_URL=http://localhost:8096 \
|
||||
--setenv=JELLYFIN_API_KEY={token} \
|
||||
--setenv=QBITTORRENT_URL=http://localhost:8080 \
|
||||
--setenv=CHECK_INTERVAL=1 \
|
||||
--setenv=STREAMING_START_DELAY=1 \
|
||||
--setenv=STREAMING_STOP_DELAY=1 \
|
||||
{python} {monitor}
|
||||
""")
|
||||
time.sleep(2)
|
||||
@@ -275,12 +285,13 @@ pkgs.testers.runNixOSTest {
|
||||
time.sleep(2)
|
||||
assert is_throttled(), "Should be throttled before qBittorrent restart"
|
||||
|
||||
# Restart mock-qbittorrent (this resets alt_speed to False)
|
||||
server.succeed("systemctl restart mock-qbittorrent.service")
|
||||
server.wait_for_unit("mock-qbittorrent.service")
|
||||
# Restart qBittorrent (this resets alt_speed to its config default - disabled)
|
||||
server.succeed("systemctl restart qbittorrent.service")
|
||||
server.wait_for_unit("qbittorrent.service")
|
||||
server.wait_for_open_port(8080)
|
||||
server.wait_until_succeeds("curl -sf http://localhost:8080/api/v2/app/version", timeout=30)
|
||||
|
||||
# qBittorrent restarted - alt_speed is now False (default)
|
||||
# qBittorrent restarted - alt_speed is now False (default on startup)
|
||||
# The monitor should detect this and re-apply throttling
|
||||
time.sleep(3) # Give monitor time to detect and re-apply
|
||||
assert is_throttled(), "Monitor should re-apply throttling after qBittorrent restart"
|
||||
@@ -300,10 +311,11 @@ pkgs.testers.runNixOSTest {
|
||||
# Verify we're unthrottled (no active streams)
|
||||
assert not is_throttled(), "Should be unthrottled before test"
|
||||
|
||||
# Restart mock-qbittorrent
|
||||
server.succeed("systemctl restart mock-qbittorrent.service")
|
||||
server.wait_for_unit("mock-qbittorrent.service")
|
||||
# Restart qBittorrent
|
||||
server.succeed("systemctl restart qbittorrent.service")
|
||||
server.wait_for_unit("qbittorrent.service")
|
||||
server.wait_for_open_port(8080)
|
||||
server.wait_until_succeeds("curl -sf http://localhost:8080/api/v2/app/version", timeout=30)
|
||||
|
||||
# Give monitor time to check state
|
||||
time.sleep(3)
|
||||
|
||||
Reference in New Issue
Block a user