summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shorin <kxepal@apache.org>2014-06-05 23:03:31 +0400
committerAlexander Shorin <kxepal@apache.org>2015-12-03 00:51:58 +0300
commit1b8730c959232c9d297f6c4c4ba84c48822cf1dc (patch)
tree202d4c69a980942bbd97cbb1e661b5ffde35423a
parentb91efbb1c81d343d7b3789cba60ce0a6217590ac (diff)
downloadcouchdb-1b8730c959232c9d297f6c4c4ba84c48822cf1dc.tar.gz
Port 200-view-group-no-db-leaks.t etap test suite to eunit
Merged into couchdb_views_tests suite. Apply minor refactor changes.
-rw-r--r--test/couchdb/couchdb_views_tests.erl240
-rwxr-xr-xtest/etap/200-view-group-no-db-leaks.t308
-rw-r--r--test/etap/Makefile.am1
3 files changed, 223 insertions, 326 deletions
diff --git a/test/couchdb/couchdb_views_tests.erl b/test/couchdb/couchdb_views_tests.erl
index d10b5675b..77ee4f5da 100644
--- a/test/couchdb/couchdb_views_tests.erl
+++ b/test/couchdb/couchdb_views_tests.erl
@@ -16,8 +16,10 @@
-include_lib("couchdb/couch_db.hrl").
-define(ADMIN_USER, {user_ctx, #user_ctx{roles=[<<"_admin">>]}}).
+-define(DELAY, 100).
-define(TIMEOUT, 1000).
+
start() ->
{ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN),
Pid.
@@ -34,7 +36,8 @@ stop(Pid) ->
setup() ->
DbName = ?tempdb(),
- {ok, _} = couch_db:create(DbName, [?ADMIN_USER]),
+ {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]),
+ ok = couch_db:close(Db),
FooRev = create_design_doc(DbName, <<"_design/foo">>, <<"bar">>),
query_view(DbName, "foo", "bar"),
BooRev = create_design_doc(DbName, <<"_design/boo">>, <<"baz">>),
@@ -43,7 +46,8 @@ setup() ->
setup_with_docs() ->
DbName = ?tempdb(),
- {ok, _} = couch_db:create(DbName, [?ADMIN_USER]),
+ {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]),
+ ok = couch_db:close(Db),
create_docs(DbName),
create_design_doc(DbName, <<"_design/foo">>, <<"bar">>),
DbName.
@@ -51,7 +55,7 @@ setup_with_docs() ->
teardown({DbName, _}) ->
teardown(DbName);
teardown(DbName) when is_binary(DbName) ->
- ok = couch_server:delete(DbName, [?ADMIN_USER]),
+ couch_server:delete(DbName, [?ADMIN_USER]),
ok.
@@ -73,17 +77,33 @@ view_indexes_cleanup_test_() ->
}
}.
+view_group_db_leaks_test_() ->
+ {
+ "View group db leaks",
+ {
+ setup,
+ fun start/0, fun stop/1,
+ {
+ foreach,
+ fun setup_with_docs/0, fun teardown/1,
+ [
+ fun couchdb_1138/1,
+ fun couchdb_1309/1
+ ]
+ }
+ }
+ }.
+
+
should_not_remember_docs_in_index_after_backup_restore_test() ->
%% COUCHDB-640
start(),
DbName = setup_with_docs(),
ok = backup_db_file(DbName),
- create_doc(DbName),
+ create_doc(DbName, "doc666"),
- Body0 = query_view(DbName, "foo", "bar"),
- ViewJson0 = ejson:decode(Body0),
- Rows0 = couch_util:get_nested_json_value(ViewJson0, [<<"rows">>]),
+ Rows0 = query_view(DbName, "foo", "bar"),
?assert(has_doc("doc1", Rows0)),
?assert(has_doc("doc2", Rows0)),
?assert(has_doc("doc3", Rows0)),
@@ -91,9 +111,7 @@ should_not_remember_docs_in_index_after_backup_restore_test() ->
restore_backup_db_file(DbName),
- Body1 = query_view(DbName, "foo", "bar"),
- ViewJson1 = ejson:decode(Body1),
- Rows1 = couch_util:get_nested_json_value(ViewJson1, [<<"rows">>]),
+ Rows1 = query_view(DbName, "foo", "bar"),
?assert(has_doc("doc1", Rows1)),
?assert(has_doc("doc2", Rows1)),
?assert(has_doc("doc3", Rows1)),
@@ -118,13 +136,106 @@ should_cleanup_all_index_files({DbName, {FooRev, BooRev}})->
view_cleanup(DbName),
?_assertEqual(0, count_index_files(DbName)).
-
-create_doc(DbName) ->
+couchdb_1138(DbName) ->
+ ?_test(begin
+ {ok, IndexerPid} = couch_index_server:get_index(
+ couch_mrview_index, DbName, <<"_design/foo">>),
+ ?assert(is_pid(IndexerPid)),
+ ?assert(is_process_alive(IndexerPid)),
+ ?assertEqual(2, count_db_refs(DbName)),
+
+ Rows0 = query_view(DbName, "foo", "bar"),
+ ?assertEqual(3, length(Rows0)),
+ ?assertEqual(2, count_db_refs(DbName)),
+ ?assert(is_process_alive(IndexerPid)),
+
+ create_doc(DbName, "doc1000"),
+ Rows1 = query_view(DbName, "foo", "bar"),
+ ?assertEqual(4, length(Rows1)),
+ ?assertEqual(2, count_db_refs(DbName)),
+ ?assert(is_process_alive(IndexerPid)),
+
+ Ref1 = get_db_ref_counter(DbName),
+ compact_db(DbName),
+ Ref2 = get_db_ref_counter(DbName),
+ ?assertEqual(2, couch_ref_counter:count(Ref2)),
+ ?assertNotEqual(Ref2, Ref1),
+ ?assertNot(is_process_alive(Ref1)),
+ ?assert(is_process_alive(IndexerPid)),
+
+ compact_view_group(DbName, "foo"),
+ ?assertEqual(2, count_db_refs(DbName)),
+ Ref3 = get_db_ref_counter(DbName),
+ ?assertEqual(Ref3, Ref2),
+ ?assert(is_process_alive(IndexerPid)),
+
+ create_doc(DbName, "doc1001"),
+ Rows2 = query_view(DbName, "foo", "bar"),
+ ?assertEqual(5, length(Rows2)),
+ ?assertEqual(2, count_db_refs(DbName)),
+ ?assert(is_process_alive(IndexerPid))
+ end).
+
+couchdb_1309(DbName) ->
+ ?_test(begin
+ {ok, IndexerPid} = couch_index_server:get_index(
+ couch_mrview_index, DbName, <<"_design/foo">>),
+ ?assert(is_pid(IndexerPid)),
+ ?assert(is_process_alive(IndexerPid)),
+ ?assertEqual(2, count_db_refs(DbName)),
+
+ create_doc(DbName, "doc1001"),
+ Rows0 = query_view(DbName, "foo", "bar"),
+ check_rows_value(Rows0, null),
+ ?assertEqual(4, length(Rows0)),
+ ?assertEqual(2, count_db_refs(DbName)),
+ ?assert(is_process_alive(IndexerPid)),
+
+ update_design_doc(DbName, <<"_design/foo">>, <<"bar">>),
+ {ok, NewIndexerPid} = couch_index_server:get_index(
+ couch_mrview_index, DbName, <<"_design/foo">>),
+ ?assert(is_pid(NewIndexerPid)),
+ ?assert(is_process_alive(NewIndexerPid)),
+ ?assertNotEqual(IndexerPid, NewIndexerPid),
+ ?assertEqual(2, count_db_refs(DbName)),
+
+ Rows1 = query_view(DbName, "foo", "bar", ok),
+ ?assertEqual(0, length(Rows1)),
+ Rows2 = query_view(DbName, "foo", "bar"),
+ check_rows_value(Rows2, 1),
+ ?assertEqual(4, length(Rows2)),
+
+ MonRef0 = erlang:monitor(process, IndexerPid),
+ receive
+ {'DOWN', MonRef0, _, _, _} ->
+ ok
+ after ?TIMEOUT ->
+ erlang:error(
+ {assertion_failed,
+ [{module, ?MODULE}, {line, ?LINE},
+ {reason, "old view group is not dead after ddoc update"}]})
+ end,
+
+ MonRef1 = erlang:monitor(process, NewIndexerPid),
+ ok = couch_server:delete(DbName, [?ADMIN_USER]),
+ receive
+ {'DOWN', MonRef1, _, _, _} ->
+ ok
+ after ?TIMEOUT ->
+ erlang:error(
+ {assertion_failed,
+ [{module, ?MODULE}, {line, ?LINE},
+ {reason, "new view group did not die after DB deletion"}]})
+ end
+ end).
+
+create_doc(DbName, DocId) when is_list(DocId) ->
+ create_doc(DbName, ?l2b(DocId));
+create_doc(DbName, DocId) when is_binary(DocId) ->
{ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
Doc666 = couch_doc:from_json_obj({[
- {<<"_id">>, <<"doc666">>},
+ {<<"_id">>, DocId},
{<<"value">>, 999}
-
]}),
{ok, _} = couch_db:update_docs(Db, [Doc666]),
couch_db:ensure_full_commit(Db),
@@ -158,7 +269,7 @@ create_design_doc(DbName, DDName, ViewName) ->
{<<"language">>, <<"javascript">>},
{<<"views">>, {[
{ViewName, {[
- {<<"map">>, <<"function(doc) { emit(doc.value, 1); }">>}
+ {<<"map">>, <<"function(doc) { emit(doc.value, null); }">>}
]}}
]}}
]}),
@@ -167,6 +278,26 @@ create_design_doc(DbName, DDName, ViewName) ->
couch_db:close(Db),
Rev.
+update_design_doc(DbName, DDName, ViewName) ->
+ {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
+ {ok, Doc} = couch_db:open_doc(Db, DDName, [?ADMIN_USER]),
+ {Props} = couch_doc:to_json_obj(Doc, []),
+ Rev = couch_util:get_value(<<"_rev">>, Props),
+ DDoc = couch_doc:from_json_obj({[
+ {<<"_id">>, DDName},
+ {<<"_rev">>, Rev},
+ {<<"language">>, <<"javascript">>},
+ {<<"views">>, {[
+ {ViewName, {[
+ {<<"map">>, <<"function(doc) { emit(doc.value, 1); }">>}
+ ]}}
+ ]}}
+ ]}),
+ {ok, NewRev} = couch_db:update_doc(Db, DDoc, [?ADMIN_USER]),
+ couch_db:ensure_full_commit(Db),
+ couch_db:close(Db),
+ NewRev.
+
delete_design_doc(DbName, DDName, Rev) ->
{ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
DDoc = couch_doc:from_json_obj({[
@@ -183,16 +314,43 @@ db_url(DbName) ->
"http://" ++ Addr ++ ":" ++ Port ++ "/" ++ ?b2l(DbName).
query_view(DbName, DDoc, View) ->
+ query_view(DbName, DDoc, View, false).
+
+query_view(DbName, DDoc, View, Stale) ->
{ok, Code, _Headers, Body} = test_request:get(
- db_url(DbName) ++ "/_design/" ++ DDoc ++ "/_view/" ++ View),
+ db_url(DbName) ++ "/_design/" ++ DDoc ++ "/_view/" ++ View
+ ++ case Stale of
+ false -> [];
+ _ -> "?stale=" ++ atom_to_list(Stale)
+ end),
?assertEqual(200, Code),
- Body.
+ {Props} = ejson:decode(Body),
+ couch_util:get_value(<<"rows">>, Props, []).
+
+check_rows_value(Rows, Value) ->
+ lists:foreach(
+ fun({Row}) ->
+ ?assertEqual(Value, couch_util:get_value(<<"value">>, Row))
+ end, Rows).
view_cleanup(DbName) ->
{ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
couch_mrview:cleanup(Db),
couch_db:close(Db).
+get_db_ref_counter(DbName) ->
+ {ok, #db{fd_ref_counter = Ref} = Db} = couch_db:open_int(DbName, []),
+ ok = couch_db:close(Db),
+ Ref.
+
+count_db_refs(DbName) ->
+ Ref = get_db_ref_counter(DbName),
+ % have to sleep a bit to let couchdb cleanup all refs and leave only
+ % active ones. otherwise the related tests will randomly fail due to
+ % count number mismatch
+ timer:sleep(200),
+ couch_ref_counter:count(Ref).
+
count_index_files(DbName) ->
% call server to fetch the index files
RootDir = couch_config:get("couchdb", "view_index_dir"),
@@ -217,3 +375,51 @@ restore_backup_db_file(DbName) ->
ok = file:rename(DbFile ++ ".backup", DbFile),
start(),
ok.
+
+compact_db(DbName) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+ {ok, _} = couch_db:start_compact(Db),
+ ok = couch_db:close(Db),
+ wait_db_compact_done(DbName, 10).
+
+wait_db_compact_done(_DbName, 0) ->
+ erlang:error({assertion_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {reason, "DB compaction failed to finish"}]});
+wait_db_compact_done(DbName, N) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+ ok = couch_db:close(Db),
+ case is_pid(Db#db.compactor_pid) of
+ false ->
+ ok;
+ true ->
+ ok = timer:sleep(?DELAY),
+ wait_db_compact_done(DbName, N - 1)
+ end.
+
+compact_view_group(DbName, DDocId) when is_list(DDocId) ->
+ compact_view_group(DbName, ?l2b("_design/" ++ DDocId));
+compact_view_group(DbName, DDocId) when is_binary(DDocId) ->
+ ok = couch_mrview:compact(DbName, DDocId),
+ wait_view_compact_done(DbName, DDocId, 10).
+
+wait_view_compact_done(_DbName, _DDocId, 0) ->
+ erlang:error({assertion_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {reason, "DB compaction failed to finish"}]});
+wait_view_compact_done(DbName, DDocId, N) ->
+ {ok, Code, _Headers, Body} = test_request:get(
+ db_url(DbName) ++ "/" ++ ?b2l(DDocId) ++ "/_info"),
+ ?assertEqual(200, Code),
+ {Info} = ejson:decode(Body),
+ {IndexInfo} = couch_util:get_value(<<"view_index">>, Info),
+ CompactRunning = couch_util:get_value(<<"compact_running">>, IndexInfo),
+ case CompactRunning of
+ false ->
+ ok;
+ true ->
+ ok = timer:sleep(?DELAY),
+ wait_view_compact_done(DbName, DDocId, N - 1)
+ end.
diff --git a/test/etap/200-view-group-no-db-leaks.t b/test/etap/200-view-group-no-db-leaks.t
deleted file mode 100755
index 9583d0984..000000000
--- a/test/etap/200-view-group-no-db-leaks.t
+++ /dev/null
@@ -1,308 +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.
-
--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,
- updater_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 = [],
- options = [],
- compression,
- before_doc_update,
- after_doc_read
-}).
-
-test_db_name() -> <<"couch_test_view_group_db_leaks">>.
-ddoc_name() -> <<"foo">>.
-
-main(_) ->
- test_util:init_code_path(),
-
- etap:plan(28),
- 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()),
- 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))),
-
- delete_db(),
- create_db(),
-
- create_docs(),
- {ok, DDocRev} = create_design_doc(),
-
- {ok, IndexerPid} = couch_index_server:get_index(
- couch_mrview_index, test_db_name(), <<"_design/", (ddoc_name())/binary>>
- ),
- etap:is(is_pid(IndexerPid), true, "got view group pid"),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- query_view(3, null, false),
- check_db_ref_count(),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- create_new_doc(<<"doc1000">>),
- query_view(4, null, false),
- check_db_ref_count(),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- Ref1 = get_db_ref_counter(),
- compact_db(),
- check_db_ref_count(),
- Ref2 = get_db_ref_counter(),
- etap:isnt(Ref1, Ref2, "DB ref counter changed"),
- etap:is(false, is_process_alive(Ref1), "old DB ref counter is not alive"),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- compact_view_group(),
- check_db_ref_count(),
- Ref3 = get_db_ref_counter(),
- etap:is(Ref3, Ref2, "DB ref counter didn't change"),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- create_new_doc(<<"doc1001">>),
- query_view(5, null, false),
- check_db_ref_count(),
- etap:is(is_process_alive(IndexerPid), true, "view group pid is alive"),
-
- etap:diag("updating the design document with a new view definition"),
- {ok, _NewDDocRev} = update_ddoc_view(DDocRev),
-
- {ok, NewIndexerPid} = couch_index_server:get_index(
- couch_mrview_index, test_db_name(), <<"_design/", (ddoc_name())/binary>>
- ),
- etap:is(is_pid(NewIndexerPid), true, "got new view group pid"),
- etap:is(is_process_alive(NewIndexerPid), true, "new view group pid is alive"),
- etap:isnt(NewIndexerPid, IndexerPid, "new view group has a different pid"),
- etap:diag("querying view with ?stale=ok, must return empty row set"),
- query_view(0, foo, ok),
- etap:diag("querying view (without stale), must return 5 rows with value 1"),
- query_view(5, 1, false),
- MonRef = erlang:monitor(process, IndexerPid),
- receive
- {'DOWN', MonRef, _, _, _} ->
- etap:diag("old view group is dead after ddoc update")
- after 5000 ->
- etap:bail("old view group is not dead after ddoc update")
- end,
-
- etap:diag("deleting database"),
- MonRef2 = erlang:monitor(process, NewIndexerPid),
- ok = couch_server:delete(test_db_name(), []),
- receive
- {'DOWN', MonRef2, _, _, _} ->
- etap:diag("new view group is dead after DB deletion")
- after 5000 ->
- etap:bail("new view group did not die after DB deletion")
- end,
-
- ok = timer:sleep(1000),
- delete_db(),
- couch_server_sup:stop(),
- ok.
-
-admin_user_ctx() ->
- {user_ctx, #user_ctx{roles=[<<"_admin">>]}}.
-
-create_db() ->
- {ok, #db{main_pid = Pid} = Db} = couch_db:create(
- test_db_name(), [admin_user_ctx()]),
- put(db_main_pid, Pid),
- ok = couch_db:close(Db).
-
-delete_db() ->
- couch_server:delete(test_db_name(), [admin_user_ctx()]).
-
-compact_db() ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- {ok, _} = couch_db:start_compact(Db),
- ok = couch_db:close(Db),
- wait_db_compact_done(10).
-
-wait_db_compact_done(0) ->
- etap:bail("DB compaction failed to finish.");
-wait_db_compact_done(N) ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- ok = couch_db:close(Db),
- case is_pid(Db#db.compactor_pid) of
- false ->
- ok;
- true ->
- ok = timer:sleep(500),
- wait_db_compact_done(N - 1)
- end.
-
-compact_view_group() ->
- DDoc = list_to_binary("_design/" ++ binary_to_list(ddoc_name())),
- ok = couch_mrview:compact(test_db_name(), DDoc),
- wait_view_compact_done(10).
-
-wait_view_compact_done(0) ->
- etap:bail("View group compaction failed to finish.");
-wait_view_compact_done(N) ->
- {ok, Code, _Headers, Body} = test_util:request(
- db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ "/_info",
- [],
- get),
- case Code of
- 200 -> ok;
- _ -> etap:bail("Invalid view group info.")
- end,
- {Info} = ejson:decode(Body),
- {IndexInfo} = couch_util:get_value(<<"view_index">>, Info),
- CompactRunning = couch_util:get_value(<<"compact_running">>, IndexInfo),
- case CompactRunning of
- false ->
- ok;
- true ->
- ok = timer:sleep(500),
- wait_view_compact_done(N - 1)
- end.
-
-get_db_ref_counter() ->
- {ok, #db{fd_ref_counter = Ref} = Db} = couch_db:open_int(test_db_name(), []),
- ok = couch_db:close(Db),
- Ref.
-
-check_db_ref_count() ->
- {ok, #db{fd_ref_counter = Ref} = Db} = couch_db:open_int(test_db_name(), []),
- ok = couch_db:close(Db),
- timer:sleep(200), % sleep a bit to prevent race condition
- etap:is(couch_ref_counter:count(Ref), 2,
- "DB ref counter is only held by couch_db and couch_db_updater"),
- ok.
-
-create_docs() ->
- {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]),
- Doc1 = couch_doc:from_json_obj({[
- {<<"_id">>, <<"doc1">>},
- {<<"value">>, 1}
- ]}),
- Doc2 = couch_doc:from_json_obj({[
- {<<"_id">>, <<"doc2">>},
- {<<"value">>, 2}
-
- ]}),
- Doc3 = couch_doc:from_json_obj({[
- {<<"_id">>, <<"doc3">>},
- {<<"value">>, 3}
- ]}),
- {ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]),
- couch_db:ensure_full_commit(Db),
- couch_db:close(Db).
-
-create_design_doc() ->
- {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]),
- DDoc = couch_doc:from_json_obj({[
- {<<"_id">>, <<"_design/", (ddoc_name())/binary>>},
- {<<"language">>, <<"javascript">>},
- {<<"views">>, {[
- {<<"bar">>, {[
- {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>}
- ]}}
- ]}}
- ]}),
- {ok, Rev} = couch_db:update_doc(Db, DDoc, []),
- couch_db:ensure_full_commit(Db),
- couch_db:close(Db),
- {ok, Rev}.
-
-update_ddoc_view(DDocRev) ->
- {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]),
- DDoc = couch_doc:from_json_obj({[
- {<<"_id">>, <<"_design/", (ddoc_name())/binary>>},
- {<<"_rev">>, couch_doc:rev_to_str(DDocRev)},
- {<<"language">>, <<"javascript">>},
- {<<"views">>, {[
- {<<"bar">>, {[
- {<<"map">>, <<"function(doc) { emit(doc._id, 1); }">>}
- ]}}
- ]}}
- ]}),
- {ok, NewRev} = couch_db:update_doc(Db, DDoc, []),
- couch_db:ensure_full_commit(Db),
- couch_db:close(Db),
- {ok, NewRev}.
-
-create_new_doc(Id) ->
- {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]),
- Doc666 = couch_doc:from_json_obj({[
- {<<"_id">>, Id},
- {<<"value">>, 999}
- ]}),
- {ok, _} = couch_db:update_docs(Db, [Doc666]),
- couch_db:ensure_full_commit(Db),
- couch_db:close(Db).
-
-db_url() ->
- "http://" ++ get(addr) ++ ":" ++ get(port) ++ "/" ++
- binary_to_list(test_db_name()).
-
-query_view(ExpectedRowCount, ExpectedRowValue, Stale) ->
- {ok, Code, _Headers, Body} = test_util:request(
- db_url() ++ "/_design/" ++ binary_to_list(ddoc_name()) ++ "/_view/bar"
- ++ case Stale of
- false -> [];
- _ -> "?stale=" ++ atom_to_list(Stale)
- end,
- [],
- get),
- etap:is(Code, 200, "got view response"),
- {Props} = ejson:decode(Body),
- Rows = couch_util:get_value(<<"rows">>, Props, []),
- etap:is(length(Rows), ExpectedRowCount, "result set has correct # of rows"),
- lists:foreach(
- fun({Row}) ->
- case couch_util:get_value(<<"value">>, Row) of
- ExpectedRowValue ->
- ok;
- _ ->
- etap:bail("row has incorrect value")
- end
- end,
- Rows).
diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am
index 72718e8f7..678b1b6c3 100644
--- a/test/etap/Makefile.am
+++ b/test/etap/Makefile.am
@@ -32,7 +32,6 @@ fixture_files = \
fixtures/test.couch
tap_files = \
- 200-view-group-no-db-leaks.t \
201-view-group-shutdown.t \
210-os-proc-pool.t \
220-compaction-daemon.t \