Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5AFE9185E7 for ; Wed, 2 Dec 2015 23:02:07 +0000 (UTC) Received: (qmail 43902 invoked by uid 500); 2 Dec 2015 23:02:05 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 43289 invoked by uid 500); 2 Dec 2015 23:02:04 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 40907 invoked by uid 99); 2 Dec 2015 23:02:02 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Dec 2015 23:02:02 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id F06DFE67D9; Wed, 2 Dec 2015 23:02:01 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Wed, 02 Dec 2015 23:02:43 -0000 Message-Id: In-Reply-To: <420563d655c74cdd8457841366bdc54d@git.apache.org> References: <420563d655c74cdd8457841366bdc54d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [43/50] couchdb commit: updated refs/heads/1.x.x to 921006f Port couch_replicator/02-httpc-pool.t etap test suite to eunit Test test_worker_dead_pool_full removed as it's redundant. Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/544748e8 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/544748e8 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/544748e8 Branch: refs/heads/1.x.x Commit: 544748e8d80bfd24e0f7dcc821c25c8e5d6eff8b Parents: 1bc015a Author: Alexander Shorin Authored: Thu Jun 12 11:03:38 2014 +0400 Committer: Alexander Shorin Committed: Thu Dec 3 00:52:10 2015 +0300 ---------------------------------------------------------------------- src/couch_replicator/Makefile.am | 2 +- src/couch_replicator/test/02-httpc-pool.t | 250 ------------------- .../test/couch_replicator_httpc_pool_tests.erl | 189 ++++++++++++++ 3 files changed, 190 insertions(+), 251 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/544748e8/src/couch_replicator/Makefile.am ---------------------------------------------------------------------- diff --git a/src/couch_replicator/Makefile.am b/src/couch_replicator/Makefile.am index 4f0aab2..522716c 100644 --- a/src/couch_replicator/Makefile.am +++ b/src/couch_replicator/Makefile.am @@ -36,8 +36,8 @@ source_files = \ src/couch_replicator.erl test_files = \ + test/couch_replicator_httpc_pool_tests.erl \ test/couch_replicator_modules_load_tests.erl \ - test/02-httpc-pool.t \ test/03-replication-compact.t \ test/04-replication-large-atts.t \ test/05-replication-many-leaves.t \ http://git-wip-us.apache.org/repos/asf/couchdb/blob/544748e8/src/couch_replicator/test/02-httpc-pool.t ---------------------------------------------------------------------- diff --git a/src/couch_replicator/test/02-httpc-pool.t b/src/couch_replicator/test/02-httpc-pool.t deleted file mode 100755 index a7bde6c..0000000 --- a/src/couch_replicator/test/02-httpc-pool.t +++ /dev/null @@ -1,250 +0,0 @@ -#!/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(55), - 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()), - ibrowse:start(), - - test_pool_full(), - test_worker_dead_pool_non_full(), - test_worker_dead_pool_full(), - - couch_server_sup:stop(), - ok. - - -test_pool_full() -> - Pool = spawn_pool(), - Client1 = spawn_client(Pool), - Client2 = spawn_client(Pool), - Client3 = spawn_client(Pool), - - etap:diag("Check that we can spawn the max number of connections."), - 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."), - - Worker1 = get_client_worker(Client1, "1"), - Worker2 = get_client_worker(Client2, "2"), - Worker3 = get_client_worker(Client3, "3"), - etap:is(is_process_alive(Worker1), true, "Client's 1 worker is alive."), - etap:is(is_process_alive(Worker2), true, "Client's 2 worker is alive."), - etap:is(is_process_alive(Worker3), true, "Client's 3 worker is alive."), - - etap:isnt(Worker1, Worker2, "Clients 1 and 2 got different workers."), - etap:isnt(Worker2, Worker3, "Clients 2 and 3 got different workers."), - etap:isnt(Worker1, Worker3, "Clients 1 and 3 got different workers."), - - etap:diag("Check that client 4 blocks waiting for a worker."), - Client4 = spawn_client(Pool), - etap:is(ping_client(Client4), timeout, "Client 4 blocked while waiting."), - - etap:diag("Check that stopping a client gives up its worker."), - etap:is(stop_client(Client1), ok, "First client stopped."), - - etap:diag("And check that our blocked client has been unblocked."), - etap:is(ping_client(Client4), ok, "Client 4 was unblocked."), - - Worker4 = get_client_worker(Client4, "4"), - etap:is(is_process_alive(Worker4), true, "Client's 4 worker is alive."), - etap:is(Worker4, Worker1, "Client 4 got worker that client 1 got before."), - - lists:foreach(fun(C) -> ok = stop_client(C) end, [Client2, Client3, Client4]), - stop_pool(Pool). - - -test_worker_dead_pool_non_full() -> - Pool = spawn_pool(), - Client1 = spawn_client(Pool), - - etap:is(ping_client(Client1), ok, "Client 1 started ok."), - Worker1 = get_client_worker(Client1, "1"), - etap:is(is_process_alive(Worker1), true, "Client's 1 worker is alive."), - - etap:diag("Kill client's 1 worker."), - etap:is(kill_client_worker(Client1), ok, "Killed client's 1 worker."), - etap:is(is_process_alive(Worker1), false, "Client's 1 worker process is dead."), - - etap:is(stop_client(Client1), ok, "First client stopped and released its worker."), - - Client2 = spawn_client(Pool), - etap:is(ping_client(Client2), ok, "Client 2 started ok."), - Worker2 = get_client_worker(Client2, "2"), - etap:isnt(Worker2, Worker1, "Client 2 got a different worker from client 1"), - etap:is(is_process_alive(Worker2), true, "Client's 2 worker is alive."), - - etap:is(stop_client(Client2), ok, "Second client stopped."), - stop_pool(Pool). - - -test_worker_dead_pool_full() -> - Pool = spawn_pool(), - Client1 = spawn_client(Pool), - Client2 = spawn_client(Pool), - Client3 = spawn_client(Pool), - - etap:diag("Check that we can spawn the max number of connections."), - 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."), - - Worker1 = get_client_worker(Client1, "1"), - Worker2 = get_client_worker(Client2, "2"), - Worker3 = get_client_worker(Client3, "3"), - etap:is(is_process_alive(Worker1), true, "Client's 1 worker is alive."), - etap:is(is_process_alive(Worker2), true, "Client's 2 worker is alive."), - etap:is(is_process_alive(Worker3), true, "Client's 3 worker is alive."), - - etap:isnt(Worker1, Worker2, "Clients 1 and 2 got different workers."), - etap:isnt(Worker2, Worker3, "Clients 2 and 3 got different workers."), - etap:isnt(Worker1, Worker3, "Clients 1 and 3 got different workers."), - - etap:diag("Check that client 4 blocks waiting for a worker."), - Client4 = spawn_client(Pool), - etap:is(ping_client(Client4), timeout, "Client 4 blocked while waiting."), - - etap:diag("Kill client's 1 worker."), - etap:is(kill_client_worker(Client1), ok, "Killed client's 1 worker."), - etap:is(is_process_alive(Worker1), false, "Client's 1 worker process is dead."), - - etap:diag("Check client 4 got unblocked after first worker's death"), - etap:is(ping_client(Client4), ok, "Client 4 not blocked anymore."), - - Worker4 = get_client_worker(Client4, "4"), - etap:is(is_process_alive(Worker4), true, "Client's 4 worker is alive."), - etap:isnt(Worker4, Worker1, "Client 4 got a worker different from client 1."), - etap:isnt(Worker4, Worker2, "Client 4 got a worker different from client 2."), - etap:isnt(Worker4, Worker3, "Client 4 got a worker different from client 3."), - - etap:diag("Check that stopping client 1 is a noop."), - etap:is(stop_client(Client1), ok, "First client stopped."), - - etap:is(is_process_alive(Worker2), true, "Client's 2 worker still alive."), - etap:is(is_process_alive(Worker3), true, "Client's 3 worker still alive."), - etap:is(is_process_alive(Worker4), true, "Client's 4 worker still alive."), - - etap:diag("Check that client 5 blocks waiting for a worker."), - Client5 = spawn_client(Pool), - etap:is(ping_client(Client5), timeout, "Client 5 blocked while waiting."), - - etap:diag("Check that stopping client 2 gives up its worker."), - etap:is(stop_client(Client2), ok, "Second client stopped."), - - etap:diag("Now check that client 5 has been unblocked."), - etap:is(ping_client(Client5), ok, "Client 5 was unblocked."), - - Worker5 = get_client_worker(Client5, "5"), - etap:is(is_process_alive(Worker5), true, "Client's 5 worker is alive."), - etap:isnt(Worker5, Worker1, "Client 5 got a worker different from client 1."), - etap:is(Worker5, Worker2, "Client 5 got same worker as client 2."), - etap:isnt(Worker5, Worker3, "Client 5 got a worker different from client 3."), - etap:isnt(Worker5, Worker4, "Client 5 got a worker different from client 4."), - - etap:is(is_process_alive(Worker3), true, "Client's 3 worker still alive."), - etap:is(is_process_alive(Worker4), true, "Client's 4 worker still alive."), - etap:is(is_process_alive(Worker5), true, "Client's 5 worker still alive."), - - lists:foreach(fun(C) -> ok = stop_client(C) end, [Client3, Client4, Client5]), - stop_pool(Pool). - - -spawn_client(Pool) -> - Parent = self(), - Ref = make_ref(), - Pid = spawn(fun() -> - {ok, Worker} = couch_replicator_httpc_pool:get_worker(Pool), - loop(Parent, Ref, Worker, Pool) - end), - {Pid, Ref}. - - -ping_client({Pid, Ref}) -> - Pid ! ping, - receive - {pong, Ref} -> - ok - after 3000 -> - timeout - end. - - -get_client_worker({Pid, Ref}, ClientName) -> - Pid ! get_worker, - receive - {worker, Ref, Worker} -> - Worker - after 3000 -> - etap:bail("Timeout getting client " ++ ClientName ++ " worker.") - end. - - -stop_client({Pid, Ref}) -> - Pid ! stop, - receive - {stop, Ref} -> - ok - after 3000 -> - timeout - end. - - -kill_client_worker({Pid, Ref}) -> - Pid ! get_worker, - receive - {worker, Ref, Worker} -> - exit(Worker, kill), - ok - after 3000 -> - timeout - end. - - -loop(Parent, Ref, Worker, Pool) -> - receive - ping -> - Parent ! {pong, Ref}, - loop(Parent, Ref, Worker, Pool); - get_worker -> - Parent ! {worker, Ref, Worker}, - loop(Parent, Ref, Worker, Pool); - stop -> - couch_replicator_httpc_pool:release_worker(Pool, Worker), - Parent ! {stop, Ref} - end. - - -spawn_pool() -> - Host = couch_config:get("httpd", "bind_address", "127.0.0.1"), - Port = couch_config:get("httpd", "port", "5984"), - {ok, Pool} = couch_replicator_httpc_pool:start_link( - "http://" ++ Host ++ ":5984", [{max_connections, 3}]), - Pool. - - -stop_pool(Pool) -> - ok = couch_replicator_httpc_pool:stop(Pool). http://git-wip-us.apache.org/repos/asf/couchdb/blob/544748e8/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl ---------------------------------------------------------------------- diff --git a/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl b/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl new file mode 100644 index 0000000..88534ed --- /dev/null +++ b/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl @@ -0,0 +1,189 @@ +% 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. + +-module(couch_replicator_httpc_pool_tests). + +-include("couch_eunit.hrl"). +-include_lib("couchdb/couch_db.hrl"). + +-define(ADMIN_USER, {user_ctx, #user_ctx{roles=[<<"_admin">>]}}). +-define(TIMEOUT, 1000). + + +start() -> + {ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN), + Pid. + +stop(Pid) -> + erlang:monitor(process, Pid), + couch_server_sup:stop(), + receive + {'DOWN', _, _, Pid, _} -> + ok + after ?TIMEOUT -> + throw({timeout, server_stop}) + end. + +setup() -> + spawn_pool(). + +teardown(Pool) -> + stop_pool(Pool). + + +httpc_pool_test_() -> + { + "httpc pool tests", + { + setup, + fun start/0, fun stop/1, + { + foreach, + fun setup/0, fun teardown/1, + [ + fun should_block_new_clients_when_full/1, + fun should_replace_worker_on_death/1 + ] + } + } + }. + + +should_block_new_clients_when_full(Pool) -> + ?_test(begin + Client1 = spawn_client(Pool), + Client2 = spawn_client(Pool), + Client3 = spawn_client(Pool), + + ?assertEqual(ok, ping_client(Client1)), + ?assertEqual(ok, ping_client(Client2)), + ?assertEqual(ok, ping_client(Client3)), + + Worker1 = get_client_worker(Client1, "1"), + Worker2 = get_client_worker(Client2, "2"), + Worker3 = get_client_worker(Client3, "3"), + + ?assert(is_process_alive(Worker1)), + ?assert(is_process_alive(Worker2)), + ?assert(is_process_alive(Worker3)), + + ?assertNotEqual(Worker1, Worker2), + ?assertNotEqual(Worker2, Worker3), + ?assertNotEqual(Worker3, Worker1), + + Client4 = spawn_client(Pool), + ?assertEqual(timeout, ping_client(Client4)), + + ?assertEqual(ok, stop_client(Client1)), + ?assertEqual(ok, ping_client(Client4)), + + Worker4 = get_client_worker(Client4, "4"), + ?assertEqual(Worker1, Worker4), + + lists:foreach( + fun(C) -> + ?assertEqual(ok, stop_client(C)) + end, [Client2, Client3, Client4]) + end). + +should_replace_worker_on_death(Pool) -> + ?_test(begin + Client1 = spawn_client(Pool), + ?assertEqual(ok, ping_client(Client1)), + Worker1 = get_client_worker(Client1, "1"), + ?assert(is_process_alive(Worker1)), + + ?assertEqual(ok, kill_client_worker(Client1)), + ?assertNot(is_process_alive(Worker1)), + ?assertEqual(ok, stop_client(Client1)), + + Client2 = spawn_client(Pool), + ?assertEqual(ok, ping_client(Client2)), + Worker2 = get_client_worker(Client2, "2"), + ?assert(is_process_alive(Worker2)), + + ?assertNotEqual(Worker1, Worker2), + ?assertEqual(ok, stop_client(Client2)) + end). + + +spawn_client(Pool) -> + Parent = self(), + Ref = make_ref(), + Pid = spawn(fun() -> + {ok, Worker} = couch_replicator_httpc_pool:get_worker(Pool), + loop(Parent, Ref, Worker, Pool) + end), + {Pid, Ref}. + +ping_client({Pid, Ref}) -> + Pid ! ping, + receive + {pong, Ref} -> + ok + after ?TIMEOUT -> + timeout + end. + +get_client_worker({Pid, Ref}, ClientName) -> + Pid ! get_worker, + receive + {worker, Ref, Worker} -> + Worker + after ?TIMEOUT -> + erlang:error( + {assertion_failed, + [{module, ?MODULE}, {line, ?LINE}, + {reason, "Timeout getting client " ++ ClientName ++ " worker"}]}) + end. + +stop_client({Pid, Ref}) -> + Pid ! stop, + receive + {stop, Ref} -> + ok + after ?TIMEOUT -> + timeout + end. + +kill_client_worker({Pid, Ref}) -> + Pid ! get_worker, + receive + {worker, Ref, Worker} -> + exit(Worker, kill), + ok + after ?TIMEOUT -> + timeout + end. + +loop(Parent, Ref, Worker, Pool) -> + receive + ping -> + Parent ! {pong, Ref}, + loop(Parent, Ref, Worker, Pool); + get_worker -> + Parent ! {worker, Ref, Worker}, + loop(Parent, Ref, Worker, Pool); + stop -> + couch_replicator_httpc_pool:release_worker(Pool, Worker), + Parent ! {stop, Ref} + end. + +spawn_pool() -> + Host = couch_config:get("httpd", "bind_address", "127.0.0.1"), + Port = couch_config:get("httpd", "port", "5984"), + {ok, Pool} = couch_replicator_httpc_pool:start_link( + "http://" ++ Host ++ ":" ++ Port, [{max_connections, 3}]), + Pool. + +stop_pool(Pool) -> + ok = couch_replicator_httpc_pool:stop(Pool).