PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/test/etap/test_web.erl

http://github.com/apache/couchdb
Erlang | 99 lines | 73 code | 14 blank | 12 comment | 0 complexity | 222c5a51d6b2d5e18133fcac0db0db16 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. % Licensed under the Apache License, Version 2.0 (the "License"); you may not
  2. % use this file except in compliance with the License. You may obtain a copy of
  3. % the License at
  4. %
  5. % http://www.apache.org/licenses/LICENSE-2.0
  6. %
  7. % Unless required by applicable law or agreed to in writing, software
  8. % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. % License for the specific language governing permissions and limitations under
  11. % the License.
  12. -module(test_web).
  13. -behaviour(gen_server).
  14. -export([start_link/0, loop/1, get_port/0, set_assert/1, check_last/0]).
  15. -export([init/1, terminate/2, code_change/3]).
  16. -export([handle_call/3, handle_cast/2, handle_info/2]).
  17. -define(SERVER, test_web_server).
  18. -define(HANDLER, test_web_handler).
  19. start_link() ->
  20. gen_server:start({local, ?HANDLER}, ?MODULE, [], []),
  21. mochiweb_http:start([
  22. {name, ?SERVER},
  23. {loop, {?MODULE, loop}},
  24. {port, 0}
  25. ]).
  26. loop(Req) ->
  27. %etap:diag("Handling request: ~p", [Req]),
  28. case gen_server:call(?HANDLER, {check_request, Req}) of
  29. {ok, RespInfo} ->
  30. {ok, Req:respond(RespInfo)};
  31. {raw, {Status, Headers, BodyChunks}} ->
  32. Resp = Req:start_response({Status, Headers}),
  33. lists:foreach(fun(C) -> Resp:send(C) end, BodyChunks),
  34. erlang:put(mochiweb_request_force_close, true),
  35. {ok, Resp};
  36. {chunked, {Status, Headers, BodyChunks}} ->
  37. Resp = Req:respond({Status, Headers, chunked}),
  38. timer:sleep(500),
  39. lists:foreach(fun(C) -> Resp:write_chunk(C) end, BodyChunks),
  40. Resp:write_chunk([]),
  41. {ok, Resp};
  42. {error, Reason} ->
  43. etap:diag("Error: ~p", [Reason]),
  44. Body = lists:flatten(io_lib:format("Error: ~p", [Reason])),
  45. {ok, Req:respond({200, [], Body})}
  46. end.
  47. get_port() ->
  48. mochiweb_socket_server:get(?SERVER, port).
  49. set_assert(Fun) ->
  50. ok = gen_server:call(?HANDLER, {set_assert, Fun}).
  51. check_last() ->
  52. gen_server:call(?HANDLER, last_status).
  53. init(_) ->
  54. {ok, nil}.
  55. terminate(_Reason, _State) ->
  56. ok.
  57. handle_call({check_request, Req}, _From, State) when is_function(State, 1) ->
  58. Resp2 = case (catch State(Req)) of
  59. {ok, Resp} -> {reply, {ok, Resp}, was_ok};
  60. {raw, Resp} -> {reply, {raw, Resp}, was_ok};
  61. {chunked, Resp} -> {reply, {chunked, Resp}, was_ok};
  62. Error -> {reply, {error, Error}, not_ok}
  63. end,
  64. Req:cleanup(),
  65. Resp2;
  66. handle_call({check_request, _Req}, _From, _State) ->
  67. {reply, {error, no_assert_function}, not_ok};
  68. handle_call(last_status, _From, State) when is_atom(State) ->
  69. {reply, State, nil};
  70. handle_call(last_status, _From, State) ->
  71. {reply, {error, not_checked}, State};
  72. handle_call({set_assert, Fun}, _From, nil) ->
  73. {reply, ok, Fun};
  74. handle_call({set_assert, _}, _From, State) ->
  75. {reply, {error, assert_function_set}, State};
  76. handle_call(Msg, _From, State) ->
  77. {reply, {ignored, Msg}, State}.
  78. handle_cast(Msg, State) ->
  79. etap:diag("Ignoring cast message: ~p", [Msg]),
  80. {noreply, State}.
  81. handle_info(Msg, State) ->
  82. etap:diag("Ignoring info message: ~p", [Msg]),
  83. {noreply, State}.
  84. code_change(_OldVsn, State, _Extra) ->
  85. {ok, State}.