Backup Tests: Split out async tests, use mox.

This commit is contained in:
Lain Soykaf 2023-12-10 18:57:46 +04:00
parent 20b76acc08
commit c068a218ea
4 changed files with 95 additions and 20 deletions

View file

@ -145,6 +145,8 @@ config :pleroma, :config_impl, Pleroma.UnstubbedConfigMock
config :pleroma, Pleroma.PromEx, disabled: true config :pleroma, Pleroma.PromEx, disabled: true
config Pleroma.User.Backup, :config_impl, Pleroma.UnstubbedConfigMock
if File.exists?("./config/test.secret.exs") do if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs" import_config "test.secret.exs"
else else

View file

@ -35,6 +35,8 @@ defmodule Pleroma.User.Backup do
timestamps() timestamps()
end end
@config_impl Application.compile_env(__MODULE__, :config_impl, Pleroma.Config)
def create(user, admin_id \\ nil) do def create(user, admin_id \\ nil) do
with :ok <- validate_limit(user, admin_id), with :ok <- validate_limit(user, admin_id),
{:ok, backup} <- user |> new() |> Repo.insert() do {:ok, backup} <- user |> new() |> Repo.insert() do
@ -124,7 +126,10 @@ defmodule Pleroma.User.Backup do
|> Repo.update() |> Repo.update()
end end
def process(%__MODULE__{} = backup) do def process(
%__MODULE__{} = backup,
processor_module \\ __MODULE__.Processor
) do
set_state(backup, :running, 0) set_state(backup, :running, 0)
current_pid = self() current_pid = self()
@ -132,7 +137,7 @@ defmodule Pleroma.User.Backup do
task = task =
Task.Supervisor.async_nolink( Task.Supervisor.async_nolink(
Pleroma.TaskSupervisor, Pleroma.TaskSupervisor,
__MODULE__, processor_module,
:do_process, :do_process,
[backup, current_pid] [backup, current_pid]
) )
@ -140,25 +145,8 @@ defmodule Pleroma.User.Backup do
wait_backup(backup, backup.processed_number, task) wait_backup(backup, backup.processed_number, task)
end end
def do_process(backup, current_pid) do
with {:ok, zip_file} <- export(backup, current_pid),
{:ok, %{size: size}} <- File.stat(zip_file),
{:ok, _upload} <- upload(backup, zip_file) do
backup
|> cast(
%{
file_size: size,
processed: true,
state: :complete
},
[:file_size, :processed, :state]
)
|> Repo.update()
end
end
defp wait_backup(backup, current_processed, task) do defp wait_backup(backup, current_processed, task) do
wait_time = Pleroma.Config.get([__MODULE__, :process_wait_time]) wait_time = @config_impl.get([__MODULE__, :process_wait_time])
receive do receive do
{:progress, new_processed} -> {:progress, new_processed} ->
@ -365,3 +353,35 @@ defmodule Pleroma.User.Backup do
) )
end end
end end
defmodule Pleroma.User.Backup.ProcessorAPI do
@callback do_process(%Pleroma.User.Backup{}, pid()) ::
{:ok, %Pleroma.User.Backup{}} | {:error, any()}
end
defmodule Pleroma.User.Backup.Processor do
@behaviour Pleroma.User.Backup.ProcessorAPI
alias Pleroma.Repo
alias Pleroma.User.Backup
import Ecto.Changeset
@impl true
def do_process(backup, current_pid) do
with {:ok, zip_file} <- Backup.export(backup, current_pid),
{:ok, %{size: size}} <- File.stat(zip_file),
{:ok, _upload} <- Backup.upload(backup, zip_file) do
backup
|> cast(
%{
file_size: size,
processed: true,
state: :complete
},
[:file_size, :processed, :state]
)
|> Repo.update()
end
end
end

View file

@ -0,0 +1,51 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.BackupAsyncTest do
use Pleroma.DataCase, async: true
import Pleroma.Factory
import Mox
alias Pleroma.User.Backup
alias Pleroma.User.Backup.ProcessorMock
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
setup do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
{:ok, backup} = user |> Backup.new() |> Repo.insert()
%{backup: backup}
end
@tag capture_log: true
test "it handles unrecoverable exceptions", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
raise "mock exception"
end)
ConfigMock
|> stub_with(Pleroma.Config)
{:error, %{backup: backup, reason: :exit}} = Backup.process(backup, ProcessorMock)
assert backup.state == :failed
end
@tag capture_log: true
test "it handles timeouts", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
Process.sleep(:timer.seconds(4))
end)
ConfigMock
|> expect(:get, fn [Pleroma.User.Backup, :process_wait_time] -> :timer.seconds(2) end)
{:error, %{backup: backup, reason: :timeout}} = Backup.process(backup, ProcessorMock)
assert backup.state == :failed
end
end

View file

@ -29,3 +29,5 @@ Mox.defmock(Pleroma.ConfigMock, for: Pleroma.Config.Getting)
Mox.defmock(Pleroma.UnstubbedConfigMock, for: Pleroma.Config.Getting) Mox.defmock(Pleroma.UnstubbedConfigMock, for: Pleroma.Config.Getting)
Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging) Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)
Mox.defmock(Pleroma.User.Backup.ProcessorMock, for: Pleroma.User.Backup.ProcessorAPI)