You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ch...@apache.org on 2014/08/29 22:43:21 UTC
[19/50] [abbrv] couch commit: updated refs/heads/1963-eunit-bigcouch
to 08c6f0b
Port 201-view-group-shutdown.t etap test suite to eunit
Merged into couchdb_views_tests suite. Database population reduced
to speedup test and removed second view index call which leaded to
race condition when compaction becomes completed in time of view index
update call and before assertion check for {error, all_dbs_active}.
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/8fc8bf02
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/8fc8bf02
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/8fc8bf02
Branch: refs/heads/1963-eunit-bigcouch
Commit: 8fc8bf02b31fd307751dafebfb062b962a773dc9
Parents: ed19104
Author: Alexander Shorin <kx...@apache.org>
Authored: Sat Jun 7 01:23:38 2014 +0400
Committer: Russell Branca <ch...@apache.org>
Committed: Fri Aug 29 13:42:24 2014 -0700
----------------------------------------------------------------------
test/couchdb/couchdb_views_tests.erl | 175 ++++++++++++++++++++++++++++++
1 file changed, 175 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/8fc8bf02/test/couchdb/couchdb_views_tests.erl
----------------------------------------------------------------------
diff --git a/test/couchdb/couchdb_views_tests.erl b/test/couchdb/couchdb_views_tests.erl
index 77ee4f5..57d5a14 100644
--- a/test/couchdb/couchdb_views_tests.erl
+++ b/test/couchdb/couchdb_views_tests.erl
@@ -94,6 +94,16 @@ view_group_db_leaks_test_() ->
}
}.
+view_group_shutdown_test_() ->
+ {
+ "View group shutdown",
+ {
+ setup,
+ fun start/0, fun stop/1,
+ [couchdb_1283()]
+ }
+ }.
+
should_not_remember_docs_in_index_after_backup_restore_test() ->
%% COUCHDB-640
@@ -229,6 +239,87 @@ couchdb_1309(DbName) ->
end
end).
+couchdb_1283() ->
+ ?_test(begin
+ ok = couch_config:set("couchdb", "max_dbs_open", "3", false),
+ ok = couch_config:set("couchdb", "delayed_commits", "false", false),
+
+ {ok, MDb1} = couch_db:create(?tempdb(), [?ADMIN_USER]),
+ DDoc = couch_doc:from_json_obj({[
+ {<<"_id">>, <<"_design/foo">>},
+ {<<"language">>, <<"javascript">>},
+ {<<"views">>, {[
+ {<<"foo">>, {[
+ {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
+ ]}},
+ {<<"foo2">>, {[
+ {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
+ ]}},
+ {<<"foo3">>, {[
+ {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
+ ]}},
+ {<<"foo4">>, {[
+ {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
+ ]}},
+ {<<"foo5">>, {[
+ {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
+ ]}}
+ ]}}
+ ]}),
+ {ok, _} = couch_db:update_doc(MDb1, DDoc, []),
+ ok = populate_db(MDb1, 100, 100),
+ query_view(MDb1#db.name, "foo", "foo"),
+ ok = couch_db:close(MDb1),
+
+ {ok, Db1} = couch_db:create(?tempdb(), [?ADMIN_USER]),
+ ok = couch_db:close(Db1),
+ {ok, Db2} = couch_db:create(?tempdb(), [?ADMIN_USER]),
+ ok = couch_db:close(Db2),
+ {ok, Db3} = couch_db:create(?tempdb(), [?ADMIN_USER]),
+ ok = couch_db:close(Db3),
+
+ Writer1 = spawn_writer(Db1#db.name),
+ Writer2 = spawn_writer(Db2#db.name),
+
+ ?assert(is_process_alive(Writer1)),
+ ?assert(is_process_alive(Writer2)),
+
+ ?assertEqual(ok, get_writer_status(Writer1)),
+ ?assertEqual(ok, get_writer_status(Writer2)),
+
+ {ok, MonRef} = couch_mrview:compact(MDb1#db.name, <<"_design/foo">>,
+ [monitor]),
+
+ Writer3 = spawn_writer(Db3#db.name),
+ ?assert(is_process_alive(Writer3)),
+ ?assertEqual({error, all_dbs_active}, get_writer_status(Writer3)),
+
+ ?assert(is_process_alive(Writer1)),
+ ?assert(is_process_alive(Writer2)),
+ ?assert(is_process_alive(Writer3)),
+
+ receive
+ {'DOWN', MonRef, process, _, Reason} ->
+ ?assertEqual(normal, Reason)
+ after ?TIMEOUT ->
+ erlang:error(
+ {assertion_failed,
+ [{module, ?MODULE}, {line, ?LINE},
+ {reason, "Failure compacting view group"}]})
+ end,
+
+ ?assertEqual(ok, writer_try_again(Writer3)),
+ ?assertEqual(ok, get_writer_status(Writer3)),
+
+ ?assert(is_process_alive(Writer1)),
+ ?assert(is_process_alive(Writer2)),
+ ?assert(is_process_alive(Writer3)),
+
+ ?assertEqual(ok, stop_writer(Writer1)),
+ ?assertEqual(ok, stop_writer(Writer2)),
+ ?assertEqual(ok, stop_writer(Writer3))
+ end).
+
create_doc(DbName, DocId) when is_list(DocId) ->
create_doc(DbName, ?l2b(DocId));
create_doc(DbName, DocId) when is_binary(DocId) ->
@@ -262,6 +353,20 @@ create_docs(DbName) ->
couch_db:ensure_full_commit(Db),
couch_db:close(Db).
+populate_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_db(Db, BatchSize, N - length(Docs));
+populate_db(_Db, _, _) ->
+ ok.
+
create_design_doc(DbName, DDName, ViewName) ->
{ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
DDoc = couch_doc:from_json_obj({[
@@ -423,3 +528,73 @@ wait_view_compact_done(DbName, DDocId, N) ->
ok = timer:sleep(?DELAY),
wait_view_compact_done(DbName, DDocId, N - 1)
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 ?TIMEOUT ->
+ timeout
+ end.
+
+writer_try_again(Writer) ->
+ Ref = make_ref(),
+ Writer ! {try_again, Ref},
+ receive
+ {ok, Ref} ->
+ ok
+ after ?TIMEOUT ->
+ timeout
+ end.
+
+stop_writer(Writer) ->
+ Ref = make_ref(),
+ Writer ! {stop, Ref},
+ receive
+ {ok, Ref} ->
+ ok
+ after ?TIMEOUT ->
+ erlang:error({assertion_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {reason, "Timeout on stopping process"}]})
+ end.
+
+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.