aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-09-28 16:22:35 +0200
committerLoïc Hoguin <[email protected]>2018-09-28 16:22:35 +0200
commit46bab37b54001a110633a6f382aa102848b07795 (patch)
tree4a671c02fbe9245cab48ade70f1082e3068b7203
parent29fa471166e033090ee424df8c6f3c5489dd9e39 (diff)
downloadgun-46bab37b54001a110633a6f382aa102848b07795.tar.gz
gun-46bab37b54001a110633a6f382aa102848b07795.tar.bz2
gun-46bab37b54001a110633a6f382aa102848b07795.zip
Run the h2specd tests in a new test suite
A number of tests are currently failing.
-rw-r--r--Makefile18
-rw-r--r--test/h2specd_SUITE.erl121
2 files changed, 139 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index f3adfa8..6012c04 100644
--- a/Makefile
+++ b/Makefile
@@ -38,3 +38,21 @@ include erlang.mk
# Generate rebar.config on build.
app:: rebar.config
+
+# h2specd setup.
+
+GOPATH := $(ERLANG_MK_TMP)/gopath
+export GOPATH
+
+H2SPECD := $(GOPATH)/src/github.com/summerwind/h2spec/h2specd
+export H2SPECD
+
+# @todo It would be better to allow these dependencies to be specified
+# on a per-target basis instead of for all targets.
+test-build:: $(H2SPECD)
+
+$(H2SPECD):
+ $(gen_verbose) mkdir -p $(GOPATH)/src/github.com/summerwind
+ $(verbose) git clone --depth 1 https://github.com/summerwind/h2spec $(dir $(H2SPECD))
+ $(verbose) $(MAKE) -C $(dir $(H2SPECD)) build MAKEFLAGS=
+ $(verbose) go build -o $(H2SPECD) $(dir $(H2SPECD))/cmd/h2spec/h2specd.go
diff --git a/test/h2specd_SUITE.erl b/test/h2specd_SUITE.erl
new file mode 100644
index 0000000..4a6c358
--- /dev/null
+++ b/test/h2specd_SUITE.erl
@@ -0,0 +1,121 @@
+%% Copyright (c) 2018, Loïc Hoguin <[email protected]>
+%%
+%% 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(h2specd_SUITE).
+-compile(export_all).
+-compile(nowarn_export_all).
+
+-import(ct_helper, [config/2]).
+-import(ct_helper, [doc/1]).
+
+%% ct.
+
+all() ->
+ [h2specd].
+
+init_per_suite(Config) ->
+ case os:getenv("H2SPECD") of
+ false -> skip;
+ _ -> Config
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+%% Tests.
+
+h2specd(Config) ->
+ doc("h2specd test suite for the HTTP/2 protocol."),
+ Self = self(),
+ Pid = spawn_link(fun() -> start_port(Config, Self) end),
+ receive ready -> ok after 10000 -> error(timeout) end,
+ try
+ run_tests(),
+ timer:sleep(100),
+ maybe_fail()
+ after
+ unlink(Pid),
+ os:cmd("killall h2specd")
+ end.
+
+start_port(Config, Pid) ->
+ H2specd = os:getenv("H2SPECD"),
+ Port = open_port(
+ {spawn, H2specd ++ " -S -p 45678"},
+ [{line, 10000}, {cd, config(priv_dir, Config)}, binary, exit_status]),
+ Pid ! ready,
+ receive_infinity(Port).
+
+receive_infinity(Port) ->
+ receive
+ {Port, {data, {eol, Line}}} ->
+ io:format(user, "~s~n", [Line]),
+ ct:log("~ts", [Line]),
+ receive_infinity(Port);
+ {Port, Reason={exit_status, _}} ->
+ exit({shutdown, Reason})
+ end.
+
+run_tests() ->
+ timer:sleep(1000),
+ Tests = scrape_tests(),
+ ct:pal("Test ports: ~p~n", [Tests]),
+ run_tests(Tests).
+
+run_tests([]) ->
+ ok;
+run_tests([Port|Tail]) ->
+ try
+ {ok, Conn} = gun:open("127.0.0.1", Port, #{
+ protocols => [http2],
+ retry => 0
+ }),
+ MRef = monitor(process, Conn),
+ {ok, http2} = gun:await_up(Conn),
+ StreamRef = gun:get(Conn, "/"),
+ receive
+ {gun_response, Conn, StreamRef, _, _, _} ->
+ timer:sleep(100);
+ {'DOWN', MRef, process, Conn, _} ->
+ ok
+ after 100 ->
+ ok
+ end,
+ ok = gun:close(Conn)
+ after
+ run_tests(Tail)
+ end.
+
+scrape_tests() ->
+ {ok, Conn} = gun:open("127.0.0.1", 45678),
+ {ok, http} = gun:await_up(Conn),
+ StreamRef = gun:get(Conn, "/"),
+ {response, nofin, 200, _} = gun:await(Conn, StreamRef),
+ {ok, Body} = gun:await_body(Conn, StreamRef),
+ ok = gun:close(Conn),
+ {match, Matches} = re:run(Body, "<a href=\"(.*?)\"", [global, {capture, all, binary}]),
+ [binary_to_integer(Port)
+ || [_, <<"http://127.0.0.1:", Port:5/binary, "/">>] <- Matches].
+
+maybe_fail() ->
+ {ok, Conn} = gun:open("127.0.0.1", 45678),
+ {ok, http} = gun:await_up(Conn),
+ StreamRef = gun:get(Conn, "/report", [{<<"accept">>, "text/plain"}]),
+ {response, nofin, 200, _} = gun:await(Conn, StreamRef),
+ {ok, Body} = gun:await_body(Conn, StreamRef),
+ ok = gun:close(Conn),
+ case binary:match(Body, <<"0 skipped, 0 failed">>) of
+ nomatch -> exit(failed);
+ _ -> ok
+ end.