defmodule GitGudWeb.RunnerAuditTest do
@moduledoc """
Runners leave audit entries where they belong — a repository's or an
org's log, or the instance's for a global one: a registration token
minted, a runner created offline (from the settings page or the mix
task) or deleted. Never a token.
"""
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.Repositories.Storage
alias GitGud.Workflows.Runner
defp entries, do: GitGud.Repo.all(from e in Entry, order_by: e.id)
test "a repository's: a runner's architecture changed", %{conn: conn} do
{owner, repo} = repository_fixture()
repo = GitGud.Repo.preload(repo, [:owner, :organization])
{:ok, lv, _} =
live(
log_in_user(conn, owner),
"/r/#{Storage.repo_handle(repo)}/#{repo.name}/settings/runners"
)
render_submit(lv, "create_runner", %{"name" => "e52c", "labels" => "ubuntu-24.04-arm"})
runner = GitGud.Repo.get_by!(Runner, name: "e52c")
lv
|> form("#runner-architecture-#{runner.id}", %{"runner" => %{"architecture" => "aarch64"}})
|> render_change()
assert GitGud.Repo.reload!(runner).architecture == "aarch64"
assert [_created, changed] = entries()
assert {changed.action, changed.target_id} == {"runner.architecture_changed", runner.id}
assert changed.metadata == %{"from" => "x86_64", "to" => "aarch64"}
assert changed.repository_id == repo.id
end
test "a repository's: token minted, runner created and deleted", %{conn: conn} do
{owner, repo} = repository_fixture()
repo = GitGud.Repo.preload(repo, [:owner, :organization])
{:ok, lv, _} =
live(
log_in_user(conn, owner),
"/r/#{Storage.repo_handle(repo)}/#{repo.name}/settings/runners"
)
html = render_click(lv, "mint_token", %{})
render_submit(lv, "create_runner", %{"name" => "fast", "labels" => "ubuntu-latest, docker"})
runner = GitGud.Repo.get_by!(Runner, name: "fast")
render_click(lv, "delete_runner", %{"id" => to_string(runner.id)})
assert [minted, created, deleted] = entries()
assert minted.action == "runner.registration_token_minted"
assert Map.keys(minted.metadata) == ["expires_at"]
assert {created.action, created.target_label} == {"runner.created", "fast"}
assert created.metadata == %{"labels" => ["ubuntu-latest", "docker"]}
assert {deleted.action, deleted.target_id} == {"runner.deleted", runner.id}
assert Enum.all?(entries(), &(&1.repository_id == repo.id))
# The minted token is on the page, once, and nowhere in the log.
token = :sys.get_state(lv.pid).socket.assigns.new_token
assert html =~ token
refute inspect(entries()) =~ token
end
test "an org's", %{conn: conn} do
admin = user_fixture()
handle = "rn#{System.unique_integer([:positive])}"
{:ok, org} = Organizations.create_organization(admin, %{"handle" => handle, "name" => handle})
{:ok, lv, _} = live(log_in_user(conn, admin), ~p"/orgs/#{handle}/settings/runners")
render_click(lv, "mint_token", %{})
assert [%Entry{action: "runner.registration_token_minted", organization_id: oid}] = entries()
assert oid == org.id
end
test "an org's: a runner's architecture changed, and only its own runners'", %{conn: conn} do
admin = user_fixture()
handle = "rn#{System.unique_integer([:positive])}"
{:ok, org} = Organizations.create_organization(admin, %{"handle" => handle, "name" => handle})
{:ok, own, _, _} =
GitGud.Workflows.Runners.create_offline(%{name: "e52c"}, org)
{:ok, global, _, _} = GitGud.Workflows.Runners.create_offline(%{name: "pool"})
{:ok, lv, _} = live(log_in_user(conn, admin), ~p"/orgs/#{handle}/settings/runners")
lv
|> form("#runner-architecture-#{own.id}", %{"runner" => %{"architecture" => "aarch64"}})
|> render_change()
assert GitGud.Repo.reload!(own).architecture == "aarch64"
assert [%Entry{action: "runner.architecture_changed", organization_id: oid}] = entries()
assert oid == org.id
# A global runner is listed, but not this page's to change.
refute has_element?(lv, "#runner-architecture-#{global.id}")
render_change(lv, "set_architecture", %{
"runner" => %{"id" => to_string(global.id), "architecture" => "aarch64"}
})
assert GitGud.Repo.reload!(global).architecture == "x86_64"
end
test "the mix task, as the console, on the instance's log" do
Mix.shell(Mix.Shell.Process)
on_exit(fn -> Mix.shell(Mix.Shell.IO) end)
Mix.Tasks.Gitgud.Runner.Create.run(~w(--scope global --name house))
assert [entry] = entries()
assert {entry.action, entry.actor_type, entry.actor_label} ==
{"runner.created", "system", "console"}
assert {entry.organization_id, entry.repository_id} == {nil, nil}
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
4.8 KiB · text
History
b868907