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 13-module(chttpd_socket_buffer_size_test). 14 15-include_lib("couch/include/couch_eunit.hrl"). 16-include_lib("couch/include/couch_db.hrl"). 17 18-define(USER, "chttpd_db_socket_buffer_size_test_admin"). 19-define(PASS, "pass"). 20-define(AUTH, {basic_auth, {?USER, ?PASS}}). 21-define(CONTENT_JSON, {"Content-Type", "application/json"}). 22 23 24setup(SocketOpts) -> 25 StartCtx = start_couch_with_cfg(SocketOpts), 26 Db = ?tempdb(), 27 create_db(url(Db)), 28 {StartCtx, Db}. 29 30 31teardown(_, {StartCtx, Db}) -> 32 delete_db(url(Db)), 33 ok = config:delete("admins", ?USER, _Persist=false), 34 test_util:stop_couch(StartCtx). 35 36 37socket_buffer_size_test_() -> 38 { 39 "chttpd socket_buffer_size_test", 40 { 41 foreachx, 42 fun setup/1, fun teardown/2, 43 [ 44 {"[{recbuf, undefined}]", fun default_buffer/2}, 45 {"[{recbuf, 1024}]", fun small_recbuf/2}, 46 {"[{buffer, 1024}]", fun small_buffer/2} 47 ] 48 } 49 }. 50 51 52small_recbuf(_, {_, Db}) -> 53 {timeout, 30, ?_test(begin 54 Id = data(2048), 55 Response = put_req(url(Db) ++ "/" ++ Id, "{}"), 56 ?assert(Response =:= 400 orelse Response =:= request_failed) 57 end)}. 58 59 60small_buffer(_, {_, Db}) -> 61 {timeout, 30, ?_test(begin 62 Id = data(2048), 63 Response = put_req(url(Db) ++ "/" ++ Id, "{}"), 64 ?assert(Response =:= 400 orelse Response =:= request_failed) 65 end)}. 66 67 68default_buffer(_, {_, Db}) -> 69 {timeout, 30, ?_test(begin 70 Id = data(7000), 71 Headers = [{"Blah", data(7000)}], 72 Status = put_req(url(Db) ++ "/" ++ Id, Headers, "{}"), 73 ?assert(Status =:= 201 orelse Status =:= 202) 74 end)}. 75 76 77% Helper functions 78 79url() -> 80 Addr = config:get("chttpd", "bind_address", "127.0.0.1"), 81 Port = integer_to_list(mochiweb_socket_server:get(chttpd, port)), 82 "http://" ++ Addr ++ ":" ++ Port. 83 84 85url(Db) -> 86 url() ++ "/" ++ ?b2l(Db). 87 88 89create_db(Url) -> 90 Status = put_req(Url ++ "?q=1&n=1", "{}"), 91 ?assert(Status =:= 201 orelse Status =:= 202). 92 93 94delete_db(Url) -> 95 {ok, 200, _, _} = test_request:delete(Url, [?AUTH]). 96 97 98put_req(Url, Body) -> 99 put_req(Url, [], Body). 100 101 102put_req(Url, Headers, Body) -> 103 AllHeaders = Headers ++ [?CONTENT_JSON, ?AUTH], 104 case test_request:put(Url, AllHeaders, Body) of 105 {ok, Status, _, _} -> Status; 106 {error, Error} -> Error 107 end. 108 109 110data(Size) -> 111 string:copies("x", Size). 112 113 114append_to_cfg_chain(Cfg) -> 115 CfgDir = filename:dirname(lists:last(?CONFIG_CHAIN)), 116 CfgFile = filename:join([CfgDir, "chttpd_socket_buffer_extra_cfg.ini"]), 117 CfgSect = io_lib:format("[chttpd]~nserver_options = ~s~n", [Cfg]), 118 ok = file:write_file(CfgFile, CfgSect), 119 ?CONFIG_CHAIN ++ [CfgFile]. 120 121 122start_couch_with_cfg(Cfg) -> 123 CfgChain = append_to_cfg_chain(Cfg), 124 StartCtx = test_util:start_couch(CfgChain, [chttpd]), 125 Hashed = couch_passwords:hash_admin_password(?PASS), 126 ok = config:set("admins", ?USER, ?b2l(Hashed), _Persist=false), 127 StartCtx. 128