aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorjdamanalo <[email protected]>2023-03-09 15:54:41 +0800
committerLoïc Hoguin <[email protected]>2023-12-15 15:37:34 +0100
commita81dc8af9db314e074512e7fc096978c64c9bed1 (patch)
tree6baf1b170887c4d3ddeb40d3c3daf98031dc7b34 /test
parenta72bf4105f6751662ff00fed85bbdc22ee9c2b80 (diff)
downloadcowboy-a81dc8af9db314e074512e7fc096978c64c9bed1.tar.gz
cowboy-a81dc8af9db314e074512e7fc096978c64c9bed1.tar.bz2
cowboy-a81dc8af9db314e074512e7fc096978c64c9bed1.zip
Add timeout to cowboy_loop
LH: I have added a test that does both hibernate and timeout and fixed a related issue. I also tweaked the docs and tests.
Diffstat (limited to 'test')
-rw-r--r--test/handlers/loop_handler_timeout_hibernate_h.erl30
-rw-r--r--test/handlers/loop_handler_timeout_info_h.erl23
-rw-r--r--test/handlers/loop_handler_timeout_init_h.erl23
-rw-r--r--test/loop_handler_SUITE.erl32
-rw-r--r--test/sys_SUITE.erl4
5 files changed, 108 insertions, 4 deletions
diff --git a/test/handlers/loop_handler_timeout_hibernate_h.erl b/test/handlers/loop_handler_timeout_hibernate_h.erl
new file mode 100644
index 0000000..0485208
--- /dev/null
+++ b/test/handlers/loop_handler_timeout_hibernate_h.erl
@@ -0,0 +1,30 @@
+%% This module implements a loop handler that first
+%% sets a timeout, then hibernates, then ensures
+%% that the timeout initially set no longer triggers.
+%% If everything goes fine a 200 is returned. If the
+%% timeout triggers again a 299 is.
+
+-module(loop_handler_timeout_hibernate_h).
+
+-export([init/2]).
+-export([info/3]).
+-export([terminate/3]).
+
+init(Req, _) ->
+ self() ! message1,
+ {cowboy_loop, Req, undefined, 100}.
+
+info(message1, Req, State) ->
+ erlang:send_after(200, self(), message2),
+ {ok, Req, State, hibernate};
+info(message2, Req, State) ->
+ erlang:send_after(200, self(), message3),
+ %% Don't set a timeout now.
+ {ok, Req, State};
+info(message3, Req, State) ->
+ {stop, cowboy_req:reply(200, Req), State};
+info(timeout, Req, State) ->
+ {stop, cowboy_req:reply(<<"299 OK!">>, Req), State}.
+
+terminate(stop, _, _) ->
+ ok.
diff --git a/test/handlers/loop_handler_timeout_info_h.erl b/test/handlers/loop_handler_timeout_info_h.erl
new file mode 100644
index 0000000..92f652e
--- /dev/null
+++ b/test/handlers/loop_handler_timeout_info_h.erl
@@ -0,0 +1,23 @@
+%% This module implements a loop handler that changes
+%% the timeout value to 500ms after the first message
+%% then sends itself another message after 1000ms.
+%% It is expected to timeout, that is, reply a 299.
+
+-module(loop_handler_timeout_info_h).
+
+-export([init/2]).
+-export([info/3]).
+-export([terminate/3]).
+
+init(Req, _) ->
+ self() ! message,
+ {cowboy_loop, Req, undefined}.
+
+info(message, Req, State) ->
+ erlang:send_after(200, self(), message),
+ {ok, Req, State, 100};
+info(timeout, Req, State) ->
+ {stop, cowboy_req:reply(<<"299 OK!">>, Req), State}.
+
+terminate(stop, _, _) ->
+ ok.
diff --git a/test/handlers/loop_handler_timeout_init_h.erl b/test/handlers/loop_handler_timeout_init_h.erl
new file mode 100644
index 0000000..ba0b34b
--- /dev/null
+++ b/test/handlers/loop_handler_timeout_init_h.erl
@@ -0,0 +1,23 @@
+%% This module implements a loop handler that reads
+%% the request query for a timeout value, then sends
+%% itself a message after 1000ms. It replies a 200 when
+%% the message does not timeout and a 299 otherwise.
+
+-module(loop_handler_timeout_init_h).
+
+-export([init/2]).
+-export([info/3]).
+-export([terminate/3]).
+
+init(Req, _) ->
+ #{timeout := Timeout} = cowboy_req:match_qs([{timeout, int}], Req),
+ erlang:send_after(200, self(), message),
+ {cowboy_loop, Req, undefined, Timeout}.
+
+info(message, Req, State) ->
+ {stop, cowboy_req:reply(200, Req), State};
+info(timeout, Req, State) ->
+ {stop, cowboy_req:reply(<<"299 OK!">>, Req), State}.
+
+terminate(stop, _, _) ->
+ ok.
diff --git a/test/loop_handler_SUITE.erl b/test/loop_handler_SUITE.erl
index a7b5303..04aa629 100644
--- a/test/loop_handler_SUITE.erl
+++ b/test/loop_handler_SUITE.erl
@@ -40,7 +40,10 @@ init_dispatch(_) ->
cowboy_router:compile([{'_', [
{"/long_polling", long_polling_h, []},
{"/loop_body", loop_handler_body_h, []},
- {"/loop_timeout", loop_handler_timeout_h, []}
+ {"/loop_request_timeout", loop_handler_timeout_h, []},
+ {"/loop_timeout_init", loop_handler_timeout_init_h, []},
+ {"/loop_timeout_info", loop_handler_timeout_info_h, []},
+ {"/loop_timeout_hibernate", loop_handler_timeout_hibernate_h, []}
]}]).
%% Tests.
@@ -79,6 +82,31 @@ long_polling_pipeline(Config) ->
request_timeout(Config) ->
doc("Ensure that the request_timeout isn't applied when a request is ongoing."),
ConnPid = gun_open(Config),
- Ref = gun:get(ConnPid, "/loop_timeout", [{<<"accept-encoding">>, <<"gzip">>}]),
+ Ref = gun:get(ConnPid, "/loop_request_timeout", [{<<"accept-encoding">>, <<"gzip">>}]),
{response, nofin, 200, _} = gun:await(ConnPid, Ref, 10000),
ok.
+
+timeout_hibernate(Config) ->
+ doc("Ensure that loop handler idle timeouts don't trigger after hibernate is returned."),
+ ConnPid = gun_open(Config),
+ Ref = gun:get(ConnPid, "/loop_timeout_hibernate", [{<<"accept-encoding">>, <<"gzip">>}]),
+ {response, fin, 200, _} = gun:await(ConnPid, Ref),
+ ok.
+
+timeout_info(Config) ->
+ doc("Ensure that loop handler idle timeouts trigger on time when set in info/3."),
+ ConnPid = gun_open(Config),
+ Ref = gun:get(ConnPid, "/loop_timeout_info", [{<<"accept-encoding">>, <<"gzip">>}]),
+ {response, fin, 299, _} = gun:await(ConnPid, Ref),
+ ok.
+
+timeout_init(Config) ->
+ doc("Ensure that loop handler idle timeouts trigger on time when set in init/2."),
+ ConnPid = gun_open(Config),
+ Ref = gun:get(ConnPid, "/loop_timeout_init?timeout=300",
+ [{<<"accept-encoding">>, <<"gzip">>}]),
+ {response, fin, 200, _} = gun:await(ConnPid, Ref),
+ Ref2 = gun:get(ConnPid, "/loop_timeout_init?timeout=100",
+ [{<<"accept-encoding">>, <<"gzip">>}]),
+ {response, fin, 299, _} = gun:await(ConnPid, Ref2),
+ ok.
diff --git a/test/sys_SUITE.erl b/test/sys_SUITE.erl
index e10491a..cd6cfa9 100644
--- a/test/sys_SUITE.erl
+++ b/test/sys_SUITE.erl
@@ -659,7 +659,7 @@ sys_get_state_loop(Config) ->
timer:sleep(100),
SupPid = get_remote_pid_tcp(Socket),
[{_, Pid, _, _}] = supervisor:which_children(SupPid),
- {Req, Env, long_polling_sys_h, undefined} = sys:get_state(Pid),
+ {Req, Env, long_polling_sys_h, undefined, infinity} = sys:get_state(Pid),
#{pid := _, streamid := _} = Req,
#{dispatch := _} = Env,
ok.
@@ -784,7 +784,7 @@ sys_replace_state_loop(Config) ->
timer:sleep(100),
SupPid = get_remote_pid_tcp(Socket),
[{_, Pid, _, _}] = supervisor:which_children(SupPid),
- {Req, Env, long_polling_sys_h, undefined} = sys:replace_state(Pid, fun(S) -> S end),
+ {Req, Env, long_polling_sys_h, undefined, infinity} = sys:replace_state(Pid, fun(S) -> S end),
#{pid := _, streamid := _} = Req,
#{dispatch := _} = Env,
ok.