@@ -99,6 +99,53 @@ t_join_after_node_down(_) ->
99
99
end ,
100
100
[]).
101
101
102
+ % % Start a cluster of two nodes, then join the third, and simulate two nodes went down
103
+ % % right after the third one joined. Restore them and verify the third one is healthy.
104
+ t_cluster_down_after_join (_ ) ->
105
+ ClusterEnv = mria_mnesia_test_util :common_env (),
106
+ Cluster = [C1 , C2 , C3 ] = mria_ct :cluster ([core , core , core ], ClusterEnv ),
107
+ ? check_trace (
108
+ #{timetrap => 10_000 },
109
+ try
110
+ % % Prepare cluster with 3 nodes:
111
+ Ns = [N1 , N2 , N3 ] = mria_ct :start_cluster (node , Cluster ),
112
+ ? assertEqual ([{ok , ok } || _ <- Ns ], erpc :multicall (Ns , mria , start , [])),
113
+ % % Join together first 2 nodes:
114
+ ? assertEqual (ok , erpc :call (N1 , mria , join , [N2 ])),
115
+ ? assertEqual ([N1 , N2 ], lists :sort (erpc :call (N1 , mria_mnesia , running_nodes , []))),
116
+ ? assertEqual (ok , erpc :call (N1 , mria_transaction_gen , init , [])),
117
+ % % Tell N3 to join but simulate it goes down after joining but before bootstrap:
118
+ ? assertEqual (ok , erpc :call (N3 , meck , new , [mria_app , [no_link , passthrough ]])),
119
+ ? assertEqual (ok , erpc :call (N3 , meck , expect , [mria_app , start , fun ? MODULE :suicide /2 ])),
120
+ % % Node N3 expectedly dies:
121
+ ? assertError ({erpc , _ }, erpc :call (N3 , mria , join , [N1 ])),
122
+ ? assertError ({erpc , _ }, erpc :call (N3 , mria_mnesia , running_nodes , [])),
123
+ % % Tell N1 and N2 to stop:
124
+ ? assertEqual (ok , erpc :call (N1 , mria , stop , [])),
125
+ ? assertEqual (ok , erpc :call (N2 , mria , stop , [])),
126
+ ? assertEqual ([ok , ok ], [slave :stop (N ) || N <- [N1 , N2 ]]),
127
+ % % Restart N3 and tell mria to start:
128
+ N3 = mria_ct :start_slave (node , C3 ),
129
+ % % This will hang waiting for N1 or N2 to go online, thus `cast/4`:
130
+ ? assertEqual (ok , erpc :cast (N3 , mria , start , [])),
131
+ % % Tell N1 and N2 to get back up:
132
+ [N1 , N2 ] = [mria_ct :start_slave (node , C ) || C <- [C1 , C2 ]],
133
+ % % Again, use `cast/4` to avoid hanging waiting for another node:
134
+ ? assertEqual (ok , erpc :cast (N1 , mria , start , [])),
135
+ ? assertEqual (ok , erpc :cast (N2 , mria , start , [])),
136
+ ? assertEqual (ok , erpc :call (N3 , mria , start , [])),
137
+ % % Verify that bootstrap process has finished and the node is alive:
138
+ _ = erpc :call (N3 , sys , get_state , [mria_schema ]),
139
+ ? assertEqual ([N1 , N2 , N3 ], lists :sort (erpc :call (N3 , mria_mnesia , running_nodes , []))),
140
+ ok
141
+ after
142
+ ok = mria_ct :teardown_cluster (Cluster )
143
+ end ,
144
+ []).
145
+
146
+ suicide (_Type , _Args ) ->
147
+ erlang :halt ().
148
+
102
149
t_diagnosis_tab (_ )->
103
150
TestTab = test_tab_1 ,
104
151
Cluster = [NS1 , NS2 ] = mria_ct :cluster ([core , core ], []),
0 commit comments