nickva commented on code in PR #4266:
URL: https://github.com/apache/couchdb/pull/4266#discussion_r1026748968
##########
src/smoosh/test/smoosh_tests.erl:
##########
@@ -3,152 +3,486 @@
-include_lib("couch/include/couch_eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
-%% ==========
-%% Setup
-%% ----------
-
-setup(ChannelType) ->
- DbName = ?tempdb(),
- {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
- couch_db:close(Db),
- {ok, ChannelPid} = smoosh_server:get_channel(ChannelType),
- smoosh_channel:flush(ChannelPid),
- ok = config:set("smoosh", "persist", "true", false),
- ok = config:set(config_section(ChannelType), "min_size", "1", false),
- ok = config:set(config_section(ChannelType), "min_priority", "1", false),
- DbName.
-
-teardown(ChannelType, DbName) ->
- ok = couch_server:delete(DbName, [?ADMIN_CTX]),
- ok = config:delete("smoosh", "persist", false),
- ok = config:delete(config_section(DbName), "min_size", false),
- ok = config:delete(config_section(DbName), "min_priority", false),
- meck:unload(),
- {ok, ChannelPid} = smoosh_server:get_channel(ChannelType),
- smoosh_channel:flush(ChannelPid),
- ok.
-
-config_section(ChannelType) ->
- "smoosh." ++ ChannelType.
-
-%% ==========
-%% Tests
-%% ----------
-
smoosh_test_() ->
{
- "Testing smoosh",
+ setup,
+ fun setup_all/0,
+ fun teardown_all/1,
{
- setup,
- fun() -> test_util:start_couch([smoosh]) end,
- fun test_util:stop/1,
+ foreach,
+ fun setup/0,
+ fun teardown/1,
[
- channels_tests(),
- persistence_tests()
+ ?TDEF_FE(t_default_channels),
+ ?TDEF_FE(t_channels_recreated_on_crash),
+ ?TDEF_FE(t_can_create_and_delete_channels),
+ ?TDEF_FE(t_db_is_enqueued_and_compacted),
+ ?TDEF_FE(t_view_is_enqueued_and_compacted),
+ ?TDEF_FE(t_index_cleanup_happens_by_default),
+ ?TDEF_FE(t_index_cleanup_can_be_disabled),
+ ?TDEF_FE(t_suspend_resume),
+ ?TDEF_FE(t_check_window_can_resume),
+ ?TDEF_FE(t_renqueue_on_crashes),
+ ?TDEF_FE(t_update_status_works),
+ ?TDEF_FE(t_checkpointing_works, 15),
+ ?TDEF_FE(t_ignore_checkpoint_resume_if_compacted_already),
+ ?TDEF_FE(t_access_cleaner_restarts),
+ ?TDEF_FE(t_event_handler_restarts),
+ ?TDEF_FE(t_manual_enqueue_api_works),
+ ?TDEF_FE(t_access_cleaner_works)
]
}
}.
-persistence_tests() ->
- Tests = [
- fun should_persist_queue/2,
- fun should_call_recover/2,
- fun should_not_call_recover/2
- ],
- {
- "Various persistence tests",
- [
- make_test_case("ratio_dbs", Tests)
- ]
- }.
+setup_all() ->
+ meck:new(smoosh_server, [passthrough]),
+ meck:new(smoosh_channel, [passthrough]),
+ meck:new(fabric, [passthrough]),
+ meck:new(couch_emsort, [passthrough]),
+ Ctx = test_util:start_couch([fabric]),
+ config:set("query_server_config", "commit_freq", "0", false),
+ Ctx.
-channels_tests() ->
- Tests = [
- fun should_enqueue/2
- ],
- {
- "Various channels tests",
+teardown_all(Ctx) ->
+ catch application:stop(smoosh),
+ config:delete("query_server_config", "commit_freq", false),
+ test_util:stop(Ctx),
+ meck:unload().
+
+setup() ->
+ config:set("smoosh", "persist", "false", false),
+ config:set("smoosh", "wait_secs", "0", false),
+ DbName = ?tempdb(),
+ fabric:create_db(DbName, [{q, 1}]),
+ {ok, _} = create_ddoc(DbName, <<"_design/foo">>, <<"bar">>),
+ {ok, _} = create_doc(DbName, <<"doc1">>, 1500000),
+ {ok, _} = fabric:query_view(DbName, <<"foo">>, <<"bar">>),
+ application:start(smoosh),
+ wait_for_channels(),
+ flush(),
+ DbName.
+
+teardown(DbName) ->
+ catch flush(),
+ catch application:stop(smoosh),
+ fabric:delete_db(DbName),
+ meck:reset(smoosh_server),
+ meck:reset(smoosh_channel),
+ meck:reset(couch_emsort),
+ meck:reset(fabric),
+ config:delete("smoosh", "db_channels", false),
+ config:delete("smoosh.ratio_dbs", "min_priority", false),
+ config:delete("smoosh.ratio_views", "min_priority", false),
+ config:delete("smoosh", "view_channels", false),
+ config:delete("smoosh", "cleanup_channels", false),
+ config:delete("smoosh", "wait_secs", false),
+ config:delete("smoosh", "persist", false),
+ config:delete("smoosh", "cleanup_index_files", false).
+
+t_default_channels(_) ->
+ ?assertMatch(
[
- make_test_case("ratio_dbs", Tests)
- ]
- }.
+ {"index_cleanup", _},
+ {"ratio_dbs", _},
+ {"ratio_views", _},
+ {"slack_dbs", _},
+ {"slack_views", _},
+ {"upgrade_dbs", _},
+ {"upgrade_views", _}
+ ],
+ status()
+ ),
+ % If app hasn't started status won't crash
+ application:stop(smoosh),
+ ?assertEqual([], status()).
-make_test_case(Type, Funs) ->
- {foreachx, fun setup/1, fun teardown/2, [{Type, Fun} || Fun <- Funs]}.
+t_channels_recreated_on_crash(_) ->
+ RatioDbsPid = get_channel_pid("ratio_dbs"),
+ meck:reset(smoosh_channel),
+ exit(RatioDbsPid, kill),
+ meck:wait(1, smoosh_channel, start_link, 1, 3000),
+ wait_for_channels(7),
+ ?assertMatch([_, {"ratio_dbs", _} | _], status()),
+ ?assertNotEqual(RatioDbsPid, get_channel_pid("ratio_dbs")).
-should_enqueue(ChannelType, DbName) ->
- ?_test(begin
- ok = grow_db_file(DbName, 300),
- ok = wait_enqueue(ChannelType, DbName),
- ?assert(is_enqueued(ChannelType, DbName)),
- ok
- end).
+t_can_create_and_delete_channels(_) ->
+ config:set("smoosh", "db_channels", "mychan1", false),
+ config:set("smoosh", "view_channels", "mychan2", false),
+ config:set("smoosh", "cleanup_channels", "mychan3", false),
+ % 7 default ones + 3 new ones
+ wait_for_channels(10),
+ meck:reset(smoosh_channel),
+ config:delete("smoosh", "db_channels", false),
+ config:delete("smoosh", "view_channels", false),
+ config:delete("smoosh", "cleanup_channels", false),
+ wait_for_channels(7).
-should_persist_queue(ChannelType, DbName) ->
- ?_test(begin
- {ok, ChannelPid} = smoosh_server:get_channel(ChannelType),
- ok = grow_db_file(DbName, 300),
- ok = wait_enqueue(ChannelType, DbName),
- ok = smoosh_channel:persist(ChannelPid),
- Q0 = channel_queue(ChannelType),
- ok = application:stop(smoosh),
- ok = application:start(smoosh),
- Q1 = channel_queue(ChannelType),
- % Assert that queues are not empty
- ?assertNotEqual(Q0, smoosh_priority_queue:new(ChannelType)),
- ?assertNotEqual(Q1, smoosh_priority_queue:new(ChannelType)),
- ?assertEqual(Q0, Q1),
- ok
- end).
+t_db_is_enqueued_and_compacted(DbName) ->
+ ?assertEqual({0, 0, 0}, sync_status("ratio_dbs")),
+ meck:reset(smoosh_channel),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_to_enqueue(DbName),
+ ok = wait_compact_start(),
+ ok = wait_normal_down().
-should_call_recover(_ChannelType, _DbName) ->
- ?_test(begin
- ok = application:stop(smoosh),
- ok = config:set("smoosh", "persist", "true", false),
- meck:new(smoosh_priority_queue, [passthrough]),
- ok = application:start(smoosh),
- timer:sleep(1000),
- ?assertNotEqual(0, meck:num_calls(smoosh_priority_queue, recover,
'_')),
- ok
- end).
+t_view_is_enqueued_and_compacted(DbName) ->
+ % We don't want index cleanup to interfere for now
+ config:set("smoosh", "cleanup_index_files", "false", false),
+ % Ensure db is compacted
+ meck:reset(smoosh_channel),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_normal_down(),
+ % Check view
+ meck:reset(smoosh_channel),
+ {ok, _} = fabric:query_view(DbName, <<"foo">>, <<"bar">>),
+ ok = wait_to_enqueue({DbName, <<"_design/foo">>}),
+ ok = wait_compact_start(),
+ ok = wait_normal_down().
-should_not_call_recover(_ChannelType, _DbName) ->
- ?_test(begin
- ok = application:stop(smoosh),
- ok = config:set("smoosh", "persist", "false", false),
- meck:new(smoosh_priority_queue, [passthrough]),
- ok = application:start(smoosh),
- timer:sleep(1000),
- ?assertEqual(0, meck:num_calls(smoosh_priority_queue, recover, '_')),
- ok
- end).
+t_index_cleanup_happens_by_default(DbName) ->
+ ?assert(config:get_boolean("smoosh", "cleanup_index_files", true)),
+ % Db compacts
+ meck:reset(smoosh_channel),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_normal_down(),
+ % View should compact as well
+ meck:reset(fabric),
+ meck:reset(smoosh_channel),
+ {ok, _} = fabric:query_view(DbName, <<"foo">>, <<"bar">>),
+ % View cleanup should have been invoked
+ meck:wait(fabric, cleanup_index_files, [DbName], 4000).
+
+t_index_cleanup_can_be_disabled(DbName) ->
+ config:set("smoosh", "cleanup_index_files", "false", false),
+ % Db compacts
+ meck:reset(smoosh_channel),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_normal_down(),
+ % View should compact as well
+ meck:reset(fabric),
+ meck:reset(smoosh_channel),
+ {ok, _} = fabric:query_view(DbName, <<"foo">>, <<"bar">>),
+ ok = wait_compact_start(),
+ ok = wait_normal_down(),
+ % View cleanup was not called
+ timer:sleep(1000),
+ ?assertEqual(0, meck:num_calls(fabric, cleanup_index_files, 1)).
+
+t_suspend_resume(DbName) ->
+ ?assertEqual({0, 0, 0}, sync_status("ratio_dbs")),
+ meck:reset(smoosh_channel),
+ setup_db_compactor_intercept(),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_to_enqueue(DbName),
+ CompPid = wait_db_compactor_pid(),
+ ok = smoosh:suspend(),
+ ?assertEqual({status, suspended}, erlang:process_info(CompPid, status)),
+ ?assertEqual({1, 0, 0}, sync_status("ratio_dbs")),
+ % Suspending twice should work too
+ ok = smoosh:suspend(),
+ ?assertEqual({status, suspended}, erlang:process_info(CompPid, status)),
+ ?assertEqual({1, 0, 0}, sync_status("ratio_dbs")),
+ ok = smoosh:resume(),
+ ?assertNotEqual({status, suspended}, erlang:process_info(CompPid, status)),
+ % Resuming twice should work too
+ ok = smoosh:resume(),
+ ?assertNotEqual({status, suspended}, erlang:process_info(CompPid, status)),
+ CompPid ! continue,
+ ok = wait_normal_down().
+
+t_check_window_can_resume(DbName) ->
+ ?assertEqual({0, 0, 0}, sync_status("ratio_dbs")),
+ meck:reset(smoosh_channel),
+ setup_db_compactor_intercept(),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_to_enqueue(DbName),
+ CompPid = wait_db_compactor_pid(),
+ ok = smoosh:suspend(),
+ ?assertEqual({status, suspended}, erlang:process_info(CompPid, status)),
+ get_channel_pid("ratio_dbs") ! check_window,
+ CompPid ! continue,
+ ok = wait_normal_down().
+
+t_renqueue_on_crashes(DbName) ->
+ ?assertEqual({0, 0, 0}, sync_status("ratio_dbs")),
+ meck:reset(smoosh_channel),
+ setup_db_compactor_intercept(),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_to_enqueue(DbName),
+ CompPid = wait_db_compactor_pid(),
+ meck:reset(smoosh_channel),
+ CompPid ! {raise, error, boom},
+ ok = wait_to_enqueue(DbName),
+ CompPid2 = wait_db_compactor_pid(),
+ CompPid2 ! continue,
+ ok = wait_normal_down().
+
+t_update_status_works(DbName) ->
+ setup_db_compactor_intercept(),
+ {ok, _} = delete_doc(DbName, <<"doc1">>),
+ ok = wait_to_enqueue(DbName),
+ CompPid = wait_db_compactor_pid(),
+ % status should have 1 starting job, but it may have not been updated yet
so
+ % we wait until update_status is called
+ wait_update_status(),
+ WaitFun = fun() ->
+ case {1, 0, 0} =:= status("ratio_dbs") of
Review Comment:
Since it's a test I thought to just make the condition check explicit on a
single line.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]