diff options
author | Loïc Hoguin <[email protected]> | 2019-07-22 16:17:10 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2019-07-22 16:17:10 +0200 |
commit | 516933f9dd2722329b3886c495d5242308958fe1 (patch) | |
tree | 60b16423184a4db405a65266c326b7944ce42256 /test | |
parent | 265ece680c53f77d1685434d0636216c94021497 (diff) | |
download | gun-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.erl | 183 | ||||
-rw-r--r-- | test/gun_SUITE.erl | 30 |
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}]), |