Membrane Core v0.5.0 Membrane.Testing.Pipeline View Source

This Pipeline was created to reduce testing boilerplate and ease communication with its elements. It also provides a utility for informing testing process about playback state changes and received notifications.

When you want a build Pipeline to test your elements you need three things:

  • Pipeline Module
  • List of elements
  • Links between those elements

When creating pipelines for tests the only essential part is the list of elements. In most cases during the tests, elements are linked in a way that :output pad is linked to :input pad of subsequent element. So we only need to pass a list of elements and links can be generated automatically.

To start a testing pipeline you need to build Membrane.Testing.Pipeline.Options struct and pass to Membrane.Testing.Pipeline.start_link/2. Links are generated by populate_links/1.

options = %Membrane.Testing.Pipeline.Options {
  elements: [
    el1: MembraneElement1,
    el2: MembraneElement2,
    ...
  ]
}
{:ok, pipeline} = Membrane.Testing.Pipeline.start_link(options)

If you need to pass custom links, you can always do it using :links field of Membrane.Testing.Pipeline.Options struct.

options = %Membrane.Testing.Pipeline.Options {
  elements: [
    el1: MembraneElement1,
    el2: MembraneElement2,
    ],
    links: %{
      {:el1, :output} => {:el2, :input}
    }
  }

You can also pass a custom pipeline module, by using :module field of Membrane.Testing.Pipeline.Options struct. Every callback of the module will be executed before the callbacks of Testing.Pipeline. Passed module has to return a proper spec. There should be no elements nor links specified in options passed to test pipeline as that would result in a failure.

options = %Membrane.Testing.Pipeline.Options {
    module: Your.Module
  }

See Membrane.Testing.Pipeline.Options for available options.

Assertions

This pipeline is designed to work with Membrane.Testing.Assertions. Check them out or see example below for more details.

Messaging children

You can send messages to children using their names specified in the elements list. Please check message_child/3 for more details.

Example usage

Firstly, we can start the pipeline providing its options:

options = %Membrane.Testing.Pipeline.Options {
  elements: [
    source: %Membrane.Testing.Source{},
    tested_element: TestedElement,
    sink: %Membrane.Testing.Sink{}
  ]
}
{:ok, pipeline} = Membrane.Testing.Pipeline.start_link(options)

We can now wait till the end of the stream reaches the sink element (don't forget to import Membrane.Testing.Assertions):

assert_end_of_stream(pipeline, :sink)

We can also assert that the Membrane.Testing.Sink processed a specific buffer:

assert_sink_buffer(pipeline, :sink, %Membrane.Buffer{payload: 1})

Link to this section Summary

Functions

Sends message to a child by Element name.

Changes playback state of pipeline to :playing

Links subsequent elements using default pads (linking :input to :output of previous element).

Changes playback state to :prepared.

Starts the pipeline Membrane.Testing.Pipeline without linking it to the current process.

Starts the pipeline Membrane.Testing.Pipeline and links it to the current process.

Changes playback state to :stopped.

Changes pipeline's playback state to :stopped and terminates its process.

Link to this section Functions

Link to this function

message_child(pipeline, child, message)

View Source
message_child(pid(), Membrane.Element.name_t(), any()) :: :ok

Sends message to a child by Element name.

Example

Knowing that pipeline has child named sink, message can be sent as follows:

message_child(pipeline, :sink, {:message, "to handle"})
Link to this function

play(pipeline)

View Source
play(pid()) :: :ok

Changes playback state of pipeline to :playing

A proxy for Membrane.Pipeline.play/1

Links subsequent elements using default pads (linking :input to :output of previous element).

Example

iex> Pipeline.populate_links([el1: MembraneElement1, el2: MembraneElement2])
%{{:el1, :output} => {:el2, :input}}
Link to this function

prepare(pipeline)

View Source
prepare(pid()) :: :ok

Changes playback state to :prepared.

A proxy for Membrane.Pipeline.prepare/1

Link to this function

start(pipeline_options \\ nil, process_options \\ [])

View Source
start(
  pipeline_options :: Membrane.Pipeline.pipeline_options_t(),
  process_options :: GenServer.options()
) :: GenServer.on_start()

Starts the pipeline Membrane.Testing.Pipeline without linking it to the current process.

A proxy for Membrane.Pipeline.start/3

Link to this function

start_link(pipeline_options \\ nil, process_options \\ [])

View Source
start_link(
  pipeline_options :: Membrane.Pipeline.pipeline_options_t(),
  process_options :: GenServer.options()
) :: GenServer.on_start()

Starts the pipeline Membrane.Testing.Pipeline and links it to the current process.

A proxy for Membrane.Pipeline.start_link/3

Changes playback state to :stopped.

A proxy for Membrane.Pipeline.stop/1

Link to this function

stop_and_terminate(pipeline)

View Source
stop_and_terminate(pid()) :: :ok

Changes pipeline's playback state to :stopped and terminates its process.

A proxy for Membrane.Pipeline.stop_and_terminate/1