mirror of
https://github.com/valitydev/riak_test.git
synced 2024-11-06 16:45:29 +00:00
Merge pull request #625 from basho/membackend-test
add expanded memory backend tests
This commit is contained in:
commit
7f0b898e33
@ -1,39 +0,0 @@
|
||||
-module(handoff_ttl).
|
||||
-export([confirm/0]).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
confirm() ->
|
||||
%% only memory supports TTL
|
||||
rt:set_backend(memory),
|
||||
Conf = [
|
||||
{riak_core, [
|
||||
{ring_creation_size, 4}
|
||||
]},
|
||||
{riak_kv, [
|
||||
{ttl, 300}, %% riak 1.4 and earlier are broken and need this
|
||||
{memory_backend, [
|
||||
{ttl, 300}
|
||||
]}
|
||||
]}
|
||||
],
|
||||
[NodeA, NodeB] = rt:deploy_nodes(2, Conf),
|
||||
|
||||
lager:info("writing 100 keys"),
|
||||
|
||||
?assertEqual([], rt:systest_write(NodeA, 0, 100, <<"ttl_test">>, 2)),
|
||||
?assertEqual([], rt:systest_read(NodeA, 0, 100, <<"ttl_test">>, 2)),
|
||||
|
||||
rt:join(NodeB, NodeA),
|
||||
|
||||
?assertEqual(ok, rt:wait_until_nodes_ready([NodeA, NodeB])),
|
||||
rt:wait_until_no_pending_changes([NodeA, NodeB]),
|
||||
|
||||
rt:leave(NodeA),
|
||||
rt:wait_until_unpingable(NodeA),
|
||||
|
||||
?assertEqual([], rt:systest_read(NodeB, 0, 100, <<"ttl_test">>, 2)),
|
||||
|
||||
%% TODO Wait the remainder of the 5 minutes and make sure all the keys are
|
||||
%% gone
|
||||
pass.
|
292
tests/verify_membackend.erl
Normal file
292
tests/verify_membackend.erl
Normal file
@ -0,0 +1,292 @@
|
||||
-module(verify_membackend).
|
||||
%% -export([confirm/0]).
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-define(BUCKET, <<"ttl_test">>).
|
||||
|
||||
%% from 2.0, but should be valid for 1.1+
|
||||
-record(state, {data_ref :: ets:tid(),
|
||||
index_ref :: ets:tid(),
|
||||
time_ref :: ets:tid(),
|
||||
max_memory :: undefined | integer(),
|
||||
used_memory=0 :: integer(),
|
||||
ttl :: integer()}).
|
||||
|
||||
confirm() ->
|
||||
Tests = [ttl, max_memory, combo],
|
||||
[Res1, Res2] =
|
||||
[begin
|
||||
lager:info("testing mode ~p", [Mode]),
|
||||
put(mode, Mode),
|
||||
[begin
|
||||
lager:info("testing setting ~p", [Test]),
|
||||
?MODULE:Test(Mode)
|
||||
end
|
||||
|| Test <- Tests]
|
||||
end
|
||||
|| Mode <- [regular, multi]],
|
||||
Res = Res1 ++ Res2,
|
||||
[ok] = lists:usort(Res),
|
||||
pass.
|
||||
|
||||
|
||||
ttl(Mode) ->
|
||||
Conf = mkconf(ttl, Mode),
|
||||
[NodeA, NodeB] = rt:deploy_nodes(2, Conf),
|
||||
|
||||
?assertEqual(ok, check_leave_and_expiry(NodeA, NodeB)),
|
||||
|
||||
rt:clean_cluster([NodeA]),
|
||||
ok.
|
||||
|
||||
max_memory(Mode) ->
|
||||
Conf = mkconf(max_memory, Mode),
|
||||
[NodeA, NodeB] = rt:deploy_nodes(2, Conf),
|
||||
|
||||
rt:join(NodeB, NodeA),
|
||||
|
||||
?assertEqual(ok, check_put_delete(NodeA)),
|
||||
|
||||
?assertEqual(ok, check_put_consistent(NodeA)),
|
||||
|
||||
?assertEqual(ok, check_eviction(NodeA)),
|
||||
|
||||
rt:clean_cluster([NodeA, NodeB]),
|
||||
|
||||
ok.
|
||||
|
||||
combo(Mode) ->
|
||||
Conf = mkconf(combo, Mode),
|
||||
|
||||
[NodeA, NodeB] = rt:deploy_nodes(2, Conf),
|
||||
|
||||
?assertEqual(ok, check_leave_and_expiry(NodeA, NodeB)),
|
||||
|
||||
%% Make sure that expiry is updating used_memory correctly
|
||||
Pid = get_remote_vnode_pid(NodeA),
|
||||
0 = get_used_space(Pid, NodeA),
|
||||
|
||||
?assertEqual(ok, check_put_delete(NodeA)),
|
||||
|
||||
?assertEqual(ok, check_put_consistent(NodeA)),
|
||||
|
||||
?assertEqual(ok, check_eviction(NodeA)),
|
||||
|
||||
rt:clean_cluster([NodeA]),
|
||||
|
||||
ok.
|
||||
|
||||
|
||||
check_leave_and_expiry(NodeA, NodeB) ->
|
||||
?assertEqual([], rt:systest_write(NodeB, 1, 100, ?BUCKET, 2)),
|
||||
?assertEqual([], rt:systest_read(NodeB, 1, 100, ?BUCKET, 2)),
|
||||
|
||||
rt:join(NodeB, NodeA),
|
||||
|
||||
?assertEqual(ok, rt:wait_until_nodes_ready([NodeA, NodeB])),
|
||||
rt:wait_until_no_pending_changes([NodeA, NodeB]),
|
||||
|
||||
rt:leave(NodeB),
|
||||
rt:wait_until_unpingable(NodeB),
|
||||
|
||||
?assertEqual([], rt:systest_read(NodeA, 1, 100, ?BUCKET, 2)),
|
||||
|
||||
lager:info("waiting for keys to expire"),
|
||||
timer:sleep(timer:seconds(210)),
|
||||
|
||||
_ = rt:systest_read(NodeA, 1, 100, ?BUCKET, 2),
|
||||
timer:sleep(timer:seconds(5)),
|
||||
Res = rt:systest_read(NodeA, 1, 100, ?BUCKET, 2),
|
||||
|
||||
?assertEqual(100, length(Res)),
|
||||
ok.
|
||||
|
||||
check_eviction(Node) ->
|
||||
lager:info("checking that values are evicted when memory limit "
|
||||
"is exceeded"),
|
||||
Size = 20000 * 8,
|
||||
Val = <<0:Size>>,
|
||||
|
||||
?assertEqual([], rt:systest_write(Node, 1, 500, ?BUCKET, 2, Val)),
|
||||
|
||||
Res = length(rt:systest_read(Node, 1, 100, ?BUCKET, 2, Val)),
|
||||
|
||||
%% this is a wider range than I'd like but the final outcome is
|
||||
%% somewhat hard to predict. Just trying to verify that some
|
||||
%% memory limit somewhere is being honored and that values are
|
||||
%% being evicted.
|
||||
case Res == 100 of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
?assertEqual(Res, memory_reclamation_issue)
|
||||
end,
|
||||
|
||||
{ok, C} = riak:client_connect(Node),
|
||||
|
||||
[begin
|
||||
C:delete(?BUCKET, <<N:32/integer>>),
|
||||
timer:sleep(100)
|
||||
end
|
||||
|| N <- lists:seq(1, 500)],
|
||||
|
||||
%% make sure all deletes propagate?
|
||||
timer:sleep(timer:seconds(10)),
|
||||
ok.
|
||||
|
||||
check_put_delete(Node) ->
|
||||
lager:info("checking that used mem is reclaimed on delete"),
|
||||
Pid = get_remote_vnode_pid(Node),
|
||||
|
||||
{MemBaseline, Key} = put_until_changed(Pid, Node, 1000),
|
||||
|
||||
{ok, C} = riak:client_connect(Node),
|
||||
|
||||
ok = C:delete(?BUCKET, <<Key:32/integer>>),
|
||||
|
||||
timer:sleep(timer:seconds(5)),
|
||||
|
||||
Mem = get_used_space(Pid, Node),
|
||||
|
||||
%% this is meh, but the value isn't always the same length.
|
||||
case (Mem == MemBaseline - 1142) orelse
|
||||
(Mem == MemBaseline - 1141) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
?assertEqual(MemBaseline, fail)
|
||||
end,
|
||||
ok.
|
||||
|
||||
check_put_consistent(Node) ->
|
||||
lager:info("checking that used mem doesn't change on re-put"),
|
||||
Pid = get_remote_vnode_pid(Node),
|
||||
|
||||
{MemBaseline, Key} = put_until_changed(Pid, Node, 1000),
|
||||
|
||||
{ok, C} = riak:client_connect(Node),
|
||||
|
||||
ok = C:put(riak_object:new(?BUCKET, <<Key:32/integer>>, <<0:8192>>)),
|
||||
|
||||
{ok, _} = C:get(?BUCKET, <<Key:32/integer>>),
|
||||
|
||||
timer:sleep(timer:seconds(2)),
|
||||
|
||||
Mem = get_used_space(Pid, Node),
|
||||
|
||||
case abs(Mem - MemBaseline) < 3 of
|
||||
true -> ok;
|
||||
false -> ?assertEqual(consistency_failure,
|
||||
{Mem, MemBaseline})
|
||||
end,
|
||||
ok.
|
||||
|
||||
put_until_changed(Pid, Node, Key) ->
|
||||
{ok, C} = riak:client_connect(Node),
|
||||
UsedSpace = get_used_space(Pid, Node),
|
||||
|
||||
C:put(riak_object:new(?BUCKET, <<Key:32/integer>>, <<0:8192>>)),
|
||||
|
||||
timer:sleep(100),
|
||||
|
||||
UsedSpace1 = get_used_space(Pid, Node),
|
||||
case UsedSpace < UsedSpace1 of
|
||||
true ->
|
||||
{UsedSpace1, Key};
|
||||
false ->
|
||||
put_until_changed(Pid, Node, Key+1)
|
||||
end.
|
||||
|
||||
mkconf(Test, Mode) ->
|
||||
MembConfig =
|
||||
case Test of
|
||||
ttl ->
|
||||
[{ttl, 200}];
|
||||
max_memory ->
|
||||
[{max_memory, 1}];
|
||||
combo ->
|
||||
[{max_memory, 1},
|
||||
{ttl, 200}]
|
||||
end,
|
||||
case Mode of
|
||||
regular ->
|
||||
%% only memory supports TTL
|
||||
rt:set_backend(memory),
|
||||
|
||||
[
|
||||
{riak_core, [
|
||||
{ring_creation_size, 4}
|
||||
]},
|
||||
{riak_kv, [
|
||||
{anti_entropy, {off, []}},
|
||||
{delete_mode, immediate},
|
||||
{memory_backend, MembConfig}
|
||||
]}
|
||||
];
|
||||
multi ->
|
||||
rt:set_backend(multi),
|
||||
[
|
||||
{riak_core, [
|
||||
{ring_creation_size, 4}
|
||||
]},
|
||||
{riak_kv, [
|
||||
{anti_entropy, {off, []}},
|
||||
{delete_mode, immediate},
|
||||
{multi_backend_default, <<"memb">>},
|
||||
{multi_backend,
|
||||
[
|
||||
{<<"memb">>, riak_kv_memory_backend,
|
||||
MembConfig}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
end.
|
||||
|
||||
get_remote_vnode_pid(Node) ->
|
||||
[{_,_,VNode}|_] = rpc:call(Node, riak_core_vnode_manager,
|
||||
all_vnodes, [riak_kv_vnode]),
|
||||
VNode.
|
||||
|
||||
%% this is silly fragile
|
||||
get_used_space(VNode, Node) ->
|
||||
S = rpc:call(Node, sys, get_state, [VNode]),
|
||||
Mode = get(mode),
|
||||
Version = rt:get_version(),
|
||||
%% lager:info("version mode ~p", [{Version, Mode}]),
|
||||
TwoOhReg =
|
||||
fun(X) ->
|
||||
element(4, element(4, element(2, X)))
|
||||
end,
|
||||
TwoOhMulti =
|
||||
fun(X) ->
|
||||
element(
|
||||
3, lists:nth(
|
||||
1, element(
|
||||
2, element(
|
||||
4, element(
|
||||
4, element(2, X))))))
|
||||
end,
|
||||
Extract =
|
||||
case {Version, Mode} of
|
||||
{<<"riak-2.0",_/binary>>, regular} ->
|
||||
TwoOhReg;
|
||||
{<<"riak_ee-2.0",_/binary>>, regular} ->
|
||||
TwoOhReg;
|
||||
{<<"riak-2.0",_/binary>>, multi} ->
|
||||
TwoOhMulti;
|
||||
{<<"riak_ee-2.0",_/binary>>, multi} ->
|
||||
TwoOhMulti;
|
||||
_Else ->
|
||||
lager:error("didn't understand version/mode tuple ~p",
|
||||
[{Version, Mode}]),
|
||||
throw(boom)
|
||||
end,
|
||||
State = Extract(S),
|
||||
Mem = State#state.used_memory,
|
||||
lager:info("got ~p used memory", [Mem]),
|
||||
Mem.
|
Loading…
Reference in New Issue
Block a user