0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 20:30:23 +00:00

Silence expected test error reports from the console output

The errors are still logged by common_test to the report it creates.
The process that is going to crash has to call cowboy_error_h:ignore/3
with the MFA where the crash is expected to occur for it to be ignored.
Gun retry failures are also ignored. Only unexpected crashes are printed.
This commit is contained in:
Loïc Hoguin 2014-04-21 21:22:08 +02:00
parent 74512fc84c
commit 75218c4be0
6 changed files with 124 additions and 7 deletions

View file

@ -8,6 +8,7 @@ ERLC_OPTS ?= -Werror +debug_info +warn_export_all +warn_export_vars \
+warn_shadow_vars +warn_obsolete_guard +warn_missing_spec
COMPILE_FIRST = cowboy_middleware cowboy_sub_protocol
CT_SUITES = eunit http spdy ws
CT_OPTS += -pa test -ct_hooks cowboy_ct_hook []
PLT_APPS = crypto public_key ssl
# Dependencies.

22
test/cowboy_ct_hook.erl Normal file
View file

@ -0,0 +1,22 @@
%% Copyright (c) 2014, Loïc Hoguin <essen@ninenines.eu>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
%% copyright notice and this permission notice appear in all copies.
%%
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(cowboy_ct_hook).
-export([init/2]).
init(_, _) ->
error_logger:tty(false),
error_logger:add_report_handler(cowboy_error_h),
{ok, undefined}.

92
test/cowboy_error_h.erl Normal file
View file

@ -0,0 +1,92 @@
%% Copyright (c) 2014, Loïc Hoguin <essen@ninenines.eu>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
%% copyright notice and this permission notice appear in all copies.
%%
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(cowboy_error_h).
-behaviour(gen_event).
%% Public interface.
-export([ignore/3]).
%% gen_event.
-export([init/1]).
-export([handle_event/2]).
-export([handle_call/2]).
-export([handle_info/2]).
-export([terminate/2]).
-export([code_change/3]).
%% Public interface.
%% Ignore crashes from Pid occuring in M:F/A.
ignore(M, F, A) ->
gen_event:call(error_logger, ?MODULE, {expect, self(), M, F, A}).
%% gen_event.
init(_) ->
{ok, []}.
%% Ignore supervisor and progress reports.
handle_event({info_report, _, {_, progress, _}}, State) ->
{ok, State};
handle_event({info_report, _, {_, std_info, _}}, State) ->
{ok, State};
handle_event({error_report, _, {_, supervisor_report, _}}, State) ->
{ok, State};
%% Ignore gun retry failures.
handle_event({error_report, _, {_, crash_report,
[[{initial_call, {gun, init, _}}, _, _,
{error_info, {error, gone, _}}|_]|_]}},
State) ->
{ok, State};
%% Ignore emulator reports, they are a duplicate of what Ranch gives us.
handle_event({error, _, {emulator, _, _}}, State) ->
{ok, State};
handle_event(Event = {error, GL,
{_, "Ranch listener" ++ _, [_, _, Pid, {[_, _,
{stacktrace, [{M, F, A, _}|_]}|_], _}]}},
State) when node(GL) =:= node() ->
A2 = if is_list(A) -> length(A); true -> A end,
Crash = {Pid, M, F, A2},
case lists:member(Crash, State) of
true ->
{ok, lists:delete(Crash, State)};
false ->
write_event(Event),
{ok, State}
end;
handle_event(Event = {_, GL, _}, State) when node(GL) =:= node() ->
write_event(Event),
{ok, State};
handle_event(_, State) ->
{ok, State}.
handle_call({expect, Pid, M, F, A}, State) ->
{ok, ok, [{Pid, M, F, A}|State]};
handle_call(_, State) ->
{ok, {error, bad_query}, State}.
handle_info(_, State) ->
{ok, State}.
terminate(_, _) ->
ok.
code_change(_, State, _) ->
{ok, State}.
write_event(Event) ->
error_logger_tty_h:write_event(
{erlang:universaltime(), Event},
io).

View file

@ -9,30 +9,28 @@ init({_Transport, http}, Req, _Opts) ->
case_init(Case, Req1).
case_init(<<"init_before_reply">> = Case, _Req) ->
cowboy_error_h:ignore(?MODULE, case_init, 2),
erlang:error(Case);
case_init(<<"init_after_reply">> = Case, Req) ->
cowboy_error_h:ignore(?MODULE, case_init, 2),
{ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
erlang:error(Case);
case_init(<<"init_reply_handle_error">> = Case, Req) ->
{ok, Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
{ok, Req1, Case};
case_init(<<"handle_before_reply">> = Case, Req) ->
{ok, Req, Case};
case_init(<<"handle_after_reply">> = Case, Req) ->
{ok, Req, Case}.
handle(_Req, <<"init_reply_handle_error">> = Case) ->
cowboy_error_h:ignore(?MODULE, handle, 2),
erlang:error(Case);
handle(_Req, <<"handle_before_reply">> = Case) ->
cowboy_error_h:ignore(?MODULE, handle, 2),
erlang:error(Case);
handle(Req, <<"handle_after_reply">> = Case) ->
cowboy_error_h:ignore(?MODULE, handle, 2),
{ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
erlang:error(Case).

View file

@ -11,11 +11,13 @@ allowed_methods(Req, State) ->
{[<<"GET">>, <<"PUT">>], Req, State}.
content_types_accepted(Req, State) ->
cowboy_error_h:ignore(cowboy_rest, process_content_type, 3),
{[
{<<"application/json">>, put_application_json}
], Req, State}.
content_types_provided(Req, State) ->
cowboy_error_h:ignore(cowboy_rest, set_resp_body, 2),
{[
{<<"text/plain">>, get_text_plain}
], Req, State}.

View file

@ -18,8 +18,10 @@ generate_etag(Req, State) ->
{<<"\"etag-header-value\"">>, Req2, State};
%% Invalid return values from generate_etag/2.
{<<"binary-strong-unquoted">>, Req2} ->
cowboy_error_h:ignore(cowboy_http, quoted_string, 2),
{<<"etag-header-value">>, Req2, State};
{<<"binary-weak-unquoted">>, Req2} ->
cowboy_error_h:ignore(cowboy_http, quoted_string, 2),
{<<"W/etag-header-value">>, Req2, State}
end.