blob: 1c3f8ebc2299d8820a3fd6db05fbcc9d356f1ac4 [file] [log] [blame]
% 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.
%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-module(couch_raft_SUITE).
-behaviour(ct_suite).
-export([all/0]).
-export([three_nodes/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
all() ->
[three_nodes].
three_nodes(Config) when is_list(Config) ->
N = 3,
Args = ["-pa", filename:dirname(code:which(craft))],
Peers = [?CT_PEER(#{wait_boot => {self(), tag}, args => Args}) || _ <- lists:seq(1, N)],
Cohort = [receive {tag, {started, Node, Peer}} -> Node end || {ok, Peer} <- Peers],
Crafts = [erpc:call(Node, craft3, start, [foo, Cohort]) || Node <- Cohort],
% wait for leader election
timer:sleep(500),
% verify only one leader elected
[{leader, FirstLeader}] = lists:filter(fun({State, _Pid}) -> State == leader end,
[{element(1, sys:get_state(Pid)), Pid} || {ok, Pid} <- Crafts]),
% make a series of calls
Hash1 = crypto:hash(sha256, <<0, 1>>),
?assertEqual(Hash1, craft3:call(FirstLeader, <<1>>)),
Hash2 = crypto:hash(sha256, <<Hash1/binary, 2>>),
?assertEqual(Hash2, craft3:call(FirstLeader, <<2>>)),
Hash3 = crypto:hash(sha256, <<Hash2/binary, 3>>),
?assertEqual(Hash3, craft3:call(FirstLeader, <<3>>)),
% force a re-election
craft3:stop(FirstLeader),
timer:sleep(500),
% verify new leader elected
[{leader, SecondLeader}] = lists:filter(fun({State, _Pid}) -> State == leader end,
[{element(1, sys:get_state(Pid)), Pid} || {ok, Pid} <- Crafts, Pid /= FirstLeader]),
?assertNotEqual(FirstLeader, SecondLeader),
% make another call
Hash4 = crypto:hash(sha256, <<Hash3/binary, 4>>),
?assertEqual(Hash4, craft3:call(SecondLeader, <<4>>)),
[craft3:stop(Pid) || {ok, Pid} <- Crafts, Pid /= FirstLeader],
[peer:stop(Peer) || {ok, Peer} <- Peers].