summaryrefslogtreecommitdiff
path: root/src/couch/test/eunit/couch_index_tests.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch/test/eunit/couch_index_tests.erl')
-rw-r--r--src/couch/test/eunit/couch_index_tests.erl232
1 files changed, 0 insertions, 232 deletions
diff --git a/src/couch/test/eunit/couch_index_tests.erl b/src/couch/test/eunit/couch_index_tests.erl
deleted file mode 100644
index 23c857d6c..000000000
--- a/src/couch/test/eunit/couch_index_tests.erl
+++ /dev/null
@@ -1,232 +0,0 @@
-% 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_index_tests).
-
--include_lib("couch/include/couch_eunit.hrl").
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch_mrview/include/couch_mrview.hrl").
--include_lib("stdlib/include/ms_transform.hrl").
-
--define(TIMEOUT, 1000).
-
-setup() ->
- DbName = ?tempdb(),
- {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
- ok = couch_db:close(Db),
- create_design_doc(DbName, <<"_design/foo">>, <<"bar">>),
- tracer_new(),
- DbName.
-
-teardown(DbName) ->
- tracer_delete(),
- couch_server:delete(DbName, [?ADMIN_CTX]).
-
-couch_index_ioq_priority_test_() ->
- {
- "Test ioq_priority for views",
- {
- setup,
- fun test_util:start_couch/0, fun test_util:stop_couch/1,
- {
- foreach,
- fun setup/0, fun teardown/1,
- [
- fun check_io_priority_for_updater/1,
- fun check_io_priority_for_compactor/1
- ]
- }
- }
- }.
-
-
-check_io_priority_for_updater(DbName) ->
- ?_test(begin
- {ok, IndexerPid} = couch_index_server:get_index(
- couch_mrview_index, DbName, <<"_design/foo">>),
- CouchIndexUpdaterPid = updater_pid(IndexerPid),
- tracer_record(CouchIndexUpdaterPid),
-
- create_docs(DbName),
-
- CommittedSeq = couch_util:with_db(DbName, fun(Db) -> couch_db:get_update_seq(Db) end),
- couch_index:get_state(IndexerPid, CommittedSeq),
- [UpdaterPid] = wait_spawn_event_for_pid(CouchIndexUpdaterPid),
-
- [UpdaterMapProcess] = wait_spawn_by_anonymous_fun(
- UpdaterPid, '-start_update/4-fun-0-'),
-
- ?assert(wait_set_io_priority(
- UpdaterMapProcess, {view_update, DbName, <<"_design/foo">>})),
-
- [UpdaterWriterProcess] = wait_spawn_by_anonymous_fun(
- UpdaterPid, '-start_update/4-fun-1-'),
- ?assert(wait_set_io_priority(
- UpdaterWriterProcess, {view_update, DbName, <<"_design/foo">>})),
-
- ok
- end).
-
-check_io_priority_for_compactor(DbName) ->
- ?_test(begin
- {ok, IndexerPid} = couch_index_server:get_index(
- couch_mrview_index, DbName, <<"_design/foo">>),
- {ok, CompactorPid} = couch_index:get_compactor_pid(IndexerPid),
- tracer_record(CompactorPid),
-
- create_docs(DbName),
-
- couch_index:compact(IndexerPid),
- wait_spawn_event_for_pid(CompactorPid),
-
- [CompactorProcess] = wait_spawn_by_anonymous_fun(
- CompactorPid, '-handle_call/3-fun-0-'),
- ?assert(wait_set_io_priority(
- CompactorProcess, {view_compact, DbName, <<"_design/foo">>})),
- ok
- end).
-
-create_docs(DbName) ->
- {ok, Db} = couch_db:open(DbName, [?ADMIN_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:close(Db).
-
-create_design_doc(DbName, DDName, ViewName) ->
- {ok, Db} = couch_db:open(DbName, [?ADMIN_CTX]),
- DDoc = couch_doc:from_json_obj({[
- {<<"_id">>, DDName},
- {<<"language">>, <<"javascript">>},
- {<<"views">>, {[
- {ViewName, {[
- {<<"map">>, <<"function(doc) { emit(doc.value, null); }">>}
- ]}}
- ]}}
- ]}),
- {ok, Rev} = couch_db:update_doc(Db, DDoc, []),
- couch_db:close(Db),
- Rev.
-
-wait_set_io_priority(Pid, IOPriority) ->
- test_util:wait_value(fun() ->
- does_process_set_io_priority(Pid, IOPriority)
- end, true).
-
-does_process_set_io_priority(Pid, IOPriority) ->
- PutCallsArgs = find_calls_to_fun(Pid, {erlang, put, 2}),
- lists:any(fun([_, Priority]) -> Priority =:= IOPriority end, PutCallsArgs).
-
-wait_events(MatchSpec) ->
- test_util:wait_other_value(fun() -> select(MatchSpec) end, []).
-
-find_spawned_by_anonymous_fun(ParentPid, Name) ->
- AnonymousFuns = select(ets:fun2ms(fun
- ({spawned, Pid, _TS, _Name, _Dict, [PPid, {erlang, apply, [Fun, _]}]})
- when is_function(Fun) andalso PPid =:= ParentPid -> {Pid, Fun}
- end)),
- lists:filtermap(fun({Pid, Fun}) ->
- case erlang:fun_info(Fun, name) of
- {name, Name} -> {true, Pid};
- _ -> false
- end
- end, AnonymousFuns).
-
-find_calls_to_fun(Pid, {Module, Function, Arity}) ->
- select(ets:fun2ms(fun
- ({call, P, _TS, _Name, _Dict, [{M, F, Args}]})
- when length(Args) =:= Arity
- andalso M =:= Module
- andalso F =:= Function
- andalso P =:= Pid
- -> Args
- end)).
-
-wait_spawn_event_for_pid(ParentPid) ->
- wait_events(ets:fun2ms(fun
- ({spawned, Pid, _TS, _Name, _Dict, [P, _]}) when P =:= ParentPid -> Pid
- end)).
-
-wait_spawn_by_anonymous_fun(ParentPid, Name) ->
- test_util:wait_other_value(fun() ->
- find_spawned_by_anonymous_fun(ParentPid, Name)
- end, []).
-
-updater_pid(IndexerPid) ->
- {links, Links} = process_info(IndexerPid, links),
- [Pid] = select_process_by_name_prefix(Links, "couch_index_updater:init/1"),
- Pid.
-
-select_process_by_name_prefix(Pids, Name) ->
- lists:filter(fun(Pid) ->
- Key = couch_debug:process_name(Pid),
- string:str(Key, Name) =:= 1
- end, Pids).
-
-select(MatchSpec) ->
- lists:filtermap(fun(Event) ->
- case ets:test_ms(Event, MatchSpec) of
- {ok, false} -> false;
- {ok, Result} -> {true, Result};
- _ -> false
- end
- end, tracer_events()).
-
-
-%% ========================
-%% Tracer related functions
-%% ------------------------
-tracer_new() ->
- ets:new(?MODULE, [public, named_table]),
- {ok, _Tracer} = dbg:tracer(process, {fun tracer_collector/2, 0}),
- ok.
-
-tracer_delete() ->
- dbg:stop_clear(),
- (catch ets:delete(?MODULE)),
- ok.
-
-tracer_record(Pid) ->
- {ok, _} = dbg:tp(erlang, put, x),
- {ok, _} = dbg:p(Pid, [c, p, sos]),
- ok.
-
-tracer_events() ->
- Events = [{Idx, E} || [Idx, E] <- ets:match(?MODULE, {{trace, '$1'}, '$2'})],
- {_, Sorted} = lists:unzip(lists:keysort(1, Events)),
- Sorted.
-
-tracer_collector(Msg, Seq) ->
- ets:insert(?MODULE, {{trace, Seq}, normalize_trace_msg(Msg)}),
- Seq + 1.
-
-normalize_trace_msg(TraceMsg) ->
- case tuple_to_list(TraceMsg) of
- [trace_ts, Pid, Type | Info] ->
- {TraceInfo, [Timestamp]} = lists:split(length(Info)-1, Info),
- {Type, Pid, Timestamp, couch_debug:process_name(Pid), process_info(Pid), TraceInfo};
- [trace, Pid, Type | TraceInfo] ->
- {Type, Pid, os:timestamp(), couch_debug:process_name(Pid), process_info(Pid), TraceInfo}
- end.