-
Notifications
You must be signed in to change notification settings - Fork 22
/
eetcd_lease_SUITE.erl
143 lines (115 loc) · 4.34 KB
/
eetcd_lease_SUITE.erl
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
-module(eetcd_lease_SUITE).
-include_lib("eunit/include/eunit.hrl").
-export([all/0, suite/0, groups/0, init_per_suite/1, end_per_suite/1, init_per_testcase/2, end_per_testcase/2]).
-export([lease_base/1, lease_timeout/1, lease_keepalive_once/1, lease_keepalive/1, put_with_lease/1]).
-define(Name, ?MODULE).
suite() ->
[{timetrap, {minutes, 2}}].
all() ->
[lease_base, lease_timeout, lease_keepalive_once, lease_keepalive, put_with_lease].
groups() ->
[].
init_per_suite(Config) ->
application:ensure_all_started(eetcd),
{ok, _Pid} = eetcd:open(?Name, ["127.0.0.1:2379", "127.0.0.1:2479", "127.0.0.1:2579"],
[{mode, random}, {transport, tcp}]),
Config.
init_per_testcase(_TestCase, Config) ->
revoke_all_leases(?Name),
Config.
end_per_testcase(_TestCase, Config) ->
revoke_all_leases(?Name),
Config.
end_per_suite(Config) ->
revoke_all_leases(?Name),
eetcd:close(?Name),
application:stop(eetcd),
Config.
lease_base(_Config) ->
TTL = 10,
{ok, #{'ID' := ID, 'TTL' := TTL}} = eetcd_lease:grant(?Name, TTL),
timer:sleep(200),
Leases1 = list_leases(?Name),
?assert(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases1)),
{ok, #{}} = eetcd_lease:revoke(?Name, ID),
Leases2 = list_leases(?Name),
?assertNot(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases2)),
ok.
lease_timeout(_Config) ->
TTL = 2,
{ok, #{'ID' := ID, 'TTL' := NewTTL}} = eetcd_lease:grant(?Name, TTL),
Leases1 = list_leases(?Name),
?assert(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases1)),
timer:sleep(NewTTL * 1000 + 1000),
Leases2 = list_leases(?Name),
?assertEqual([], Leases2),
{error, {grpc_error, #{'grpc-status' := 5}}} = eetcd_lease:revoke(?Name, ID),
ok.
lease_keepalive_once(_Config) ->
TTL = 2,
{ok, #{'ID' := ID, 'TTL' := NewTTL}} = eetcd_lease:grant(?Name, TTL),
Leases1 = list_leases(?Name),
[#{'ID' := ID} | _] = Leases1,
timer:sleep(900),
{ok, _Pid} = eetcd_lease:keep_alive_once(?Name, ID),
timer:sleep(NewTTL * 1000 - 300),
Leases2 = list_leases(?Name),
?assert(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases2)),
timer:sleep(2100),
{ok, #{leases := Leases3}} = eetcd_lease:leases(?Name),
?assertNot(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases3)),
{error, {grpc_error, #{'grpc-status' := 5}}} = eetcd_lease:revoke(?Name, ID),
ok.
lease_keepalive(_Config) ->
TTL = 3,
{ok, #{'ID' := ID, 'TTL' := TTL}}
= eetcd_lease:grant(?Name, TTL),
{ok, _Pid} = eetcd_lease:keep_alive(?Name, ID),
Leases1 = list_leases(?Name),
[#{'ID' := ID} | _] = Leases1,
timer:sleep(10000),
Leases2 = list_leases(?Name),
[#{'ID' := ID} | _ ] = Leases2,
eetcd_lease:revoke(?Name, ID),
Leases3 = list_leases(?Name),
?assertNot(lists:any(fun(#{'ID' := Val}) -> Val =:= ID end, Leases3)),
ok.
put_with_lease(_Config) ->
TTL = 3,
Key = <<"eetcd_key">>,
Value = <<"eetcd_value">>,
{ok, #{'ID' := ID, 'TTL' := TTL}}
= eetcd_lease:grant(?Name, TTL),
{ok, _Pid} = eetcd_lease:keep_alive(?Name, ID),
Req = eetcd_kv:with_lease(eetcd_kv:with_value(eetcd_kv:with_key(eetcd_kv:new(?Name), Key), Value), ID),
eetcd_kv:put(Req),
timer:sleep(TTL * 1000 * 2),
{ok, #{kvs := [#{key := Key, value := Value, lease := ID}]}}
= eetcd_kv:get(eetcd_kv:with_key(eetcd_kv:new(?Name), Key)),
Leases = list_leases(?Name),
[#{'ID' := ID} | _] = Leases,
eetcd_lease:revoke(?Name, ID),
{ok, #{kvs := [], more := false, count := 0}}
= eetcd_kv:get(eetcd_kv:with_key(eetcd_kv:new(?Name), Key)),
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
list_leases(?Name) ->
list_leases(?Name, 10).
%% Lists leases with retries up to N times
list_leases(?Name, 0) ->
[];
list_leases(?Name, RetriesLeft) ->
case eetcd_lease:leases(?Name) of
{ok, #{leases := []}} ->
timer:sleep(100),
list_leases(?Name, RetriesLeft - 1);
{ok, #{leases := Leases}} when is_list(Leases) ->
Leases
end.
revoke_all_leases(?Name) ->
{ok, #{leases := Leases}} = eetcd_lease:leases(?Name),
lists:foreach(fun(#{'ID' := ID}) ->
eetcd_lease:revoke(?Name, ID)
end, Leases).