mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +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:
parent
74512fc84c
commit
75218c4be0
6 changed files with 124 additions and 7 deletions
1
Makefile
1
Makefile
|
@ -8,6 +8,7 @@ ERLC_OPTS ?= -Werror +debug_info +warn_export_all +warn_export_vars \
|
||||||
+warn_shadow_vars +warn_obsolete_guard +warn_missing_spec
|
+warn_shadow_vars +warn_obsolete_guard +warn_missing_spec
|
||||||
COMPILE_FIRST = cowboy_middleware cowboy_sub_protocol
|
COMPILE_FIRST = cowboy_middleware cowboy_sub_protocol
|
||||||
CT_SUITES = eunit http spdy ws
|
CT_SUITES = eunit http spdy ws
|
||||||
|
CT_OPTS += -pa test -ct_hooks cowboy_ct_hook []
|
||||||
PLT_APPS = crypto public_key ssl
|
PLT_APPS = crypto public_key ssl
|
||||||
|
|
||||||
# Dependencies.
|
# Dependencies.
|
||||||
|
|
22
test/cowboy_ct_hook.erl
Normal file
22
test/cowboy_ct_hook.erl
Normal 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
92
test/cowboy_error_h.erl
Normal 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).
|
|
@ -9,30 +9,28 @@ init({_Transport, http}, Req, _Opts) ->
|
||||||
case_init(Case, Req1).
|
case_init(Case, Req1).
|
||||||
|
|
||||||
case_init(<<"init_before_reply">> = Case, _Req) ->
|
case_init(<<"init_before_reply">> = Case, _Req) ->
|
||||||
|
cowboy_error_h:ignore(?MODULE, case_init, 2),
|
||||||
erlang:error(Case);
|
erlang:error(Case);
|
||||||
|
|
||||||
case_init(<<"init_after_reply">> = Case, Req) ->
|
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),
|
{ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
|
||||||
erlang:error(Case);
|
erlang:error(Case);
|
||||||
|
|
||||||
case_init(<<"init_reply_handle_error">> = Case, Req) ->
|
case_init(<<"init_reply_handle_error">> = Case, Req) ->
|
||||||
{ok, Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
|
{ok, Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
|
||||||
{ok, Req1, Case};
|
{ok, Req1, Case};
|
||||||
|
|
||||||
case_init(<<"handle_before_reply">> = Case, Req) ->
|
case_init(<<"handle_before_reply">> = Case, Req) ->
|
||||||
{ok, Req, Case};
|
{ok, Req, Case};
|
||||||
|
|
||||||
case_init(<<"handle_after_reply">> = Case, Req) ->
|
case_init(<<"handle_after_reply">> = Case, Req) ->
|
||||||
{ok, Req, Case}.
|
{ok, Req, Case}.
|
||||||
|
|
||||||
|
|
||||||
handle(_Req, <<"init_reply_handle_error">> = Case) ->
|
handle(_Req, <<"init_reply_handle_error">> = Case) ->
|
||||||
|
cowboy_error_h:ignore(?MODULE, handle, 2),
|
||||||
erlang:error(Case);
|
erlang:error(Case);
|
||||||
|
|
||||||
handle(_Req, <<"handle_before_reply">> = Case) ->
|
handle(_Req, <<"handle_before_reply">> = Case) ->
|
||||||
|
cowboy_error_h:ignore(?MODULE, handle, 2),
|
||||||
erlang:error(Case);
|
erlang:error(Case);
|
||||||
|
|
||||||
handle(Req, <<"handle_after_reply">> = Case) ->
|
handle(Req, <<"handle_after_reply">> = Case) ->
|
||||||
|
cowboy_error_h:ignore(?MODULE, handle, 2),
|
||||||
{ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
|
{ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req),
|
||||||
erlang:error(Case).
|
erlang:error(Case).
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@ allowed_methods(Req, State) ->
|
||||||
{[<<"GET">>, <<"PUT">>], Req, State}.
|
{[<<"GET">>, <<"PUT">>], Req, State}.
|
||||||
|
|
||||||
content_types_accepted(Req, State) ->
|
content_types_accepted(Req, State) ->
|
||||||
|
cowboy_error_h:ignore(cowboy_rest, process_content_type, 3),
|
||||||
{[
|
{[
|
||||||
{<<"application/json">>, put_application_json}
|
{<<"application/json">>, put_application_json}
|
||||||
], Req, State}.
|
], Req, State}.
|
||||||
|
|
||||||
content_types_provided(Req, State) ->
|
content_types_provided(Req, State) ->
|
||||||
|
cowboy_error_h:ignore(cowboy_rest, set_resp_body, 2),
|
||||||
{[
|
{[
|
||||||
{<<"text/plain">>, get_text_plain}
|
{<<"text/plain">>, get_text_plain}
|
||||||
], Req, State}.
|
], Req, State}.
|
||||||
|
|
|
@ -18,8 +18,10 @@ generate_etag(Req, State) ->
|
||||||
{<<"\"etag-header-value\"">>, Req2, State};
|
{<<"\"etag-header-value\"">>, Req2, State};
|
||||||
%% Invalid return values from generate_etag/2.
|
%% Invalid return values from generate_etag/2.
|
||||||
{<<"binary-strong-unquoted">>, Req2} ->
|
{<<"binary-strong-unquoted">>, Req2} ->
|
||||||
|
cowboy_error_h:ignore(cowboy_http, quoted_string, 2),
|
||||||
{<<"etag-header-value">>, Req2, State};
|
{<<"etag-header-value">>, Req2, State};
|
||||||
{<<"binary-weak-unquoted">>, Req2} ->
|
{<<"binary-weak-unquoted">>, Req2} ->
|
||||||
|
cowboy_error_h:ignore(cowboy_http, quoted_string, 2),
|
||||||
{<<"W/etag-header-value">>, Req2, State}
|
{<<"W/etag-header-value">>, Req2, State}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue