From da304799fee8ac93ce83d9349bb8128af3985671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 3 Nov 2017 17:52:18 +0000 Subject: Add a terminate event to the tracer and more tests --- src/cowboy_tracer_h.erl | 14 ++++++++---- test/tracer_SUITE.erl | 61 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/cowboy_tracer_h.erl b/src/cowboy_tracer_h.erl index 1f054e3..b69faf4 100644 --- a/src/cowboy_tracer_h.erl +++ b/src/cowboy_tracer_h.erl @@ -80,7 +80,7 @@ init_tracer(StreamID, Req, Opts=#{tracer_match_specs := List, tracer_callback := start_tracer(StreamID, Req, Opts) end; %% When the options tracer_match_specs or tracer_callback -%% arenot provided we do not enable tracing. +%% are not provided we do not enable tracing. init_tracer(_, _, _) -> no_tracing. @@ -138,6 +138,8 @@ start_tracer(StreamID, Req, Opts) -> -spec tracer_process(_, _, _) -> no_return(). tracer_process(StreamID, Req=#{pid := Parent}, Opts=#{tracer_callback := Fun}) -> + %% This is necessary because otherwise the tracer could stop + %% before it has finished processing the events in its queue. process_flag(trap_exit, true), State = Fun(init, {StreamID, Req, Opts}), tracer_loop(Parent, Fun, State). @@ -148,7 +150,7 @@ tracer_loop(Parent, Fun, State) -> Fun(Msg, State), tracer_loop(Parent, Fun, State); {'EXIT', Parent, Reason} -> - exit(Reason); + tracer_terminate(Reason, Fun, State); {system, From, Request} -> sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {Fun, State}); Msg -> @@ -157,6 +159,10 @@ tracer_loop(Parent, Fun, State) -> tracer_loop(Parent, Fun, State) end. +tracer_terminate(Reason, Fun, State) -> + _ = Fun(terminate, State), + exit(Reason). + %% System callbacks. -spec system_continue(pid(), _, {fun(), any()}) -> no_return(). @@ -164,8 +170,8 @@ system_continue(Parent, _, {Fun, State}) -> tracer_loop(Parent, Fun, State). -spec system_terminate(any(), _, _, _) -> no_return(). -system_terminate(Reason, _, _, _) -> - exit(Reason). +system_terminate(Reason, _, _, {Fun, State}) -> + tracer_terminate(Reason, Fun, State). -spec system_code_change(Misc, _, _, _) -> {ok, Misc} when Misc::any(). system_code_change(Misc, _, _, _) -> diff --git a/test/tracer_SUITE.erl b/test/tracer_SUITE.erl index 40ede6c..6f83fd3 100644 --- a/test/tracer_SUITE.erl +++ b/test/tracer_SUITE.erl @@ -93,16 +93,69 @@ do_get(Path, Config) -> {ok, _Body} = gun:await_body(ConnPid, Ref), gun:close(ConnPid). -%% We only care about cowboy_req:reply/4 calls. +%% We only care about cowboy_req:reply/4 calls and init/terminate events. do_tracer_callback(Pid) -> fun - (init, _) -> undefined; - (Event={trace_ts, _, call, {cowboy_req, reply, _}, _}, State) -> Pid ! Event, State; - (_, State) -> State + (Event, _) when Event =:= init; Event =:= terminate -> + Pid ! Event, + undefined; + (Event={trace_ts, _, call, {cowboy_req, reply, _}, _}, State) -> + Pid ! Event, + State; + (_, State) -> + State end. %% Tests. +init(Config) -> + doc("Ensure the init event is triggered."), + Ref = config(ref, Config), + Opts = ranch:get_protocol_options(Ref), + ranch:set_protocol_options(Ref, Opts#{ + tracer_callback => do_tracer_callback(self()), + tracer_match_specs => [fun(_,_,_) -> true end] + }), + do_get("/", Config), + receive + init -> + ok + after 100 -> + error(timeout) + end. + +terminate(Config) -> + doc("Ensure the terminate event is triggered."), + Ref = config(ref, Config), + Opts = ranch:get_protocol_options(Ref), + ranch:set_protocol_options(Ref, Opts#{ + tracer_callback => do_tracer_callback(self()), + tracer_match_specs => [fun(_,_,_) -> true end] + }), + do_get("/", Config), + receive + terminate -> + ok + after 100 -> + error(timeout) + end. + +empty(Config) -> + doc("Empty match specs unconditionally enable tracing."), + Ref = config(ref, Config), + Opts = ranch:get_protocol_options(Ref), + ranch:set_protocol_options(Ref, Opts#{ + tracer_callback => do_tracer_callback(self()), + tracer_match_specs => [] + }), + do_get("/", Config), + receive + {trace_ts, _, call, {cowboy_req, reply, [200, _, _, _]}, _} -> + ok + after 100 -> + error(timeout) + end. + predicate_true(Config) -> doc("Predicate function returns true, unconditionally enable tracing."), Ref = config(ref, Config), -- cgit v1.2.3