You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ei...@apache.org on 2016/08/16 15:21:57 UTC
[2/3] couch commit: updated refs/heads/master to 8bd756e
Add tests for process pool
This adds tests for re-use of procs,
proper waiters dequeue and idle pool reduction
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/b4c05798
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/b4c05798
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/b4c05798
Branch: refs/heads/master
Commit: b4c05798e8e0ce3012156dd82e83905b8e4f581b
Parents: f0b8451
Author: Eric Avdey <ei...@eiri.ca>
Authored: Mon Aug 15 13:45:20 2016 -0300
Committer: Eric Avdey <ei...@eiri.ca>
Committed: Tue Aug 16 12:06:15 2016 -0300
----------------------------------------------------------------------
src/couch_query_servers.erl | 2 +-
test/couchdb_os_proc_pool.erl | 146 ++++++++++++++++++++++++++++++++++---
2 files changed, 136 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/b4c05798/src/couch_query_servers.erl
----------------------------------------------------------------------
diff --git a/src/couch_query_servers.erl b/src/couch_query_servers.erl
index a3d7a47..ea7628e 100644
--- a/src/couch_query_servers.erl
+++ b/src/couch_query_servers.erl
@@ -22,7 +22,7 @@
-export([with_ddoc_proc/2, proc_prompt/2, ddoc_prompt/3, ddoc_proc_prompt/3, json_doc/1]).
% For 210-os-proc-pool.t
--export([get_os_process/1, ret_os_process/1]).
+-export([get_os_process/1, get_ddoc_process/2, ret_os_process/1]).
-include_lib("couch/include/couch_db.hrl").
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/b4c05798/test/couchdb_os_proc_pool.erl
----------------------------------------------------------------------
diff --git a/test/couchdb_os_proc_pool.erl b/test/couchdb_os_proc_pool.erl
index a698070..54d19f0 100644
--- a/test/couchdb_os_proc_pool.erl
+++ b/test/couchdb_os_proc_pool.erl
@@ -15,26 +15,33 @@
-include_lib("couch/include/couch_eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
--define(TIMEOUT, 3000).
+-define(TIMEOUT, 1000).
-start() ->
- Ctx = test_util:start_couch(),
- config:set("query_server_config", "os_process_limit", "3", false),
- timer:sleep(100), %% we need to wait to let gen_server:cast finish
- Ctx.
+setup() ->
+ ok = couch_proc_manager:reload(),
+ ok = setup_config().
+teardown(_) ->
+ ok.
os_proc_pool_test_() ->
{
"OS processes pool tests",
{
setup,
- fun start/0, fun test_util:stop_couch/1,
- [
- should_block_new_proc_on_full_pool(),
- should_free_slot_on_proc_unexpected_exit()
- ]
+ fun test_util:start_couch/0, fun test_util:stop_couch/1,
+ {
+ foreach,
+ fun setup/0, fun teardown/1,
+ [
+ should_block_new_proc_on_full_pool(),
+ should_free_slot_on_proc_unexpected_exit(),
+ should_reuse_known_proc(),
+ should_process_waiting_queue_as_fifo(),
+ should_reduce_pool_on_idle_os_procs()
+ ]
+ }
}
}.
@@ -115,6 +122,112 @@ should_free_slot_on_proc_unexpected_exit() ->
end).
+should_reuse_known_proc() ->
+ ?_test(begin
+ Client1 = spawn_client(<<"ddoc1">>),
+ Client2 = spawn_client(<<"ddoc2">>),
+
+ ?assertEqual(ok, ping_client(Client1)),
+ ?assertEqual(ok, ping_client(Client2)),
+
+ Proc1 = get_client_proc(Client1, "1"),
+ Proc2 = get_client_proc(Client2, "2"),
+ ?assertNotEqual(Proc1#proc.pid, Proc2#proc.pid),
+
+ ?assertEqual(ok, stop_client(Client1)),
+ ?assertEqual(ok, stop_client(Client2)),
+ ?assert(is_process_alive(Proc1#proc.pid)),
+ ?assert(is_process_alive(Proc2#proc.pid)),
+
+ Client1Again = spawn_client(<<"ddoc1">>),
+ ?assertEqual(ok, ping_client(Client1Again)),
+ Proc1Again = get_client_proc(Client1Again, "1-again"),
+ ?assertEqual(Proc1#proc.pid, Proc1Again#proc.pid),
+ ?assertNotEqual(Proc1#proc.client, Proc1Again#proc.client),
+ ?assertEqual(ok, stop_client(Client1Again))
+ end).
+
+
+should_process_waiting_queue_as_fifo() ->
+ ?_test(begin
+ Client1 = spawn_client(<<"ddoc1">>),
+ Client2 = spawn_client(<<"ddoc2">>),
+ Client3 = spawn_client(<<"ddoc3">>),
+ Client4 = spawn_client(<<"ddoc4">>),
+ Client5 = spawn_client(<<"ddoc5">>),
+
+ ?assertEqual(ok, ping_client(Client1)),
+ ?assertEqual(ok, ping_client(Client2)),
+ ?assertEqual(ok, ping_client(Client3)),
+ ?assertEqual(timeout, ping_client(Client4)),
+ ?assertEqual(timeout, ping_client(Client5)),
+
+ Proc1 = get_client_proc(Client1, "1"),
+ ?assertEqual(ok, stop_client(Client1)),
+ ?assertEqual(ok, ping_client(Client4)),
+ Proc4 = get_client_proc(Client4, "4"),
+
+ ?assertNotEqual(Proc4#proc.client, Proc1#proc.client),
+ ?assertEqual(Proc1#proc.pid, Proc4#proc.pid),
+ ?assertEqual(timeout, ping_client(Client5)),
+
+ ?assertEqual(ok, stop_client(Client2)),
+ ?assertEqual(ok, stop_client(Client3)),
+ ?assertEqual(ok, stop_client(Client4)),
+ ?assertEqual(ok, stop_client(Client5))
+ end).
+
+
+should_reduce_pool_on_idle_os_procs() ->
+ ?_test(begin
+ %% os_process_idle_limit is in sec
+ config:set("query_server_config",
+ "os_process_idle_limit", "1", false),
+ ok = confirm_config("os_process_idle_limit", "1"),
+
+ Client1 = spawn_client(<<"ddoc1">>),
+ Client2 = spawn_client(<<"ddoc2">>),
+ Client3 = spawn_client(<<"ddoc3">>),
+
+ ?assertEqual(ok, ping_client(Client1)),
+ ?assertEqual(ok, ping_client(Client2)),
+ ?assertEqual(ok, ping_client(Client3)),
+
+ ?assertEqual(3, couch_proc_manager:get_proc_count()),
+
+ ?assertEqual(ok, stop_client(Client1)),
+ ?assertEqual(ok, stop_client(Client2)),
+ ?assertEqual(ok, stop_client(Client3)),
+
+ timer:sleep(1200),
+ ?assertEqual(1, couch_proc_manager:get_proc_count())
+ end).
+
+
+setup_config() ->
+ config:set("query_server_config", "os_process_limit", "3", false),
+ config:set("query_server_config", "os_process_soft_limit", "2", false),
+ ok = confirm_config("os_process_soft_limit", "2").
+
+confirm_config(Key, Value) ->
+ confirm_config(Key, Value, 0).
+
+confirm_config(Key, Value, Count) ->
+ case config:get("query_server_config", Key) of
+ Value ->
+ ok;
+ _ when Count > 10 ->
+ erlang:error({config_setup, [
+ {module, ?MODULE},
+ {line, ?LINE},
+ {value, timeout}
+ ]});
+ _ ->
+ %% we need to wait to let gen_server:cast finish
+ timer:sleep(10),
+ confirm_config(Key, Value, Count + 1)
+ end.
+
spawn_client() ->
Parent = self(),
Ref = make_ref(),
@@ -124,6 +237,17 @@ spawn_client() ->
end),
{Pid, Ref}.
+spawn_client(DDocId) ->
+ Parent = self(),
+ Ref = make_ref(),
+ Pid = spawn(fun() ->
+ DDocKey = {DDocId, <<"1-abcdefgh">>},
+ DDoc = #doc{body={[]}},
+ Proc = couch_query_servers:get_ddoc_process(DDoc, DDocKey),
+ loop(Parent, Ref, Proc)
+ end),
+ {Pid, Ref}.
+
ping_client({Pid, Ref}) ->
Pid ! ping,
receive