1: %%==============================================================================
    2: %% Copyright 2016 Erlang Solutions Ltd.
    3: %%
    4: %% Licensed under the Apache License, Version 2.0 (the "License");
    5: %% you may not use this file except in compliance with the License.
    6: %% You may obtain a copy of the License at
    7: %%
    8: %% http://www.apache.org/licenses/LICENSE-2.0
    9: %%
   10: %% Unless required by applicable law or agreed to in writing, software
   11: %% distributed under the License is distributed on an "AS IS" BASIS,
   12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13: %% See the License for the specific language governing permissions and
   14: %% limitations under the License.
   15: %%==============================================================================
   16: -module(http_client_SUITE).
   17: 
   18: -compile([export_all, nowarn_export_all]).
   19: 
   20: -import(config_parser_helper, [config/2]).
   21: 
   22: -include_lib("eunit/include/eunit.hrl").
   23: 
   24: all() ->
   25:     [get_test,
   26:      no_pool_test,
   27:      post_test,
   28:      request_timeout_test,
   29:      pool_timeout_test
   30:     ].
   31: 
   32: init_per_suite(Config) ->
   33:     http_helper:start(8080, '_', fun process_request/1),
   34:     Pid = self(),
   35:     spawn(fun() ->
   36:                   register(test_helper, self()),
   37:                   mim_ct_sup:start_link(ejabberd_sup),
   38:                   mongoose_wpool:ensure_started(),
   39:                   Pid ! ready,
   40:                   receive stop -> ok end
   41:           end),
   42:     receive ready -> ok end,
   43:     Config.
   44: 
   45: process_request(Req) ->
   46:     QS = cowboy_req:parse_qs(Req),
   47:     case proplists:get_value(<<"sleep">>, QS) of
   48:         <<"true">> -> timer:sleep(100);
   49:         _ -> ok
   50:     end,
   51:     cowboy_req:reply(200, #{<<"content-type">> => <<"text/plain">>}, <<"OK">>, Req).
   52: 
   53: end_per_suite(_Config) ->
   54:     http_helper:stop(),
   55:     exit(whereis(ejabberd_sup), shutdown),
   56:     whereis(test_helper) ! stop.
   57: 
   58: init_per_testcase(TC, Config) ->
   59:     Pool = config([outgoing_pools, http, pool()], pool_opts(TC)),
   60:     mongoose_wpool:start_configured_pools([Pool], [], [<<"a.com">>]),
   61:     Config.
   62: 
   63: pool_opts(request_timeout_test) ->
   64:     #{conn_opts => #{host => "http://localhost:8080", request_timeout => 10}};
   65: pool_opts(pool_timeout_test) ->
   66:     #{opts => #{workers => 1, max_overflow => 0, strategy => available_worker, call_timeout => 10},
   67:       conn_opts => #{host => "http://localhost:8080", request_timeout => 5000}};
   68: pool_opts(_TC) ->
   69:     #{conn_opts => #{host => "http://localhost:8080", request_timeout => 1000}}.
   70: 
   71: end_per_testcase(_TC, _Config) ->
   72:     mongoose_wpool:stop(http, global, pool()).
   73: 
   74: get_test(_Config) ->
   75:     Result = mongoose_http_client:get(global, pool(), <<"some/path">>, []),
   76:     ?assertEqual({ok, {<<"200">>, <<"OK">>}}, Result).
   77: 
   78: no_pool_test(_Config) ->
   79:     Result = mongoose_http_client:get(global, non_existent_pool, <<"some/path">>, []),
   80:     ?assertEqual({error, pool_not_started}, Result).
   81: 
   82: post_test(_Config) ->
   83:     Result = mongoose_http_client:post(global, pool(), <<"some/path">>, [], <<"test request">>),
   84:     ?assertEqual({ok, {<<"200">>, <<"OK">>}}, Result).
   85: 
   86: request_timeout_test(_Config) ->
   87:     Result = mongoose_http_client:get(global, pool(), <<"some/path?sleep=true">>, []),
   88:     ?assertEqual({error, request_timeout}, Result).
   89: 
   90: pool_timeout_test(_Config) ->
   91:     Pid = self(),
   92:     spawn(fun() ->
   93:                   mongoose_http_client:get(global, pool(), <<"/some/path?sleep=true">>, []),
   94:                   Pid ! finished
   95:           end),
   96:     timer:sleep(10), % wait for the only pool worker to start handling the request
   97:     Result = mongoose_http_client:get(global, pool(), <<"some/path">>, []),
   98:     ?assertEqual({error, pool_timeout}, Result),
   99:     receive finished -> ok after 1000 -> error(no_finished_message) end.
  100: 
  101: pool() -> tmp_pool.