Skip to content

Commit

Permalink
mock resource guard
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-hek committed Nov 17, 2022
1 parent a37d3e4 commit 5524166
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 6 deletions.
79 changes: 75 additions & 4 deletions lib/membrane/testing/assertions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,50 @@ defmodule Membrane.Testing.Assertions do

@default_timeout 2000

defp do_assert_receive_from_pipeline(assertion, pid, pattern, timeout, failure_message) do
defp assert_receive_from_entity(assertion, entity, pid, pattern, timeout, failure_message) do
quote do
import ExUnit.Assertions
pid_value = unquote(pid)

unquote(assertion)(
{Membrane.Testing.Pipeline, ^pid_value, unquote(pattern)},
{unquote(entity), ^pid_value, unquote(pattern)},
unquote(timeout),
unquote(failure_message)
)
end
end

defp assert_receive_from_pipeline(pid, pattern, timeout, failure_message \\ nil) do
do_assert_receive_from_pipeline(:assert_receive, pid, pattern, timeout, failure_message)
assert_receive_from_entity(
:assert_receive,
Membrane.Testing.Pipeline,
pid,
pattern,
timeout,
failure_message
)
end

defp refute_receive_from_pipeline(pid, pattern, timeout, failure_message \\ nil) do
do_assert_receive_from_pipeline(:refute_receive, pid, pattern, timeout, failure_message)
assert_receive_from_entity(
:refute_receive,
Membrane.Testing.Pipeline,
pid,
pattern,
timeout,
failure_message
)
end

defp assert_receive_from_resource_guard(pid, pattern, timeout, failure_message \\ nil) do
assert_receive_from_entity(
:assert_receive,
Membrane.Testing.MockResourceGuard,
pid,
pattern,
timeout,
failure_message
)
end

@doc """
Expand Down Expand Up @@ -423,4 +448,50 @@ defmodule Membrane.Testing.Assertions do
timeout
)
end

@doc """
Asserts that a cleanup function was registered in `Membrane.Testing.MockResourceGuard`.
"""
defmacro assert_resource_guard_register(
mock_guard,
function,
tag,
timeout \\ @default_timeout
) do
assert_receive_from_resource_guard(
mock_guard,
{:register, {function, tag}},
timeout
)
end

@doc """
Asserts that a tag was unregistered in `Membrane.Testing.MockResourceGuard`.
"""
defmacro assert_resource_guard_unregister(
mock_guard,
tag,
timeout \\ @default_timeout
) do
assert_receive_from_resource_guard(
mock_guard,
{:cleanup, tag},
timeout
)
end

@doc """
Asserts that `Membrane.Testing.MockResourceGuard` was requested to cleanup a given tag.
"""
defmacro assert_resource_guard_cleanup(
mock_guard,
tag,
timeout \\ @default_timeout
) do
assert_receive_from_resource_guard(
mock_guard,
{:cleanup, tag},
timeout
)
end
end
73 changes: 73 additions & 0 deletions lib/membrane/testing/mock_resource_guard.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
defmodule Membrane.Testing.MockResourceGuard do
@moduledoc """
Mock for `Membrane.ResourceGuard`.
Informs the test process about registered cleanup functions and tags.
Works with `Membrane.Testing.Assertions`, for example
`Membrane.Testing.Assertions.assert_resource_guard_register/4`:
iex> guard = #{inspect(__MODULE__)}.start_link_supervised!()
...> Membrane.ResourceGuard.register(guard, fn -> :abc end, tag: :some_tag)
...> import Membrane.Testing.Assertions
...> assert_resource_guard_register(guard, function, :some_tag)
...> function.()
:abc
"""
use GenServer

require Membrane.Core.Message, as: Message

@type options :: [test_process: pid]

@spec child_spec(test_process: pid()) :: Supervisor.child_spec()
def child_spec(options) do
super(options) |> Map.merge(%{restart: :transient, id: {__MODULE__, make_ref()}})
end

@spec start_link(options) :: {:ok, pid}
def start_link(options \\ []) do
options = Keyword.put_new(options, :test_process, self())
GenServer.start_link(__MODULE__, options)
end

@spec start_link_supervised!(options) :: pid
def start_link_supervised!(options \\ []) do
options = Keyword.put_new(options, :test_process, self())
{:ok, pid} = ex_unit_start_supervised({__MODULE__, options})
pid
end

@impl true
def init(options) do
{:ok, Map.new(options)}
end

@impl true
def handle_info(Message.new(:register, [function, options]), state) do
tag = Keyword.fetch!(options, :tag)
send_to_test_process(state, :register, {function, tag})
{:noreply, state}
end

@impl true
def handle_info(Message.new(:unregister, tag), state) do
send_to_test_process(state, :unregister, tag)
{:noreply, state}
end

@impl true
def handle_info(Message.new(:cleanup, tag), state) do
send_to_test_process(state, :cleanup, tag)
{:noreply, state}
end

defp ex_unit_start_supervised(child_spec) do
# It's not a 'normal' call to keep dialyzer quiet
apply(ExUnit.Callbacks, :start_supervised, [child_spec])
end

defp send_to_test_process(%{test_process: test_process}, type, args) do
send(test_process, {__MODULE__, self(), {type, args}})
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ defmodule Membrane.Mixfile do
[
{:qex, "~> 0.3"},
{:telemetry, "~> 1.0"},
{:bunch, github: "membraneframework/bunch", branch: "config-require"},
{:bunch, github: "membraneframework/bunch"},
{:ratio, "~> 2.0"},
# Development
{:ex_doc, "~> 0.28", only: :dev, runtime: false},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%{
"bunch": {:git, "https://github.com/membraneframework/bunch.git", "d86e7ca7d26e434d9c5d28b6a1cb662eaa48ac5f", [branch: "config-require"]},
"bunch": {:git, "https://github.com/membraneframework/bunch.git", "179707e46972afee21c8e9b57805df4a9b66d708", []},
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"},
Expand Down
5 changes: 5 additions & 0 deletions test/membrane/testing/mock_resource_guard_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule Membrane.Testing.MockResourceGuardTest do
use ExUnit.Case

doctest Membrane.Testing.MockResourceGuard
end

0 comments on commit 5524166

Please sign in to comment.