- %%% File : ibrowse_functional_tests.erl
- %%% Authors : Benjamin Lee <http://github.com/benjaminplee>
- %%% Dan Schwabe <http://github.com/dfschwabe>
- %%% Brian Richards <http://github.com/richbria>
- %%% Description : Functional tests of the ibrowse library using a live test HTTP server
- %%% Created : 18 November 2014 by Benjamin Lee <yardspoon@gmail.com>
-
- -module(ibrowse_functional_tests).
-
- -include_lib("eunit/include/eunit.hrl").
- -define(PER_TEST_TIMEOUT_SEC, 60).
- -define(TIMEDTEST(Desc, Fun), {Desc, {timeout, ?PER_TEST_TIMEOUT_SEC, fun Fun/0}}).
-
- -define(SERVER_PORT, 8181).
- -define(BASE_URL, "http://localhost:" ++ integer_to_list(?SERVER_PORT)).
- -define(SHORT_TIMEOUT_MS, 5000).
- -define(LONG_TIMEOUT_MS, 30000).
- -define(PAUSE_FOR_CONNECTIONS_MS, 2000).
-
- -compile(export_all).
-
- setup() ->
- application:start(crypto),
- application:start(public_key),
- application:start(ssl),
- ibrowse_test_server:start_server(?SERVER_PORT, tcp),
- ibrowse:start(),
- ok.
-
- teardown(_) ->
- ibrowse:stop(),
- ibrowse_test_server:stop_server(?SERVER_PORT),
- ok.
-
- running_server_fixture_test_() ->
- {foreach,
- fun setup/0,
- fun teardown/1,
- [
- ?TIMEDTEST("Simple request can be honored", simple_request),
- ?TIMEDTEST("Slow server causes timeout", slow_server_timeout),
- ?TIMEDTEST("Pipeline depth goes down with responses", pipeline_depth),
- ?TIMEDTEST("Pipelines refill", pipeline_refill),
- ?TIMEDTEST("Timeout closes pipe", closing_pipes),
- ?TIMEDTEST("Requests are balanced over connections", balanced_connections),
- ?TIMEDTEST("Pipeline too small signals retries", small_pipeline),
- ?TIMEDTEST("Dest status can be gathered", status)
- ]
- }.
-
- simple_request() ->
- ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [])).
-
- slow_server_timeout() ->
- ?assertMatch({error, req_timedout}, ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [], 5000)).
-
- pipeline_depth() ->
- MaxSessions = 2,
- MaxPipeline = 2,
- RequestsSent = 2,
- EmptyPipelineDepth = 0,
-
- ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
-
- Fun = fun() -> ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
- times(RequestsSent, fun() -> spawn_link(Fun) end),
-
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
-
- Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
- ?assertEqual(MaxSessions, length(Counts)),
- ?assertEqual(lists:duplicate(MaxSessions, EmptyPipelineDepth), Counts).
-
- pipeline_refill() ->
- MaxSessions = 2,
- MaxPipeline = 2,
- RequestsToFill = MaxSessions * MaxPipeline,
-
- %% Send off enough requests to fill sessions and pipelines in rappid succession
- Fun = fun() -> ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
- times(RequestsToFill, fun() -> spawn_link(Fun) end),
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
-
- % Verify that connections properly reported their completed responses and can still accept more
- ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS)),
-
- % and do it again to make sure we really are clear
- times(RequestsToFill, fun() -> spawn_link(Fun) end),
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
-
- % Verify that connections properly reported their completed responses and can still accept more
- ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS)).
-
- closing_pipes() ->
- MaxSessions = 2,
- MaxPipeline = 2,
- RequestsSent = 2,
- BalancedNumberOfRequestsPerConnection = 1,
-
- ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
-
- Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
- times(RequestsSent, fun() -> spawn_link(Fun) end),
-
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
-
- Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
- ?assertEqual(MaxSessions, length(Counts)),
- ?assertEqual(lists:duplicate(MaxSessions, BalancedNumberOfRequestsPerConnection), Counts),
-
- timer:sleep(?SHORT_TIMEOUT_MS),
-
- ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()).
-
- balanced_connections() ->
- MaxSessions = 4,
- MaxPipeline = 100,
- RequestsSent = 80,
- BalancedNumberOfRequestsPerConnection = 20,
-
- ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
-
- Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?LONG_TIMEOUT_MS) end,
- times(RequestsSent, fun() -> spawn_link(Fun) end),
-
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
-
- Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
- ?assertEqual(MaxSessions, length(Counts)),
-
- ?assertEqual(lists:duplicate(MaxSessions, BalancedNumberOfRequestsPerConnection), Counts).
-
- small_pipeline() ->
- MaxSessions = 10,
- MaxPipeline = 10,
- RequestsSent = 100,
- FullRequestsPerConnection = 10,
-
- ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
-
- Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
- times(RequestsSent, fun() -> spawn(Fun) end),
-
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS), %% Wait for everyone to get in line
-
- ibrowse:show_dest_status("localhost", 8181),
- Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
- ?assertEqual(MaxSessions, length(Counts)),
-
- ?assertEqual(lists:duplicate(MaxSessions, FullRequestsPerConnection), Counts),
-
- Response = ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS),
-
- ?assertEqual({error, retry_later}, Response).
-
- status() ->
- MaxSessions = 10,
- MaxPipeline = 10,
- RequestsSent = 100,
-
- Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
- times(RequestsSent, fun() -> spawn(Fun) end),
-
- timer:sleep(?PAUSE_FOR_CONNECTIONS_MS), %% Wait for everyone to get in line
-
- ibrowse:show_dest_status(),
- ibrowse:show_dest_status("http://localhost:8181").
-
-
- times(0, _) ->
- ok;
- times(X, Fun) ->
- Fun(),
- times(X - 1, Fun).
|