1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2008-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%%%------------------------------------------------------------------- 22%%% File : conn_SUITE 23%%% Description : Check that the generic connection handling in CT 24%%% works as expected. 25%%%------------------------------------------------------------------- 26-module(conn_SUITE). 27 28%% Note: This directive should only be used in test suites. 29-compile(export_all). 30 31-include_lib("common_test/include/ct.hrl"). 32 33%%-------------------------------------------------------------------- 34%% COMMON TEST CALLBACK FUNCTIONS 35%%-------------------------------------------------------------------- 36 37suite() -> 38 [{timetrap,{seconds,5}}]. 39 40init_per_suite(Config) -> 41 Config. 42 43end_per_suite(_Config) -> 44 ok. 45 46init_per_testcase(_TestCase, Config) -> 47 Config. 48 49end_per_testcase(_TestCase, _Config) -> 50 ok. 51 52all() -> 53 [handles_to_multi_conn_pids, handles_to_single_conn_pids, 54 names_to_multi_conn_pids, names_to_single_conn_pids]. 55 56%%-------------------------------------------------------------------- 57%% TEST CASES 58%%-------------------------------------------------------------------- 59 60handles_to_multi_conn_pids() -> 61 [{require,multi_conn_pid}]. 62 63handles_to_multi_conn_pids(_Config) -> 64 application:set_env(ct_test, reconnect, true), 65 66 Handle1 = proto:open(multi_conn_pid), 67 ConnPid1 = ct_gen_conn:get_conn_pid(Handle1), 68 {true,true} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, 69 Handle2 = proto:open(multi_conn_pid), 70 ConnPid2 = ct_gen_conn:get_conn_pid(Handle2), 71 {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, 72 Handle3 = proto:open(multi_conn_pid), 73 ConnPid3 = ct_gen_conn:get_conn_pid(Handle3), 74 {true,true} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, 75 76 monitor_procs([Handle1,ConnPid1,Handle2,ConnPid2,Handle3,ConnPid3]), 77 78 ok = proto:close(Handle1), 79 ok = wait_procs_down([Handle1,ConnPid1]), 80 {false,false} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, 81 {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, 82 83 ok = proto:kill_conn_proc(Handle2), 84 ok = wait_procs_down([ConnPid2]), 85 {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, 86 ConnPid2x = ct_gen_conn:get_conn_pid(Handle2), 87 true = is_process_alive(ConnPid2x), 88 89 monitor_procs([ConnPid2x]), 90 91 ok = proto:close(Handle2), 92 ok = wait_procs_down([Handle2,ConnPid2x]), 93 {false,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2x)}, 94 95 application:set_env(ct_test, reconnect, false), 96 ok = proto:kill_conn_proc(Handle3), 97 ok = wait_procs_down([Handle3,ConnPid3]), 98 {false,false} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, 99 100 ok. 101 102handles_to_single_conn_pids() -> 103 [{require,single_conn_pid}]. 104 105handles_to_single_conn_pids(_Config) -> 106 application:set_env(ct_test, reconnect, true), 107 108 Handle1 = proto:open(single_conn_pid), 109 ConnPid = ct_gen_conn:get_conn_pid(Handle1), 110 {true,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, 111 Handle2 = proto:open(single_conn_pid), 112 ConnPid = ct_gen_conn:get_conn_pid(Handle2), 113 {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid)}, 114 Handle3 = proto:open(single_conn_pid), 115 ConnPid = ct_gen_conn:get_conn_pid(Handle3), 116 {true,true} = {is_process_alive(Handle3),is_process_alive(ConnPid)}, 117 118 Conns = [{undefined,Handle1,_,_}, 119 {undefined,Handle2,_,_}, 120 {undefined,Handle3,_,_}] = lists:sort(ct_util:get_connections(ConnPid)), 121 ct:pal("CONNS = ~n~p", [Conns]), 122 123 monitor_procs([Handle1,Handle2,Handle3,ConnPid]), 124 ok = proto:close(Handle1), 125 ok = wait_procs_down([Handle1]), 126 {false,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, 127 128 ok = proto:kill_conn_proc(Handle2), 129 ok = wait_procs_down([ConnPid]), 130 NewConnPid = ct_gen_conn:get_conn_pid(Handle2), 131 NewConnPid = ct_gen_conn:get_conn_pid(Handle3), 132 true = is_process_alive(Handle2), 133 true = is_process_alive(Handle3), 134 false = is_process_alive(ConnPid), 135 136 monitor_procs([NewConnPid]), 137 138 ok = proto:close(Handle2), 139 ok = wait_procs_down([Handle2]), 140 {false,true} = {is_process_alive(Handle2),is_process_alive(NewConnPid)}, 141 142 application:set_env(ct_test, reconnect, false), 143 ok = proto:kill_conn_proc(Handle3), 144 ok = wait_procs_down([Handle3,NewConnPid]), 145 {false,false} = {is_process_alive(Handle3),is_process_alive(NewConnPid)}, 146 147 ok. 148 149names_to_multi_conn_pids() -> 150 [{require,mconn1,multi_conn_pid}, 151 {require,mconn2,multi_conn_pid}, 152 {require,mconn3,multi_conn_pid}]. 153 154names_to_multi_conn_pids(_Config) -> 155 application:set_env(ct_test, reconnect, true), 156 157 Handle1 = proto:open(mconn1), 158 ConnPid1 = ct_gen_conn:get_conn_pid(Handle1), 159 {true,true} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, 160 Handle2 = proto:open(mconn2), 161 ConnPid2 = ct_gen_conn:get_conn_pid(Handle2), 162 {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, 163 Handle3 = proto:open(mconn3), 164 ConnPid3 = ct_gen_conn:get_conn_pid(Handle3), 165 {true,true} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, 166 167 Handle1 = proto:open(mconn1), 168 169 monitor_procs([Handle1,ConnPid1,Handle2,ConnPid2,Handle3,ConnPid3]), 170 171 ok = proto:close(mconn1), 172 ok = wait_procs_down([Handle1,ConnPid1]), 173 {false,false} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, 174 175 ok = proto:kill_conn_proc(Handle2), 176 ok = wait_procs_down([ConnPid2]), 177 Handle2 = proto:open(mconn2), % should've been reconnected already 178 {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, 179 ConnPid2x = ct_gen_conn:get_conn_pid(Handle2), 180 true = is_process_alive(ConnPid2x), 181 182 monitor_procs([ConnPid2x]), 183 184 ok = proto:close(mconn2), 185 ok = wait_procs_down([Handle2,ConnPid2x]), 186 {false,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2x)}, 187 Handle2y = proto:open(mconn2), 188 ConnPid2y = ct_gen_conn:get_conn_pid(Handle2y), 189 {true,true} = {is_process_alive(Handle2y),is_process_alive(ConnPid2y)}, 190 191 monitor_procs([Handle2y,ConnPid2y]), 192 193 ok = proto:close(mconn2), 194 ok = wait_procs_down([Handle2y,ConnPid2y]), 195 {false,false} = {is_process_alive(Handle2y),is_process_alive(ConnPid2y)}, 196 197 application:set_env(ct_test, reconnect, false), 198 ok = proto:kill_conn_proc(Handle3), 199 ok = wait_procs_down([Handle3,ConnPid3]), 200 {false,false} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, 201 202 ok. 203 204names_to_single_conn_pids() -> 205 [{require,sconn1,single_conn_pid}, 206 {require,sconn2,single_conn_pid}, 207 {require,sconn3,single_conn_pid}]. 208 209names_to_single_conn_pids(_Config) -> 210 application:set_env(ct_test, reconnect, true), 211 212 Handle1 = proto:open(sconn1), 213 ConnPid = ct_gen_conn:get_conn_pid(Handle1), 214 {true,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, 215 Handle2 = proto:open(sconn2), 216 ConnPid = ct_gen_conn:get_conn_pid(Handle2), 217 {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid)}, 218 Handle3 = proto:open(sconn3), 219 ConnPid = ct_gen_conn:get_conn_pid(Handle3), 220 {true,true} = {is_process_alive(Handle3),is_process_alive(ConnPid)}, 221 222 Handle1 = proto:open(sconn1), 223 224 Conns = [{sconn1,Handle1,_,_}, 225 {sconn2,Handle2,_,_}, 226 {sconn3,Handle3,_,_}] = lists:sort(ct_util:get_connections(ConnPid)), 227 ct:pal("CONNS on ~p = ~n~p", [ConnPid,Conns]), 228 229 monitor_procs([Handle1,Handle2,Handle3,ConnPid]), 230 231 ok = proto:close(sconn1), 232 ok = wait_procs_down([Handle1]), 233 {false,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, 234 235 ok = proto:kill_conn_proc(Handle2), 236 ok = wait_procs_down([ConnPid]), 237 {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid)}, 238 Handle2 = proto:open(sconn2), % should've been reconnected already 239 NewConnPid = ct_gen_conn:get_conn_pid(Handle2), 240 true = is_process_alive(NewConnPid), 241 242 monitor_procs([NewConnPid]), 243 244 Conns1 = [{sconn2,Handle2,_,_}, 245 {sconn3,Handle3,_,_}] = 246 lists:sort(ct_util:get_connections(NewConnPid)), 247 ct:pal("CONNS on ~p = ~n~p", [NewConnPid,Conns1]), 248 249 ok = proto:close(sconn2), 250 ok = wait_procs_down([Handle2]), 251 {false,true} = {is_process_alive(Handle2),is_process_alive(NewConnPid)}, 252 253 application:set_env(ct_test, reconnect, false), 254 ok = proto:kill_conn_proc(Handle3), 255 ok = wait_procs_down([Handle3,NewConnPid]), 256 {false,false} = {is_process_alive(Handle3),is_process_alive(NewConnPid)}, 257 258 ok. 259 260 261%%%----------------------------------------------------------------- 262monitor_procs(Pids) -> 263 [erlang:monitor(process,Pid) || Pid <- Pids], 264 ok. 265 266wait_procs_down([]) -> 267 ok; 268wait_procs_down(Pids) -> 269 receive 270 {'DOWN',_,process,Pid,_} -> 271 wait_procs_down(lists:delete(Pid,Pids)) 272 after 2000 -> 273 timeout 274 end. 275 276