summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shorin <kxepal@apache.org>2014-05-26 20:23:41 +0400
committerAlexander Shorin <kxepal@apache.org>2015-12-02 03:49:04 +0300
commit4a0ce96dfff3a4c7636437c1f1171c502e787622 (patch)
treecdc45300d90a766bdc8dd4c44db40188ca20fd7f
parented10866b4c546e158ecfa8f81ecc48afec8169d5 (diff)
downloadcouchdb-4a0ce96dfff3a4c7636437c1f1171c502e787622.tar.gz
Port 090-task-status.t etap test suite to eunit
Split huge test case into multiple ones. Fix issue with get_task_prop when Acc may be reset if searched task isn't last in the list.
-rw-r--r--test/couchdb/Makefile.am1
-rw-r--r--test/couchdb/couch_task_status_tests.erl225
-rwxr-xr-xtest/etap/090-task-status.t279
-rw-r--r--test/etap/Makefile.am1
4 files changed, 226 insertions, 280 deletions
diff --git a/test/couchdb/Makefile.am b/test/couchdb/Makefile.am
index ea4e32c66..36c5d676f 100644
--- a/test/couchdb/Makefile.am
+++ b/test/couchdb/Makefile.am
@@ -30,6 +30,7 @@ eunit_files = \
couch_file_tests.erl \
couch_key_tree_tests.erl \
couch_stream_tests.erl \
+ couch_task_status_tests.erl \
couch_util_tests.erl \
couch_uuids_tests.erl \
couch_work_queue_tests.erl \
diff --git a/test/couchdb/couch_task_status_tests.erl b/test/couchdb/couch_task_status_tests.erl
new file mode 100644
index 000000000..f71ad2bf7
--- /dev/null
+++ b/test/couchdb/couch_task_status_tests.erl
@@ -0,0 +1,225 @@
+% 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_task_status_tests).
+
+-include("couch_eunit.hrl").
+-include_lib("couchdb/couch_db.hrl").
+
+-define(TIMEOUT, 1000).
+
+
+setup() ->
+ {ok, TaskStatusPid} = couch_task_status:start_link(),
+ TaskUpdaterPid = spawn(fun() -> loop() end),
+ {TaskStatusPid, TaskUpdaterPid}.
+
+teardown({TaskStatusPid, _}) ->
+ erlang:monitor(process, TaskStatusPid),
+ couch_task_status:stop(),
+ receive
+ {'DOWN', _, _, TaskStatusPid, _} ->
+ ok
+ after ?TIMEOUT ->
+ throw(timeout_error)
+ end.
+
+
+couch_task_status_test_() ->
+ {
+ "CouchDB task status updates",
+ {
+ foreach,
+ fun setup/0, fun teardown/1,
+ [
+ fun should_register_task/1,
+ fun should_set_task_startup_time/1,
+ fun should_have_update_time_as_startup_before_any_progress/1,
+ fun should_set_task_type/1,
+ fun should_not_register_multiple_tasks_for_same_pid/1,
+ fun should_set_task_progress/1,
+ fun should_update_task_progress/1,
+ fun should_update_time_changes_on_task_progress/1,
+ fun should_control_update_frequency/1,
+ fun should_reset_control_update_frequency/1,
+ fun should_track_multiple_tasks/1,
+ fun should_finish_task/1
+
+ ]
+ }
+ }.
+
+
+should_register_task({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?_assertEqual(1, length(couch_task_status:all())).
+
+should_set_task_startup_time({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?_assert(is_integer(get_task_prop(Pid, started_on))).
+
+should_have_update_time_as_startup_before_any_progress({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ StartTime = get_task_prop(Pid, started_on),
+ ?_assertEqual(StartTime, get_task_prop(Pid, updated_on)).
+
+should_set_task_type({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?_assertEqual(replication, get_task_prop(Pid, type)).
+
+should_not_register_multiple_tasks_for_same_pid({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?_assertEqual({add_task_error, already_registered},
+ call(Pid, add, [{type, compaction}, {progress, 0}])).
+
+should_set_task_progress({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?_assertEqual(0, get_task_prop(Pid, progress)).
+
+should_update_task_progress({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ call(Pid, update, [{progress, 25}]),
+ ?_assertEqual(25, get_task_prop(Pid, progress)).
+
+should_update_time_changes_on_task_progress({_, Pid}) ->
+ ?_assert(
+ begin
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ok = timer:sleep(1000), % sleep awhile to customize update time
+ call(Pid, update, [{progress, 25}]),
+ get_task_prop(Pid, updated_on) > get_task_prop(Pid, started_on)
+ end).
+
+should_control_update_frequency({_, Pid}) ->
+ ?_assertEqual(66,
+ begin
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ call(Pid, update, [{progress, 50}]),
+ call(Pid, update_frequency, 500),
+ call(Pid, update, [{progress, 66}]),
+ call(Pid, update, [{progress, 77}]),
+ get_task_prop(Pid, progress)
+ end).
+
+should_reset_control_update_frequency({_, Pid}) ->
+ ?_assertEqual(87,
+ begin
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ call(Pid, update, [{progress, 50}]),
+ call(Pid, update_frequency, 500),
+ call(Pid, update, [{progress, 66}]),
+ call(Pid, update, [{progress, 77}]),
+ call(Pid, update_frequency, 0),
+ call(Pid, update, [{progress, 87}]),
+ get_task_prop(Pid, progress)
+ end).
+
+should_track_multiple_tasks(_) ->
+ ?_assert(run_multiple_tasks()).
+
+should_finish_task({_, Pid}) ->
+ ok = call(Pid, add, [{type, replication}, {progress, 0}]),
+ ?assertEqual(1, length(couch_task_status:all())),
+ ok = call(Pid, done),
+ ?_assertEqual(0, length(couch_task_status:all())).
+
+
+run_multiple_tasks() ->
+ Pid1 = spawn(fun() -> loop() end),
+ Pid2 = spawn(fun() -> loop() end),
+ Pid3 = spawn(fun() -> loop() end),
+ call(Pid1, add, [{type, replication}, {progress, 0}]),
+ call(Pid2, add, [{type, compaction}, {progress, 0}]),
+ call(Pid3, add, [{type, indexer}, {progress, 0}]),
+
+ ?assertEqual(3, length(couch_task_status:all())),
+ ?assertEqual(replication, get_task_prop(Pid1, type)),
+ ?assertEqual(compaction, get_task_prop(Pid2, type)),
+ ?assertEqual(indexer, get_task_prop(Pid3, type)),
+
+ call(Pid2, update, [{progress, 33}]),
+ call(Pid3, update, [{progress, 42}]),
+ call(Pid1, update, [{progress, 11}]),
+ ?assertEqual(42, get_task_prop(Pid3, progress)),
+ call(Pid1, update, [{progress, 72}]),
+ ?assertEqual(72, get_task_prop(Pid1, progress)),
+ ?assertEqual(33, get_task_prop(Pid2, progress)),
+
+ call(Pid1, done),
+ ?assertEqual(2, length(couch_task_status:all())),
+ call(Pid3, done),
+ ?assertEqual(1, length(couch_task_status:all())),
+ call(Pid2, done),
+ ?assertEqual(0, length(couch_task_status:all())),
+
+ true.
+
+
+loop() ->
+ receive
+ {add, Props, From} ->
+ Resp = couch_task_status:add_task(Props),
+ From ! {ok, self(), Resp},
+ loop();
+ {update, Props, From} ->
+ Resp = couch_task_status:update(Props),
+ From ! {ok, self(), Resp},
+ loop();
+ {update_frequency, Msecs, From} ->
+ Resp = couch_task_status:set_update_frequency(Msecs),
+ From ! {ok, self(), Resp},
+ loop();
+ {done, From} ->
+ From ! {ok, self(), ok}
+ end.
+
+call(Pid, Command) ->
+ Pid ! {Command, self()},
+ wait(Pid).
+
+call(Pid, Command, Arg) ->
+ Pid ! {Command, Arg, self()},
+ wait(Pid).
+
+wait(Pid) ->
+ receive
+ {ok, Pid, Msg} ->
+ Msg
+ after ?TIMEOUT ->
+ throw(timeout_error)
+ end.
+
+get_task_prop(Pid, Prop) ->
+ From = list_to_binary(pid_to_list(Pid)),
+ Element = lists:foldl(
+ fun(PropList, Acc) ->
+ case couch_util:get_value(pid, PropList) of
+ From ->
+ [PropList | Acc];
+ _ ->
+ Acc
+ end
+ end,
+ [], couch_task_status:all()
+ ),
+ case couch_util:get_value(Prop, hd(Element), nil) of
+ nil ->
+ erlang:error({assertion_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {reason, "Could not get property '"
+ ++ couch_util:to_list(Prop)
+ ++ "' for task "
+ ++ pid_to_list(Pid)}]});
+ Value ->
+ Value
+ end.
diff --git a/test/etap/090-task-status.t b/test/etap/090-task-status.t
deleted file mode 100755
index 23115bdaa..000000000
--- a/test/etap/090-task-status.t
+++ /dev/null
@@ -1,279 +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.
-
-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.
-
-get_task_prop(Pid, Prop) ->
- From = list_to_binary(pid_to_list(Pid)),
- Element = lists:foldl(
- fun(PropList,Acc) ->
- case couch_util:get_value(pid,PropList) of
- From ->
- [PropList | Acc];
- _ ->
- []
- end
- end,
- [], couch_task_status:all()
- ),
- case couch_util:get_value(Prop, hd(Element), nil) of
- nil ->
- etap:bail("Could not get property '" ++ couch_util:to_list(Prop) ++
- "' for task " ++ pid_to_list(Pid));
- Value ->
- Value
- end.
-
-
-loop() ->
- receive
- {add, Props, From} ->
- Resp = couch_task_status:add_task(Props),
- From ! {ok, self(), Resp},
- loop();
- {update, Props, From} ->
- Resp = couch_task_status:update(Props),
- From ! {ok, self(), Resp},
- loop();
- {update_frequency, Msecs, From} ->
- Resp = couch_task_status:set_update_frequency(Msecs),
- From ! {ok, self(), Resp},
- loop();
- {done, From} ->
- From ! {ok, self(), ok}
- end.
-
-call(Pid, Command) ->
- Pid ! {Command, self()},
- wait(Pid).
-
-call(Pid, Command, Arg) ->
- Pid ! {Command, Arg, self()},
- wait(Pid).
-
-wait(Pid) ->
- receive
- {ok, Pid, Msg} -> Msg
- after 1000 ->
- throw(timeout_error)
- end.
-
-test() ->
- {ok, TaskStatusPid} = couch_task_status:start_link(),
-
- TaskUpdater = fun() -> loop() end,
- % create three updaters
- Pid1 = spawn(TaskUpdater),
- Pid2 = spawn(TaskUpdater),
- Pid3 = spawn(TaskUpdater),
-
- ok = call(Pid1, add, [{type, replication}, {progress, 0}]),
- etap:is(
- length(couch_task_status:all()),
- 1,
- "Started a task"
- ),
- Task1StartTime = get_task_prop(Pid1, started_on),
- etap:is(
- is_integer(Task1StartTime),
- true,
- "Task start time is defined."
- ),
- etap:is(
- get_task_prop(Pid1, updated_on),
- Task1StartTime,
- "Task's start time is the same as the update time before an update."
- ),
-
- etap:is(
- call(Pid1, add, [{type, compaction}, {progress, 0}]),
- {add_task_error, already_registered},
- "Unable to register multiple tasks for a single Pid."
- ),
-
- etap:is(
- get_task_prop(Pid1, type),
- replication,
- "Task type is 'replication'."
- ),
- etap:is(
- get_task_prop(Pid1, progress),
- 0,
- "Task progress is 0."
- ),
-
- ok = timer:sleep(1000),
- call(Pid1, update, [{progress, 25}]),
- etap:is(
- get_task_prop(Pid1, progress),
- 25,
- "Task progress is 25."
- ),
- etap:is(
- get_task_prop(Pid1, updated_on) > Task1StartTime,
- true,
- "Task's last update time has increased after an update."
- ),
-
- call(Pid2, add, [{type, compaction}, {progress, 0}]),
- etap:is(
- length(couch_task_status:all()),
- 2,
- "Started a second task."
- ),
- Task2StartTime = get_task_prop(Pid2, started_on),
- etap:is(
- is_integer(Task2StartTime),
- true,
- "Second task's start time is defined."
- ),
- etap:is(
- get_task_prop(Pid2, updated_on),
- Task2StartTime,
- "Second task's start time is the same as the update time before an update."
- ),
-
- etap:is(
- get_task_prop(Pid2, type),
- compaction,
- "Second task's type is 'compaction'."
- ),
- etap:is(
- get_task_prop(Pid2, progress),
- 0,
- "Second task's progress is 0."
- ),
-
- ok = timer:sleep(1000),
- call(Pid2, update, [{progress, 33}]),
- etap:is(
- get_task_prop(Pid2, progress),
- 33,
- "Second task's progress updated to 33."
- ),
- etap:is(
- get_task_prop(Pid2, updated_on) > Task2StartTime,
- true,
- "Second task's last update time has increased after an update."
- ),
-
- call(Pid3, add, [{type, indexer}, {progress, 0}]),
- etap:is(
- length(couch_task_status:all()),
- 3,
- "Registered a third task."
- ),
- Task3StartTime = get_task_prop(Pid3, started_on),
- etap:is(
- is_integer(Task3StartTime),
- true,
- "Third task's start time is defined."
- ),
- etap:is(
- get_task_prop(Pid3, updated_on),
- Task3StartTime,
- "Third task's start time is the same as the update time before an update."
- ),
-
- etap:is(
- get_task_prop(Pid3, type),
- indexer,
- "Third task's type is 'indexer'."
- ),
- etap:is(
- get_task_prop(Pid3, progress),
- 0,
- "Third task's progress is 0."
- ),
-
- ok = timer:sleep(1000),
- call(Pid3, update, [{progress, 50}]),
- etap:is(
- get_task_prop(Pid3, progress),
- 50,
- "Third task's progress updated to 50."
- ),
- etap:is(
- get_task_prop(Pid3, updated_on) > Task3StartTime,
- true,
- "Third task's last update time has increased after an update."
- ),
-
- call(Pid3, update_frequency, 500),
- call(Pid3, update, [{progress, 66}]),
- etap:is(
- get_task_prop(Pid3, progress),
- 66,
- "Third task's progress updated to 66."
- ),
-
- call(Pid3, update, [{progress, 67}]),
- etap:is(
- get_task_prop(Pid3, progress),
- 66,
- "Task update dropped because of frequency limit."
- ),
-
- call(Pid3, update_frequency, 0),
- call(Pid3, update, [{progress, 77}]),
- etap:is(
- get_task_prop(Pid3, progress),
- 77,
- "Task updated after reseting frequency limit."
- ),
-
-
- call(Pid1, done),
- etap:is(
- length(couch_task_status:all()),
- 2,
- "First task finished."
- ),
-
- call(Pid2, done),
- etap:is(
- length(couch_task_status:all()),
- 1,
- "Second task finished."
- ),
-
- call(Pid3, done),
- etap:is(
- length(couch_task_status:all()),
- 0,
- "Third task finished."
- ),
-
- erlang:monitor(process, TaskStatusPid),
- couch_task_status:stop(),
- receive
- {'DOWN', _, _, TaskStatusPid, _} ->
- ok
- after
- 1000 ->
- throw(timeout_error)
- end,
-
- ok.
diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am
index 091dae9db..4657656d0 100644
--- a/test/etap/Makefile.am
+++ b/test/etap/Makefile.am
@@ -36,7 +36,6 @@ fixture_files = \
fixtures/test.couch
tap_files = \
- 090-task-status.t \
100-ref-counter.t \
120-stats-collect.t \
121-stats-aggregates.cfg \