From 5fa79a85bcb2eea059fd948e89433965f8160b1f Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Mon, 4 Jul 2011 14:35:13 +0000 Subject: Backport r1142685 from trunk: Allow "/" as vhost target. Includes a one-line whitespace fix. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1142689 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/160-vhosts.t | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'test/etap') diff --git a/test/etap/160-vhosts.t b/test/etap/160-vhosts.t index 8dac53e5..4bb8e926 100755 --- a/test/etap/160-vhosts.t +++ b/test/etap/160-vhosts.t @@ -52,7 +52,7 @@ admin_user_ctx() -> {user_ctx, #user_ctx{roles=[<<"_admin">>]}}. main(_) -> test_util:init_code_path(), - etap:plan(14), + etap:plan(15), case (catch test()) of ok -> etap:end_tests(); @@ -115,6 +115,7 @@ test() -> ok = couch_config:set("vhosts", "*.example2.com/test", "/*", false), ok = couch_config:set("vhosts", "*/test1", "/etap-test-db/_design/doc1/_show/test", false), + ok = couch_config:set("vhosts", "example3.com", "/", false), % let couch_httpd restart timer:sleep(100), @@ -133,6 +134,7 @@ test() -> test_vhost_request_path1(), test_vhost_request_path2(), test_vhost_request_path3(), + test_vhost_request_to_root(), %% restart boilerplate couch_db:close(Db), @@ -289,3 +291,13 @@ test_vhost_request_path3() -> end, true, <<"path in req ok">>); _Else -> etap:is(false, true, <<"ibrowse fail">>) end. + +test_vhost_request_to_root() -> + Uri = server(), + case ibrowse:send_req(Uri, [], get, [], []) of + {ok, _, _, Body} -> + {JsonBody} = couch_util:json_decode(Body), + HasCouchDBWelcome = proplists:is_defined(<<"couchdb">>, JsonBody), + etap:is(HasCouchDBWelcome, true, "should allow redirect to /"); + _Else -> etap:is(false, true, <<"ibrowse fail">>) + end. -- cgit v1.2.3 From 916f33c309b53f981400e39a0d65281fd03c6754 Mon Sep 17 00:00:00 2001 From: Randall Leeds Date: Sat, 30 Jul 2011 00:37:37 +0000 Subject: Backport of r1152399 from trunk add an etap test for btree traversal callbacks git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1152407 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/020-btree-basics.t | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test/etap') diff --git a/test/etap/020-btree-basics.t b/test/etap/020-btree-basics.t index 18c4a836..8ab453ee 100755 --- a/test/etap/020-btree-basics.t +++ b/test/etap/020-btree-basics.t @@ -127,6 +127,7 @@ test_btree(Btree, KeyValues) -> ok = test_key_access(Btree, KeyValues), ok = test_lookup_access(Btree, KeyValues), ok = test_final_reductions(Btree, KeyValues), + ok = test_traversal_callbacks(Btree, KeyValues), true. test_add_remove(Btree, OutKeyValues, RemainingKeyValues) -> @@ -187,6 +188,18 @@ test_final_reductions(Btree, KeyValues) -> KVLen = FoldLRed + FoldRRed, ok. +test_traversal_callbacks(Btree, KeyValues) -> + FoldFun = + fun + (visit, GroupedKey, Unreduced, Acc) -> + {ok, Acc andalso false}; + (traverse, _LK, _Red, Acc) -> + {skip, Acc andalso true} + end, + % With 250 items the root is a kp. Always skipping should reduce to true. + {ok, _, true} = couch_btree:fold(Btree, FoldFun, true, [{dir, fwd}]), + ok. + shuffle(List) -> randomize(round(math:log(length(List)) + 0.5), List). -- cgit v1.2.3 From 82a10d77d0c206c89e640ca7097d8e12e95eb8be Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 18 Aug 2011 05:50:42 +0000 Subject: Merge revision 1159045 from trunk Fix dead lock case in the os process pool Part of this patch was done by Paul Davis. The patch also introduces a test case to validate that the os process pool (couch_query_servers) operates as it should. Closes COUCHDB-1246. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1159049 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/210-os-proc-pool.t | 161 +++++++++++++++++++++++++++++++++++++++++++ test/etap/Makefile.am | 4 +- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 test/etap/210-os-proc-pool.t (limited to 'test/etap') diff --git a/test/etap/210-os-proc-pool.t b/test/etap/210-os-proc-pool.t new file mode 100644 index 00000000..b68d66be --- /dev/null +++ b/test/etap/210-os-proc-pool.t @@ -0,0 +1,161 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +main(_) -> + test_util:init_code_path(), + + etap:plan(19), + case (catch test()) of + ok -> + etap:end_tests(); + Other -> + etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), + etap:bail(Other) + end, + ok. + + +test() -> + couch_server_sup:start_link(test_util:config_files()), + couch_config:set("query_server_config", "os_process_limit", "3", false), + + test_pool_full(), + test_client_unexpected_exit(), + + couch_server_sup:stop(), + ok. + + +test_pool_full() -> + Client1 = spawn_client(), + Client2 = spawn_client(), + Client3 = spawn_client(), + + etap:diag("Check that we can spawn the max number of processes."), + etap:is(ping_client(Client1), ok, "Client 1 started ok."), + etap:is(ping_client(Client2), ok, "Client 2 started ok."), + etap:is(ping_client(Client3), ok, "Client 3 started ok."), + + Proc1 = get_client_proc(Client1, "1"), + Proc2 = get_client_proc(Client2, "2"), + Proc3 = get_client_proc(Client3, "3"), + etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."), + etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."), + + etap:diag("Check that client 4 blocks waiting for a process."), + Client4 = spawn_client(), + etap:is(ping_client(Client4), timeout, "Client 4 blocked while waiting."), + + etap:diag("Check that stopping a client gives up its process."), + etap:is(stop_client(Client1), ok, "First client stopped."), + + etap:diag("And check that our blocked process has been unblocked."), + etap:is(ping_client(Client4), ok, "Client was unblocked."), + + Proc4 = get_client_proc(Client4, "4"), + etap:is(Proc4, Proc1, "Client 4 got proc that client 1 got before."), + + lists:map(fun(C) -> ok = stop_client(C) end, [Client2, Client3, Client4]). + + +test_client_unexpected_exit() -> + Client1 = spawn_client(), + Client2 = spawn_client(), + Client3 = spawn_client(), + + etap:diag("Check that up to os_process_limit clients started."), + etap:is(ping_client(Client1), ok, "Client 1 started ok."), + etap:is(ping_client(Client2), ok, "Client 2 started ok."), + etap:is(ping_client(Client3), ok, "Client 3 started ok."), + + Proc1 = get_client_proc(Client1, "1"), + Proc2 = get_client_proc(Client2, "2"), + Proc3 = get_client_proc(Client3, "3"), + etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."), + etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."), + + etap:diag("Check that killing a client frees an os_process."), + etap:is(kill_client(Client1), ok, "Client 1 died all right."), + + etap:diag("Check that a new client is not blocked on boot."), + Client4 = spawn_client(), + etap:is(ping_client(Client4), ok, "New client booted without blocking."), + + Proc4 = get_client_proc(Client4, "4"), + etap:isnt(Proc4, Proc1, + "Client 4 got a proc different from the one client 1 got before."), + etap:isnt(Proc4, Proc2, "Client 4's proc different from client 2's proc."), + etap:isnt(Proc4, Proc3, "Client 4's proc different from client 3's proc."), + + lists:map(fun(C) -> ok = stop_client(C) end, [Client2, Client3, Client4]). + + +spawn_client() -> + Parent = self(), + Ref = make_ref(), + Pid = spawn(fun() -> + Proc = couch_query_servers:get_os_process(<<"javascript">>), + loop(Parent, Ref, Proc) + end), + {Pid, Ref}. + + +ping_client({Pid, Ref}) -> + Pid ! ping, + receive + {pong, Ref} -> ok + after 3000 -> timeout + end. + + +get_client_proc({Pid, Ref}, ClientName) -> + Pid ! get_proc, + receive + {proc, Ref, Proc} -> Proc + after 3000 -> + etap:bail("Timeout getting client " ++ ClientName ++ " proc.") + end. + + +stop_client({Pid, Ref}) -> + Pid ! stop, + receive + {stop, Ref} -> ok + after 3000 -> timeout + end. + + +kill_client({Pid, Ref}) -> + Pid ! die, + receive + {die, Ref} -> ok + after 3000 -> timeout + end. + + +loop(Parent, Ref, Proc) -> + receive + ping -> + Parent ! {pong, Ref}, + loop(Parent, Ref, Proc); + get_proc -> + Parent ! {proc, Ref, Proc}, + loop(Parent, Ref, Proc); + stop -> + couch_query_servers:ret_os_process(Proc), + Parent ! {stop, Ref}; + die -> + Parent ! {die, Ref}, + exit(some_error) + end. diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am index ecbc3a93..c3a4ddab 100644 --- a/test/etap/Makefile.am +++ b/test/etap/Makefile.am @@ -87,4 +87,6 @@ EXTRA_DIST = \ 180-http-proxy.ini \ 180-http-proxy.t \ 190-oauth.t \ - 200-view-group-no-db-leaks.t + 200-view-group-no-db-leaks.t \ + 210-os-proc-pool.t + -- cgit v1.2.3 From 33c0215fb3b06d814ea8c48e6f88c68833e8d1b3 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 18 Aug 2011 05:51:31 +0000 Subject: Added executable bit to test/etap/210-os-proc-pool.t git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1159050 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/210-os-proc-pool.t | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test/etap/210-os-proc-pool.t (limited to 'test/etap') diff --git a/test/etap/210-os-proc-pool.t b/test/etap/210-os-proc-pool.t old mode 100644 new mode 100755 -- cgit v1.2.3 From 542f2732a4240a737cac02a29e6c58d90571e742 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 18 Aug 2011 06:40:39 +0000 Subject: Add missing assertions to test/etap/210-os-proc-pool.t git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1159059 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/210-os-proc-pool.t | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test/etap') diff --git a/test/etap/210-os-proc-pool.t b/test/etap/210-os-proc-pool.t index b68d66be..d80707e8 100755 --- a/test/etap/210-os-proc-pool.t +++ b/test/etap/210-os-proc-pool.t @@ -15,7 +15,7 @@ main(_) -> test_util:init_code_path(), - etap:plan(19), + etap:plan(21), case (catch test()) of ok -> etap:end_tests(); @@ -52,6 +52,7 @@ test_pool_full() -> Proc3 = get_client_proc(Client3, "3"), etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."), etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."), + etap:isnt(Proc1, Proc3, "Clients 1 and 3 got different procs."), etap:diag("Check that client 4 blocks waiting for a process."), Client4 = spawn_client(), @@ -84,6 +85,7 @@ test_client_unexpected_exit() -> Proc3 = get_client_proc(Client3, "3"), etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."), etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."), + etap:isnt(Proc1, Proc3, "Clients 1 and 3 got different procs."), etap:diag("Check that killing a client frees an os_process."), etap:is(kill_client(Client1), ok, "Client 1 died all right."), -- cgit v1.2.3 From dc5c3520db2a1491ffeb9fec1b9c5a5a5694148e Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 15 Sep 2011 23:48:23 +0000 Subject: Make sure view compaction terminates If a view group is compacting and the corresponding database is shutdown by the LRU system, then the view compaction is aborted because its couch view group process shutdowns. This could lead to situations where the number of active databases is much higher than max_dbs_open and making it impossible to compact view groups. Issue reported and patch tested by Mike Leddy. Thanks. COUCHDB-1283 This is a backport of revision 1171328 from branch 1.2.x git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1171329 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/200-view-group-no-db-leaks.t | 2 +- test/etap/201-view-group-shutdown.t | 300 +++++++++++++++++++++++++++++++++ test/etap/Makefile.am | 1 + 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100755 test/etap/201-view-group-shutdown.t (limited to 'test/etap') diff --git a/test/etap/200-view-group-no-db-leaks.t b/test/etap/200-view-group-no-db-leaks.t index 9c77f1a8..f506b7dc 100755 --- a/test/etap/200-view-group-no-db-leaks.t +++ b/test/etap/200-view-group-no-db-leaks.t @@ -165,7 +165,7 @@ wait_db_compact_done(N) -> end. compact_view_group() -> - ok = couch_view_compactor:start_compact(test_db_name(), ddoc_name()), + {ok, _} = couch_view_compactor:start_compact(test_db_name(), ddoc_name()), wait_view_compact_done(10). wait_view_compact_done(0) -> diff --git a/test/etap/201-view-group-shutdown.t b/test/etap/201-view-group-shutdown.t new file mode 100755 index 00000000..03feac2b --- /dev/null +++ b/test/etap/201-view-group-shutdown.t @@ -0,0 +1,300 @@ +#!/usr/bin/env escript +%% -*- erlang -*- + +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-record(user_ctx, { + name = null, + roles = [], + handler +}). + +-record(db, { + main_pid = nil, + update_pid = nil, + compactor_pid = nil, + instance_start_time, % number of microsecs since jan 1 1970 as a binary string + fd, + fd_ref_counter, + header = nil, + committed_update_seq, + fulldocinfo_by_id_btree, + docinfo_by_seq_btree, + local_docs_btree, + update_seq, + name, + filepath, + validate_doc_funs = [], + security = [], + security_ptr = nil, + user_ctx = #user_ctx{}, + waiting_delayed_commit = nil, + revs_limit = 1000, + fsync_options = [], + is_sys_db = false +}). + +main_db_name() -> <<"couch_test_view_group_shutdown">>. + + +main(_) -> + test_util:init_code_path(), + + etap:plan(17), + case (catch test()) of + ok -> + etap:end_tests(); + Other -> + etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), + etap:bail(Other) + end, + ok. + + +test() -> + couch_server_sup:start_link(test_util:config_files()), + ok = couch_config:set("couchdb", "max_dbs_open", "3", false), + ok = couch_config:set("couchdb", "delayed_commits", "false", false), + crypto:start(), + + % Test that while a view group is being compacted its database can not + % be closed by the database LRU system. + test_view_group_compaction(), + + couch_server_sup:stop(), + ok. + + +test_view_group_compaction() -> + {ok, DbWriter3} = create_db(<<"couch_test_view_group_shutdown_w3">>), + ok = couch_db:close(DbWriter3), + + {ok, MainDb} = create_main_db(), + ok = couch_db:close(MainDb), + + {ok, DbWriter1} = create_db(<<"couch_test_view_group_shutdown_w1">>), + ok = couch_db:close(DbWriter1), + + {ok, DbWriter2} = create_db(<<"couch_test_view_group_shutdown_w2">>), + ok = couch_db:close(DbWriter2), + + Writer1 = spawn_writer(DbWriter1#db.name), + Writer2 = spawn_writer(DbWriter2#db.name), + etap:is(is_process_alive(Writer1), true, "Spawned writer 1"), + etap:is(is_process_alive(Writer2), true, "Spawned writer 2"), + + etap:is(get_writer_status(Writer1), ok, "Writer 1 opened his database"), + etap:is(get_writer_status(Writer2), ok, "Writer 2 opened his database"), + + {ok, CompactPid} = couch_view_compactor:start_compact( + MainDb#db.name, <<"foo">>), + MonRef = erlang:monitor(process, CompactPid), + + % Add some more docs to database and trigger view update + {ok, MainDb2} = couch_db:open_int(MainDb#db.name, []), + ok = populate_main_db(MainDb2, 3, 3), + update_view(MainDb2#db.name, <<"_design/foo">>, <<"foo">>), + ok = couch_db:close(MainDb2), + + % Assuming the view compaction takes more than 50ms to complete + ok = timer:sleep(50), + Writer3 = spawn_writer(DbWriter3#db.name), + etap:is(is_process_alive(Writer3), true, "Spawned writer 3"), + + etap:is(get_writer_status(Writer3), {error, all_dbs_active}, + "Writer 3 got {error, all_dbs_active} when opening his database"), + + etap:is(is_process_alive(Writer1), true, "Writer 1 still alive"), + etap:is(is_process_alive(Writer2), true, "Writer 2 still alive"), + etap:is(is_process_alive(Writer3), true, "Writer 3 still alive"), + + receive + {'DOWN', MonRef, process, CompactPid, normal} -> + etap:diag("View group compaction successful"), + ok; + {'DOWN', MonRef, process, CompactPid, _Reason} -> + etap:bail("Failure compacting view group") + end, + + ok = timer:sleep(2000), + + etap:is(writer_try_again(Writer3), ok, + "Told writer 3 to try open his database again"), + etap:is(get_writer_status(Writer3), ok, + "Writer 3 was able to open his database"), + + etap:is(is_process_alive(Writer1), true, "Writer 1 still alive"), + etap:is(is_process_alive(Writer2), true, "Writer 2 still alive"), + etap:is(is_process_alive(Writer3), true, "Writer 3 still alive"), + + etap:is(stop_writer(Writer1), ok, "Stopped writer 1"), + etap:is(stop_writer(Writer2), ok, "Stopped writer 2"), + etap:is(stop_writer(Writer3), ok, "Stopped writer 3"), + + delete_db(MainDb), + delete_db(DbWriter1), + delete_db(DbWriter2), + delete_db(DbWriter3). + + +create_main_db() -> + {ok, Db} = create_db(main_db_name()), + DDoc = couch_doc:from_json_obj({[ + {<<"_id">>, <<"_design/foo">>}, + {<<"language">>, <<"javascript">>}, + {<<"views">>, {[ + {<<"foo">>, {[ + {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>} + ]}}, + {<<"foo2">>, {[ + {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>} + ]}}, + {<<"foo3">>, {[ + {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>} + ]}}, + {<<"foo4">>, {[ + {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>} + ]}}, + {<<"foo5">>, {[ + {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>} + ]}} + ]}} + ]}), + {ok, _} = couch_db:update_doc(Db, DDoc, []), + ok = populate_main_db(Db, 1000, 20000), + update_view(Db#db.name, <<"_design/foo">>, <<"foo">>), + {ok, Db}. + + +populate_main_db(Db, BatchSize, N) when N > 0 -> + Docs = lists:map( + fun(_) -> + couch_doc:from_json_obj({[ + {<<"_id">>, couch_uuids:new()}, + {<<"value">>, base64:encode(crypto:rand_bytes(1000))} + ]}) + end, + lists:seq(1, BatchSize)), + {ok, _} = couch_db:update_docs(Db, Docs, []), + populate_main_db(Db, BatchSize, N - length(Docs)); +populate_main_db(_Db, _, _) -> + ok. + + +update_view(DbName, DDocName, ViewName) -> + % Use a dedicated process - we can't explicitly drop the #group ref counter + Pid = spawn(fun() -> + {ok, Db} = couch_db:open_int(DbName, []), + couch_view:get_map_view(Db, DDocName, ViewName, false), + ok = couch_db:close(Db) + end), + MonRef = erlang:monitor(process, Pid), + receive + {'DOWN', MonRef, process, Pid, normal} -> + etap:diag("View group updated"), + ok; + {'DOWN', MonRef, process, Pid, _Reason} -> + etap:bail("Failure updating view group") + end. + + +create_db(DbName) -> + {ok, Db} = couch_db:create( + DbName, + [{user_ctx, #user_ctx{roles = [<<"_admin">>]}}, overwrite]), + {ok, Db}. + + +delete_db(#db{name = DbName, main_pid = Pid}) -> + ok = couch_server:delete( + DbName, [{user_ctx, #user_ctx{roles = [<<"_admin">>]}}]), + MonRef = erlang:monitor(process, Pid), + receive + {'DOWN', MonRef, process, Pid, _Reason} -> + ok + after 30000 -> + etap:bail("Timeout deleting database") + end. + + +spawn_writer(DbName) -> + Parent = self(), + spawn(fun() -> + process_flag(priority, high), + writer_loop(DbName, Parent) + end). + + +get_writer_status(Writer) -> + Ref = make_ref(), + Writer ! {get_status, Ref}, + receive + {db_open, Ref} -> + ok; + {db_open_error, Error, Ref} -> + Error + after 5000 -> + timeout + end. + + +writer_try_again(Writer) -> + Ref = make_ref(), + Writer ! {try_again, Ref}, + receive + {ok, Ref} -> + ok + after 5000 -> + timeout + end. + + +stop_writer(Writer) -> + Ref = make_ref(), + Writer ! {stop, Ref}, + receive + {ok, Ref} -> + ok + after 5000 -> + etap:bail("Timeout stopping writer process") + end. + + +% Just keep the database open, no need to actually do something on it. +writer_loop(DbName, Parent) -> + case couch_db:open_int(DbName, []) of + {ok, Db} -> + writer_loop_1(Db, Parent); + Error -> + writer_loop_2(DbName, Parent, Error) + end. + +writer_loop_1(Db, Parent) -> + receive + {get_status, Ref} -> + Parent ! {db_open, Ref}, + writer_loop_1(Db, Parent); + {stop, Ref} -> + ok = couch_db:close(Db), + Parent ! {ok, Ref} + end. + +writer_loop_2(DbName, Parent, Error) -> + receive + {get_status, Ref} -> + Parent ! {db_open_error, Error, Ref}, + writer_loop_2(DbName, Parent, Error); + {try_again, Ref} -> + Parent ! {ok, Ref}, + writer_loop(DbName, Parent) + end. diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am index c3a4ddab..313945d7 100644 --- a/test/etap/Makefile.am +++ b/test/etap/Makefile.am @@ -88,5 +88,6 @@ EXTRA_DIST = \ 180-http-proxy.t \ 190-oauth.t \ 200-view-group-no-db-leaks.t \ + 201-view-group-shutdown.t \ 210-os-proc-pool.t -- cgit v1.2.3 From 1285cd95c8fe351991218f886bbfe28d9a9a3b09 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 29 Sep 2011 23:34:40 +0000 Subject: Remove usage of http module from etap tests This module is deprecated in OTP R15, which is going to be released by the end of this year. The etap tests now use ibrowse instead. This is a backport of revision 1177459 from trunk. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1177463 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/072-cleanup.t | 8 +- test/etap/113-replication-attachment-comp.t | 77 +++---- test/etap/140-attachment-comp.t | 319 ++++++++++++---------------- test/etap/150-invalid-view-seq.t | 15 +- test/etap/200-view-group-no-db-leaks.t | 33 +-- test/etap/test_util.erl.in | 28 +++ 6 files changed, 217 insertions(+), 263 deletions(-) (limited to 'test/etap') diff --git a/test/etap/072-cleanup.t b/test/etap/072-cleanup.t index 61790bc6..6f97193d 100755 --- a/test/etap/072-cleanup.t +++ b/test/etap/072-cleanup.t @@ -41,7 +41,6 @@ main(_) -> test() -> {ok, _} = couch_server_sup:start_link(test_util:config_files()), - ok = application:start(inets), couch_server:delete(?TEST_DB, []), timer:sleep(1000), @@ -110,11 +109,8 @@ db_url() -> binary_to_list(?TEST_DB). query_view(DDoc, View) -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( - get, - {db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, []}, - [], - [{sync, true}]), + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, [], get), etap:is(Code, 200, "Built view index for " ++ DDoc ++ "."), ok. diff --git a/test/etap/113-replication-attachment-comp.t b/test/etap/113-replication-attachment-comp.t index e30a96bc..bc98ca18 100755 --- a/test/etap/113-replication-attachment-comp.t +++ b/test/etap/113-replication-attachment-comp.t @@ -41,8 +41,6 @@ test() -> couch_server_sup:start_link(test_util:config_files()), put(addr, couch_config:get("httpd", "bind_address", "127.0.0.1")), put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - application:start(inets), - ibrowse:start(), timer:sleep(1000), % @@ -133,12 +131,11 @@ test() -> ok. put_text_att(DbName) -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, Body} = test_util:request( + db_url(DbName) ++ "/testdoc1/readme.txt", + [{"Content-Type", "text/plain"}], put, - {db_url(DbName) ++ "/testdoc1/readme.txt", [], - "text/plain", test_text_data()}, - [], - [{sync, true}]), + test_text_data()), etap:is(Code, 201, "Created text attachment"), ok. @@ -147,12 +144,11 @@ do_pull_replication(SourceDbName, TargetDbName) -> {<<"source">>, list_to_binary(db_url(SourceDbName))}, {<<"target">>, TargetDbName} ]}, - {ok, {{_, Code, _}, _Headers, Body}} = http:request( + {ok, Code, _Headers, Body} = test_util:request( + rep_url(), + [{"Content-Type", "application/json"}], post, - {rep_url(), [], - "application/json", list_to_binary(couch_util:json_encode(RepObj))}, - [], - [{sync, true}]), + iolist_to_binary(couch_util:json_encode(RepObj))), etap:is(Code, 200, "Pull replication successfully triggered"), Json = couch_util:json_decode(Body), RepOk = couch_util:get_nested_json_value(Json, [<<"ok">>]), @@ -164,12 +160,11 @@ do_push_replication(SourceDbName, TargetDbName) -> {<<"source">>, SourceDbName}, {<<"target">>, list_to_binary(db_url(TargetDbName))} ]}, - {ok, {{_, Code, _}, _Headers, Body}} = http:request( + {ok, Code, _Headers, Body} = test_util:request( + rep_url(), + [{"Content-Type", "application/json"}], post, - {rep_url(), [], - "application/json", list_to_binary(couch_util:json_encode(RepObj))}, - [], - [{sync, true}]), + iolist_to_binary(couch_util:json_encode(RepObj))), etap:is(Code, 200, "Push replication successfully triggered"), Json = couch_util:json_decode(Body), RepOk = couch_util:get_nested_json_value(Json, [<<"ok">>]), @@ -181,12 +176,11 @@ do_local_replication(SourceDbName, TargetDbName) -> {<<"source">>, SourceDbName}, {<<"target">>, TargetDbName} ]}, - {ok, {{_, Code, _}, _Headers, Body}} = http:request( + {ok, Code, _Headers, Body} = test_util:request( + rep_url(), + [{"Content-Type", "application/json"}], post, - {rep_url(), [], - "application/json", list_to_binary(couch_util:json_encode(RepObj))}, - [], - [{sync, true}]), + iolist_to_binary(couch_util:json_encode(RepObj))), etap:is(Code, 200, "Local replication successfully triggered"), Json = couch_util:json_decode(Body), RepOk = couch_util:get_nested_json_value(Json, [<<"ok">>]), @@ -194,16 +188,14 @@ do_local_replication(SourceDbName, TargetDbName) -> ok. check_att_is_compressed(DbName) -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url(DbName) ++ "/testdoc1/readme.txt", - [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url(DbName) ++ "/testdoc1/readme.txt", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code for the attachment request is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, true, "The attachment was received in compressed form"), - Uncompressed = binary_to_list(zlib:gunzip(list_to_binary(Body))), + Uncompressed = zlib:gunzip(Body), etap:is( Uncompressed, test_text_data(), @@ -212,13 +204,12 @@ check_att_is_compressed(DbName) -> ok. check_server_can_decompress_att(DbName) -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url(DbName) ++ "/testdoc1/readme.txt", []}, + {ok, Code, Headers, Body} = test_util:request( + db_url(DbName) ++ "/testdoc1/readme.txt", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code for the attachment request is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is( Gziped, false, "The attachment was not received in compressed form" ), @@ -230,11 +221,10 @@ check_server_can_decompress_att(DbName) -> ok. check_att_stubs(SourceDbName, TargetDbName) -> - {ok, {{_, Code1, _}, _Headers1, Body1}} = http:request( - get, - {db_url(SourceDbName) ++ "/testdoc1?att_encoding_info=true", []}, + {ok, Code1, _Headers1, Body1} = test_util:request( + db_url(SourceDbName) ++ "/testdoc1?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is( Code1, 200, @@ -245,11 +235,10 @@ check_att_stubs(SourceDbName, TargetDbName) -> Json1, [<<"_attachments">>, <<"readme.txt">>] ), - {ok, {{_, Code2, _}, _Headers2, Body2}} = http:request( - get, - {db_url(TargetDbName) ++ "/testdoc1?att_encoding_info=true", []}, + {ok, Code2, _Headers2, Body2} = test_util:request( + db_url(SourceDbName) ++ "/testdoc1?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is( Code2, 200, @@ -311,4 +300,4 @@ rep_url() -> test_text_data() -> {ok, Data} = file:read_file(test_util:source_file("README")), - binary_to_list(Data). + Data. diff --git a/test/etap/140-attachment-comp.t b/test/etap/140-attachment-comp.t index 475f4fb0..861096a0 100755 --- a/test/etap/140-attachment-comp.t +++ b/test/etap/140-attachment-comp.t @@ -33,7 +33,6 @@ test() -> couch_server_sup:start_link(test_util:config_files()), put(addr, couch_config:get("httpd", "bind_address", "127.0.0.1")), put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - application:start(inets), timer:sleep(1000), couch_server:delete(test_db_name(), []), couch_db:create(test_db_name(), []), @@ -84,22 +83,20 @@ db_url() -> binary_to_list(test_db_name()). create_1st_text_att() -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc1/readme.txt", + [{"Content-Type", "text/plain"}], put, - {db_url() ++ "/testdoc1/readme.txt", [], - "text/plain", test_text_data()}, - [], - [{sync, true}]), + test_text_data()), etap:is(Code, 201, "Created text attachment using the standalone api"), ok. create_1st_png_att() -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc2/icon.png", + [{"Content-Type", "image/png"}], put, - {db_url() ++ "/testdoc2/icon.png", [], - "image/png", test_png_data()}, - [], - [{sync, true}]), + test_png_data()), etap:is(Code, 201, "Created png attachment using the standalone api"), ok. @@ -113,12 +110,11 @@ create_2nd_text_att() -> ]} }]}} ]}, - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc3", + [{"Content-Type", "application/json"}], put, - {db_url() ++ "/testdoc3", [], - "application/json", list_to_binary(couch_util:json_encode(DocJson))}, - [], - [{sync, true}]), + iolist_to_binary(couch_util:json_encode(DocJson))), etap:is(Code, 201, "Created text attachment using the non-standalone api"), ok. @@ -132,22 +128,20 @@ create_2nd_png_att() -> ]} }]}} ]}, - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc4", + [{"Content-Type", "application/json"}], put, - {db_url() ++ "/testdoc4", [], - "application/json", list_to_binary(couch_util:json_encode(DocJson))}, - [], - [{sync, true}]), + iolist_to_binary(couch_util:json_encode(DocJson))), etap:is(Code, 201, "Created png attachment using the non-standalone api"), ok. create_already_compressed_att(DocUri, AttName) -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + DocUri ++ "/" ++ AttName, + [{"Content-Type", "text/plain"}, {"Content-Encoding", "gzip"}], put, - {DocUri ++ "/" ++ AttName, [{"Content-Encoding", "gzip"}], - "text/plain", zlib:gzip(test_text_data())}, - [], - [{sync, true}]), + zlib:gzip(test_text_data())), etap:is( Code, 201, @@ -183,15 +177,14 @@ tests_for_2nd_png_att() -> test_2nd_png_att_stub(). test_get_1st_text_att_with_accept_encoding_gzip() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc1/readme.txt", [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc1/readme.txt", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, true, "received body is gziped"), - Uncompressed = binary_to_list(zlib:gunzip(list_to_binary(Body))), + Uncompressed = zlib:gunzip(Body), etap:is( Uncompressed, test_text_data(), @@ -200,13 +193,12 @@ test_get_1st_text_att_with_accept_encoding_gzip() -> ok. test_get_1st_text_att_without_accept_encoding_header() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc1/readme.txt", []}, + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc1/readme.txt", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), etap:is( Body, @@ -216,15 +208,14 @@ test_get_1st_text_att_without_accept_encoding_header() -> ok. test_get_1st_text_att_with_accept_encoding_deflate() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc1/readme.txt", [{"Accept-Encoding", "deflate"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc1/readme.txt", + [{"Accept-Encoding", "deflate"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), - Deflated = lists:member({"content-encoding", "deflate"}, Headers), + Deflated = lists:member({"Content-Encoding", "deflate"}, Headers), etap:is(Deflated, false, "received body is not deflated"), etap:is( Body, @@ -234,12 +225,10 @@ test_get_1st_text_att_with_accept_encoding_deflate() -> ok. test_get_1st_text_att_with_accept_encoding_deflate_only() -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( - get, - {db_url() ++ "/testdoc1/readme.txt", - [{"Accept-Encoding", "deflate, *;q=0"}]}, - [], - [{sync, true}]), + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc1/readme.txt", + [{"Accept-Encoding", "deflate, *;q=0"}], + get), etap:is( Code, 406, @@ -248,13 +237,12 @@ test_get_1st_text_att_with_accept_encoding_deflate_only() -> ok. test_get_1st_png_att_without_accept_encoding_header() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc2/icon.png", []}, + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc2/icon.png", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("content-encoding", Headers), + Encoding = couch_util:get_value("Content-Encoding", Headers), etap:is(Encoding, undefined, "received body is not gziped"), etap:is( Body, @@ -264,13 +252,12 @@ test_get_1st_png_att_without_accept_encoding_header() -> ok. test_get_1st_png_att_with_accept_encoding_gzip() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc2/icon.png", [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc2/icon.png", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("content-encoding", Headers), + Encoding = couch_util:get_value("Content-Encoding", Headers), etap:is(Encoding, undefined, "received body is not gziped"), etap:is( Body, @@ -280,13 +267,12 @@ test_get_1st_png_att_with_accept_encoding_gzip() -> ok. test_get_1st_png_att_with_accept_encoding_deflate() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc2/icon.png", [{"Accept-Encoding", "deflate"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc2/icon.png", + [{"Accept-Encoding", "deflate"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("content-encoding", Headers), + Encoding = couch_util:get_value("Content-Encoding", Headers), etap:is(Encoding, undefined, "received body is in identity form"), etap:is( Body, @@ -296,12 +282,10 @@ test_get_1st_png_att_with_accept_encoding_deflate() -> ok. test_get_doc_with_1st_text_att() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc1?attachments=true", - [{"Accept", "application/json"}]}, - [], - [{sync, true}]), + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc1?attachments=true", + [{"Accept", "application/json"}], + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), TextAttJson = couch_util:get_nested_json_value( @@ -331,11 +315,10 @@ test_get_doc_with_1st_text_att() -> ok. test_1st_text_att_stub() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc1?att_encoding_info=true", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc1?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), {TextAttJson} = couch_util:get_nested_json_value( @@ -345,7 +328,7 @@ test_1st_text_att_stub() -> TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), etap:is( TextAttLength, - length(test_text_data()), + byte_size(test_text_data()), "1st text attachment stub length matches the uncompressed length" ), TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), @@ -363,12 +346,10 @@ test_1st_text_att_stub() -> ok. test_get_doc_with_1st_png_att() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc2?attachments=true", - [{"Accept", "application/json"}]}, - [], - [{sync, true}]), + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc2?attachments=true", + [{"Accept", "application/json"}], + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), PngAttJson = couch_util:get_nested_json_value( @@ -392,11 +373,10 @@ test_get_doc_with_1st_png_att() -> ok. test_1st_png_att_stub() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc2?att_encoding_info=true", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc2?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), {PngAttJson} = couch_util:get_nested_json_value( @@ -406,7 +386,7 @@ test_1st_png_att_stub() -> PngAttLength = couch_util:get_value(<<"length">>, PngAttJson), etap:is( PngAttLength, - length(test_png_data()), + byte_size(test_png_data()), "1st png attachment stub length matches the uncompressed length" ), PngEncoding = couch_util:get_value(<<"encoding">>, PngAttJson), @@ -424,15 +404,14 @@ test_1st_png_att_stub() -> ok. test_get_2nd_text_att_with_accept_encoding_gzip() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc3/readme.txt", [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc3/readme.txt", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, true, "received body is gziped"), - Uncompressed = binary_to_list(zlib:gunzip(list_to_binary(Body))), + Uncompressed = zlib:gunzip(Body), etap:is( Uncompressed, test_text_data(), @@ -441,13 +420,12 @@ test_get_2nd_text_att_with_accept_encoding_gzip() -> ok. test_get_2nd_text_att_without_accept_encoding_header() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc3/readme.txt", []}, + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc3/readme.txt", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), etap:is( Body, @@ -457,13 +435,12 @@ test_get_2nd_text_att_without_accept_encoding_header() -> ok. test_get_2nd_png_att_without_accept_encoding_header() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc4/icon.png", []}, + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc4/icon.png", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), etap:is( Body, @@ -473,13 +450,12 @@ test_get_2nd_png_att_without_accept_encoding_header() -> ok. test_get_2nd_png_att_with_accept_encoding_gzip() -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc4/icon.png", [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + db_url() ++ "/testdoc4/icon.png", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), etap:is( Body, @@ -489,12 +465,10 @@ test_get_2nd_png_att_with_accept_encoding_gzip() -> ok. test_get_doc_with_2nd_text_att() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc3?attachments=true", - [{"Accept", "application/json"}]}, - [], - [{sync, true}]), + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc3?attachments=true", + [{"Accept", "application/json"}], + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), TextAttJson = couch_util:get_nested_json_value( @@ -520,11 +494,10 @@ test_get_doc_with_2nd_text_att() -> ok. test_2nd_text_att_stub() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc3?att_encoding_info=true", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc3?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), {TextAttJson} = couch_util:get_nested_json_value( @@ -534,7 +507,7 @@ test_2nd_text_att_stub() -> TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), etap:is( TextAttLength, - length(test_text_data()), + byte_size(test_text_data()), "2nd text attachment stub length matches the uncompressed length" ), TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), @@ -552,12 +525,10 @@ test_2nd_text_att_stub() -> ok. test_get_doc_with_2nd_png_att() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc4?attachments=true", - [{"Accept", "application/json"}]}, - [], - [{sync, true}]), + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc4?attachments=true", + [{"Accept", "application/json"}], + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), PngAttJson = couch_util:get_nested_json_value( @@ -581,11 +552,10 @@ test_get_doc_with_2nd_png_att() -> ok. test_2nd_png_att_stub() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/testdoc4?att_encoding_info=true", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/testdoc4?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), {PngAttJson} = couch_util:get_nested_json_value( @@ -595,7 +565,7 @@ test_2nd_png_att_stub() -> PngAttLength = couch_util:get_value(<<"length">>, PngAttJson), etap:is( PngAttLength, - length(test_png_data()), + byte_size(test_png_data()), "2nd png attachment stub length matches the uncompressed length" ), PngEncoding = couch_util:get_value(<<"encoding">>, PngAttJson), @@ -618,43 +588,40 @@ test_already_compressed_att(DocUri, AttName) -> test_get_already_compressed_att_stub(DocUri, AttName). test_get_already_compressed_att_with_accept_gzip(DocUri, AttName) -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {DocUri ++ "/" ++ AttName, [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code, Headers, Body} = test_util:request( + DocUri ++ "/" ++ AttName, + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, true, "received body is gziped"), etap:is( - iolist_to_binary(Body), - iolist_to_binary(zlib:gzip(test_text_data())), + Body, + zlib:gzip(test_text_data()), "received data for the already compressed attachment is ok" ), ok. test_get_already_compressed_att_without_accept(DocUri, AttName) -> - {ok, {{_, Code, _}, Headers, Body}} = http:request( - get, - {DocUri ++ "/" ++ AttName, []}, + {ok, Code, Headers, Body} = test_util:request( + DocUri ++ "/" ++ AttName, [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), etap:is(Gziped, false, "received body is not gziped"), etap:is( - iolist_to_binary(Body), - iolist_to_binary(test_text_data()), + Body, + test_text_data(), "received data for the already compressed attachment is ok" ), ok. test_get_already_compressed_att_stub(DocUri, AttName) -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {DocUri ++ "?att_encoding_info=true", []}, + {ok, Code, _Headers, Body} = test_util:request( + DocUri ++ "?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body), {AttJson} = couch_util:get_nested_json_value( @@ -685,12 +652,11 @@ test_get_already_compressed_att_stub(DocUri, AttName) -> test_create_already_compressed_att_with_invalid_content_encoding( DocUri, AttName, AttData, Encoding) -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + DocUri ++ "/" ++ AttName, + [{"Content-Encoding", Encoding}, {"Content-Type", "text/plain"}], put, - {DocUri ++ "/" ++ AttName, [{"Content-Encoding", Encoding}], - "text/plain", AttData}, - [], - [{sync, true}]), + AttData), etap:is( Code, 415, @@ -700,29 +666,26 @@ test_create_already_compressed_att_with_invalid_content_encoding( ok. test_compressible_type_with_parameters() -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/testdoc5/readme.txt", + [{"Content-Type", "text/plain; charset=UTF-8"}], put, - {db_url() ++ "/testdoc5/readme.txt", [], - "text/plain; charset=UTF-8", test_text_data()}, - [], - [{sync, true}]), + test_text_data()), etap:is(Code, 201, "Created text attachment with MIME type " "'text/plain; charset=UTF-8' using the standalone api"), - {ok, {{_, Code2, _}, Headers2, Body}} = http:request( - get, - {db_url() ++ "/testdoc5/readme.txt", [{"Accept-Encoding", "gzip"}]}, - [], - [{sync, true}]), + {ok, Code2, Headers2, Body} = test_util:request( + db_url() ++ "/testdoc5/readme.txt", + [{"Accept-Encoding", "gzip"}], + get), etap:is(Code2, 200, "HTTP response code is 200"), - Gziped = lists:member({"content-encoding", "gzip"}, Headers2), + Gziped = lists:member({"Content-Encoding", "gzip"}, Headers2), etap:is(Gziped, true, "received body is gziped"), - Uncompressed = binary_to_list(zlib:gunzip(list_to_binary(Body))), + Uncompressed = zlib:gunzip(Body), etap:is(Uncompressed, test_text_data(), "received data is gzipped"), - {ok, {{_, Code3, _}, _Headers3, Body3}} = http:request( - get, - {db_url() ++ "/testdoc5?att_encoding_info=true", []}, + {ok, Code3, _Headers3, Body3} = test_util:request( + db_url() ++ "/testdoc5?att_encoding_info=true", [], - [{sync, true}]), + get), etap:is(Code3, 200, "HTTP response code is 200"), Json = couch_util:json_decode(Body3), {TextAttJson} = couch_util:get_nested_json_value( @@ -732,7 +695,7 @@ test_compressible_type_with_parameters() -> TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), etap:is( TextAttLength, - length(test_text_data()), + byte_size(test_text_data()), "text attachment stub length matches the uncompressed length" ), TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), @@ -753,10 +716,10 @@ test_png_data() -> {ok, Data} = file:read_file( test_util:source_file("share/www/image/logo.png") ), - binary_to_list(Data). + Data. test_text_data() -> {ok, Data} = file:read_file( test_util:source_file("README") ), - binary_to_list(Data). + Data. diff --git a/test/etap/150-invalid-view-seq.t b/test/etap/150-invalid-view-seq.t index 594d3416..bc44592e 100755 --- a/test/etap/150-invalid-view-seq.t +++ b/test/etap/150-invalid-view-seq.t @@ -52,7 +52,6 @@ test() -> put(addr, couch_config:get("httpd", "bind_address", "127.0.0.1")), put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - application:start(inets), create_new_doc(), query_view_before_restore_backup(), @@ -133,11 +132,10 @@ db_url() -> binary_to_list(test_db_name()). query_view_before_restore_backup() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/_design/foo/_view/bar", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/_design/foo/_view/bar", [], - [{sync, true}]), + get), etap:is(Code, 200, "Got view response before restoring backup."), ViewJson = couch_util:json_decode(Body), Rows = couch_util:get_nested_json_value(ViewJson, [<<"rows">>]), @@ -171,11 +169,10 @@ restore_backup_db_file() -> ok. query_view_after_restore_backup() -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/_design/foo/_view/bar", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/_design/foo/_view/bar", [], - [{sync, true}]), + get), etap:is(Code, 200, "Got view response after restoring backup."), ViewJson = couch_util:json_decode(Body), Rows = couch_util:get_nested_json_value(ViewJson, [<<"rows">>]), diff --git a/test/etap/200-view-group-no-db-leaks.t b/test/etap/200-view-group-no-db-leaks.t index f506b7dc..6c076674 100755 --- a/test/etap/200-view-group-no-db-leaks.t +++ b/test/etap/200-view-group-no-db-leaks.t @@ -19,21 +19,6 @@ handler }). --define(LATEST_DISK_VERSION, 5). - --record(db_header, - {disk_version = ?LATEST_DISK_VERSION, - update_seq = 0, - unused = 0, - fulldocinfo_by_id_btree_state = nil, - docinfo_by_seq_btree_state = nil, - local_docs_btree_state = nil, - purge_seq = 0, - purged_docs = nil, - security_ptr = nil, - revs_limit = 1000 -}). - -record(db, { main_pid = nil, update_pid = nil, @@ -41,7 +26,7 @@ instance_start_time, % number of microsecs since jan 1 1970 as a binary string fd, fd_ref_counter, - header = #db_header{}, + header = nil, committed_update_seq, fulldocinfo_by_id_btree, docinfo_by_seq_btree, @@ -80,7 +65,6 @@ test() -> timer:sleep(1000), put(addr, couch_config:get("httpd", "bind_address", "127.0.0.1")), put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - application:start(inets), delete_db(), create_db(), @@ -171,11 +155,10 @@ compact_view_group() -> wait_view_compact_done(0) -> etap:bail("View group compaction failed to finish."); wait_view_compact_done(N) -> - {ok, {{_, Code, _}, _Headers, Body}} = http:request( - get, - {db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ "/_info", []}, + {ok, Code, _Headers, Body} = test_util:request( + db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ "/_info", [], - [{sync, true}]), + get), case Code of 200 -> ok; _ -> etap:bail("Invalid view group info.") @@ -252,11 +235,9 @@ db_url() -> binary_to_list(test_db_name()). query_view() -> - {ok, {{_, Code, _}, _Headers, _Body}} = http:request( - get, - {db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ - "/_view/bar", []}, + {ok, Code, _Headers, _Body} = test_util:request( + db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ "/_view/bar", [], - [{sync, true}]), + get), etap:is(Code, 200, "got view response"), ok. diff --git a/test/etap/test_util.erl.in b/test/etap/test_util.erl.in index 460b0293..b986ff35 100644 --- a/test/etap/test_util.erl.in +++ b/test/etap/test_util.erl.in @@ -14,6 +14,7 @@ -export([init_code_path/0]). -export([source_file/1, build_file/1, config_files/0]). +-export([request/3, request/4]). srcdir() -> "@abs_top_srcdir@". @@ -40,3 +41,30 @@ config_files() -> source_file("test/etap/random_port.ini") ]. +request(Url, Headers, Method) -> + request(Url, Headers, Method, []). + +request(Url, Headers, Method, Body) -> + request(Url, Headers, Method, Body, 3). + +request(_Url, _Headers, _Method, _Body, 0) -> + {error, request_failed}; +request(Url, Headers, Method, Body, N) -> + case code:is_loaded(ibrowse) of + false -> + {ok, _} = ibrowse:start(); + _ -> + ok + end, + case ibrowse:send_req(Url, Headers, Method, Body) of + {ok, Code0, RespHeaders, RespBody0} -> + Code = list_to_integer(Code0), + RespBody = iolist_to_binary(RespBody0), + {ok, Code, RespHeaders, RespBody}; + {error, {'EXIT', {normal, _}}} -> + % Connection closed right after a successful request that + % used the same connection. + request(Url, Headers, Method, Body, N - 1); + Error -> + Error + end. -- cgit v1.2.3