summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2017-07-12 17:25:50 -0500
committerPaul J. Davis <paul.joseph.davis@gmail.com>2017-07-12 17:25:50 -0500
commita50dd7e292858ab1707eaf1ac05d036e08af0fe9 (patch)
tree863ad6d27b0641858abcb0e95a0b603b3c304a87
parent94f2907ea2d75a08f5dd8dae2edbfc6eea5c6bd7 (diff)
downloadcouchdb-655-fix-couchdb-views-tests.tar.gz
Fix timeout in couchdb_views_test for couchdb_1283655-fix-couchdb-views-tests
I believe the race here was that the query could return before the actual index updating process exited. Then it was just a race to creating a database before the monitor is released. If we do end up creating the database before the monitor is released then the database we want to have closed ends up being ignored as its not idle. The second two created databases then don't end up forcing the database from couch_server's LRU which leads us to the timeout waiting for DatabaseMonRef to fire. Fixes #655
-rw-r--r--src/couch/test/couchdb_views_tests.erl27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/couch/test/couchdb_views_tests.erl b/src/couch/test/couchdb_views_tests.erl
index e320b54c6..50c4da4ce 100644
--- a/src/couch/test/couchdb_views_tests.erl
+++ b/src/couch/test/couchdb_views_tests.erl
@@ -345,6 +345,13 @@ couchdb_1283() ->
% monitor db and index pids
{ok, DDPid} = couch_index_server:get_index(
couch_mrview_index, MDb1#db.name, <<"_design/foo">>),
+
+ % Our query could have run after a partial update
+ % so we need to make sure that the updater has
+ % exited and released its monitor on the database
+ % fd.
+ wait_for_updater_exit(DDPid),
+
DesignDocMonRef = erlang:monitor(process, DDPid),
DatabaseMonRef = erlang:monitor(process, MDb1#db.main_pid),
@@ -629,6 +636,26 @@ wait_view_compact_done(DbName, DDocId, N) ->
wait_view_compact_done(DbName, DDocId, N - 1)
end.
+% This is a bit of a dirty hack fishing through various
+% state records but at least its better than putting
+% a sleep on it and calling it fixed.
+wait_for_updater_exit(DDPid) ->
+ % #st record from couch_index.erl
+ IdxState = sys:get_state(DDPid),
+ UpdaterPid = element(4, IdxState),
+
+ % #st record from couch_index_updater.erl
+ UpdaterState = sys:get_state(UpdaterPid),
+ RunnerPid = element(4, UpdaterState),
+
+ % RunnerPid can be nil, undefined, or a pid so
+ % just check if its a pid and wait on it to
+ % exit
+ if not is_pid(RunnerPid) -> ok; true ->
+ Ref = erlang:monitor(process, RunnerPid),
+ receive {'DOWN', Ref, _, _, _} -> ok end
+ end.
+
spawn_writer(DbName) ->
Parent = self(),
spawn(fun() ->