summaryrefslogtreecommitdiff
path: root/src/mem3/test/eunit/mem3_cluster_test.erl
blob: d1a0fcd380f3cde242390c173db4132520baa7aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
% 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.

-module(mem3_cluster_test).

-behavior(mem3_cluster).

-include_lib("eunit/include/eunit.hrl").

-export([
    cluster_unstable/1,
    cluster_stable/1
]).

% Mem3 cluster callbacks

cluster_unstable(Server) ->
    Server ! cluster_unstable,
    Server.

cluster_stable(Server) ->
    Server ! cluster_stable,
    Server.

mem3_cluster_test_test_() ->
    {
        foreach,
        fun setup/0,
        fun teardown/1,
        [
            t_cluster_stable_during_startup_period(),
            t_cluster_unstable_delivered_on_nodeup(),
            t_cluster_unstable_delivered_on_nodedown(),
            t_wait_period_is_reset_after_last_change()
        ]
    }.

t_cluster_stable_during_startup_period() ->
    ?_test(begin
        {ok, Pid} = mem3_cluster:start_link(?MODULE, self(), 1, 2),
        register(?MODULE, Pid),
        receive
            cluster_stable ->
                ?assert(true)
        after 1500 ->
            throw(timeout)
        end,
        unlink(Pid),
        exit(Pid, kill)
    end).

t_cluster_unstable_delivered_on_nodeup() ->
    ?_test(begin
        {ok, Pid} = mem3_cluster:start_link(?MODULE, self(), 1, 2),
        register(?MODULE, Pid),
        Pid ! {nodeup, node()},
        receive
            cluster_unstable ->
                ?assert(true)
        after 1000 ->
            throw(timeout)
        end,
        unlink(Pid),
        exit(Pid, kill)
    end).

t_cluster_unstable_delivered_on_nodedown() ->
    ?_test(begin
        {ok, Pid} = mem3_cluster:start_link(?MODULE, self(), 1, 2),
        register(?MODULE, Pid),
        Pid ! {nodedown, node()},
        receive
            cluster_unstable ->
                ?assert(true)
        after 1000 ->
            throw(timeout)
        end,
        unlink(Pid),
        exit(Pid, kill)
    end).

t_wait_period_is_reset_after_last_change() ->
    ?_test(begin
        {ok, Pid} = mem3_cluster:start_link(?MODULE, self(), 1, 1),
        register(?MODULE, Pid),
        timer:sleep(800),
        % after 800 sec send a nodeup
        Pid ! {nodeup, node()},
        receive
            cluster_stable ->
                ?assert(false)
        after 400 ->
            % stability check should have been reset
            ?assert(true)
        end,
        timer:sleep(1000),
        receive
            cluster_stable ->
                ?assert(true)
        after 0 ->
            % cluster_stable arrives after enough quiet time
            ?assert(false)
        end,
        unlink(Pid),
        exit(Pid, kill)
    end).

% Test helper functions

setup() ->
    ok.

teardown(_) ->
    case whereis(?MODULE) of
        undefined ->
            ok;
        Pid when is_pid(Pid) ->
            unlink(Pid),
            exit(Pid, kill)
    end.