towerops/test/towerops/workers/backup_summary_worker_test.exs

232 lines
7.5 KiB
Elixir

defmodule Towerops.Workers.BackupSummaryWorkerTest do
use Towerops.DataCase, async: false
import ExUnit.CaptureLog
import Towerops.AccountsFixtures
alias Towerops.Devices
alias Towerops.Devices.BackupRequests
alias Towerops.Organizations
alias Towerops.Sites
alias Towerops.Workers.BackupSummaryWorker
require Logger
setup do
# Ensure Logger level is set to info for capturing logs
original_level = Logger.level()
Logger.configure(level: :info)
on_exit(fn ->
Logger.configure(level: original_level)
end)
:ok
end
describe "perform/1" do
test "returns :ok when no backup requests exist" do
# Execute the worker
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end
test "logs summary when only successful backups exist" do
device = insert_device()
# Create successful requests
{:ok, req} = BackupRequests.create_request(device.id, "job1")
BackupRequests.update_request_status(req.id, "success", nil)
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify summary was logged
assert log =~ "Backup summary for past 24 hours"
refute log =~ "Backup failures detected"
end
test "logs warning when failed backups exist" do
device = insert_device()
# Create a failed request
{:ok, req} = BackupRequests.create_request(device.id, "job_failed")
BackupRequests.update_request_status(req.id, "failed", "Connection error")
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify warning was logged
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "logs warning when timeout backups exist" do
device = insert_device()
# Create a timeout request
{:ok, req} = BackupRequests.create_request(device.id, "job_timeout")
BackupRequests.update_request_status(req.id, "timeout", "Request timed out")
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify warning was logged
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "logs warning when both failed and timeout backups exist" do
device = insert_device()
# Create a failed request
{:ok, req1} = BackupRequests.create_request(device.id, "job_failed")
BackupRequests.update_request_status(req1.id, "failed", "Connection error")
# Create a timeout request
{:ok, req2} = BackupRequests.create_request(device.id, "job_timeout")
BackupRequests.update_request_status(req2.id, "timeout", "Request timed out")
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify warning was logged
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "includes device IDs in warning log" do
device1 = insert_device()
device2 = insert_device()
# Create failed requests for multiple devices
{:ok, req1} = BackupRequests.create_request(device1.id, "job1")
BackupRequests.update_request_status(req1.id, "failed", "Error")
{:ok, req2} = BackupRequests.create_request(device2.id, "job2")
BackupRequests.update_request_status(req2.id, "timeout", "Timeout")
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify warnings were logged (metadata fields like device IDs aren't captured in text logs)
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "only includes requests from past 24 hours" do
device = insert_device()
# Create an old failed request (30 hours ago)
{:ok, old_req} = BackupRequests.create_request(device.id, "job_old")
old_req
|> Ecto.Changeset.change(
requested_at: DateTime.utc_now() |> DateTime.add(-30 * 60 * 60, :second) |> DateTime.truncate(:second)
)
|> Repo.update!()
BackupRequests.update_request_status(old_req.id, "failed", "Old error")
# Create a recent failed request (12 hours ago)
{:ok, recent_req} = BackupRequests.create_request(device.id, "job_recent")
recent_req
|> Ecto.Changeset.change(
requested_at: DateTime.utc_now() |> DateTime.add(-12 * 60 * 60, :second) |> DateTime.truncate(:second)
)
|> Repo.update!()
BackupRequests.update_request_status(recent_req.id, "failed", "Recent error")
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify summary and failure warning are logged (only recent failure should be counted)
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "handles mixed statuses correctly" do
device = insert_device()
# Create requests with various statuses
{:ok, req1} = BackupRequests.create_request(device.id, "job_success")
BackupRequests.update_request_status(req1.id, "success", nil)
{:ok, req2} = BackupRequests.create_request(device.id, "job_failed")
BackupRequests.update_request_status(req2.id, "failed", "Error")
{:ok, req3} = BackupRequests.create_request(device.id, "job_timeout")
BackupRequests.update_request_status(req3.id, "timeout", "Timeout")
{:ok, _req4} = BackupRequests.create_request(device.id, "job_pending")
# Leave as pending
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify summary and failure warnings are logged
assert log =~ "Backup summary for past 24 hours"
assert log =~ "Backup failures detected"
end
test "does not log warning when all backups are successful or pending" do
device = insert_device()
# Create successful and pending requests
{:ok, req1} = BackupRequests.create_request(device.id, "job_success")
BackupRequests.update_request_status(req1.id, "success", nil)
{:ok, _req2} = BackupRequests.create_request(device.id, "job_pending")
# Leave as pending
# Execute the worker and capture logs
log =
capture_log(fn ->
assert :ok = BackupSummaryWorker.perform(%Oban.Job{args: %{}})
end)
# Verify no warning was logged
assert log =~ "Backup summary for past 24 hours"
refute log =~ "Backup failures detected"
end
end
# Helper function to create a device
defp insert_device do
user = user_fixture()
{:ok, organization} = Organizations.create_organization(%{name: "Test Org"}, user.id)
{:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: organization.id})
{:ok, device} =
Devices.create_device(%{
name: "Test Device #{System.unique_integer()}",
ip_address: "192.168.1.#{:rand.uniform(254)}",
site_id: site.id,
organization_id: organization.id
})
device
end
end