defmodule GitGudWeb.AdminRunnersTest do
@moduledoc """
The instance admins' runners page: every runner whatever its scope,
global runners minted here, any runner's architecture changed or the
runner removed — each audited where the runner belongs, and each in
sudo mode.
"""
use GitGudWeb.ConnCase, async: false
import Ecto.Query
import Phoenix.LiveViewTest
import GitGud.AccountsFixtures
import GitGud.ForgeFixtures
alias GitGud.Audit.Entry
alias GitGud.Organizations
alias GitGud.Repo
alias GitGud.Workflows.Runner
alias GitGud.Workflows.Runners
setup do
admin = user_fixture() |> Ecto.Changeset.change(is_admin: true) |> Repo.update!()
%{admin: admin}
end
defp entries, do: Repo.all(from e in Entry, order_by: e.id)
test "lists every runner, with its scope", %{conn: conn, admin: admin} do
{_owner, repo} = repository_fixture()
handle = "ar#{System.unique_integer([:positive])}"
{:ok, org} = Organizations.create_organization(admin, %{"handle" => handle, "name" => handle})
{:ok, in_repo, _, _} = Runners.create_offline(%{name: "in-repo"}, repo)
{:ok, in_org, _, _} = Runners.create_offline(%{name: "in-org"}, org)
{:ok, global, _, _} = Runners.create_offline(%{name: "pool"})
{:ok, lv, _} = conn |> log_in_user(admin) |> live(~p"/admin/runners")
assert has_element?(lv, "#runner-row-#{in_repo.id}", repo.name)
assert has_element?(lv, "#runner-row-#{in_org.id}", handle)
assert has_element?(lv, "#runner-row-#{global.id}", "global")
end
test "mints a global runner, shown once and audited in the instance's log", %{
conn: conn,
admin: admin
} do
{:ok, lv, _} = conn |> log_in_user(admin) |> live(~p"/admin/runners")
lv
|> form("#new-runner-form", %{
"new_runner" => %{"name" => "house", "labels" => "self-hosted, arc-runner-set"}
})
|> render_submit()
runner = Repo.get_by!(Runner, name: "house")
assert {runner.repository_id, runner.organization_id} == {nil, nil}
assert runner.labels == %{"labels" => ["self-hosted", "arc-runner-set"]}
assert has_element?(lv, "#new-runner-config", runner.uuid)
assert has_element?(lv, "#runner-row-#{runner.id}", "never connected")
assert [%Entry{action: "runner.created", repository_id: nil, organization_id: nil} = e] =
entries()
assert e.target_id == runner.id
refute inspect(e.metadata) =~ "token"
end
test "changes an org runner's architecture, audited in the org's log", %{
conn: conn,
admin: admin
} do
owner = user_fixture()
handle = "ar#{System.unique_integer([:positive])}"
{:ok, org} = Organizations.create_organization(owner, %{"handle" => handle, "name" => handle})
{:ok, runner, _, _} = Runners.create_offline(%{name: "e52c"}, org)
{:ok, lv, _} = conn |> log_in_user(admin) |> live(~p"/admin/runners")
lv
|> form("#runner-architecture-#{runner.id}", %{"runner" => %{"architecture" => "aarch64"}})
|> render_change()
assert Repo.reload!(runner).architecture == "aarch64"
assert [%Entry{action: "runner.architecture_changed", organization_id: oid}] = entries()
assert oid == org.id
end
test "removes a runner", %{conn: conn, admin: admin} do
{:ok, runner, _, _} = Runners.create_offline(%{name: "gone"})
{:ok, lv, _} = conn |> log_in_user(admin) |> live(~p"/admin/runners")
lv |> element("#runner-remove-#{runner.id}") |> render_click()
refute Repo.get(Runner, runner.id)
refute has_element?(lv, "#runner-row-#{runner.id}")
assert [%Entry{action: "runner.deleted"}] = entries()
end
test "a runner connecting for the first time shows, with a toast", %{
conn: conn,
admin: admin
} do
{_owner, repo} = repository_fixture()
{:ok, runner, _, _} = Runners.create_offline(%{name: "caprica"}, repo)
{:ok, lv, _} = conn |> log_in_user(admin) |> live(~p"/admin/runners")
{:ok, _} = Runners.touch_last_seen(runner)
assert has_element?(lv, "#runner-row-#{runner.id}", "last seen")
assert has_element?(lv, "#flash-info", "Runner 'caprica' connected.")
end
test "changes need sudo mode", %{conn: conn, admin: admin} do
{:ok, runner, _, _} = Runners.create_offline(%{name: "kept"})
stale = DateTime.add(DateTime.utc_now(:second), -30, :minute)
{:ok, lv, _} =
conn |> log_in_user(admin, token_authenticated_at: stale) |> live(~p"/admin/runners")
assert {:error, {:redirect, %{to: to}}} =
lv |> element("#runner-remove-#{runner.id}") |> render_click()
assert to =~ "/users/log-in"
assert Repo.get(Runner, runner.id)
assert entries() == []
end
test "not for anyone else", %{conn: conn} do
user = user_fixture()
assert {:error, {:redirect, %{to: "/"}}} =
conn |> log_in_user(user) |> live(~p"/admin/runners")
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
4.7 KiB · text
History
b868907