Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

WIP Update eqc test and resultant changes to the counter code

  • Loading branch information...
commit 7c99ea1bf2a30cdd4a289473cb5684c9e7296bad 1 parent 55cb4bc
@russelldb russelldb authored
Showing with 44 additions and 14 deletions.
  1. +18 −12 src/riak_kv_counter.erl
  2. +26 −2 test/kv_counter_eqc.erl
View
30 src/riak_kv_counter.erl
@@ -37,12 +37,12 @@
-spec update(riak_object:riak_object(), riak_object:index_specs(),
binary(), integer()) ->
riak_object:riak_object().
-update(RObj, _IndexSpecs, _Actor, 0) ->
- RObj;
update(RObj, IndexSpecs, Actor, Amt) ->
- {Counter0, NonCounterSiblings, Meta} = merge_object(RObj, IndexSpecs,
- riak_kv_pncounter:new()),
- Counter = update_counter(Counter0, Actor, Amt),
+ {Counter0, NonCounterSiblings, Meta} = merge_object(RObj, IndexSpecs),
+ Counter = case Amt of
+ 0 -> Counter0;
+ _ -> update_counter(Counter0, Actor, Amt)
+ end,
update_object(RObj, Meta, Counter, NonCounterSiblings).
%% @doc Unlike regular, opaque `riak_object' values, conflicting
@@ -51,7 +51,7 @@ update(RObj, IndexSpecs, Actor, Amt) ->
-spec merge(riak_object:riak_object(), riak_object:index_specs()) ->
riak_object:riak_object().
merge(RObj, IndexSpecs) ->
- {Counter, NonCounterSiblings, Meta} = merge_object(RObj, IndexSpecs, undefined),
+ {Counter, NonCounterSiblings, Meta} = merge_object(RObj, IndexSpecs),
update_object(RObj, Meta, Counter, NonCounterSiblings).
%% @doc Currently _IGNORES_ all non-counter sibling values
@@ -59,21 +59,25 @@ merge(RObj, IndexSpecs) ->
integer().
value(RObj) ->
Contents = riak_object:get_contents(RObj),
- {Counter, _NonCounterSiblings} = merge_contents(Contents, riak_kv_pncounter:new()),
- riak_kv_pncounter:value(Counter).
+ {Counter, _NonCounterSiblings} = merge_contents(Contents),
+ case Counter of
+ undefined -> 0;
+ _ ->
+ riak_kv_pncounter:value(Counter)
+ end.
%% Merge contents _AND_ meta
-merge_object(RObj, IndexSpecs, Seed) ->
+merge_object(RObj, IndexSpecs) ->
Contents = riak_object:get_contents(RObj),
- {Counter, NonCounterSiblings} = merge_contents(Contents, Seed),
+ {Counter, NonCounterSiblings} = merge_contents(Contents),
Meta = merged_meta(IndexSpecs),
{Counter, NonCounterSiblings, Meta}.
%% Only merge the values of actual PN-Counters
%% If a non-CRDT datum is present, keep it as a sibling value
-merge_contents(Contents, Seed) ->
+merge_contents(Contents) ->
lists:foldl(fun merge_value/2,
- {Seed, []},
+ {undefined, []},
Contents).
%% worker for `do_merge/1'
@@ -98,6 +102,8 @@ merged_meta(IndexSpecs) ->
dict:store(?MD_INDEX, Indexes, dict:new())
end.
+update_counter(undefined, Actor, Amt) ->
+ update_counter(riak_kv_pncounter:new(), Actor, Amt);
update_counter(Counter, Actor, Amt) ->
Op = counter_op(Amt),
riak_kv_pncounter:update(Op, Actor, Counter).
View
28 test/kv_counter_eqc.erl
@@ -122,18 +122,42 @@ prop_update() ->
begin
Updated = riak_kv_counter:update(RObj, IndexSpecs, Actor, Amt),
+ NumMergedCounters = num_counters(Updated),
+ ExpectedCounters = case {NumMergedCounters, Amt} of
+ {0, 0} -> 0;
+ _ -> 1
+ end,
+ %% Check that the structure of the merged counter is correct
+ CounterSeed = case Amt of
+ 0 -> undefined;
+ _ -> riak_kv_pncounter:new(Actor, Amt)
+ end,
+ ExpectedCounter = merge_object(RObj, CounterSeed),
+ {MergedMeta, MergedCounter} = single_counter(Updated),
+ %% Check that the meta is correct
+ ExpectedIndexMeta = expected_indexes(IndexSpecs, ExpectedCounters),
+ %% Check that non-sibling values and meta are untouched
+ ExpectedSiblings = non_counter_siblings(RObj),
+ ActualSiblings = non_counter_siblings(Updated),
+
?WHENFAIL(
begin
io:format("Gen ~p~n", [RObj]),
io:format("Updated ~p~n", [Updated]),
io:format("Index Specs ~p~n", [IndexSpecs]),
- io:format("Amt ~p~n", [Amt])
+ io:format("Amt ~p~n", [Amt]),
+ io:format("Merged counter ~p Expected counter ~p", [ExpectedCounter, MergedCounter])
end,
collect(Amt,
conjunction([
{counter_value, equals(sumthem(RObj) + Amt,
riak_kv_counter:value(Updated))},
- {merge_checks, verify_merge(RObj, Updated, IndexSpecs)}
+ {number_of_counters,
+ equals(ExpectedCounters, NumMergedCounters)},
+ {counter_structure,
+ counters_equal(ExpectedCounter, MergedCounter)},
+ {siblings, equals(lists:sort(ExpectedSiblings), lists:sort(ActualSiblings))},
+ {index_meta, equals(ExpectedIndexMeta, sorted_index_meta(MergedMeta))}
])
))
end).
Please sign in to comment.
Something went wrong with that request. Please try again.