Files
rohit267-champdev-comfyui-n…/tests/test_telemetry.py
T
Rohit MahtoandClaude Opus 4.8 d861d7ccaa feat(telemetry): fleet telemetry client + PowerShell default on Windows
Adds telemetry.py: on pack load, a daemon thread collects device specs, the
ComfyUI port, and public/private IPs and POSTs one event to the fleet telemetry
server (CHAMPDEV_TELEMETRY_URL, kill switch CHAMPDEV_TELEMETRY=0). Fully
exception-swallowed so it never blocks or breaks ComfyUI startup.

Also makes PowerShell (pwsh.exe, then powershell.exe) the default Windows shell
for the terminal node, falling back to cmd.exe. Bumps version to 0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 16:18:42 +05:30

109 lines
3.3 KiB
Python

import telemetry
EXPECTED_KEYS = {
"install_id", "event_ts", "comfy_port", "comfy_listen", "private_ip",
"public_ip", "os", "os_release", "os_version", "arch", "hostname",
"python_version", "comfy_version", "pack_version", "cpu_model", "cpu_count",
"ram_gb", "gpu_name", "vram_gb",
}
def test_gather_payload_has_expected_keys(monkeypatch):
# Stub the network-touching helpers so the test stays hermetic.
monkeypatch.setattr(telemetry, "_public_ip", lambda: "203.0.113.9")
monkeypatch.setattr(telemetry, "_private_ip", lambda: "192.168.1.5")
payload = telemetry.gather_payload()
assert set(payload.keys()) == EXPECTED_KEYS
assert payload["os"] # platform.system() is always present
assert payload["event_ts"]
assert payload["private_ip"] == "192.168.1.5"
assert payload["public_ip"] == "203.0.113.9"
def test_gather_payload_never_raises_without_optional_deps(monkeypatch):
# Simulate torch / psutil / nvidia-smi / comfy all being unavailable.
import builtins
real_import = builtins.__import__
def fake_import(name, *args, **kwargs):
if name in ("torch", "psutil", "comfy", "comfy.cli_args",
"comfyui_version", "server"):
raise ImportError(name)
return real_import(name, *args, **kwargs)
monkeypatch.setattr(builtins, "__import__", fake_import)
def boom(*a, **k):
raise OSError("no nvidia-smi")
monkeypatch.setattr(telemetry.subprocess, "run", boom)
import urllib.request
def no_net(*a, **k):
raise OSError("no network")
monkeypatch.setattr(urllib.request, "urlopen", no_net)
payload = telemetry.gather_payload()
assert payload["gpu_name"] is None
assert payload["vram_gb"] is None
assert payload["public_ip"] is None # network unreachable → swallowed
assert set(payload.keys()) == EXPECTED_KEYS
def test_kill_switch_suppresses_send(monkeypatch):
telemetry._sent = False
called = []
monkeypatch.setattr(telemetry, "_run", lambda: called.append(True))
monkeypatch.setenv("CHAMPDEV_TELEMETRY", "0")
telemetry.maybe_send()
assert called == []
def test_sends_only_once_per_process(monkeypatch):
telemetry._sent = False
starts = []
class FakeThread:
def __init__(self, *a, **k):
self._target = k.get("target")
def start(self):
starts.append(True)
monkeypatch.setattr(telemetry.threading, "Thread", FakeThread)
monkeypatch.delenv("CHAMPDEV_TELEMETRY", raising=False)
telemetry.maybe_send()
telemetry.maybe_send()
telemetry.maybe_send()
assert len(starts) == 1
def test_public_ip_returns_none_on_failure(monkeypatch):
import urllib.request
def boom(*a, **k):
raise OSError("no network")
monkeypatch.setattr(urllib.request, "urlopen", boom)
assert telemetry._public_ip() is None
def test_private_ip_is_a_string_or_none():
result = telemetry._private_ip()
assert result is None or isinstance(result, str)
def test_server_url_env_override(monkeypatch):
monkeypatch.setenv("CHAMPDEV_TELEMETRY_URL", "https://my.host")
assert telemetry._server_url() == "https://my.host"
monkeypatch.delenv("CHAMPDEV_TELEMETRY_URL", raising=False)
assert telemetry._server_url() == telemetry.DEFAULT_TELEMETRY_URL