Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

WIP Update eqc test and resultant changes to the counter code

  • Loading branch information...
commit 6f135a7c56467e1eefd0efe4910e2dc4701118b4 1 parent acc7514
@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.