From 0724dbf536c22fc978ba0bc96052c65f0edafa69 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Mon, 5 Jul 2021 11:53:35 +0200 Subject: Add tests for the SSE handler --- test/handlers/sse_clock_close_h.erl | 23 +++++++++++++++ test/handlers/sse_mime_param_h.erl | 19 ++++++++++++ test/sse_SUITE.erl | 58 ++++++++++++++++++++++++++++++++----- 3 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 test/handlers/sse_clock_close_h.erl create mode 100644 test/handlers/sse_mime_param_h.erl (limited to 'test') diff --git a/test/handlers/sse_clock_close_h.erl b/test/handlers/sse_clock_close_h.erl new file mode 100644 index 0000000..c5911ff --- /dev/null +++ b/test/handlers/sse_clock_close_h.erl @@ -0,0 +1,23 @@ +%% This module implements a loop handler that sends +%% the current time every second using SSE. In contrast +%% to sse_clock_h, this one sends a "Connection: close" +%% header. + +-module(sse_clock_close_h). + +-export([init/2]). +-export([info/3]). + +init(Req, State) -> + self() ! timeout, + {cowboy_loop, cowboy_req:stream_reply(200, #{ + <<"content-type">> => <<"text/event-stream">>, + <<"connection">> => <<"close">> + }, Req), State}. + +info(timeout, Req, State) -> + erlang:send_after(1000, self(), timeout), + cowboy_req:stream_events(#{ + data => cowboy_clock:rfc1123() + }, nofin, Req), + {ok, Req, State}. diff --git a/test/handlers/sse_mime_param_h.erl b/test/handlers/sse_mime_param_h.erl new file mode 100644 index 0000000..7e0c0e9 --- /dev/null +++ b/test/handlers/sse_mime_param_h.erl @@ -0,0 +1,19 @@ +%% This module implements a loop handler that sends +%% a lone id: line. + +-module(sse_mime_param_h). + +-export([init/2]). +-export([info/3]). + +init(Req, State) -> + self() ! timeout, + {cowboy_loop, cowboy_req:stream_reply(200, #{ + <<"content-type">> => <<"text/event-stream;encoding=UTF-8">> + }, Req), State}. + +info(timeout, Req, State) -> + cowboy_req:stream_events(#{ + id => <<"hello">> + }, nofin, Req), + {stop, Req, State}. diff --git a/test/sse_SUITE.erl b/test/sse_SUITE.erl index d364399..1e68914 100644 --- a/test/sse_SUITE.erl +++ b/test/sse_SUITE.erl @@ -19,7 +19,7 @@ -import(ct_helper, [config/2]). all() -> - [http_clock, http2_clock, lone_id]. + [http_clock, http2_clock, lone_id, with_mime_param, http_clock_close]. init_per_suite(Config) -> gun_test:init_cowboy_tls(?MODULE, #{ @@ -32,7 +32,9 @@ end_per_suite(Config) -> init_routes() -> [ {"localhost", [ {"/clock", sse_clock_h, date}, - {"/lone_id", sse_lone_id_h, []} + {"/lone_id", sse_lone_id_h, []}, + {"/with_mime_param", sse_mime_param_h, []}, + {"/connection_close", sse_clock_close_h, []} ]} ]. @@ -43,7 +45,7 @@ http_clock(Config) -> http_opts => #{content_handlers => [gun_sse_h, gun_data_h]} }), {ok, http} = gun:await_up(Pid), - do_clock_common(Pid). + do_clock_common(Pid, "/clock"). http2_clock(Config) -> {ok, Pid} = gun:open("localhost", config(port, Config), #{ @@ -52,10 +54,22 @@ http2_clock(Config) -> http2_opts => #{content_handlers => [gun_sse_h, gun_data_h]} }), {ok, http2} = gun:await_up(Pid), - do_clock_common(Pid). + do_clock_common(Pid, "/clock"). -do_clock_common(Pid) -> - Ref = gun:get(Pid, "/clock", [ +http_clock_close(Config) -> + {ok, Pid} = gun:open("localhost", config(port, Config), #{ + transport => tls, + protocols => [http], + http_opts => #{ + content_handlers => [gun_sse_h, gun_data_h], + closing_timeout => 1000 + } + }), + {ok, http} = gun:await_up(Pid), + do_clock_common(Pid, "/connection_close"). + +do_clock_common(Pid, Path) -> + Ref = gun:get(Pid, Path, [ {<<"host">>, <<"localhost">>}, {<<"accept">>, <<"text/event-stream">>} ]), @@ -73,13 +87,16 @@ event_loop(Pid, _, 0) -> event_loop(Pid, Ref, N) -> receive {gun_sse, Pid, Ref, Event} -> + ct:pal("Event: ~p~n", [Event]), #{ last_event_id := <<>>, event_type := <<"message">>, data := Data } = Event, true = is_list(Data) orelse is_binary(Data), - event_loop(Pid, Ref, N - 1) + event_loop(Pid, Ref, N - 1); + Other -> + ct:pal("Other: ~p~n", [Other]) after 10000 -> error(timeout) end. @@ -110,3 +127,30 @@ lone_id(Config) -> after 5000 -> error(timeout) end. + +with_mime_param(Config) -> + {ok, Pid} = gun:open("localhost", config(port, Config), #{ + transport => tls, + protocols => [http], + http_opts => #{content_handlers => [gun_sse_h, gun_data_h]} + }), + {ok, http} = gun:await_up(Pid), + Ref = gun:get(Pid, "/with_mime_param", [ + {<<"host">>, <<"localhost">>}, + {<<"accept">>, <<"text/event-stream">>} + ]), + receive + {gun_response, Pid, Ref, nofin, 200, Headers} -> + {_, <<"text/event-stream;", _Params/binary>>} + = lists:keyfind(<<"content-type">>, 1, Headers), + receive + {gun_sse, Pid, Ref, Event} -> + #{last_event_id := <<"hello">>} = Event, + 1 = maps:size(Event), + gun:close(Pid) + after 10000 -> + error(timeout) + end + after 5000 -> + error(timeout) + end. -- cgit v1.2.3