1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2006-2011. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: %%%------------------------------------------------------------------- 21: %%% File : z_SUITE.erl 22: %%% Author : Rickard Green <rickard.s.green@ericsson.com> 23: %%% Description : Misc tests that should be run last 24: %%% 25: %%% Created : 15 Jul 2005 by Rickard Green <rickard.s.green@ericsson.com> 26: %%%------------------------------------------------------------------- 27: -module(z_SUITE). 28: -author('rickard.s.green@ericsson.com'). 29: 30: %-define(line_trace, 1). 31: 32: -include_lib("test_server/include/test_server.hrl"). 33: 34: %-compile(export_all). 35: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 36: init_per_group/2,end_per_group/2, init_per_testcase/2, 37: end_per_testcase/2]). 38: 39: -export([schedulers_alive/1, node_container_refc_check/1, 40: long_timers/1, pollset_size/1, 41: check_io_debug/1]). 42: 43: -define(DEFAULT_TIMEOUT, ?t:minutes(5)). 44: 45: suite() -> [{ct_hooks,[ts_install_cth]}]. 46: 47: all() -> 48: [schedulers_alive, node_container_refc_check, 49: long_timers, pollset_size, check_io_debug]. 50: 51: groups() -> 52: []. 53: 54: init_per_suite(Config) -> 55: Config. 56: 57: end_per_suite(_Config) -> 58: ok. 59: 60: init_per_group(_GroupName, Config) -> 61: Config. 62: 63: end_per_group(_GroupName, Config) -> 64: Config. 65: 66: 67: init_per_testcase(_Case, Config) when is_list(Config) -> 68: Dog = ?t:timetrap(?DEFAULT_TIMEOUT), 69: [{watchdog, Dog}|Config]. 70: 71: end_per_testcase(_Case, Config) when is_list(Config) -> 72: Dog = ?config(watchdog, Config), 73: ?t:timetrap_cancel(Dog), 74: ok. 75: 76: %%% 77: %%% The test cases ------------------------------------------------------------- 78: %%% 79: 80: schedulers_alive(doc) -> ["Tests that all schedulers are actually used"]; 81: schedulers_alive(suite) -> []; 82: schedulers_alive(Config) when is_list(Config) -> 83: ?line Master = self(), 84: ?line NoSchedulersOnline = erlang:system_flag( 85: schedulers_online, 86: erlang:system_info(schedulers)), 87: ?line NoSchedulers = erlang:system_info(schedulers), 88: UsedScheds = 89: try 90: ?line ?t:format("Number of schedulers configured: ~p~n", [NoSchedulers]), 91: ?line case erlang:system_info(multi_scheduling) of 92: blocked -> 93: ?line ?t:fail(multi_scheduling_blocked); 94: disabled -> 95: ?line ok; 96: enabled -> 97: ?t:format("Testing blocking process exit~n"), 98: BF = fun () -> 99: blocked = erlang:system_flag(multi_scheduling, 100: block), 101: Master ! {self(), blocking}, 102: receive after infinity -> ok end 103: end, 104: ?line Blocker = spawn_link(BF), 105: ?line Mon = erlang:monitor(process, Blocker), 106: ?line receive {Blocker, blocking} -> ok end, 107: ?line [Blocker] 108: = erlang:system_info(multi_scheduling_blockers), 109: ?line unlink(Blocker), 110: ?line exit(Blocker, kill), 111: ?line receive {'DOWN', Mon, _, _, _} -> ok end, 112: ?line enabled = erlang:system_info(multi_scheduling), 113: ?line [] = erlang:system_info(multi_scheduling_blockers), 114: ?line ok 115: end, 116: ?t:format("Testing blocked~n"), 117: ?line erlang:system_flag(multi_scheduling, block), 118: ?line case erlang:system_info(multi_scheduling) of 119: enabled -> 120: ?line ?t:fail(multi_scheduling_enabled); 121: blocked -> 122: ?line [Master] = erlang:system_info(multi_scheduling_blockers); 123: disabled -> ?line ok 124: end, 125: ?line Ps = lists:map( 126: fun (_) -> 127: spawn_link(fun () -> 128: run_on_schedulers(none, 129: [], 130: Master) 131: end) 132: end, 133: lists:seq(1,NoSchedulers)), 134: ?line receive after 1000 -> ok end, 135: ?line {_, 1} = verify_all_schedulers_used({[],0}, 1), 136: ?line lists:foreach(fun (P) -> 137: unlink(P), 138: exit(P, bang) 139: end, 140: Ps), 141: ?line case erlang:system_flag(multi_scheduling, unblock) of 142: blocked -> ?line ?t:fail(multi_scheduling_blocked); 143: disabled -> ?line ok; 144: enabled -> ?line ok 145: end, 146: erts_debug:set_internal_state(available_internal_state, true), 147: %% node_and_dist_references will use emulator interal thread blocking... 148: erts_debug:get_internal_state(node_and_dist_references), 149: erts_debug:set_internal_state(available_internal_state, false), 150: ?t:format("Testing not blocked~n"), 151: ?line Ps2 = lists:map( 152: fun (_) -> 153: spawn_link(fun () -> 154: run_on_schedulers(none, 155: [], 156: Master) 157: end) 158: end, 159: lists:seq(1,NoSchedulers)), 160: ?line receive after 1000 -> ok end, 161: ?line {_, NoSIDs} = verify_all_schedulers_used({[],0},NoSchedulers), 162: ?line lists:foreach(fun (P) -> 163: unlink(P), 164: exit(P, bang) 165: end, 166: Ps2), 167: NoSIDs 168: after 169: NoSchedulers = erlang:system_flag(schedulers_online, 170: NoSchedulersOnline), 171: NoSchedulersOnline = erlang:system_info(schedulers_online) 172: end, 173: ?line {comment, "Number of schedulers " ++ integer_to_list(UsedScheds)}. 174: 175: 176: run_on_schedulers(LastSID, SIDs, ReportTo) -> 177: case erlang:system_info(scheduler_id) of 178: LastSID -> 179: erlang:yield(), 180: run_on_schedulers(LastSID, SIDs, ReportTo); 181: SID -> 182: NewSIDs = case lists:member(SID, SIDs) of 183: true -> 184: SIDs; 185: false -> 186: ReportTo ! {scheduler_used, SID}, 187: [SID | SIDs] 188: end, 189: erlang:yield(), 190: run_on_schedulers(SID, NewSIDs, ReportTo) 191: end. 192: 193: wait_on_used_scheduler({SIDs, SIDsLen} = State) -> 194: receive 195: {scheduler_used, SID} -> 196: case lists:member(SID, SIDs) of 197: true -> 198: wait_on_used_scheduler(State); 199: false -> 200: ?t:format("Scheduler ~p used~n", [SID]), 201: {[SID|SIDs], SIDsLen+1} 202: end 203: end. 204: 205: verify_all_schedulers_used({UsedSIDs, UsedSIDsLen} = State, NoSchedulers) -> 206: ?line case NoSchedulers of 207: UsedSIDsLen -> 208: ?line State; 209: NoSchdlrs when NoSchdlrs < UsedSIDsLen -> 210: ?line ?t:fail({more_schedulers_used_than_exist, 211: {existing_schedulers, NoSchdlrs}, 212: {used_schedulers, UsedSIDsLen}, 213: {used_scheduler_ids, UsedSIDs}}); 214: _ -> 215: ?line NewState = wait_on_used_scheduler(State), 216: ?line verify_all_schedulers_used(NewState, NoSchedulers) 217: end. 218: 219: node_container_refc_check(doc) -> []; 220: node_container_refc_check(suite) -> []; 221: node_container_refc_check(Config) when is_list(Config) -> 222: ?line node_container_SUITE:node_container_refc_check(node()), 223: ?line ok. 224: 225: long_timers(doc) -> 226: []; 227: long_timers(suite) -> 228: []; 229: long_timers(Config) when is_list(Config) -> 230: ?line ok = long_timers_test:check_result(). 231: 232: pollset_size(doc) -> 233: []; 234: pollset_size(suite) -> 235: []; 236: pollset_size(Config) when is_list(Config) -> 237: ?line Name = pollset_size_testcase_initial_state_holder, 238: ?line Mon = erlang:monitor(process, Name), 239: ?line (catch Name ! {get_initial_check_io_result, self()}), 240: ?line InitChkIo = receive 241: {initial_check_io_result, ICIO} -> 242: ?line erlang:demonitor(Mon, [flush]), 243: ?line ICIO; 244: {'DOWN', Mon, _, _, Reason} -> 245: ?line ?t:fail({non_existing, Name, Reason}) 246: end, 247: ?line FinChkIo = get_check_io_info(), 248: ?line io:format("Initial: ~p~nFinal: ~p~n", [InitChkIo, FinChkIo]), 249: ?line InitPollsetSize = lists:keysearch(total_poll_set_size, 1, InitChkIo), 250: ?line FinPollsetSize = lists:keysearch(total_poll_set_size, 1, FinChkIo), 251: ?line case InitPollsetSize =:= FinPollsetSize of 252: true -> 253: case InitPollsetSize of 254: {value, {total_poll_set_size, Size}} -> 255: ?line {comment, 256: "Pollset size: " ++ integer_to_list(Size)}; 257: _ -> 258: ?line {skipped, 259: "Pollset size information not available"} 260: end; 261: false -> 262: %% Somtimes we have fewer descriptors in the 263: %% pollset at the end than when we started, but 264: %% that is ok as long as there are at least 2 265: %% descriptors (dist listen socket and 266: %% epmd socket) in the pollset. 267: ?line {value, {total_poll_set_size, InitSize}} 268: = InitPollsetSize, 269: ?line {value, {total_poll_set_size, FinSize}} 270: = FinPollsetSize, 271: ?line true = FinSize < InitSize, 272: ?line true = 2 =< FinSize, 273: ?line {comment, 274: "Start pollset size: " 275: ++ integer_to_list(InitSize) 276: ++ " End pollset size: " 277: ++ integer_to_list(FinSize)} 278: end. 279: 280: check_io_debug(doc) -> 281: []; 282: check_io_debug(suite) -> 283: []; 284: check_io_debug(Config) when is_list(Config) -> 285: ?line case lists:keysearch(name, 1, erlang:system_info(check_io)) of 286: {value, {name, erts_poll}} -> ?line check_io_debug_test(); 287: _ -> ?line {skipped, "Not implemented in this emulator"} 288: end. 289: 290: check_io_debug_test() -> 291: ?line erts_debug:set_internal_state(available_internal_state, true), 292: ?line erlang:display(erlang:system_info(check_io)), 293: ?line NoOfErrorFds = erts_debug:get_internal_state(check_io_debug), 294: ?line erts_debug:set_internal_state(available_internal_state, false), 295: ?line 0 = NoOfErrorFds, 296: ?line ok. 297: 298: 299: 300: %% 301: %% Internal functions... 302: %% 303: 304: display_check_io(ChkIo) -> 305: catch erlang:display('--- CHECK IO INFO ---'), 306: catch erlang:display(ChkIo), 307: catch erts_debug:set_internal_state(available_internal_state, true), 308: NoOfErrorFds = (catch erts_debug:get_internal_state(check_io_debug)), 309: catch erlang:display({'NoOfErrorFds', NoOfErrorFds}), 310: catch erts_debug:set_internal_state(available_internal_state, false), 311: catch erlang:display('--- CHECK IO INFO ---'), 312: ok. 313: 314: get_check_io_info() -> 315: ChkIo = erlang:system_info(check_io), 316: case lists:keysearch(pending_updates, 1, ChkIo) of 317: {value, {pending_updates, 0}} -> 318: display_check_io(ChkIo), 319: ChkIo; 320: false -> 321: ChkIo; 322: _ -> 323: receive after 10 -> ok end, 324: get_check_io_info() 325: end. 326: 327: 328: