feat(server): host channel with token auth and metric events

This commit is contained in:
Carsten 2026-04-21 22:04:31 +02:00
parent d9a52db4ea
commit 61595e0293
3 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,94 @@
defmodule ServerWeb.HostChannelTest do
use ServerWeb.ChannelCase, async: false
alias Server.Hosts
alias ServerWeb.AgentSocket
setup do
{:ok, {host, token}} = Hosts.create_host("pve-01")
%{host: host, token: token}
end
describe "join" do
test "succeeds with valid token and marks host online", %{host: host, token: token} do
{:ok, socket} = connect(AgentSocket, %{})
assert {:ok, _reply, socket} =
subscribe_and_join(socket, "host:pve-01", %{
"token" => token,
"agent_version" => "0.1.0"
})
assert socket.assigns.host_id == host.id
reloaded = Server.Repo.reload!(host)
assert reloaded.status == "online"
assert reloaded.agent_version == "0.1.0"
assert reloaded.last_seen_at != nil
end
test "rejects invalid token" do
{:ok, socket} = connect(AgentSocket, %{})
assert {:error, %{reason: "invalid_token"}} =
subscribe_and_join(socket, "host:pve-01", %{
"token" => "garbage",
"agent_version" => "0.1.0"
})
end
test "rejects unknown host name" do
{:ok, socket} = connect(AgentSocket, %{})
assert {:error, %{reason: "unknown_host"}} =
subscribe_and_join(socket, "host:nope", %{
"token" => "x",
"agent_version" => "0.1.0"
})
end
end
describe "metric:fast event" do
setup %{token: token} do
{:ok, socket} = connect(AgentSocket, %{})
{:ok, _reply, joined} =
subscribe_and_join(socket, "host:pve-01", %{
"token" => token,
"agent_version" => "0.1.0"
})
%{socket: joined}
end
test "accepts metric payload and replies :ok", %{socket: socket} do
ref =
push(socket, "metric:fast", %{
"collected_at" => "2026-04-21T12:00:00Z",
"data" => %{"cpu_percent" => 12.3, "load1" => 0.2}
})
assert_reply ref, :ok
end
end
describe "terminate" do
test "marks host offline when channel process exits", %{host: host, token: token} do
{:ok, socket} = connect(AgentSocket, %{})
{:ok, _, joined} =
subscribe_and_join(socket, "host:pve-01", %{
"token" => token,
"agent_version" => "0.1.0"
})
Process.unlink(joined.channel_pid)
ref = Process.monitor(joined.channel_pid)
close(joined)
assert_receive {:DOWN, ^ref, :process, _, _}, 1_000
reloaded = Server.Repo.reload!(host)
assert reloaded.status == "offline"
end
end
end

View file

@ -0,0 +1,24 @@
defmodule ServerWeb.ChannelCase do
@moduledoc """
Test helpers for Phoenix Channels.
Imports conveniences for testing channels and the sandbox-based Repo so tests
run concurrently and are isolated.
"""
use ExUnit.CaseTemplate
using do
quote do
import Phoenix.ChannelTest
import ServerWeb.ChannelCase
@endpoint ServerWeb.Endpoint
end
end
setup tags do
Server.DataCase.setup_sandbox(tags)
:ok
end
end