%% Copyright (c) 2017, 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(h2spec_SUITE). -compile(export_all). -compile(nowarn_export_all). -import(ct_helper, [config/2]). -import(ct_helper, [doc/1]). %% ct. all() -> [h2spec]. init_per_suite(Config) -> case os:getenv("H2SPEC") of false -> {skip, "H2SPEC environment variable undefined."}; H2spec -> case filelib:is_file(H2spec) of false -> {skip, "H2SPEC executable not found."}; true -> cowboy_test:init_http(h2spec, #{ env => #{dispatch => init_dispatch()}, max_concurrent_streams => 100, %% This test suite expects an HTTP/2-only connection. protocols => [http2], %% Disable the DATA threshold for this test suite. stream_window_data_threshold => 0 }, Config) end end. end_per_suite(_Config) -> cowboy:stop_listener(h2spec). %% Dispatch configuration. init_dispatch() -> cowboy_router:compile([ {'_', [ {"/", delay_hello_h, 50} ]} ]). %% Tests. h2spec(Config) -> doc("h2spec test suite for the HTTP/2 protocol."), Self = self(), spawn_link(fun() -> start_port(Config, Self) end), receive {h2spec_exit, 0, Log} -> ct:log("~ts", [Log]), ok; {h2spec_exit, Status, Log} -> ct:log("~ts", [Log]), error({exit_status, Status}) end. start_port(Config, Pid) -> H2spec = os:getenv("H2SPEC"), ListenPort = config(port, Config), Port = open_port( {spawn, H2spec ++ " -S -p " ++ integer_to_list(ListenPort)}, [{line, 10000}, {cd, config(priv_dir, Config)}, binary, exit_status]), receive_infinity(Port, Pid, []). receive_infinity(Port, Pid, Acc) -> receive {Port, {data, {eol, Line}}} -> io:format(user, "~s~n", [Line]), receive_infinity(Port, Pid, [Line|Acc]); {Port, {exit_status, Status}} -> Pid ! {h2spec_exit, Status, [[L, $\n] || L <- lists:reverse(Acc)]} end.