aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-07-22 16:17:10 +0200
committerLoïc Hoguin <[email protected]>2019-07-22 16:17:10 +0200
commit516933f9dd2722329b3886c495d5242308958fe1 (patch)
tree60b16423184a4db405a65266c326b7944ce42256 /test
parent265ece680c53f77d1685434d0636216c94021497 (diff)
downloadgun-516933f9dd2722329b3886c495d5242308958fe1.tar.gz
gun-516933f9dd2722329b3886c495d5242308958fe1.tar.bz2
gun-516933f9dd2722329b3886c495d5242308958fe1.zip
Split domain lookup/connect/TLS handshake and add events
This changes the way we connect to servers entirely. We now have three states when connecting (domain_lookup, connect and tls_handshake when applicable) and as a result three corresponding timeout options. Each state has a start/end event associated and the event data was tweaked to best match each event. Since the TLS handshake is separate, the transport_opts option was also split into two: tcp_opts and tls_opts.
Diffstat (limited to 'test')
-rw-r--r--test/event_SUITE.erl183
-rw-r--r--test/gun_SUITE.erl30
2 files changed, 183 insertions, 30 deletions
diff --git a/test/event_SUITE.erl b/test/event_SUITE.erl
index 5f56b27..f7cae4e 100644
--- a/test/event_SUITE.erl
+++ b/test/event_SUITE.erl
@@ -38,7 +38,7 @@ groups() ->
].
init_per_suite(Config) ->
- {ok, _} = cowboy:start_clear(?MODULE, [], #{env => #{
+ ProtoOpts = #{env => #{
dispatch => cowboy_router:compile([{'_', [
{"/", hello_h, []},
{"/empty", empty_h, []},
@@ -47,12 +47,16 @@ init_per_suite(Config) ->
{"/trailers", trailers_h, []},
{"/ws", ws_echo, []}
]}])
- }}),
- OriginPort = ranch:get_port(?MODULE),
- [{origin_port, OriginPort}|Config].
+ }},
+ {ok, _} = cowboy:start_clear({?MODULE, tcp}, [], ProtoOpts),
+ TCPOriginPort = ranch:get_port({?MODULE, tcp}),
+ {ok, _} = cowboy:start_tls({?MODULE, tls}, ct_helper:get_certs_from_ets(), ProtoOpts),
+ TLSOriginPort = ranch:get_port({?MODULE, tls}),
+ [{tcp_origin_port, TCPOriginPort}, {tls_origin_port, TLSOriginPort}|Config].
end_per_suite(_) ->
- ok = cowboy:stop_listener(?MODULE).
+ ok = cowboy:stop_listener({?MODULE, tls}),
+ ok = cowboy:stop_listener({?MODULE, tcp}).
%% init.
@@ -74,16 +78,64 @@ init(Config) ->
} = do_receive_event(?FUNCTION_NAME),
gun:close(Pid).
+%% domain_lookup_start/domain_lookup_end.
+
+domain_lookup_start(Config) ->
+ doc("Confirm that the domain_lookup_start event callback is called."),
+ {ok, Pid, _} = do_gun_open(12345, Config),
+ #{
+ host := "localhost",
+ port := 12345,
+ tcp_opts := _,
+ timeout := _
+ } = do_receive_event(?FUNCTION_NAME),
+ gun:close(Pid).
+
+domain_lookup_end_error(Config) ->
+ doc("Confirm that the domain_lookup_end event callback is called on lookup failure."),
+ Opts = #{
+ event_handler => {?MODULE, self()},
+ protocols => [config(name, config(tc_group_properties, Config))]
+ },
+ {ok, Pid} = gun:open("this.should.not.exist", 12345, Opts),
+ #{
+ host := "this.should.not.exist",
+ port := 12345,
+ tcp_opts := _,
+ timeout := _,
+ error := nxdomain
+ } = do_receive_event(domain_lookup_end),
+ gun:close(Pid).
+
+domain_lookup_end_ok(Config) ->
+ doc("Confirm that the domain_lookup_end event callback is called on lookup success."),
+ {ok, Pid, _} = do_gun_open(12345, Config),
+ #{
+ host := "localhost",
+ port := 12345,
+ tcp_opts := _,
+ timeout := _,
+ lookup_info := #{
+ ip_addresses := [_|_],
+ port := 12345,
+ tcp_module := _,
+ tcp_opts := _
+ }
+ } = do_receive_event(domain_lookup_end),
+ gun:close(Pid).
+
%% connect_start/connect_end.
connect_start(Config) ->
doc("Confirm that the connect_start event callback is called."),
{ok, Pid, _} = do_gun_open(12345, Config),
#{
- host := "localhost",
- port := 12345,
- transport := tcp,
- transport_opts := _,
+ lookup_info := #{
+ ip_addresses := [_|_],
+ port := 12345,
+ tcp_module := _,
+ tcp_opts := _
+ },
timeout := _
} = do_receive_event(?FUNCTION_NAME),
gun:close(Pid).
@@ -92,30 +144,93 @@ connect_end_error(Config) ->
doc("Confirm that the connect_end event callback is called on connect failure."),
{ok, Pid, _} = do_gun_open(12345, Config),
#{
- host := "localhost",
- port := 12345,
- transport := tcp,
- transport_opts := _,
+ lookup_info := #{
+ ip_addresses := [_|_],
+ port := 12345,
+ tcp_module := _,
+ tcp_opts := _
+ },
timeout := _,
error := _
} = do_receive_event(connect_end),
gun:close(Pid).
-connect_end_ok(Config) ->
- doc("Confirm that the connect_end event callback is called on connect success."),
+connect_end_ok_tcp(Config) ->
+ doc("Confirm that the connect_end event callback is called on connect success with TCP."),
{ok, Pid, OriginPort} = do_gun_open(Config),
{ok, Protocol} = gun:await_up(Pid),
#{
- host := "localhost",
- port := OriginPort,
- transport := tcp,
- transport_opts := _,
+ lookup_info := #{
+ ip_addresses := [_|_],
+ port := OriginPort,
+ tcp_module := _,
+ tcp_opts := _
+ },
timeout := _,
socket := _,
protocol := Protocol
} = do_receive_event(connect_end),
gun:close(Pid).
+connect_end_ok_tls(Config) ->
+ doc("Confirm that the connect_end event callback is called on connect success with TLS."),
+ {ok, Pid, OriginPort} = do_gun_open_tls(Config),
+ Event = #{
+ lookup_info := #{
+ ip_addresses := [_|_],
+ port := OriginPort,
+ tcp_module := _,
+ tcp_opts := _
+ },
+ timeout := _,
+ socket := _
+ } = do_receive_event(connect_end),
+ false = maps:is_key(protocol, Event),
+ gun:close(Pid).
+
+tls_handshake_start(Config) ->
+ doc("Confirm that the tls_handshake_start event callback is called."),
+ {ok, Pid, _} = do_gun_open_tls(Config),
+ #{
+ socket := Socket,
+ tls_opts := _,
+ timeout := _
+ } = do_receive_event(?FUNCTION_NAME),
+ true = is_port(Socket),
+ gun:close(Pid).
+
+tls_handshake_end_error(Config) ->
+ doc("Confirm that the tls_handshake_end event callback is called on TLS handshake error."),
+ %% We use the wrong port on purpose to trigger a handshake error.
+ OriginPort = config(tcp_origin_port, Config),
+ Opts = #{
+ event_handler => {?MODULE, self()},
+ protocols => [config(name, config(tc_group_properties, Config))],
+ transport => tls
+ },
+ {ok, Pid} = gun:open("localhost", OriginPort, Opts),
+ #{
+ socket := Socket,
+ tls_opts := _,
+ timeout := _,
+ error := {tls_alert, _}
+ } = do_receive_event(tls_handshake_end),
+ true = is_port(Socket),
+ gun:close(Pid).
+
+tls_handshake_end_ok(Config) ->
+ doc("Confirm that the tls_handshake_end event callback is called on TLS handshake success."),
+ {ok, Pid, _} = do_gun_open_tls(Config),
+ {ok, Protocol} = gun:await_up(Pid),
+ #{
+ socket := Socket,
+ tls_opts := _,
+ timeout := _,
+ protocol := Protocol
+ } = do_receive_event(tls_handshake_end),
+ false = is_port(Socket),
+ gun:close(Pid).
+
request_start(Config) ->
doc("Confirm that the request_start event callback is called."),
do_request_event(Config, ?FUNCTION_NAME),
@@ -477,7 +592,7 @@ terminate(Config) ->
{ok, Pid, _} = do_gun_open(12345, Config),
gun:close(Pid),
#{
- state := not_connected,
+ state := _,
reason := shutdown
} = do_receive_event(terminate),
ok.
@@ -485,7 +600,7 @@ terminate(Config) ->
%% Internal.
do_gun_open(Config) ->
- OriginPort = config(origin_port, Config),
+ OriginPort = config(tcp_origin_port, Config),
do_gun_open(OriginPort, Config).
do_gun_open(OriginPort, Config) ->
@@ -496,6 +611,16 @@ do_gun_open(OriginPort, Config) ->
{ok, Pid} = gun:open("localhost", OriginPort, Opts),
{ok, Pid, OriginPort}.
+do_gun_open_tls(Config) ->
+ OriginPort = config(tls_origin_port, Config),
+ Opts = #{
+ event_handler => {?MODULE, self()},
+ protocols => [config(name, config(tc_group_properties, Config))],
+ transport => tls
+ },
+ {ok, Pid} = gun:open("localhost", OriginPort, Opts),
+ {ok, Pid, OriginPort}.
+
do_receive_event(Event) ->
receive
{Event, EventData} ->
@@ -513,6 +638,14 @@ init(EventData, Pid) ->
Pid ! {?FUNCTION_NAME, EventData},
Pid.
+domain_lookup_start(EventData, Pid) ->
+ Pid ! {?FUNCTION_NAME, EventData},
+ Pid.
+
+domain_lookup_end(EventData, Pid) ->
+ Pid ! {?FUNCTION_NAME, EventData},
+ Pid.
+
connect_start(EventData, Pid) ->
Pid ! {?FUNCTION_NAME, EventData},
Pid.
@@ -521,6 +654,14 @@ connect_end(EventData, Pid) ->
Pid ! {?FUNCTION_NAME, EventData},
Pid.
+tls_handshake_start(EventData, Pid) ->
+ Pid ! {?FUNCTION_NAME, EventData},
+ Pid.
+
+tls_handshake_end(EventData, Pid) ->
+ Pid ! {?FUNCTION_NAME, EventData},
+ Pid.
+
request_start(EventData, Pid) ->
Pid ! {?FUNCTION_NAME, EventData},
Pid.
diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl
index 6afaaf5..6a01cf6 100644
--- a/test/gun_SUITE.erl
+++ b/test/gun_SUITE.erl
@@ -54,18 +54,22 @@ atom_hostname(_) ->
connect_timeout(_) ->
doc("Ensure an integer value for connect_timeout is accepted."),
- {ok, Pid} = gun:open("localhost", 12345, #{connect_timeout => 1000, retry => 0}),
- Ref = monitor(process, Pid),
- receive
- {'DOWN', Ref, process, Pid, {shutdown, _}} ->
- ok
- after 5000 ->
- error(timeout)
- end.
+ do_timeout(connect_timeout, 1000).
connect_timeout_infinity(_) ->
doc("Ensure infinity for connect_timeout is accepted."),
- {ok, Pid} = gun:open("localhost", 12345, #{connect_timeout => infinity, retry => 0}),
+ do_timeout(connect_timeout, infinity).
+
+domain_lookup_timeout(_) ->
+ doc("Ensure an integer value for domain_lookup_timeout is accepted."),
+ do_timeout(domain_lookup_timeout, 1000).
+
+domain_lookup_timeout_infinity(_) ->
+ doc("Ensure infinity for domain_lookup_timeout is accepted."),
+ do_timeout(domain_lookup_timeout, infinity).
+
+do_timeout(Opt, Timeout) ->
+ {ok, Pid} = gun:open("localhost", 12345, #{Opt => Timeout, retry => 0}),
Ref = monitor(process, Pid),
receive
{'DOWN', Ref, process, Pid, {shutdown, _}} ->
@@ -496,6 +500,14 @@ supervise_false(_) ->
[] = [P || {_, P, _, _} <- supervisor:which_children(gun_sup), P =:= Pid],
ok.
+tls_handshake_timeout(_) ->
+ doc("Ensure an integer value for tls_handshake_timeout is accepted."),
+ do_timeout(tls_handshake_timeout, 1000).
+
+tls_handshake_timeout_infinity(_) ->
+ doc("Ensure infinity for tls_handshake_timeout is accepted."),
+ do_timeout(tls_handshake_timeout, infinity).
+
transform_header_name(_) ->
doc("The transform_header_name option allows changing the case of header names."),
{ok, ListenSocket} = gen_tcp:listen(0, [binary, {active, false}]),