fork(1) download
  1. %% #0. BASIC INFORMATION
  2. %% ----------------------------------------------------------------------
  3. %% %CCaseFile: sbgStSupport.erl
  4. %% Author: etxkols
  5. %% Description: IS hardware functions.
  6. %%
  7. %% ----------------------------------------------------------------------
  8.  
  9. %% @doc This the the API interface for module <code>sbgStSupport</code>.
  10. %%
  11. %% <font size="4">Follow this guide, feature team can run eNST easily.
  12. %% <ol>
  13. %% <li>prepare your sipp scenario file, and call <code>sbgEstSupport:prepare_sipp_cmd/3</code> to generate sipp commands.<br></br>
  14. %% <strong>Note:</strong> Some import parameters have default value, and there are configurable.</li>
  15. %% <li>call <code>sbgEstSupport:prepare_systeminfo_filenames/1</code> to prepare the log files according which blades you want to monitor.</li>
  16. %% <li>call <code>sbgEstSupport:start_collect_system_infos/1</code> to start collecting logs.</li>
  17. %% <li>call <code>sbgEstSupport:run_scenario</code> to run your sipp traffic.<br></br>
  18. %% <strong>Note:</strong> the traffic run time is configurable and you also can configure monitoring the SIPp running status.</li>
  19. %% <li>call <code>sbgEstSupport:generate_log_statistics/4</code> to analyze the log files and draw the picture.</li>
  20. %% </ol>
  21. %% You can refter the demo case in suite <code>sbg_eST_template.erl</code>, here is the <a href="https://a...content-available-to-author-only...n.se/jpT/elqstux/15-11-02/ct_run.ct_5@sekilxc0007.2015-11-02_12.04.49/auto.suite.sbg_eST_template.sbg_est_001.logs/run.2015-11-02_12.04.54/suite.log.html">log</a>
  22. %% </font>
  23. -module(sbgEstSupport).
  24. -date('2015-11-02').
  25. -author('elqstux').
  26. -vsn('/main/R20A/R21A/R22A/R99A/2, checkout by elqstux in elqstux_ki_ppb').
  27.  
  28. %% ----------------------------------------------------------------------
  29. %% %CCaseCopyrightBegin%
  30. %% Copyright (c) Ericsson AB 2009-2013 All rights reserved.
  31. %%
  32. %% The program may be used and/or copied only with the written
  33. %% permission from Ericsson Telecom AB, or in accordance with
  34. %% the terms and conditions stipulated in the agreement/contract
  35. %% under which the program has been supplied.
  36. %%
  37. %% All rights reserved
  38. %%
  39. %% ----------------------------------------------------------------------
  40. %%
  41. %% #1. EXPORT LISTS
  42. %% ----------------------------------------------------------------------
  43. %% #1.1 EXPORTED INTERFACE FUNCTIONS
  44. %% ----------------------------------------------------------------------
  45.  
  46. %% ----------------------------------------------------------------------
  47. %% #2. REVISION LOG
  48. %% ----------------------------------------------------------------------
  49. %% Rev Date Name What
  50. %% ----------------------------------------------------------------------
  51. %% R21A/1 130731 elilige Created
  52. %% R21A/2 131016 elilige Add draw_graph
  53. %% ----------------------------------------------------------------------
  54. %% ----------------------------------------------------------
  55. %% #2. EXPORT LISTS
  56. %% ----------------------------------------------------------
  57. %% #2.1 EXPORTED INTERFACE FUNCTIONS
  58. %% ----------------------------------------------------------
  59. -export([prepare_sipp_cmd/3,
  60. prepare_systeminfo_filenames/1,
  61. start_collect_system_infos/1,
  62. stop_collect_system_infos/1,
  63. generate_log_statistics/4,
  64. run_scenario/6]).
  65.  
  66. -define(DEBUG(Format, Args), ct:pal(Format, Args)).
  67.  
  68. -define(INFO_MSG(Format, Args), ct:pal(Format, Args)).
  69.  
  70. -define(WARNING_MSG(Format, Args), ct:pal(Format, Args)).
  71.  
  72. -define(ERROR_MSG(Format, Args), ct:pal(Format, Args)).
  73.  
  74. -define(CRITICAL_MSG(Format, Args), ct:pal(Format, Args)).
  75.  
  76. -define(STAT_FAIL, 10).
  77. -define(CALL_LOSS_RATE, 0.0005).
  78.  
  79. -define(SIPP_PARAS, [
  80. {service, [" -s ", ""]},
  81. {scenarioFile, [" -sf ", ""]},
  82. {infFile, [" -inf ", ""]},
  83. {localIp, [" -i ", ""]},
  84. {localPort, [" -p ", ""]},
  85. {mediaIp, [" -mi ", ""]},
  86. {mediaPort, [" -mp ", ""]},
  87. {autoAnswer, [" -aa"]},
  88. {background, [" -bg"]},
  89. {callRate, [" -r ", ""]},
  90. {maxCalls, [" -m ", ""]},
  91. {callLength, [" -d ", ""]},
  92. {parallelCalls, [" -l ", ""]},
  93. {statFile, [" -stf ", ""]},
  94. {errorFile, [" -error_file ", ""]},
  95. {statFrequence, [" -fd ", ""]},
  96. {openStat, [" -trace_stat"]},
  97. {traceScreen, [" -trace_screen"]},
  98. {traceErr, [" -trace_err"]},
  99. {transport, [" -t ", ""]}
  100. ]).
  101. -define(SIPP_MANDATORY_PARAMETERS, [scenarioFile, localIp, localPort, mediaIp, statFile]).
  102. -define(SIPP_DEFAULT_PARAMETERS, [autoAnswer, background, openStat, traceScreen, traceErr]).
  103. -define(SIPP_OPTIONAL_PARAMETERS, [service, callRate, infFile, mediaPort, maxCalls, callLength,
  104. parallelCalls, statFrequence, transport, errorFile]).
  105.  
  106. -define(SIPP_BIN, "/vobs/mgwblade/PPB/SBG_HSD10196_1/test/auto/suite/test/est_script/sipp").
  107. -define(XML_DIR, "/vobs/mgwblade/PPB/SBG_HSD10196_1/test/auto/suite/test/sipp_xml/").
  108. -define(EST_LOG_DIR, "/home/"++os:getenv("USER")++"/est_log_tmp/").
  109. -define(EST_DATA_BIN, "/vobs/mgwblade/PPB/SBG_HSD10196_1/test/auto/suite/test/est_script/data_analysis/").
  110.  
  111. %%-define(SGCchNode,jpTstates:find_role(jpTnames:ty2na(sgc),ch)).
  112. -define(SGCchNode,jpTstates:find_role(sbgFtSupport:get_bs_name(sgc,1),ch)).
  113. -define(CH(M,F,A), jpTrpc:call(?SGCchNode, M, F, A)).
  114.  
  115. -define(SGComNode,jpTstates:find_role(sbgFtSupport:get_bs_name(sgc,1),om)).
  116. -define(OM(M,F,A), jpTrpc:call(?SGComNode, M, F, A)).
  117.  
  118. -define(SBGchNode,jpTstates:find_role(sbgFtSupport:get_bs_name(ommp,1),ch)).
  119. -define(SBGCH(M,F,A), jpTrpc:call(?SBGchNode, M, F, A)).
  120.  
  121. -define(SBGomNode,jpTstates:find_role(sbgFtSupport:get_bs_name(ommp,1),om)).
  122. -define(SBGOM(M,F,A), jpTrpc:call(?SBGomNode, M, F, A)).
  123.  
  124. -define(REG_MATCH, {regKey, '_', '_', '_', '_', '_', '_', '_', '_'}).
  125. -define(REG_MATCH2, {regKey, '_', '_', '_'}).
  126. -define(DC_MATCH(APP), {APP, list_to_atom(atom_to_list(APP)++"DcMain"),'_'}).
  127.  
  128. -define(DEFAULT_MONITOR_INTERVAL, {0, 5, 0}).
  129.  
  130.  
  131. %% @spec prepare_sipp_cmd(SIPp_Config, Role, IpVsn) -> Res :: tuple()
  132. %% @doc Shows <a href="http://s...content-available-to-author-only...e.net/">SIPp</a> online help documentation of what config parameters there are.<br></br>
  133. %% Prepare sipp cmd for starting sipp process, default value is used if cannot get from user input.<br></br>
  134. %% <pre>
  135. %% <strong>Node:</strong>
  136. %% SIPp_Config proplists()
  137. %% Role access | core4access
  138. %% IpVsm ipv4 | ipv6
  139. %% Res tuple, just like {ok, {UacScenarioFile, UacStatFile, UacSippCmd}=UacParam}
  140. %% </pre>
  141. %% <dl>
  142. %% <dt>======================================================================== </dt>
  143. %% <dt> The key for parameter(SIPp_Config) </dt>
  144. %% <dt>======================================================================== </dt>
  145. %% <dt><pre><strong>Parameter</strong> <strong>Description</strong> </pre></dt>
  146. %% <dt><pre>localIp IP address of source, mandatory but has default value</pre></dt>
  147. %% <dt><pre>mediaIp Media address of source, mandatory but has default value</pre></dt>
  148. %% <dt><pre>localPort Source port, mandatory but has default value</pre></dt>
  149. %% <dt><pre>remoteIp IP address of destination, mandatory but has default value</pre></dt>
  150. %% <dt><pre>remotePort Destination port, mandatory but has default value</pre></dt>
  151. %% <dt><pre>scenarioFile Path of scenario file, mandatory</pre></dt>
  152. %% <dt><pre>statFile Path of statistics file, mandatory but has default value</pre></dt>
  153. %% <dt><pre>infFile Path of inject parameter file, optional</pre></dt>
  154. %% <dt><pre>callrate Number of calls/s, optional</pre></dt>
  155. %% <dt><pre>maxcalls Maximum number of calls setup, optional</pre></dt>
  156. %% <dt><pre>calllength Length in seconds of calls, optional</pre></dt>
  157. %% <dt><pre>parallelCalls Total number of calls in parallel, optional</pre></dt>
  158. %% <dt><pre>statFrequence The statistics dump log report frequency, optional</pre></dt>
  159. %% <dt><pre>transport The transport mode, optional</pre></dt>
  160. %% <dt>======================================================================== </dt>
  161. %% </dl>
  162. %% === Example usage ===
  163. %% ```jpTsipp:prepare_sipp_cmd([{localIp, "10.10.121.7"},
  164. %% {mediaIp, "10.10.121.7"},
  165. %% {localPort, "8004"},
  166. %% {remoteIp, "10.21.0.4"},
  167. %% {remotePort, "10004"},
  168. %% {scenarioFile, "./sipp/st/uac_register.xml"},
  169. %% {infFile, "./sipp/st/database.csv"},
  170. %% {statFile, "./sipp/st/sipp_regtister_uac.csv"},
  171. %% {callRate, "5"}], access, ipv4).'''
  172.  
  173. prepare_sipp_cmd(SIPp_Config, Role, IpVsn) ->
  174.  
  175. SippParameters = prepare_sipp_param(SIPp_Config, Role, IpVsn),
  176.  
  177. RemoteAddr = proplists:get_value(remoteIp, SippParameters),
  178. RemotePort = proplists:get_value(remotePort, SippParameters),
  179. RemoteUri = build_remote_uri(RemoteAddr, RemotePort),
  180. StatFile = proplists:get_value(statFile, SippParameters),
  181. ScenarioFile = proplists:get_value(scenarioFile, SippParameters),
  182.  
  183. MandatoryBool= check_sipp_param(SippParameters,
  184. ?SIPP_MANDATORY_PARAMETERS, mandatory),
  185. OptionalBool = check_sipp_param(SippParameters,
  186. ?SIPP_OPTIONAL_PARAMETERS, optional),
  187.  
  188. if
  189. (MandatoryBool =:= true) and (OptionalBool =:= true) ->
  190. NewSippParameters = set_default_sipp_param(SippParameters,
  191. ?SIPP_DEFAULT_PARAMETERS),
  192. SippParaString = build_sipp_parameters_string(NewSippParameters,
  193. ""),
  194. if
  195. RemoteUri =:= "" ->
  196. ?ERROR_MSG("Error:~nRemote Address Information is invalid: ~p, ~p~n",
  197. [RemoteAddr, RemotePort]),
  198. {error, RemoteAddr};
  199. true ->
  200. SippCmd = ?SIPP_BIN ++ " " ++ RemoteUri ++ " " ++ SippParaString,
  201. ?DEBUG("Generate Sipp command:~n~p~nGet StatFile:~n~p~n",
  202. [SippCmd, StatFile]),
  203. {ok, {ScenarioFile, StatFile, SippCmd}}
  204. end;
  205. true ->
  206. ?WARNING_MSG("Warning:~nThe mandatory parameters check result: ~p~n the optional check result: ~p.~n",
  207. [MandatoryBool, OptionalBool]),
  208. {error, {MandatoryBool, OptionalBool}}
  209. end.
  210.  
  211. %% -----------------------------------------------------------------------
  212. %% prepare_sipp_param(SIPp_Config, Role, IpVsn)
  213. %% @spec prepare_sipp_param(SIPp_Config::list(), Role::atom(), IpVsn::atom()) -> ResList::list()
  214. %% @doc Update sipp parameters, combine path with file
  215. %% SIPp_Config::list() is a list of parameters to sipp. More info about parameters
  216. %% in jpTsipp:prepare_sipp_cmd/1
  217. %% <pre>
  218. %% <b>Input:</b>
  219. %% SIPp_Config List Argument list of tuples in form {TypeTag,Param}
  220. %% Role Atom access|core4access|foreign|core4foreign
  221. %% IpVsn Atom ipv4|ipv6
  222. %%
  223. %% <b>Output:</b>
  224. %% ResList List Argument list of tuples
  225. %%
  226. %% <i>Example:</i>
  227. %% jpTsipp:prepare_sipp_param([{localIp, "10.10.121.7"},
  228. %% {mediaIp, "10.10.121.7"},
  229. %% {localPort, "8004"},
  230. %% {remoteIp, "10.21.0.4"},
  231. %% {remotePort, "10004"}
  232. %% {scenarioFile, "./sipp/st/uac_register.xml"},
  233. %% {infFile, "./sipp/st/database.csv"},
  234. %% {statFile, "./sipp/st/sipp_regtister_uac.csv"},
  235. %% {errorFile, "./sipp/st/sipp-error.log"},
  236. %% {callRate, "5"}], access, ipv4).
  237. %% </pre>
  238. %% @end
  239. %% -----------------------------------------------------------------------
  240. prepare_sipp_param(SIPp_Config, Role, IpVsn)->
  241. PreLocalIp = proplists:get_value(localIp, SIPp_Config),
  242. PreLocalPort = proplists:get_value(localPort, SIPp_Config),
  243. PreRemoteIp = proplists:get_value(remoteIp, SIPp_Config),
  244. PreRemotePort = proplists:get_value(remotePort, SIPp_Config),
  245.  
  246. LocalIp = handle_local_ip(PreLocalIp, Role, IpVsn),
  247. LocalPort = handle_local_port(PreLocalPort, Role),
  248. RemoteIp = handle_remote_ip(PreRemoteIp, Role, IpVsn),
  249. RemotePort = handle_remote_port(PreRemotePort, Role),
  250.  
  251. PreMediaIp = proplists:get_value(mediaIp, SIPp_Config),
  252. MediaIp = choose(PreMediaIp=:=undefined, LocalIp, PreMediaIp),
  253.  
  254. ErrorFile = case proplists:get_value(errorFile, SIPp_Config) of
  255. undefined ->
  256. ?EST_LOG_DIR ++ to_string(Role) ++ "_" ++ write_time(now) ++ "_" ++ "sipp-error.log";
  257. TmpErrorFile ->
  258. filename:dirname(TmpErrorFile) ++ "/" ++ write_time(now) ++ "_" ++ filename:basename(TmpErrorFile)
  259. end,
  260.  
  261. StatFile = case proplists:get_value(statFile, SIPp_Config) of
  262. undefined ->
  263. ?EST_LOG_DIR ++ to_string(Role) ++ "_" ++ write_time(now) ++ "_" ++ "sipp-statistics.csv";
  264. TmpStatFile ->
  265. filename:dirname(TmpStatFile) ++ "/" ++ write_time(now) ++ "_" ++ filename:basename(TmpStatFile)
  266. end,
  267.  
  268. update_sipp_param([{localIp, LocalIp}, {localPort, LocalPort}, {remoteIp, RemoteIp},
  269. {remotePort, RemotePort}, {mediaIp, MediaIp}, {statFile, StatFile},
  270. {errorFile, ErrorFile}], SIPp_Config).
  271.  
  272.  
  273. update_sipp_param([], []) ->
  274. [];
  275. update_sipp_param([], SIPp_Config) ->
  276. SIPp_Config;
  277. update_sipp_param([{Attr, Value}|Rest]=_Param_List, SIPp_Config) ->
  278. case {Attr, Value} of
  279. {_, undefined} ->
  280. update_sipp_param(Rest, SIPp_Config);
  281. {_, _} ->
  282. NewSIPp_Config = proplists:delete(Attr, SIPp_Config) ++ [{Attr, Value}],
  283. update_sipp_param(Rest, NewSIPp_Config)
  284. end.
  285.  
  286. %% -----------------------------------------------------------------------
  287. %% check_sipp_param(SippParameters, _ParameterList, Type)
  288. %% @spec check_sipp_param(SippParameters::list(), _ParameterList::list(), Type::atom()) -> Res::atom()
  289. %% @doc Check whether parameters are lost and duplicated in parameter list
  290. %% SippParameters::list() is a list of parameters to sipp. More info about parameters
  291. %% in jpTsipp:prepare_sipp_cmd/1
  292. %% <pre>
  293. %% <b>Input:</b>
  294. %% SippParameters List Argument list of tuples in form {TypeTag,Param}
  295. %% _ParameterList List Parameter list
  296. %% Type Atom mandatory|optional
  297. %%
  298. %% <b>Output:</b>
  299. %% Res Atom true|false
  300. %%
  301. %% <i>Example:</i>
  302. %% jpTsipp:check_sipp_param([{localIp, "10.10.121.7"},
  303. %% {mediaIp, "10.10.121.7"},
  304. %% {localPort, "8004"},
  305. %% {remoteIp, "10.21.0.4"},
  306. %% {remotePort, "10004"},
  307. %% {scenarioFile, "./sipp/st/uac_register.xml"},
  308. %% {infFile, "./sipp/st/database.csv"},
  309. %% {statFile, "./sipp/st/sipp_regtister_uac.csv"},
  310. %% {callRate, "5"}],
  311. %% [scenarioFile, localIp, localPort, mediaIp, statFile],
  312. %% mandatory).
  313. %% </pre>
  314. %% @end
  315. %% -----------------------------------------------------------------------
  316. check_sipp_param(SippParameters, [Parameter|Rest]=_ParameterList, mandatory) ->
  317. case get_parame_quantity(Parameter, SippParameters) of
  318. 1 ->
  319. Cont=proplists:get_value(Parameter, SippParameters),
  320. case is_string(Cont) of
  321. true ->
  322. check_sipp_param(SippParameters, Rest, mandatory);
  323. false ->
  324. ?WARNING_MSG("Wrong Parameter ~p Content: ~p~n",[Parameter, Cont]),
  325. false
  326. end;
  327. 0 ->
  328. ?WARNING_MSG("the mandatory parameter(~p) is not included.~n ",[Parameter]),
  329. false;
  330. _ ->
  331. ?WARNING_MSG("the mandatory parameter(~p) is more than one.~n", [Parameter]),
  332. false
  333. end;
  334. check_sipp_param(SippParameters, [Parameter|Rest]=_ParameterList, optional) ->
  335. case get_parame_quantity(Parameter, SippParameters) of
  336. 1 ->
  337. case is_string(proplists:get_value(Parameter, SippParameters)) of
  338. true ->
  339. check_sipp_param(SippParameters, Rest, optional);
  340. false ->
  341. false
  342. end;
  343. 0 ->
  344. check_sipp_param(SippParameters, Rest, optional);
  345. _ ->
  346. ?WARNING_MSG("the optional parameter(~p) is more than one.~n", [Parameter]),
  347. false
  348. end;
  349. check_sipp_param(_SippParameters, [], _) ->
  350. true.
  351.  
  352. %% -----------------------------------------------------------------------
  353. %% set_default_sipp_param(SippParameters, _DefaultParameterList)
  354. %% @spec set_default_sipp_param(SippParameters::list(), _DefaultParameterList::list()) -> ResList::list()
  355. %% @doc Add default sipp parameter in SippParameters
  356. %% SippParameters::list() is a list of parameters to sipp. More info about parameters
  357. %% in jpTsipp:prepare_sipp_cmd/1
  358. %% <pre>
  359. %% <b>Input:</b>
  360. %% SippParameters List Argument list of tuples in form {TypeTag,Param}
  361. %% _ParameterList List Parameter list
  362. %%
  363. %% <b>Output:</b>
  364. %% ResList List Argument list of tuples in form {TypeTag, Param}
  365. %%
  366. %% <i>Example:</i>
  367. %% jpTsipp:set_default_sipp_param([{localIp, "10.10.121.7"},
  368. %% {mediaIp, "10.10.121.7"},
  369. %% {localPort, "8004"},
  370. %% {remoteIp, "10.21.0.4"},
  371. %% {remotePort, "10004"},
  372. %% {scenarioFile, "./sipp/st/uac_register.xml"},
  373. %% {infFile, "./sipp/st/database.csv"},
  374. %% {statFile, "./sipp/st/sipp_regtister_uac.csv"},
  375. %% {callRate, "5"},
  376. %% {maxCalls, "20000"}],
  377. %% [autoAnswer, background, openStat]).
  378. %% </pre>
  379. %% @end
  380. %% -----------------------------------------------------------------------
  381. set_default_sipp_param(SippParameters, [Parameter|Rest] = _DefaultParameterList) ->
  382. case get_parame_quantity(Parameter, SippParameters) of
  383. 0 ->
  384. set_default_sipp_param([{Parameter, true}|SippParameters], Rest);
  385. _ ->
  386. NewSippParameters = proplists:delete(Parameter, SippParameters),
  387. set_default_sipp_param([{Parameter, true}|NewSippParameters], Rest)
  388. end;
  389. set_default_sipp_param(SippParameters, []) ->
  390. SippParameters.
  391.  
  392.  
  393. %% -----------------------------------------------------------------------
  394. %% get_parame_quantity(Key, Parameters)
  395. %% @spec get_parame_quantity(Key::atom(), Parameters::list()) -> Res::atom()
  396. %% @doc Calculate the number of Key in Parameters list
  397. %% Parameters::list() is a list of parameters to sipp. More info about parameters
  398. %% in jpTsipp:prepare_sipp_cmd/1
  399. %% <pre>
  400. %% <b>Input:</b>
  401. %% Key Atom key in Parameters list
  402. %% Parameters List Argument list of tuples in form {TypeTag,Param}
  403. %%
  404. %% <b>Output:</b>
  405. %% Res Atom Number of keys
  406. %%
  407. %% <i>Example:</i>
  408. %% jpTsipp:get_parame_quantity(localIp, [{localIp, "10.10.121.7"},
  409. %% {mediaIp, "10.10.121.7"},
  410. %% {localPort, "8004"},
  411. %% {callRate, "5"}]).
  412. %% </pre>
  413. %% @end
  414. %% -----------------------------------------------------------------------
  415. get_parame_quantity(Key, Parameters) ->
  416. length(proplists:get_all_values(Key, Parameters)).
  417.  
  418. %% -----------------------------------------------------------------------
  419. %% build_sipp_parameters_string(_CmdList, CmdStr)
  420. %% @spec build_sipp_parameters_string(_CmdList::list(), CmdStr::string()) -> Res::string()
  421. %% @doc Generate parameters part of sipp cmd
  422. %% _CmdList::list() is a list of parameters to sipp
  423. %% <pre>
  424. %% <b>Input:</b>
  425. %% _CmdList List Parameters list
  426. %% CmdStr String connector
  427. %%
  428. %% <b>Output:</b>
  429. %% Res String Parameters part of sipp cmd
  430. %%
  431. %% </pre>
  432. %% @end
  433. %% -----------------------------------------------------------------------
  434. build_sipp_parameters_string([{Attr, Cont}|Rest]=_CmdList, CmdStr) ->
  435. case proplists:get_value(Attr, ?SIPP_PARAS) of
  436. [Parameter] ->
  437. if
  438. Cont =:= true ->
  439. build_sipp_parameters_string(Rest, CmdStr ++ Parameter);
  440. Cont =:= false ->
  441. build_sipp_parameters_string(Rest, CmdStr)
  442. end;
  443. [Parameter, ""] ->
  444. build_sipp_parameters_string(Rest, CmdStr ++ Parameter ++ to_string(Cont));
  445. undefined ->
  446. ?WARNING_MSG("Warning:~nbuild_sipp_parameters_string recv unexpected input: ~p, skip the parameter and go ahead.~n",[Attr]),
  447. build_sipp_parameters_string(Rest, CmdStr)
  448. end;
  449. build_sipp_parameters_string([], CmdStr) ->
  450. CmdStr.
  451.  
  452. %% -----------------------------------------------------------------------
  453. %% build_remote_uri(RemoteIp, RemoterPort)
  454. %% @spec build_remote_uri(RemoteIp::string(), RemoterPort::string()) -> Res::string()
  455. %% @doc Generate remoter uri
  456. %% <pre>
  457. %% <b>Input:</b>
  458. %% RemoterIp String
  459. %% RemoterPort String
  460. %%
  461. %% <b>Output:</b>
  462. %% Res String Remtoe URI part of sipp cmd
  463. %%
  464. %% </pre>
  465. %% @end
  466. %% -----------------------------------------------------------------------
  467. build_remote_uri(RemoteIp, RemotePort) ->
  468. if
  469. (RemoteIp =:= undefined) or (RemotePort =:=undefined) ->
  470. ?ERROR_MSG("Error:~nbuild_remote_uri unknow remote parameters: remote ip=~p; remote port=~p~n",[RemoteIp, RemotePort]),
  471. "";
  472. true ->
  473. to_string(RemoteIp) ++ ":" ++ to_string(RemotePort)
  474. end.
  475.  
  476. run_scenario(UacParam, UasParam, CallDuration, RunTime) ->
  477. run_scenario(UacParam, UasParam, CallDuration, RunTime, ?DEFAULT_MONITOR_INTERVAL, false).
  478. %% -----------------------------------------------------------------------
  479. %% run_scenario(_UacParam, _UasParam, CallDuration, RunTime, MonitorInterval, StatMonitorFlag)
  480. %% @spec run_scenario(_UacParam::tuple(), _UasParam::tuple(), CallDuration::integer(),
  481. %% RunTime::tuple(), MonitorInterval::tuple(),
  482. %% StatMonitorFlag::atom()) -> Res::atom()
  483. %% @doc Run the SIPp scenario.
  484. %% <pre>
  485. %% <b>Input:</b>
  486. %% _UacParam Tuple {UacSnrFile, UacStatFile, UacCmd}
  487. %% UacSnrFile String The scenario file for UAC
  488. %% UacStatFile String The Statistic file for UAC
  489. %% UacCmd String The SIPp command string for UAC
  490. %%
  491. %% _UasParam Tuple {UasSnrFile, UasStatFile, UasCmd}
  492. %% UasSnrFile String The scenario file for UAS
  493. %% UasStatFile String The Statistic file for UAS
  494. %% UasCmd String The SIPp command string for UAS
  495. %%
  496. %% CallDuration Integer Duration time for each call
  497. %% RunTime Tuple Total runtime for SIPp
  498. %% MonitorInterval Tuple The monitor interval for SIPp
  499. %% StatMonitorFlag Atom true|false whether to monitor pass rate during call ongoing
  500. %%
  501. %% <b>Output:</b>
  502. %% Res Atom ok|error
  503. %% </pre>
  504. %% @end
  505. %% ----------------------------------------------------------------------
  506. run_scenario({UacSnrFile, UacStatFile, UacCmd} = _UacParam,
  507. {UasSnrFile, UasStatFile, UasCmd} = _UasParam,
  508. CallDuration, RunTime, MonitorInterval, StatMonitorFlag) ->
  509.  
  510. %% Start SIPp
  511. case start_sipp(UasCmd) of
  512. {ok, UasPid} ->
  513. ct:pal("### UAS started, UasPid=~p ###~n", [UasPid]),
  514. timer:sleep(1000), % Sometimes UAS needs more time to open TCP port etc.
  515.  
  516. case start_sipp(UacCmd) of
  517. {ok, UacPid} ->
  518. ct:pal("### UAC started, UacPid=~p ###~n", [UacPid]),
  519. do_handle_scenario({UasPid, UasSnrFile, UasStatFile},
  520. {UacPid, UacSnrFile, UacStatFile},
  521. CallDuration, RunTime, MonitorInterval,
  522. StatMonitorFlag);
  523.  
  524. _ ->
  525. ct:pal("### UAC start failed, kill the started UAS process and quit the function!"),
  526. os:cmd("kill -9" ++ to_string(UasPid)),
  527. timer:sleep(1000),
  528. UasScreenFile = filename:dirname(UasSnrFile) ++
  529. "/" ++ filename:basename(UasSnrFile, ".xml") ++
  530. "_" ++ to_string(UasPid) ++ "_screen.log",
  531. ct:pal("UasScreenFile is:~p~n", [UasScreenFile]),
  532. os:cmd("mv "++UasScreenFile++" "++?EST_LOG_DIR),
  533. error
  534. end;
  535. _ ->
  536. ct:pal("### UAS start failed, quit the function!"),
  537. error
  538. end.
  539.  
  540. %% -----------------------------------------------------------------------
  541. %% do_handle_scenario(_UasParam, _UacParam, CallDuration,
  542. %% RunTime, MonitorInterval, StatMonitorFlag)
  543. %% @spec do_handle_scenario(_UasParam :: tuple(),
  544. %% _UacParam :: tuple(),
  545. %% CallDuration :: integer(),
  546. %% RunTime :: tuple(),
  547. %% MonitorInterval :: tuple(),
  548. %% StatMonitorFlag :: atom()) -> Res::atom()
  549. %%
  550. %% @doc monitor SIPp running status and returns the result of scenario executing
  551. %% <pre>
  552. %% <b>Input:</b>
  553. %% _UasParam Tuple {UasPid, UasSnrFile, UasStatFile}
  554. %% UasPid String The SIPp process id for UAS
  555. %% UaSSnrFile String The scenario file for UAS
  556. %% UaSStatFile String The Statistic file for UAS
  557. %%
  558. %% _UacParam Tuple {UacPid, UacSnrFile, UacStatFile}
  559. %% UacPid String The SIPp process id for UAC
  560. %% UacSnrFile String The scenario file for UAC
  561. %% UacStatFile String The Statistic file for UAC
  562. %% UasPid Pid The SIPp process id for UAS
  563. %% UacPid Pid The SIPp process id for UAC
  564. %% CallDuration Integer Call duration for each call
  565. %% RunTime Tuple Total runtime for SIPp
  566. %% MonitorInterval Tuple The monitor interval for SIPp
  567. %% StatMonitorFlag Atom true|false whether to monitor pass rate during call ongoing
  568. %%
  569. %% <b>Output:</b>
  570. %% Res Atom ok|error
  571. %%
  572. %% </pre>
  573. %% @end
  574. %% ----------------------------------------------------------------------
  575. do_handle_scenario({UasPid, UasSnrFile, UasStatFile} = _UasParam,
  576. {UacPid, UacSnrFile, UacStatFile} = _UacParam,
  577. CallDuration, RunTime, MonitorInterval,
  578. StatMonitorFlag) ->
  579. %% Start Interval Check Timer
  580. {{RunHour, RunMinute, RunSecond},
  581. {MonitorHour, MonitorMinute, MonitorSecond}} = {RunTime, MonitorInterval},
  582.  
  583. %% check the status of sipp process
  584. {ok, MonitorSippStatusRef} =
  585. timer:apply_interval(timer:hms(MonitorHour, MonitorMinute, MonitorSecond),
  586. ?MODULE,
  587. check_sipp_process_status,
  588. [self(), [UasPid, UacPid]]),
  589.  
  590. MonitorRefs =
  591. case StatMonitorFlag of
  592. true ->
  593. %% check the call status of sipp traffic
  594. {ok, MonitorCallStatusRef}
  595. = timer:apply_interval(timer:hms(MonitorHour, MonitorMinute, MonitorSecond),
  596. ?MODULE,
  597. check_sipp_call_status,
  598. [self(), [UasStatFile, UacStatFile]]),
  599. [MonitorSippStatusRef, MonitorCallStatusRef];
  600. _ ->
  601. [MonitorSippStatusRef]
  602. end,
  603.  
  604. {ok, TRefClose} =
  605. timer:apply_after(timer:hms(RunHour, RunMinute, RunSecond),
  606. ?MODULE,
  607. close_monitor,
  608. [self(), MonitorRefs]),
  609.  
  610. TRefList = MonitorRefs ++ [TRefClose],
  611.  
  612. %% Interval Check
  613. IntervalCheckResult = interval_loop_check([{UacStatFile, 0}, {UasStatFile, 0}]),
  614. case IntervalCheckResult of
  615. ok ->
  616. ct:pal("Interval check ok~n"),
  617. ok;
  618. {failed, FailedResult} ->
  619. ?WARNING_MSG("Warning: interval_loop_check recv failed(~p)~nto cancel all timers~n", [FailedResult]),
  620. lists:foreach(fun(P) -> timer:cancel(P) end, TRefList)
  621. end,
  622.  
  623. stop_uac_uas_sipp_processes([UacPid, UasPid], CallDuration),
  624.  
  625. %% Final Check
  626. {ok, UacStatData} = ?MODULE:get_stat_tail(UacStatFile),
  627. UacStatResult = check_sipp_stat(final, UacStatData),
  628. case UacStatResult of
  629. true ->
  630. ?DEBUG("Final UAC call failed rate is less than 0.05%.~n", []);
  631. false ->
  632. ?WARNING_MSG("Warning: final UAC call failed rate is more than 0.05%.~n", [])
  633. end,
  634.  
  635. {ok, UasStatData} = ?MODULE:get_stat_tail(UasStatFile),
  636. UasStatResult = check_sipp_stat(final, UasStatData),
  637. case UasStatResult of
  638. true ->
  639. ?DEBUG("Final UAS call failed rate is less than 0.05%.~n", []);
  640. false ->
  641. ?WARNING_MSG("Warning: final UAS call failed rate is more than 0.05%.~n", [])
  642. end,
  643.  
  644. UasScreenFile = filename:dirname(UasSnrFile) ++ "/" ++ filename:basename(UasSnrFile, ".xml") ++
  645. "_" ++ to_string(list_to_integer(UasPid)-1) ++ "_screen.log",
  646.  
  647. UacScreenFile = filename:dirname(UacSnrFile) ++ "/" ++ filename:basename(UacSnrFile, ".xml") ++
  648. "_" ++ to_string(list_to_integer(UacPid)-1) ++ "_screen.log",
  649.  
  650. ct:pal("UasScreenFile is:~p~n", [UasScreenFile]),
  651. ct:pal("UacScreenFile is:~p~n", [UacScreenFile]),
  652.  
  653. os:cmd("mv "++UasScreenFile++" "++?EST_LOG_DIR),
  654. os:cmd("mv "++UacScreenFile++" "++?EST_LOG_DIR),
  655.  
  656. if
  657. IntervalCheckResult =:= ok, UacStatResult =:=true, UasStatResult =:= true -> ok;
  658. true -> error
  659. end.
  660.  
  661. prepare_env() ->
  662. %% Kill any lingering SIPp processes to avoid that the scenario fails
  663. os:cmd("pkill -9 sipp"),
  664. os:cmd("mkdir "++ ?EST_LOG_DIR),
  665. {ok, _} = ?CH(b2bDbg, start_error_trace, []),
  666. ok = ?CH(oabDbg, log, [start]),
  667. true = ?CH(regDbg, err_trace, []),
  668. true = ?CH(sipDbg, err_trace, []).
  669.  
  670. fallback_env() ->
  671. ok = ?CH(dbg, stop_clear, []).
  672.  
  673.  
  674. prepare_systeminfo_filename(CurrentTime, sgc1, ch) ->
  675. Filename_suffix = write_time(CurrentTime) ++ ".log",
  676.  
  677. Vmstat_Filename = string:concat("/blade/homedir/sgc1-ch-vmstat-", Filename_suffix),
  678. SysInfo_Filename = ?EST_LOG_DIR ++ "sgc1-ch-system-info-" ++ Filename_suffix,
  679.  
  680. PlcRes_Filename = ?EST_LOG_DIR ++ "sgc1-ch-plc-res-" ++ Filename_suffix,
  681.  
  682. {SysInfo_Filename, Vmstat_Filename, PlcRes_Filename};
  683.  
  684. prepare_systeminfo_filename(CurrentTime, sgc1, om) ->
  685. Filename_suffix = write_time(CurrentTime) ++ ".log",
  686.  
  687. Vmstat_Filename = string:concat("/blade/homedir/sgc1-om-vmstat-", Filename_suffix),
  688. SysInfo_Filename = ?EST_LOG_DIR ++ "sgc1-om-system-info-" ++ Filename_suffix,
  689.  
  690. PlcRes_Filename = ?EST_LOG_DIR ++ "sgc1-om-plc-res-" ++ Filename_suffix,
  691.  
  692. {SysInfo_Filename, Vmstat_Filename, PlcRes_Filename};
  693.  
  694. prepare_systeminfo_filename(CurrentTime, ommp, ch) ->
  695. Filename_suffix = write_time(CurrentTime) ++ ".log",
  696.  
  697. Vmstat_Filename = string:concat("/blade/homedir/ommp-ch-vmstat-", Filename_suffix),
  698. SysInfo_Filename = ?EST_LOG_DIR ++ "ommp-ch-system-info-" ++ Filename_suffix,
  699.  
  700. PlcRes_Filename = ?EST_LOG_DIR ++ "ommp-ch-plc-res-" ++ Filename_suffix,
  701.  
  702. {SysInfo_Filename, Vmstat_Filename, PlcRes_Filename};
  703.  
  704. prepare_systeminfo_filename(CurrentTime, ommp, om) ->
  705. Filename_suffix = write_time(CurrentTime) ++ ".log",
  706.  
  707. Vmstat_Filename = string:concat("/blade/homedir/ommp-om-vmstat-", Filename_suffix),
  708. SysInfo_Filename = ?EST_LOG_DIR ++ "ommp-om-system-info-" ++ Filename_suffix,
  709.  
  710. PlcRes_Filename = ?EST_LOG_DIR ++ "ommp-om-plc-res-" ++ Filename_suffix,
  711.  
  712. {SysInfo_Filename, Vmstat_Filename, PlcRes_Filename}.
  713.  
  714. collect_system_info(SysInfo_Filename, Vmstat_Filename,sgc1,ch) ->
  715. Mem_result = ?CH(ets, tab2list, [plcInfo]),
  716. ProcessNum = length(?CH(erlang, processes, [])),
  717. Result = Mem_result ++ [{process_Num, ProcessNum}],
  718.  
  719. {ok, File_handler} = file:open(SysInfo_Filename, [append]),
  720. io:format(File_handler, "~p~n", [Result]),
  721. ok = file:close(File_handler),
  722.  
  723. VmCmd = "vmstat 5 5 >>" ++ Vmstat_Filename,
  724. ?CH(os, cmd, [VmCmd]);
  725.  
  726. collect_system_info(SysInfo_Filename, Vmstat_Filename,sgc1,om) ->
  727. Mem_result = ?OM(ets, tab2list, [plcInfo]),
  728. ProcessNum = length(?OM(erlang, processes, [])),
  729. Result = Mem_result ++ [{process_Num, ProcessNum}],
  730.  
  731. {ok, File_handler} = file:open(SysInfo_Filename, [append]),
  732. io:format(File_handler, "~p~n", [Result]),
  733. ok = file:close(File_handler),
  734.  
  735. VmCmd = "vmstat 5 5 >>" ++ Vmstat_Filename,
  736. ?OM(os, cmd, [VmCmd]);
  737.  
  738. collect_system_info(SysInfo_Filename, Vmstat_Filename,ommp,ch) ->
  739. Mem_result = ?SBGCH(ets, tab2list, [plcInfo]),
  740. ProcessNum = length(?SBGCH(erlang, processes, [])),
  741. Result = Mem_result ++ [{process_Num, ProcessNum}],
  742.  
  743. {ok, File_handler} = file:open(SysInfo_Filename, [append]),
  744. io:format(File_handler, "~p~n", [Result]),
  745. ok = file:close(File_handler),
  746.  
  747. VmCmd = "vmstat 5 5 >>" ++ Vmstat_Filename,
  748. ?SBGCH(os, cmd, [VmCmd]);
  749.  
  750. collect_system_info(SysInfo_Filename, Vmstat_Filename,ommp,om) ->
  751. Mem_result = ?SBGOM(ets, tab2list, [plcInfo]),
  752. ProcessNum = length(?SBGOM(erlang, processes, [])),
  753. Result = Mem_result ++ [{process_Num, ProcessNum}],
  754.  
  755. {ok, File_handler} = file:open(SysInfo_Filename, [append]),
  756. io:format(File_handler, "~p~n", [Result]),
  757. ok = file:close(File_handler),
  758.  
  759. VmCmd = "vmstat 5 5 >>" ++ Vmstat_Filename,
  760. ?SBGOM(os, cmd, [VmCmd]).
  761.  
  762. collect_plc_res(PlcRes_Filename) ->
  763. PlcRes_result = ?CH(plcScheduler, plc_res, [1, 1000]),
  764. {ok, File_handler} = file:open(PlcRes_Filename, [append]),
  765. io:format(File_handler, "~p~n", [PlcRes_result]),
  766. ok = file:close(File_handler).
  767.  
  768. transfer_vmstat_file(Filename,Type, Role) ->
  769. BladeNum = get_blade_no(Type, Role),
  770. File = "/private" ++ re:replace(Filename, "blade", BladeNum, [{return, list}]),
  771.  
  772. LocalFile = filename:join([?EST_LOG_DIR, filename:basename(File)]),
  773. SisRootPswd = sbgFtSupport:get_sis_root_pw(),
  774. ok = scp_from("root", SisRootPswd, "sis1", File, LocalFile),
  775. LocalFile.
  776.  
  777. get_blade_no(sgc1, ch) ->
  778. [_, BladeNum] = re:split(to_string(?SGCchNode), "[\@]", [{return, list}]),
  779. BladeNum;
  780. get_blade_no(sgc1, om) ->
  781. [_, BladeNum] = re:split(to_string(?SGComNode), "[\@]", [{return, list}]),
  782. BladeNum;
  783. get_blade_no(ommp, ch) ->
  784. [_, BladeNum] = re:split(to_string(?SBGchNode), "[\@]", [{return, list}]),
  785. BladeNum;
  786. get_blade_no(ommp, om) ->
  787. [_, BladeNum] = re:split(to_string(?SBGomNode), "[\@]", [{return, list}]),
  788. BladeNum.
  789.  
  790. scp_from(User, Passwd, RemoteHost, RemoteFile, LocalFile) ->
  791. H = case is_atom(RemoteHost) of
  792. true -> atom_to_list(RemoteHost);
  793. false -> RemoteHost
  794. end,
  795.  
  796. RemoteIp = jpTutil:get_ip_from_hostname(H),
  797. Options = [{user,User},
  798. {password,Passwd},
  799. {user_interaction,false},
  800. {silently_accept_hosts,true}],
  801.  
  802. application:start(crypto),
  803. application:start(ssh),
  804.  
  805. case ssh_sftp:start_channel(RemoteIp, Options) of
  806. {ok, Pid, ConnRef} ->
  807. case ssh_sftp:read_file(Pid, RemoteFile) of
  808. {ok, Data} ->
  809. case file:write_file(LocalFile, Data) of
  810. ok ->
  811. ssh:close(ConnRef);
  812. {error, Error} ->
  813. ct:pal("scp_from remote host ~p Error ~p~n", [RemoteHost, Error]),
  814. ssh:close(ConnRef),
  815. {nok, Error}
  816. end;
  817. ErrorReadingFile ->
  818. ssh:close(ConnRef),
  819. {nok, {error_reading_source_file, ErrorReadingFile}}
  820. end;
  821. {error, Error} ->
  822. {nok, Error};
  823. ErrorFromConnect ->
  824. {nok, ErrorFromConnect}
  825. end.
  826.  
  827. get_all_counter() ->
  828. RegCount = count(reg),
  829. B2bCount = count(b2b),
  830. HiwCount = count(hiw),
  831. OabCount = count(oab),
  832. [RegCount, B2bCount, HiwCount, OabCount].
  833.  
  834. count(reg) ->
  835. Count1 = ?CH(sysProc, select_count_names, [[{{?REG_MATCH, '_'},[],[true]}]]),
  836. Count2 = ?CH(sysProc, select_count_names, [[{{?REG_MATCH2, '_'},[],[true]}]]),
  837. Count = reg_count(Count1, Count2),
  838. ResultCount = count(Count),
  839. io:format("\t Number of REG processes in the system are ~p~n", [ResultCount]),
  840. ResultCount;
  841. count(b2b) ->
  842. Count = ?CH(sysProc, select_count_names, [[{{?DC_MATCH(b2b), '_'},[],[true]}]]),
  843. ResultCount = count(Count),
  844. io:format("\t Number of B2B processes in the system are ~p~n", [ResultCount]),
  845. ResultCount;
  846. count(hiw) ->
  847. Count = ?CH(sysProc, select_count_names, [[{{?DC_MATCH(hiw),'_'},[],[true]}]]),
  848. ResultCount = count(Count),
  849. io:format("\t Number of HIW processes in the system are ~p~n", [ResultCount]),
  850. ResultCount;
  851. count(oab) ->
  852. Count = ?CH(sysProc, select_count_names, [[{{?DC_MATCH(oab),'_'},[],[true]}]]),
  853. ResultCount = count(Count),
  854. io:format("\t Number of OAB processes in the system are ~p~n", [ResultCount]),
  855. ResultCount;
  856. count(Int) when is_integer(Int)->
  857. Int;
  858. count(Other) ->
  859. [Other].
  860.  
  861. reg_count( C1, C2) when is_integer(C1), is_integer(C2) -> C1+C2;
  862. reg_count( C1, _C2) when is_integer(C1) -> C1;
  863. reg_count(_C1, C2) when is_integer(C2) -> C2;
  864. reg_count(_C1, _C2) -> 0.
  865.  
  866. draw_graph(InputFile, sysinfo) ->
  867. OutputFile = ?EST_LOG_DIR ++ filename:rootname(filename:basename(InputFile)) ++ ".svg",
  868. Cmd = "java -jar " ++ ?EST_DATA_BIN ++ "sysinfo.jar " ++ "\<" ++ " " ++
  869. InputFile ++ " \| java -jar " ++ ?EST_DATA_BIN ++ "xml2svg.jar " ++
  870. "\>" ++ " " ++ OutputFile,
  871. ct:pal("The graph draw sysinfo command:~n~p~n", [Cmd]),
  872. os:cmd(Cmd),
  873. OutputFile;
  874.  
  875. draw_graph(InputFile, vmstat) ->
  876. OutputFile = ?EST_LOG_DIR ++ filename:rootname(filename:basename(InputFile)) ++ ".svg",
  877. Cmd = "java -jar " ++ ?EST_DATA_BIN ++ "vmstat.jar " ++ "\<" ++ " " ++
  878. InputFile ++ " \| java -jar " ++ ?EST_DATA_BIN ++ "xml2svg.jar " ++
  879. "\>" ++ " " ++ OutputFile,
  880. ct:pal("The graph draw vmstat command:~n~p~n", [Cmd]),
  881. os:cmd(Cmd),
  882. OutputFile;
  883.  
  884. draw_graph(InputFile, passrate) ->
  885. OutputFile = ?EST_LOG_DIR ++ filename:rootname(filename:basename(InputFile)) ++ ".svg",
  886. Cmd = "java -jar " ++ ?EST_DATA_BIN ++ "passrate.jar " ++ "\<" ++ " " ++
  887. InputFile ++ " \| java -jar " ++ ?EST_DATA_BIN ++ "xml2svg.jar " ++
  888. "\>" ++ " " ++ OutputFile,
  889. ct:pal("The graph draw passrate command:~n~p~n", [Cmd]),
  890. os:cmd(Cmd),
  891. OutputFile.
  892.  
  893. generate_html(SysInfoSvg, VmstatSvg, UacPassrateSvg, UasPassrateSvg) ->
  894. Cmd = ?EST_DATA_BIN ++ "html_generate.sh" ++ " " ++ SysInfoSvg ++ " " ++
  895. VmstatSvg ++ " " ++ UacPassrateSvg ++ " " ++ UasPassrateSvg ++ " " ++ ?EST_LOG_DIR,
  896. os:cmd(Cmd).
  897.  
  898. generate_graph_on_log_html(SysInfoSvg, VmstatSvg, UacPassrateSvg, UasPassrateSvg) ->
  899. {ok, Cwd} = file:get_cwd(),
  900. Cmd = "cp " ++ SysInfoSvg ++ " " ++ VmstatSvg ++ " " ++ UacPassrateSvg ++
  901. " " ++ UasPassrateSvg ++ " " ++ Cwd ++ "/",
  902. os:cmd(Cmd),
  903. FileInfo = [{"Erlang VM Information", filename:basename(SysInfoSvg)},
  904. {"Vmstat Information", filename:basename(VmstatSvg)},
  905. {"UacPass Rate", filename:basename(UacPassrateSvg)},
  906. {"UasPass Rate", filename:basename(UasPassrateSvg)}],
  907. Res = gen_html_format(FileInfo),
  908. io:format(Res).
  909.  
  910. gen_html_format(FileInfo) ->
  911. F = fun({Desp, FileName}) ->
  912. "<h1>" ++ Desp ++ "</h1>" ++ "<embed type=\"image/svg+xml\" src=\"../../" ++ FileName ++ "\"/>"
  913. end,
  914. List = lists:map(F, FileInfo),
  915. lists:flatten(["<div>" | List], "</div>").
  916.  
  917.  
  918. %% #---------------------------------------------------------
  919. %% #3.2 CODE FOR INTERNAL FUNCTIONS
  920. %% #---------------------------------------------------------
  921.  
  922. %% -----------------------------------------------------------------------
  923. %% start_sipp(SIPpCommand)
  924. %% @spec start_sipp(SIPpCommand) -> Res::tuple()
  925. %% @doc Start SIPP command and returns the process id of SIPp
  926. %% <pre>
  927. %% <b>Input:</b>
  928. %% SIPpCommand String
  929. %%
  930. %% <b>Output:</b>
  931. %% Res Tuple {ok|error, PID::string()}
  932. %%
  933. %% </pre>
  934. %% @end
  935. %% -----------------------------------------------------------------------
  936. start_sipp(SIPpCommand) ->
  937. SIPpShellPrintout = os:cmd(SIPpCommand),
  938. ct:pal("startsipp result: ##### ~p~n", [SIPpShellPrintout]),
  939. get_pid_str(SIPpShellPrintout).
  940.  
  941.  
  942. %% -----------------------------------------------------------------------
  943. %% interval_loop_check(Counters)
  944. %% @spec interval_loop_check(Counters::integer()) -> Res::atom()
  945. %% @doc Check the sipp process status and sipp call status, return failed if
  946. %% sipp process killed or call fail rate is more than expect in a certain time
  947. %% <pre>
  948. %% <b>Input:</b>
  949. %% Counters Integer The number of times for check
  950. %%
  951. %% <b>Output:</b>
  952. %% Res Tuple
  953. %%
  954. %% </pre>
  955. %% @end
  956. %% -----------------------------------------------------------------------
  957. interval_loop_check(Counters)->
  958. receive
  959. {ua, SippPid, SippStatus} ->
  960. case SippStatus of
  961. true ->
  962. ct:pal("Sipp(PID=~p) is running~n", [SippPid]),
  963. interval_loop_check(Counters);
  964. false ->
  965. ?WARNING_MSG("the SIPp process(~p) doesn't work", [SippPid]),
  966. {failed, {sippStatus, SippPid}}
  967. end;
  968. {uaStat, StatFile, StatData} ->
  969. CounterValue = proplists:get_value(StatFile, Counters),
  970. RestCounters = proplists:delete(StatFile, Counters),
  971. case check_sipp_stat(interval, StatData) of
  972. true ->
  973. ct:pal("Statistics file(~p) interval loop check ok~n", [StatFile]),
  974. interval_loop_check([{StatFile, 0}|RestCounters]);
  975. false ->
  976. ?WARNING_MSG("the SIPp(~p) has some failed calls in the past ~p interval times~n",
  977. [StatFile, CounterValue]),
  978. if CounterValue < ?STAT_FAIL ->
  979. interval_loop_check([{StatFile, CounterValue + 1}|RestCounters]);
  980. true ->
  981. {failed, {sippStat, StatFile}}
  982. end
  983. end;
  984. stop ->
  985. ok
  986. end.
  987.  
  988. %% -----------------------------------------------------------------------
  989. %% close_monitor(Pid, TRefs)
  990. %% @spec close_monitor(Pid, TRefs)->Res
  991. %% @doc Close the monitor for SIPp
  992. %% <pre>
  993. %% <b>Input:</b>
  994. %% TRefs Time Reference of monitor
  995. %%
  996. %% </pre>
  997. %% @end
  998. %% -----------------------------------------------------------------------
  999. close_monitor(Pid, TRefs) ->
  1000. [timer:cancel(TRef)||TRef<-TRefs],
  1001. ct:pal("close_monitor: TRefs: ~p~n", [TRefs]),
  1002. Pid ! stop.
  1003.  
  1004. choose(true, __True, _) -> __True;
  1005. choose(false, _, __False) -> __False.
  1006.  
  1007.  
  1008. handle_local_ip(undefined, Role, IpVsn) ->
  1009. local_ip_string(IpVsn, Role);
  1010. handle_local_ip(LocalIp, _, _) ->
  1011. LocalIp.
  1012.  
  1013.  
  1014. local_ip_string(IpVsn, Role) ->
  1015. case ?CH(sysEnv, is_ssit, []) of
  1016. true ->
  1017. ip_string_ssit(IpVsn);
  1018. _ ->
  1019. local_ip_string_stp(IpVsn, Role)
  1020. end.
  1021.  
  1022. local_ip_string_stp(ipv4, access) ->
  1023. "10.10.121.7";
  1024. local_ip_string_stp(ipv6, access) ->
  1025. "3001:10:121::7";
  1026. local_ip_string_stp(ipv4, core4access) ->
  1027. "10.10.240.7";
  1028. local_ip_string_stp(ipv6, core4access) ->
  1029. "3001:10:240::7";
  1030. local_ip_string_stp(ipv4, foreign) ->
  1031. "10.10.141.7";
  1032. local_ip_string_stp(ipv6, foreign) ->
  1033. "3001:10:141::7";
  1034. local_ip_string_stp(ipv4, core4foreign) ->
  1035. "10.10.240.7";
  1036. local_ip_string_stp(ipv6, core4foreign) ->
  1037. "3001:10:240::7";
  1038. local_ip_string_stp(_IpVsn, Role) ->
  1039. local_ip_string(ipv4, Role).
  1040.  
  1041. ip_string_ssit(IpVsn) ->
  1042. IPtuple = case IpVsn of
  1043. ipv6 ->
  1044. get_local_ip_tuple(inet6);
  1045. _ ->
  1046. get_local_ip_tuple(inet)
  1047. end,
  1048. inet_parse:ntoa(IPtuple).
  1049.  
  1050. get_local_ip_tuple(inet6) ->
  1051. %% The IPv6 linc local address that exists on the linux machine
  1052. %% can not be used by erlang. The address must be a global address or
  1053. %% loopback. Only loopback address is available in simulated environment.
  1054. {0,0,0,0,0,0,0,1};
  1055. get_local_ip_tuple(InetFamily) ->
  1056. {ok, Host} = inet:gethostname(),
  1057. {ok, IP} = inet:getaddr(Host, InetFamily),
  1058. IP.
  1059.  
  1060. handle_local_port(undefined, Role) ->
  1061. local_port_string(Role);
  1062. handle_local_port(LocalPort, _Role) ->
  1063. LocalPort.
  1064.  
  1065. local_port_string(access) ->
  1066. "8004";
  1067. local_port_string(core4access) ->
  1068. "8003";
  1069. local_port_string(foreign) ->
  1070. "8002";
  1071. local_port_string(core4foreign) ->
  1072. "8003".
  1073.  
  1074.  
  1075. handle_remote_ip(undefined, Role, IpVsn) ->
  1076. remote_ip_string(IpVsn, Role);
  1077. handle_remote_ip(RemoteIp, _, _) ->
  1078. RemoteIp.
  1079.  
  1080. remote_ip_string(IpVsn, Role) ->
  1081. case ?CH(sysEnv, is_ssit, []) of
  1082. true ->
  1083. ip_string_ssit(IpVsn);
  1084. _ ->
  1085. remote_ip_string_stp(IpVsn, Role)
  1086. end.
  1087.  
  1088. remote_ip_string_stp(ipv4, access) ->
  1089. "10.21.0.4";
  1090. remote_ip_string_stp(ipv6, access) ->
  1091. "3001:21::4";
  1092. remote_ip_string_stp(ipv4, core4access) ->
  1093. "10.10.230.4";
  1094. remote_ip_string_stp(ipv6, core4access) ->
  1095. "3001:10:230::4";
  1096. remote_ip_string_stp(ipv4, foreign) ->
  1097. "10.41.0.4";
  1098. remote_ip_string_stp(ipv6, foreign) ->
  1099. "3001:41::4";
  1100. remote_ip_string_stp(ipv4, core4foreign) ->
  1101. "10.10.230.5";
  1102. remote_ip_string_stp(ipv6, core4foreign) ->
  1103. "3001:10:230::5";
  1104. remote_ip_string_stp(_IpVsn, Role) ->
  1105. remote_ip_string_stp(ipv4, Role).
  1106.  
  1107.  
  1108. handle_remote_port(undefined, Role) ->
  1109. remote_port_string(Role);
  1110. handle_remote_port(RemotePort, _) ->
  1111. RemotePort.
  1112.  
  1113. remote_port_string(access) ->
  1114. "10004";
  1115. remote_port_string(core4access) ->
  1116. "10003";
  1117. remote_port_string(foreign) ->
  1118. "10002";
  1119. remote_port_string(core4foreign) ->
  1120. "10005".
  1121.  
  1122. stop_sipp_process(Pid) ->
  1123. stop_sipp_process(Pid, graceful).
  1124.  
  1125. stop_sipp_process(Pid, graceful) ->
  1126. Cmd = "kill -USR1 " ++ to_string(Pid),
  1127. ?DEBUG("the command is ~p~n",[Cmd]),
  1128. Res = os:cmd(Cmd),
  1129. ?DEBUG("the command result is ~p~n",[Res]);
  1130. stop_sipp_process(Pid, enforced) ->
  1131. os:cmd("kill -9 " ++ to_string(Pid)).
  1132.  
  1133. stop_uac_uas_sipp_processes([Pid|T] = _Pids, CallDuration) ->
  1134. stop_sipp_process(Pid),
  1135. timer:sleep(CallDuration+180000),
  1136. case check_pid_alive(Pid) of
  1137. false ->
  1138. ok;
  1139. _ ->
  1140. ?WARNING_MSG("Failed to stop the PID(~p) gracefully.~n",[Pid]),
  1141. ?DEBUG("the PID(~p) status ~p~n", [Pid, check_pid_alive(Pid)]),
  1142. stop_sipp_process(Pid, enforced)
  1143. end,
  1144. timer:sleep(120000),
  1145. stop_uac_uas_sipp_processes(T, 0);
  1146.  
  1147. stop_uac_uas_sipp_processes([], _CallDuration) ->
  1148. ok.
  1149.  
  1150. close_sipp()->
  1151. Res = os:cmd("pgrep sipp"),
  1152. case length(Res) of
  1153. 0 -> ok;
  1154. _ -> os:cmd("pkill sipp")
  1155. end.
  1156.  
  1157. check_sipp_process_status(Pid, [SippPid|T]=_SippPids) ->
  1158. Pid ! {ua, SippPid, check_pid_alive(SippPid)},
  1159. check_sipp_process_status(Pid, T);
  1160. check_sipp_process_status(_Pid, []) ->
  1161. ok.
  1162.  
  1163. check_sipp_call_status(Pid, [StatFile|T]=_StatFiles)->
  1164. {ok, StatData} = get_stat_tail(StatFile),
  1165. Pid ! {uaStat, StatFile, StatData},
  1166. check_sipp_call_status(Pid, T);
  1167. check_sipp_call_status(_Pid, []) ->
  1168. ok.
  1169.  
  1170. check_pid_alive(Pid) ->
  1171. IsString=is_string(Pid),
  1172. if
  1173. IsString ->
  1174. filelib:is_dir("/proc/" ++ Pid);
  1175. is_integer(Pid) ->
  1176. filelib:is_dir("/proc/" ++ to_string(Pid));
  1177. true ->
  1178. ?WARNING_MSG("Wrong Pid Content:~p~n",[Pid]),
  1179. false
  1180. end.
  1181.  
  1182. check_sipp_stat(interval, StatData)->
  1183. FailedCall_P = lists:nth(17, StatData),
  1184. if
  1185. FailedCall_P > 0 ->
  1186. false;
  1187. FailedCall_P == 0 ->
  1188. true
  1189. end;
  1190. check_sipp_stat(final, StatData)->
  1191. TotalCreatedCall=lists:nth(13, StatData),
  1192. FailedCall_C = lists:nth(18, StatData),
  1193.  
  1194. ct:pal("Total number of calls is:~p~n", [TotalCreatedCall]),
  1195. ct:pal("Number of failed calls is:~p~n", [FailedCall_C]),
  1196.  
  1197. if
  1198. TotalCreatedCall > 0 ->
  1199. CallLossRate = FailedCall_C / TotalCreatedCall;
  1200. true ->
  1201. CallLossRate = 0
  1202. end,
  1203.  
  1204. PrintInfo = [{"Total calls", to_list(TotalCreatedCall)},
  1205. {"Total failed calls", to_list(FailedCall_C)},
  1206. {"Error rate", to_list(CallLossRate*100) ++ "%"}],
  1207. print(PrintInfo),
  1208.  
  1209. SIPpResult = if
  1210. CallLossRate > ?CALL_LOSS_RATE ->
  1211. false;
  1212. true ->
  1213. true
  1214. end,
  1215.  
  1216. SIPpResult.
  1217.  
  1218. get_stat_tail(StatFile) ->
  1219. case filelib:is_regular(StatFile) of
  1220. true ->
  1221. TailStat = os:cmd("tail -1 " ++ StatFile),
  1222. StrippedTailStat=string:strip(TailStat, right, $\n),
  1223. RowList=convert_datatype(split_statistics(StrippedTailStat, ";")),
  1224. {ok, RowList};
  1225. false ->
  1226. ?WARNING_MSG("the StatFile ~p doesn't exist~n", [StatFile]),
  1227. {error, StatFile}
  1228. end.
  1229.  
  1230. get_stat_head(StatFile) ->
  1231. case filelib:is_regular(StatFile) of
  1232. true ->
  1233. HeadStat = os:cmd("head -1 " ++ StatFile),
  1234. StrippedHeadStat=string:strip(HeadStat, right, $\n),
  1235. RowList=split_statistics(StrippedHeadStat, ";"),
  1236. {ok, RowList};
  1237. false ->
  1238. ?WARNING_MSG("the StatFile ~p doesn't exist~n", [StatFile]),
  1239. {error, StatFile}
  1240. end.
  1241.  
  1242. get_pid_str(Str)->
  1243. {ok, Mp} = re:compile("PID=\\\[([0-9]+)\\\]"),
  1244. case re:run(Str, Mp, [{capture, all_but_first, list}]) of
  1245. {match, [PID]} -> {ok, PID};
  1246. _ -> {error, Str}
  1247. end.
  1248.  
  1249. convert_datatype(List) ->
  1250. %% the first 5 items are date
  1251. %% the next 13 items are counters
  1252. lists:sublist(List, 5)++[to_number(X)||X<-lists:sublist(List, 6, 13)].
  1253.  
  1254.  
  1255. write_time(now)->
  1256. write_time(calendar:local_time());
  1257.  
  1258. write_time({{Year, Month, Day}, {Hour, Minute, Second}}=_Time)->
  1259. lists:flatten(io_lib:format("~w-~.2.0w-~.2.0w_~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])).
  1260.  
  1261. %%18 is for SIPp stat File
  1262. split_statistics(String, StatDelimiter) ->
  1263. split_statistics(String, StatDelimiter, 18).
  1264.  
  1265. split_statistics(String, StatDelimiter, Length) ->
  1266. RowList = re:split(String, StatDelimiter, [{return, list}]),
  1267. lists:sublist(RowList, Length).
  1268.  
  1269. print(PrintInfo) ->
  1270. erlang:yield(),
  1271. Subject = "Early ST test report",
  1272. L1 = length(Subject),
  1273. L = integer_to_list(trunc((69 - L1)/2 + L1)),
  1274. io:format("+~69.0.-~+"),
  1275. io:format("|~69."++ L ++". s|", [Subject]),
  1276. io:format("+~69.35.-s+", ["+"]),
  1277. lists:foreach(fun({Desp, Num}) ->
  1278. io:format("|~34.33. s|~34.20. s|", [Desp, Num]),
  1279. io:format("+~69.35.-s+", ["+"])
  1280. end, PrintInfo),
  1281.  
  1282. io:format("+~69.0.-~+~n").
  1283.  
  1284. to_list(Integer) when is_integer(Integer)->
  1285. erlang:integer_to_list(Integer);
  1286. to_list(Atom) when is_atom(Atom) ->
  1287. erlang:atom_to_list(Atom);
  1288. to_list(Float) when is_float(Float) ->
  1289. N = math:pow(10, 3),
  1290. Result = round(Float*N)/N,
  1291. lists:flatten(io_lib:print(Result));
  1292. to_list(0) ->
  1293. "0";
  1294. to_list(0.0) ->
  1295. "0".
  1296.  
  1297. is_string(Input)->
  1298. io_lib:printable_unicode_list(Input).
  1299.  
  1300. to_string(Input) when is_integer(Input) ->
  1301. erlang:integer_to_list(Input);
  1302. to_string(Input) when is_float(Input) ->
  1303. erlang:float_to_list(Input);
  1304. to_string(Input) when is_atom(Input) ->
  1305. erlang:atom_to_list(Input);
  1306. to_string(Input) ->
  1307. case is_string(Input) of
  1308. true -> Input;
  1309. false -> lists:flatten(io_lib:print(Input))
  1310. end. %% Is String already
  1311.  
  1312. to_number(Str) ->
  1313. case string:to_float(Str) of
  1314. {error, _} ->
  1315. case string:to_integer(Str) of
  1316. {error, _} ->
  1317. ?WARNING_MSG("the String(~p) is not integer and float.~n", [Str]),
  1318. Str;
  1319. {Int, _} ->
  1320. Int
  1321. end;
  1322. {Float, _} ->
  1323. Float
  1324. end.
  1325.  
  1326.  
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346. -define(FILE_NAMES, [
  1347. {sgc1_ch, ["/blade/homedir/sgc1-ch-vmstat-", ?EST_LOG_DIR ++ "sgc1-ch-system-info-", ?EST_LOG_DIR ++ "sgc1-ch-plc-res-"]},
  1348. {sgc1_om, ["/blade/homedir/sgc1-om-vmstat-", ?EST_LOG_DIR ++ "sgc1-om-system-info-", ?EST_LOG_DIR ++ "sgc1-om-plc-res-"]},
  1349. {ommp_ch, ["/blade/homedir/ommp-ch-vmstat-", ?EST_LOG_DIR ++ "ommp-ch-system-info-", ?EST_LOG_DIR ++ "ommp-ch-plc-res-"]},
  1350. {ommp_om, ["/blade/homedir/ommp-om-vmstat-", ?EST_LOG_DIR ++ "ommp-om-system-info-", ?EST_LOG_DIR ++ "ommp-om-plc-res-"]}
  1351. ]).
  1352. %% -----------------------------------------------------------------------
  1353. %% @spec prepare_systeminfo_filenames(Input :: lists()) -> lists()
  1354. %% @doc Prepare the log files according which blades you want to monitor.
  1355. %% <pre>
  1356. %% <strong>Example</strong>:
  1357. %% prepare_systeminfo_filenames([sgc1_ch])
  1358. %% prepare_systeminfo_filenames([sgc1_ch, sgc1_om, ommp_ch, ommp_om])
  1359. %% </pre>
  1360. %% @end
  1361. %% -----------------------------------------------------------------------
  1362. prepare_systeminfo_filenames(Input) when is_list(Input) ->
  1363. CurrentTime = calendar:local_time(),
  1364. Filename_suffix = write_time(CurrentTime) ++ ".log",
  1365. prepare_systeminfo_filenames_help(Input, Filename_suffix, []);
  1366. prepare_systeminfo_filenames(_) ->
  1367. ct:pal("prepare_systeminfo_filenames: wrong input, just like [sgc1_ch, sgc1_om, ommp_ch, ommp_om]~n"),
  1368. [].
  1369.  
  1370. prepare_systeminfo_filenames_help([], _, Res) ->
  1371. lists:reverse(Res);
  1372. prepare_systeminfo_filenames_help([H | T], Filename_suffix, Res) ->
  1373. case proplists:get_value(H, ?FILE_NAMES) of
  1374. [VmStat, SysInfo, Plc] ->
  1375. TempRes = {H, {SysInfo ++ Filename_suffix, VmStat ++ Filename_suffix, Plc ++ Filename_suffix}},
  1376. print_systeminfo_file(TempRes),
  1377. prepare_systeminfo_filenames_help(T, Filename_suffix, [TempRes | Res]);
  1378. undefined ->
  1379. ct:pal("There have wrong input parmeters, please select from (sgc1_ch, sgc1_om, ommp_ch, ommp_om)~n"),
  1380. prepare_systeminfo_filenames_help(T, Filename_suffix, Res)
  1381. end.
  1382.  
  1383. print_systeminfo_file({Blade, {SysInfo_Filename, Vmstat_Filename, PlcRes_Filename}}) ->
  1384. ct:pal("Blade: ~p~nSysInfo_Filename:~p~nVmstat_Filename:~p~nPlcRes_Filename:~p~n",
  1385. [Blade, SysInfo_Filename, Vmstat_Filename, PlcRes_Filename]).
  1386.  
  1387.  
  1388.  
  1389. %% -----------------------------------------------------------------------
  1390. %% @spec start_collect_system_infos(Input :: lists()) -> lists()
  1391. %% @doc Start collecting the logs.<br></br>
  1392. %% <strong>Note</strong>: The input parameter of this function is the result of <code>sbgEstSupport:prepare_systeminfo_filenames/1</code>.
  1393. %% @end
  1394. %% -----------------------------------------------------------------------
  1395. start_collect_system_infos(FileNames) ->
  1396. start_collect_system_infos(FileNames, []).
  1397.  
  1398. start_collect_system_infos([], Res) ->
  1399. lists:reverse(Res);
  1400. start_collect_system_infos([{sgc1_ch, {Sys, VmStat, Plc}} | T], Res) ->
  1401. {ok, SysInfoTimerRef} = timer:apply_interval(timer:hms(0, 2, 0),
  1402. ?MODULE, collect_system_info, [sgc1_ch, Sys, VmStat]),
  1403. {ok, PlcResTimerRef} = timer:apply_interval(timer:hms(0, 5, 0),
  1404. sbgEstSupport, collect_plc_res, [Plc]),
  1405. start_collect_system_infos(T,
  1406. [{sgc1_ch, SysInfoTimerRef, PlcResTimerRef} | Res]);
  1407.  
  1408. start_collect_system_infos([{sgc1_om, {Sys, VmStat, Plc}} | T], Res) ->
  1409. {ok, SysInfoTimerRef} = timer:apply_interval(timer:hms(0, 2, 0),
  1410. ?MODULE, collect_system_info, [sgc1_om, Sys, VmStat]),
  1411. {ok, PlcResTimerRef} = timer:apply_interval(timer:hms(0, 5, 0),
  1412. sbgEstSupport, collect_plc_res, [Plc]),
  1413. start_collect_system_infos(T, [{sgc1_om, SysInfoTimerRef, PlcResTimerRef} | Res]);
  1414.  
  1415. start_collect_system_infos([{ommp_ch, {Sys, VmStat, Plc}} | T], Res) ->
  1416. {ok, SysInfoTimerRef} = timer:apply_interval(timer:hms(0, 2, 0),
  1417. ?MODULE, collect_system_info, [ommp_ch, Sys, VmStat]),
  1418. {ok, PlcResTimerRef} = timer:apply_interval(timer:hms(0, 5, 0),
  1419. sbgEstSupport, collect_plc_res, [Plc]),
  1420. start_collect_system_infos(T, [{ommp_ch, SysInfoTimerRef, PlcResTimerRef} | Res]);
  1421.  
  1422. start_collect_system_infos([{ommp_om, {Sys, VmStat, Plc}} | T], Res) ->
  1423. {ok, SysInfoTimerRef} = timer:apply_interval(timer:hms(0, 2, 0),
  1424. ?MODULE, collect_system_info, [ommp_om, Sys, VmStat]),
  1425. {ok, PlcResTimerRef} = timer:apply_interval(timer:hms(0, 5, 0),
  1426. sbgEstSupport, collect_plc_res, [Plc]),
  1427. start_collect_system_infos(T, [{ommp_om, SysInfoTimerRef, PlcResTimerRef} | Res]).
  1428.  
  1429.  
  1430. -define(BLADES, [
  1431. {sgc1_ch, ?SGCchNode},
  1432. {sgc1_om, ?SGComNode},
  1433. {ommp_ch, ?SBGchNode},
  1434. {ommp_om, ?SBGomNode}
  1435. ]).
  1436. collect_system_info(BladeType, SysInfo_Filename, Vmstat_Filename) ->
  1437. case proplists:get_value(BladeType, ?BLADES) of
  1438. undefined ->
  1439. ct:pal("The BladeType is wrong, pleaea refer: ~p~n", [?BLADES]);
  1440. Node ->
  1441. io:format("data is collecting, node:~p~n", [Node]),
  1442. Mem_result = jpTrpc:call(Node, ets, tab2list, [plcInfo]),
  1443. ProcessNum = length(jpTrpc:call(Node, erlang, processes, [])),
  1444. Result = lists:sort(Mem_result ++ [{process_Num, ProcessNum}]),
  1445.  
  1446. {ok, File_handler} = file:open(SysInfo_Filename, [append]),
  1447. io:format(File_handler, "~p~n", [Result]),
  1448. ok = file:close(File_handler),
  1449.  
  1450. VmCmd = "vmstat 5 5 >>" ++ Vmstat_Filename,
  1451. jpTrpc:call(Node, os, cmd, [VmCmd])
  1452. end.
  1453.  
  1454.  
  1455.  
  1456. %% -----------------------------------------------------------------------
  1457. %% @spec stop_collect_system_infos(Input :: lists()) -> lists()
  1458. %% @doc Stop collecting the logs.<br></br>
  1459. %% <strong>Note</strong>: The input parameter of this function is the result of <code>sbgEstSupport:start_collect_system_infos/1</code>.
  1460. %% @end
  1461. %% -----------------------------------------------------------------------
  1462. stop_collect_system_infos(TimerRefs) ->
  1463. Fun = fun({BladeType, SysTimerRef, PlcTimerRef}) ->
  1464. ct:pal("stop_collect_system_infos: ~p ~p ~p~n",
  1465. [BladeType, SysTimerRef, PlcTimerRef]),
  1466. timer:cancel(SysTimerRef),
  1467. timer:cancel(PlcTimerRef)
  1468. end,
  1469. lists:foreach(Fun, TimerRefs).
  1470.  
  1471.  
  1472. %% -----------------------------------------------------------------------
  1473. %% @spec generate_log_statistics(FileInfos :: lists(), UacStatFile :: string(), UasStatFile :: string(), BladeType :: atom()) -> ok
  1474. %% @doc Analyse the log files and draw graph.<br></br>
  1475. %% <pre>
  1476. %% <strong>Note</strong>:
  1477. %% FileInfos is the result of sbgEstSupport:prepare_systeminfo_filenames/1.
  1478. %% UacStatFile can get from the result of sbgEstSupport:prepare_sipp_cmd/3.
  1479. %% UasStatFile can get from the result of sbgEstSupport:prepare_sipp_cmd/3.
  1480. %% BladeType sgc1_ch | sgc1_om | ommp_ch | ommp_om
  1481. %% </pre>
  1482. %% @end
  1483. %% -----------------------------------------------------------------------
  1484. generate_log_statistics(FileInfos, UacStatFile, UasStatFile, BladeType)
  1485. when is_atom(BladeType) andalso is_list(FileInfos) ->
  1486. case proplists:get_value(BladeType, FileInfos) of
  1487. {SysInfo, VmState, _PlcInfo} ->
  1488. ct:pal("generate_log_statistics for blade: ~p~n", [BladeType]),
  1489. %% --- transfer the collected vmstat file to LMWP ---
  1490. Local_Vmstat = sbgEstSupport:transfer_vmstat_file(VmState, sgc1, ch),
  1491.  
  1492. timer:sleep(60000),
  1493.  
  1494. %% ------ script to draw graph need to be updated-----
  1495. SysInfo_Svg = sbgEstSupport:draw_graph(SysInfo, sysinfo),
  1496. Vmstat_Svg = sbgEstSupport:draw_graph(Local_Vmstat, vmstat),
  1497. Uac_Svg = sbgEstSupport:draw_graph(UacStatFile, passrate),
  1498. Uas_Svg = sbgEstSupport:draw_graph(UasStatFile, passrate),
  1499. timer:sleep(60000),
  1500.  
  1501. %% --- generate graph on jpt log page
  1502. sbgEstSupport:generate_graph_on_log_html(SysInfo_Svg, Vmstat_Svg,
  1503. Uac_Svg, Uas_Svg);
  1504. undefined ->
  1505. ct:pal("generate_log_statistics: The fourth parameter should be atom: sgc1_ch, sgc1_om, ommp_ch, ommp_om.~n")
  1506. end;
  1507. generate_log_statistics(_, _, _, _) ->
  1508. ct:pal("generate_log_statistics: The input parameters are wrong, the fourth should be atom: sgc1_ch, sgc1_om, ommp_ch, ommp_om.~n").
  1509.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
/home/qmTVjQ/prog.beam: Module name 'sbgEstSupport' does not match file name 'prog'
prog.erl:476: Warning: function run_scenario/4 is unused
prog.erl:661: Warning: function prepare_env/0 is unused
prog.erl:670: Warning: function fallback_env/0 is unused
prog.erl:674: Warning: function prepare_systeminfo_filename/3 is unused
prog.erl:714: Warning: function collect_system_info/4 is unused
prog.erl:762: Warning: function collect_plc_res/1 is unused
prog.erl:768: Warning: function transfer_vmstat_file/3 is unused
prog.erl:777: Warning: function get_blade_no/2 is unused
prog.erl:790: Warning: function scp_from/5 is unused
prog.erl:827: Warning: function get_all_counter/0 is unused
prog.erl:834: Warning: function count/1 is unused
prog.erl:861: Warning: function reg_count/2 is unused
prog.erl:866: Warning: function draw_graph/2 is unused
prog.erl:893: Warning: function generate_html/4 is unused
prog.erl:898: Warning: function generate_graph_on_log_html/4 is unused
prog.erl:910: Warning: function gen_html_format/1 is unused
prog.erl:999: Warning: function close_monitor/2 is unused
prog.erl:1150: Warning: function close_sipp/0 is unused
prog.erl:1157: Warning: function check_sipp_process_status/2 is unused
prog.erl:1163: Warning: function check_sipp_call_status/2 is unused
prog.erl:1218: Warning: function get_stat_tail/1 is unused
prog.erl:1230: Warning: function get_stat_head/1 is unused
prog.erl:1249: Warning: function convert_datatype/1 is unused
prog.erl:1262: Warning: function split_statistics/2 is unused
prog.erl:1265: Warning: function split_statistics/3 is unused
prog.erl:1312: Warning: function to_number/1 is unused
prog.erl:1436: Warning: function collect_system_info/3 is unused
stdout
Standard output is empty