From 29d347bf5bed001ae8d8763e6af53950c190de40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 6 Aug 2018 15:16:01 +0200 Subject: Rewrite the SSE suite using Cowboy --- Makefile | 3 ++- test/gun_ct_hook.erl | 2 +- test/gun_test.erl | 24 +++++++++++++++++++++++ test/handlers/sse_clock_h.erl | 21 +++++++++++++++++++++ test/sse_SUITE.erl | 44 +++++++++++++++++++++++++++++++++---------- 5 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 test/gun_test.erl create mode 100644 test/handlers/sse_clock_h.erl diff --git a/Makefile b/Makefile index 3f11643..53c6417 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,9 @@ dep_cowlib = git https://github.com/ninenines/cowlib 2.5.1 DOC_DEPS = asciideck -TEST_DEPS = $(if $(CI_ERLANG_MK),ci.erlang.mk) ct_helper +TEST_DEPS = $(if $(CI_ERLANG_MK),ci.erlang.mk) ct_helper cowboy dep_ct_helper = git https://github.com/extend/ct_helper.git master +dep_cowboy_commit = master # CI configuration. diff --git a/test/gun_ct_hook.erl b/test/gun_ct_hook.erl index bf71530..8a2f0a5 100644 --- a/test/gun_ct_hook.erl +++ b/test/gun_ct_hook.erl @@ -17,6 +17,6 @@ -export([init/2]). init(_, _) -> - ct_helper:start([gun]), + ct_helper:start([cowboy, gun]), ct_helper:make_certs_in_ets(), {ok, undefined}. diff --git a/test/gun_test.erl b/test/gun_test.erl new file mode 100644 index 0000000..4e9aedd --- /dev/null +++ b/test/gun_test.erl @@ -0,0 +1,24 @@ +%% Copyright (c) 2018, Loïc Hoguin +%% +%% 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(gun_test). +-compile(export_all). +-compile(nowarn_export_all). + +%% Cowboy listeners. + +init_cowboy_tls(Ref, ProtoOpts, Config) -> + Opts = ct_helper:get_certs_from_ets(), + {ok, _} = cowboy:start_tls(Ref, Opts ++ [{port, 0}], ProtoOpts), + [{ref, Ref}, {port, ranch:get_port(Ref)}|Config]. diff --git a/test/handlers/sse_clock_h.erl b/test/handlers/sse_clock_h.erl new file mode 100644 index 0000000..23b834f --- /dev/null +++ b/test/handlers/sse_clock_h.erl @@ -0,0 +1,21 @@ +%% This module implements a loop handler that sends +%% the current time every second using SSE. + +-module(sse_clock_h). + +-export([init/2]). +-export([info/3]). + +init(Req, State) -> + self() ! timeout, + {cowboy_loop, cowboy_req:stream_reply(200, #{ + <<"content-type">> => <<"text/event-stream">> + }, Req), State}. + +info(timeout, Req, State) -> + erlang:send_after(1000, self(), timeout), + Time = calendar:system_time_to_rfc3339(erlang:system_time(second)), + cowboy_req:stream_events(#{ + data => Time + }, nofin, Req), + {ok, Req, State}. diff --git a/test/sse_SUITE.erl b/test/sse_SUITE.erl index d9ffeda..ce4dae3 100644 --- a/test/sse_SUITE.erl +++ b/test/sse_SUITE.erl @@ -16,19 +16,37 @@ -compile(export_all). -compile(nowarn_export_all). +-import(ct_helper, [config/2]). + all() -> [http, http2]. -http(_) -> - {ok, Pid} = gun:open("sse.now.sh", 443, #{ +init_per_suite(Config) -> + gun_test:init_cowboy_tls(?MODULE, #{ + env => #{dispatch => cowboy_router:compile(init_routes())} + }, Config). + +end_per_suite(Config) -> + cowboy:stop_listener(config(ref, Config)). + +init_routes() -> [ + {"localhost", [ + {"/", sse_clock_h, []} + ]} +]. + +http(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), common(Pid). -http2(_) -> - {ok, Pid} = gun:open("sse.now.sh", 443, #{ +http2(Config) -> + {ok, Pid} = gun:open("localhost", config(port, Config), #{ + transport => tls, protocols => [http2], http2_opts => #{content_handlers => [gun_sse_h, gun_data_h]} }), @@ -37,23 +55,29 @@ http2(_) -> common(Pid) -> Ref = gun:get(Pid, "/", [ - {<<"host">>, <<"sse.now.sh">>}, + {<<"host">>, <<"localhost">>}, {<<"accept">>, <<"text/event-stream">>} ]), receive - {gun_response, Pid, Ref, nofin, Status, Headers} -> - ct:print("response ~p ~p", [Status, Headers]), + {gun_response, Pid, Ref, nofin, 200, Headers} -> + {_, <<"text/event-stream">>} + = lists:keyfind(<<"content-type">>, 1, Headers), event_loop(Pid, Ref, 3) after 5000 -> error(timeout) end. -event_loop(_, _, 0) -> - ok; +event_loop(Pid, _, 0) -> + gun:close(Pid); event_loop(Pid, Ref, N) -> receive {gun_sse, Pid, Ref, Event} -> - ct:print("event ~p", [Event]), + #{ + last_event_id := <<>>, + event_type := <<"message">>, + data := Data + } = Event, + true = is_list(Data) orelse is_binary(Data), event_loop(Pid, Ref, N - 1) after 10000 -> error(timeout) -- cgit v1.2.3