232 lines
7.5 KiB
Elixir
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
|