您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

174 行
6.7 KiB

  1. %%% File : ibrowse_functional_tests.erl
  2. %%% Authors : Benjamin Lee <http://github.com/benjaminplee>
  3. %%% Dan Schwabe <http://github.com/dfschwabe>
  4. %%% Brian Richards <http://github.com/richbria>
  5. %%% Description : Functional tests of the ibrowse library using a live test HTTP server
  6. %%% Created : 18 November 2014 by Benjamin Lee <yardspoon@gmail.com>
  7. -module(ibrowse_functional_tests).
  8. -include_lib("eunit/include/eunit.hrl").
  9. -define(PER_TEST_TIMEOUT_SEC, 60).
  10. -define(TIMEDTEST(Desc, Fun), {Desc, {timeout, ?PER_TEST_TIMEOUT_SEC, fun Fun/0}}).
  11. -define(SERVER_PORT, 8181).
  12. -define(BASE_URL, "http://localhost:" ++ integer_to_list(?SERVER_PORT)).
  13. -define(SHORT_TIMEOUT_MS, 5000).
  14. -define(LONG_TIMEOUT_MS, 30000).
  15. -define(PAUSE_FOR_CONNECTIONS_MS, 2000).
  16. -compile(export_all).
  17. setup() ->
  18. application:start(crypto),
  19. application:start(public_key),
  20. application:start(ssl),
  21. ibrowse_test_server:start_server(?SERVER_PORT, tcp),
  22. ibrowse:start(),
  23. ok.
  24. teardown(_) ->
  25. ibrowse:stop(),
  26. ibrowse_test_server:stop_server(?SERVER_PORT),
  27. ok.
  28. running_server_fixture_test_() ->
  29. {foreach,
  30. fun setup/0,
  31. fun teardown/1,
  32. [
  33. ?TIMEDTEST("Simple request can be honored", simple_request),
  34. ?TIMEDTEST("Slow server causes timeout", slow_server_timeout),
  35. ?TIMEDTEST("Pipeline depth goes down with responses", pipeline_depth),
  36. ?TIMEDTEST("Pipelines refill", pipeline_refill),
  37. ?TIMEDTEST("Timeout closes pipe", closing_pipes),
  38. ?TIMEDTEST("Requests are balanced over connections", balanced_connections),
  39. ?TIMEDTEST("Pipeline too small signals retries", small_pipeline),
  40. ?TIMEDTEST("Dest status can be gathered", status)
  41. ]
  42. }.
  43. simple_request() ->
  44. ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [])).
  45. slow_server_timeout() ->
  46. ?assertMatch({error, req_timedout}, ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [], 5000)).
  47. pipeline_depth() ->
  48. MaxSessions = 2,
  49. MaxPipeline = 2,
  50. RequestsSent = 2,
  51. EmptyPipelineDepth = 0,
  52. ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
  53. Fun = fun() -> ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
  54. times(RequestsSent, fun() -> spawn_link(Fun) end),
  55. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
  56. Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
  57. ?assertEqual(MaxSessions, length(Counts)),
  58. ?assertEqual(lists:duplicate(MaxSessions, EmptyPipelineDepth), Counts).
  59. pipeline_refill() ->
  60. MaxSessions = 2,
  61. MaxPipeline = 2,
  62. RequestsToFill = MaxSessions * MaxPipeline,
  63. %% Send off enough requests to fill sessions and pipelines in rappid succession
  64. Fun = fun() -> ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
  65. times(RequestsToFill, fun() -> spawn_link(Fun) end),
  66. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
  67. % Verify that connections properly reported their completed responses and can still accept more
  68. ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS)),
  69. % and do it again to make sure we really are clear
  70. times(RequestsToFill, fun() -> spawn_link(Fun) end),
  71. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
  72. % Verify that connections properly reported their completed responses and can still accept more
  73. ?assertMatch({ok, "200", _, _}, ibrowse:send_req(?BASE_URL, [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS)).
  74. closing_pipes() ->
  75. MaxSessions = 2,
  76. MaxPipeline = 2,
  77. RequestsSent = 2,
  78. BalancedNumberOfRequestsPerConnection = 1,
  79. ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
  80. Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
  81. times(RequestsSent, fun() -> spawn_link(Fun) end),
  82. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
  83. Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
  84. ?assertEqual(MaxSessions, length(Counts)),
  85. ?assertEqual(lists:duplicate(MaxSessions, BalancedNumberOfRequestsPerConnection), Counts),
  86. timer:sleep(?SHORT_TIMEOUT_MS),
  87. ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()).
  88. balanced_connections() ->
  89. MaxSessions = 4,
  90. MaxPipeline = 100,
  91. RequestsSent = 80,
  92. BalancedNumberOfRequestsPerConnection = 20,
  93. ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
  94. Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?LONG_TIMEOUT_MS) end,
  95. times(RequestsSent, fun() -> spawn_link(Fun) end),
  96. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS),
  97. Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
  98. ?assertEqual(MaxSessions, length(Counts)),
  99. ?assertEqual(lists:duplicate(MaxSessions, BalancedNumberOfRequestsPerConnection), Counts).
  100. small_pipeline() ->
  101. MaxSessions = 10,
  102. MaxPipeline = 10,
  103. RequestsSent = 100,
  104. FullRequestsPerConnection = 10,
  105. ?assertEqual([], ibrowse_test_server:get_conn_pipeline_depth()),
  106. Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
  107. times(RequestsSent, fun() -> spawn(Fun) end),
  108. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS), %% Wait for everyone to get in line
  109. ibrowse:show_dest_status("localhost", 8181),
  110. Counts = [Count || {_Pid, Count} <- ibrowse_test_server:get_conn_pipeline_depth()],
  111. ?assertEqual(MaxSessions, length(Counts)),
  112. ?assertEqual(lists:duplicate(MaxSessions, FullRequestsPerConnection), Counts),
  113. Response = ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS),
  114. ?assertEqual({error, retry_later}, Response).
  115. status() ->
  116. MaxSessions = 10,
  117. MaxPipeline = 10,
  118. RequestsSent = 100,
  119. Fun = fun() -> ibrowse:send_req(?BASE_URL ++ "/never_respond", [], get, [], [{max_sessions, MaxSessions}, {max_pipeline_size, MaxPipeline}], ?SHORT_TIMEOUT_MS) end,
  120. times(RequestsSent, fun() -> spawn(Fun) end),
  121. timer:sleep(?PAUSE_FOR_CONNECTIONS_MS), %% Wait for everyone to get in line
  122. ibrowse:show_dest_status(),
  123. ibrowse:show_dest_status("http://localhost:8181").
  124. times(0, _) ->
  125. ok;
  126. times(X, Fun) ->
  127. Fun(),
  128. times(X - 1, Fun).