Skip to content

Commit

Permalink
Renamespaced testing generic testing utilities.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hajto committed Dec 7, 2018
1 parent e5ed6d6 commit be19a96
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 150 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ erl_crash.dump
.LSOverride

# Icon must end with two \r
Icon
Icon

# Thumbnails
._*
Expand Down Expand Up @@ -127,7 +127,6 @@ tags
!.vscode/launch.json
!.vscode/extensions.json
.history
.vscode/settings.json

### Windows ###
# Windows thumbnail cache files
Expand Down
102 changes: 0 additions & 102 deletions lib/membrane/integration/testing_configurable_pipeline.ex

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
defmodule Membrane.Element.TestingDataSource do
defmodule Membrane.Testing.DataSource do
@moduledoc """
Testing Element for suplying data from Enumerable passed through options.
Testing Element for supplying data from list passed through options.
"""

use Membrane.Element.Base.Source

alias Membrane.{Buffer, Event}

def_options data: [
type: :buffers
type: :payloads,
spec: [Membrane.Payload.t()]
]

def_output_pads output: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Membrane.Support.TestingEvent do
defmodule Membrane.Testing.Event do
@derive Membrane.EventProtocol
defstruct []
end
143 changes: 143 additions & 0 deletions lib/membrane/testing/pipeline.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
defmodule Membrane.Testing.Pipeline do
@moduledoc """
Provides a testing utility pipeline which can be easily configured from test.
"""

use Membrane.Pipeline

alias Membrane.Element
alias Membrane.Pipeline.Spec

defmodule Options do
@moduledoc """
Structure representing `options` passed to testing pipeline.
## Monitored Callbacks
List of callback names that shall be sent to process in `test_process` field
## Test Process
`pid` of process that shall receive messages about Pipeline state.
## Elements
List of element specs.
## Links
If links is not present or set to nil it will be populated automatically based on elements order using default pad names.
"""

@enforce_keys [:elements, :test_process]
defstruct @enforce_keys ++ [:monitored_callbacks, :links]

@type pipeline_callback ::
:handle_notification
| :handle_playing_to_prepared
| :handle_prepared_to_playing
| :handle_prepared_to_stopped
| :handle_stopped_to_prepared

@type t :: %__MODULE__{
monitored_callbacks: pipeline_callback(),
test_process: pid(),
elements: Spec.children_spec_t(),
links: Spec.links_spec_t()
}
end

@doc """
Links subsequent elements using default pads (linking `:input` to `:output` of previous element).
## Examples
iex> Pipeline.populate_links([el1: MembraneElement1, el2: MembraneElement2], :my_pid)
%{{:output, :el1} => {:input, :el2}}
"""
@spec populate_links(elements :: Spec.children_spec_t()) :: Spec.links_spec_t()
def populate_links(elements) do
[first_name | element_names] = Enum.map(elements, fn {name, _} -> name end)

{links, _} =
Enum.reduce(element_names, {%{}, first_name}, fn x, {links, previous_element} ->
links = Map.put(links, {:output, previous_element}, {:input, x})
{links, x}
end)

links
end

@doc """
Sends message to a child by Element name.
## Examples
message_child(pipeline, :sink, {:message, "to handle"})
"""
@spec message_child(pid(), Element.name_t(), any()) :: :ok
def message_child(pipeline, child, message) do
send(pipeline, {:for_element, child, message})
:ok
end

@impl true
def handle_init(options)

def handle_init(%Options{monitored_callbacks: nil} = options),
do: handle_init(%Options{options | monitored_callbacks: []})

def handle_init(%Options{links: nil, elements: elements} = options) do
new_links = populate_links(elements)
%Options{options | links: new_links}
end

def handle_init(args) do
%Options{elements: elements, links: links} = args

spec = %Membrane.Pipeline.Spec{
children: elements,
links: links
}

new_state = Map.take(args, [:monitored_callbacks, :test_process])
{{:ok, spec}, new_state}
end

@impl true
def handle_stopped_to_prepared(state),
do: notify_parent(:handle_stopped_to_prepared, state)

@impl true
def handle_playing_to_prepared(state),
do: notify_parent(:handle_playing_to_prepared, state)

@impl true
def handle_prepared_to_playing(state),
do: notify_parent(:handle_prepared_to_playing, state)

@impl true
def handle_prepared_to_stopped(state),
do: notify_parent(:handle_prepared_to_stopped, state)

@impl true
def handle_notification(notification, from, state),
do: notify_parent({:handle_notification, {notification, from}}, state)

@impl true
def handle_other({:for_element, element, message}, state) do
{{:ok, forward: {element, message}}, state}
end

def handle_other(message, state),
do: notify_parent({:handle_other, message}, state)

defp get_callback_name(name) when is_atom(name), do: name
defp get_callback_name({name, _}), do: name

defp notify_parent(message, state) do
%{test_process: parent, monitored_callbacks: monitored_callbacks} = state

if get_callback_name(message) in monitored_callbacks do
send(parent, {__MODULE__, message})
end

{:ok, state}
end
end
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
defmodule Membrane.Integration.TestingConfigurablePipeline.Assertions do
defmodule Membrane.Testing.Pipeline.Assertions do
@doc """
Asserts that a message matching `pattern` was or is going to be received
within the `timeout` period, specified in milliseconds.
The `pattern` argument must be a match pattern. Flunks with `failure_message`
if a message matching `pattern` is not received.
"""
defmacro receive_message(
defmacro assert_receive_message(
pattern,
timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout),
failure_message \\ nil
) do
import ExUnit.Assertions, only: [assert_receive: 1]

quote do
assert_receive {Membrane.Integration.TestingConfigurable.Pipeline, unquote(pattern)},
assert_receive {Membrane.Testing.Pipeline, unquote(pattern)},
unquote(timeout),
unquote(failure_message)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
defmodule Membrane.Integration.TestingSink do
defmodule Membrane.Testing.Sink do
@moduledoc """
Sink Element that will send every buffer it receive to pid passed as argument.
Sink Element that will send every buffer it receives to pid passed as argument.
"""

use Membrane.Element.Base.Sink

def_input_pads input: [demand_unit: :buffers, caps: :any]
Expand All @@ -14,7 +15,7 @@ defmodule Membrane.Integration.TestingSink do
type: :boolean,
default: true,
description:
"If true element will automatically place demands, otherwise it will be triggered by `:make_demand` message."
"If true element will automatically place demands. If it is set to false demand has to be triggered manually by sending `:make_demand` message."
]

@impl true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
defmodule Membrane.Integration.TestingSource do
defmodule Membrane.Testing.Source do
@moduledoc """
Testing Element for suplying data based on generator function passed through options.
Generator function must take two arguments (`counter` and `size`) and return buffer with payload of size `size`.
Testing Element for supplying data based on generator function passed through options.
"""

use Membrane.Element.Base.Source
alias Membrane.Buffer
use Bunch
Expand All @@ -13,7 +12,9 @@ defmodule Membrane.Integration.TestingSource do
def_options actions_generator: [
type: :function,
spec: (non_neg_integer, non_neg_integer -> [Membrane.Action.t()]),
default: &__MODULE__.default_buf_gen/2
default: &__MODULE__.default_buf_gen/2,
description:
"Action generator takes two arguments. First is counter which is incremented by 1 every call and second argument represents size of demand."
]

@impl true
Expand All @@ -22,13 +23,7 @@ defmodule Membrane.Integration.TestingSource do
end

@impl true
def handle_demand(
:output,
size,
:buffers,
_ctx,
%{cnt: cnt} = state
) do
def handle_demand(:output, size, :buffers, _ctx, %{cnt: cnt} = state) do
{actions, cnt} = state.actions_generator.(cnt, size)

{{:ok, actions}, %{state | cnt: cnt}}
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ defmodule Membrane.Mixfile do
{:espec, "~> 1.6", only: :test},
{:excoveralls, "~> 0.8", only: :test},
{:qex, "~> 0.3"},
{:bunch, "~> 0.1.2"}
{:bunch, "~> 0.1.2"},
{:dialyxir, "~> 1.0.0-rc.4", only: [:dev], runtime: false}
]
end
end
2 changes: 2 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
%{
"bunch": {:hex, :bunch, "0.1.2", "2389a4bcdb62382fbfeed9e19952cc22452dc0c01b4bcac941cce00ef212d7b4", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.4", "71b42f5ee1b7628f3e3a6565f4617dfb02d127a0499ab3e72750455e986df001", [:mix], [{:erlex, "~> 0.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
"erlex": {:hex, :erlex, "0.1.6", "c01c889363168d3fdd23f4211647d8a34c0f9a21ec726762312e08e083f3d47e", [:mix], [], "hexpm"},
"espec": {:hex, :espec, "1.6.3", "d9355788e508b82743a1b1b9aa5ac64ba37b0547c6210328d909e8a6eb56d42e", [:mix], [{:meck, "0.8.12", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.10.2", "fb4abd5b8a1b9d52d35e1162e7e2ea8bfb84b47ae07c38d39aa8ce64be0b0794", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
Expand Down
Loading

0 comments on commit be19a96

Please sign in to comment.