|
| 1 | +%%%------------------------------------------------------------------- |
| 2 | +%% @doc Functions for testing execution of Telemetry events. |
| 3 | +%% |
| 4 | +%% Testing that the correct Telemetry events are emitted with the |
| 5 | +%% right measurements and metadata is essential for library authors. |
| 6 | +%% It helps to maintain stable APIs and avoid accidental changes |
| 7 | +%% to events. |
| 8 | +%% @end |
| 9 | +%%%------------------------------------------------------------------- |
| 10 | + |
| 11 | +-module(telemetry_test). |
| 12 | + |
| 13 | +-export([attach_event_handlers/2]). |
| 14 | + |
| 15 | +%% @doc Attaches a "message" handler to the given events. |
| 16 | +%% |
| 17 | +%% The attached handler sends a message to `destination_pid` every time it handles one of the |
| 18 | +%% events in `events`. The function returns a reference that you can use to make sure that |
| 19 | +%% messages come from this handler. This reference is also used as the handler ID, so you |
| 20 | +%% can use it to detach the handler with {link telemetry:detach/1}. |
| 21 | +%% |
| 22 | +%% The shape of messages sent to `destination_pid` is: |
| 23 | +%% |
| 24 | +%% ``` |
| 25 | +%% {Event, Ref, Measurements, Metadata} |
| 26 | +%% ''' |
| 27 | +%% |
| 28 | +%% For example, in Erlang a test could look like this: |
| 29 | +%% |
| 30 | +%% ``` |
| 31 | +%% Ref = telemetry_test:attach_event_handlers(self(), [[some, event]]), |
| 32 | +%% function_that_emits_the_event(), |
| 33 | +%% receive |
| 34 | +%% {[some, event], Ref, #{measurement := _}, #{meta := _}} -> |
| 35 | +%% telemetry:detach(Ref) |
| 36 | +%% after 1000 -> |
| 37 | +%% ct:fail(timeout_receive_attach_event_handlers) |
| 38 | +%% end. |
| 39 | +%% ''' |
| 40 | +%% |
| 41 | +%% In Elixir, a similar test would look like this: |
| 42 | +%% |
| 43 | +%% ``` |
| 44 | +%% ref = :telemetry.attach_event_handlers(self(), [[:some, :event]]) |
| 45 | +%% function_that_emits_the_event() |
| 46 | +%% assert_received {[:some, :event], ^ref, %{measurement: _}, %{meta: _}} |
| 47 | +%% ''' |
| 48 | +%% |
| 49 | +-spec attach_event_handlers(DestinationPID, Events) -> reference() when |
| 50 | + DestinationPID :: pid(), |
| 51 | + Events :: [telemetry:event_name(), ...]. |
| 52 | +attach_event_handlers(DestPID, Events) when is_pid(DestPID) and is_list(Events) -> |
| 53 | + Ref = make_ref(), |
| 54 | + Config = #{dest_pid => DestPID, ref => Ref}, |
| 55 | + telemetry:attach_many(Ref, Events, fun handle_event/4, Config), |
| 56 | + Ref. |
| 57 | + |
| 58 | +handle_event(Event, Measurements, Metadata, #{dest_pid := DestPID, ref := Ref}) -> |
| 59 | + DestPID ! {Event, Ref, Measurements, Metadata}. |
0 commit comments