From 46bab37b54001a110633a6f382aa102848b07795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 28 Sep 2018 16:22:35 +0200 Subject: Run the h2specd tests in a new test suite A number of tests are currently failing. --- Makefile | 18 ++++++++ test/h2specd_SUITE.erl | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 test/h2specd_SUITE.erl 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 +%% +%% 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, ">] <- 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. -- cgit v1.2.3