benchmark.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. /**
  17. * Page designed to help in benchmarkink the scalability of itop
  18. *
  19. * @author Erwan Taloc <erwan.taloc@combodo.com>
  20. * @author Romain Quetiez <romain.quetiez@combodo.com>
  21. * @author Denis Flaven <denis.flaven@combodo.com>
  22. * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
  23. */
  24. require_once('../application/application.inc.php');
  25. require_once('../application/itopwebpage.class.inc.php');
  26. require_once('../application/wizardhelper.class.inc.php');
  27. require_once('../application/startup.inc.php');
  28. require_once('../application/loginwebpage.class.inc.php');
  29. require_once('../application/utils.inc.php');
  30. require_once('./setuppage.class.inc.php');
  31. class BenchmarkDataCreation
  32. {
  33. var $m_aPlanned = array();
  34. var $m_aCreated = array();
  35. var $m_aStatsByClass = array();
  36. public function __construct($iPlannedCIs, $iPlannedContacts, $iPlannedContracts)
  37. {
  38. $this->m_aPlanned = array(
  39. 'CIs' => $iPlannedCIs,
  40. 'Contacts' => $iPlannedContacts,
  41. 'Contracts' => $iPlannedContracts,
  42. 'SubCIs' => 10 * $iPlannedCIs,
  43. 'Incidents' => 2 * 12 * $iPlannedCIs,
  44. 'ServiceCalls' => 1 * 12 * $iPlannedContacts,
  45. 'Changes' => 1 * 12 * $iPlannedCIs,
  46. 'Documents' => 12 * $iPlannedContracts + $iPlannedCIs,
  47. );
  48. }
  49. public function GetPlan()
  50. {
  51. return $this->m_aPlanned;
  52. }
  53. protected function CreateObject($sClass, $aData, $oChange)
  54. {
  55. $mu_t1 = MyHelpers::getmicrotime();
  56. $oMyObject = MetaModel::NewObject($sClass);
  57. foreach($aData as $sProp => $value)
  58. {
  59. $oMyObject->Set($sProp, $value);
  60. }
  61. $iId = $oMyObject->DBInsertTrackedNoReload($oChange);
  62. $this->m_aCreated[$sClass][] = $iId;
  63. $mu_t2 = MyHelpers::getmicrotime();
  64. $this->m_aStatsByClass[$sClass][] = $mu_t2 - $mu_t1;
  65. return $iId;
  66. }
  67. protected function RandomId($sClass)
  68. {
  69. return $this->m_aCreated[$sClass][array_rand($this->m_aCreated[$sClass])];
  70. }
  71. protected function MakeFeedback($oP, $sClass)
  72. {
  73. $iSample = reset($this->m_aCreated[$sClass]);
  74. $sSample = "<a href=\"../pages/UI.php?operation=details&class=$sClass&id=$iSample\">sample</a>";
  75. $iDuration = number_format(array_sum($this->m_aStatsByClass[$sClass]), 3);
  76. $fDurationMin = number_format(min($this->m_aStatsByClass[$sClass]), 3);
  77. $fDurationMax = number_format(max($this->m_aStatsByClass[$sClass]), 3);
  78. $fDurationAverage = number_format(array_sum($this->m_aStatsByClass[$sClass]) / count($this->m_aStatsByClass[$sClass]), 3);
  79. $oP->add("<ul>");
  80. $oP->add("<li>");
  81. $oP->add("$sClass: ".count($this->m_aCreated[$sClass])." - $sSample<br/>");
  82. $oP->add("Duration: $fDurationMin =&gt; $fDurationMax; Avg:$fDurationAverage; Total: $iDuration");
  83. $oP->add("</li>");
  84. $oP->add("</ul>");
  85. }
  86. public function Go(WebPage $oP, $oChange)
  87. {
  88. // 1 - Organizations
  89. //
  90. $aData = array(
  91. 'name' => 'benchmark',
  92. );
  93. $iOrg = $this->CreateObject('bizOrganization', $aData, $oChange);
  94. $this->MakeFeedback($oP, 'bizOrganization');
  95. // 2 - Locations
  96. //
  97. $aData = array(
  98. 'org_id' => $iOrg,
  99. 'name' => 'rio',
  100. );
  101. $iLoc = $this->CreateObject('bizLocation', $aData, $oChange);
  102. $this->MakeFeedback($oP, 'bizLocation');
  103. // 3 - Teams
  104. //
  105. $aData = array(
  106. 'org_id' => $iOrg,
  107. 'location_id' => $iLoc,
  108. 'name' => 'fluminense',
  109. );
  110. $iTeam = $this->CreateObject('bizTeam', $aData, $oChange);
  111. $this->MakeFeedback($oP, 'bizTeam');
  112. // 3' - Workgroups
  113. //
  114. $iAnyTeam = $this->RandomId('bizTeam');
  115. $aData = array(
  116. 'org_id' => $iOrg,
  117. 'team_id' => $iAnyTeam,
  118. 'name' => 'trabolhogrupo'.$iAnyTeam,
  119. );
  120. $iTeam = $this->CreateObject('bizWorkgroup', $aData, $oChange);
  121. $this->MakeFeedback($oP, 'bizWorkgroup');
  122. // 4 - Persons
  123. //
  124. for($i = 0 ; $i < $this->m_aPlanned['Contacts'] ; $i++)
  125. {
  126. $aData = array(
  127. 'org_id' => $iOrg,
  128. 'location_id' => $iLoc,
  129. 'name' => 'ningem'.$i,
  130. );
  131. $this->CreateObject('bizPerson', $aData, $oChange);
  132. }
  133. $this->MakeFeedback($oP, 'bizPerson');
  134. // 5 - Servers
  135. //
  136. for($i = 0 ; $i < $this->m_aPlanned['CIs'] ; $i++)
  137. {
  138. $aData = array(
  139. 'org_id' => $iOrg,
  140. 'location_id' => $iLoc,
  141. 'name' => 'server'.$i,
  142. );
  143. $this->CreateObject('bizServer', $aData, $oChange);
  144. }
  145. $this->MakeFeedback($oP, 'bizServer');
  146. // 6 - Incident Tickets
  147. //
  148. for($i = 0 ; $i < $this->m_aPlanned['Incidents'] ; $i++)
  149. {
  150. $aData = array(
  151. 'org_id' => $iOrg,
  152. 'caller_id' => $this->RandomId('bizPerson'),
  153. 'workgroup_id' => $this->RandomId('bizWorkgroup'),
  154. 'agent_id' => $this->RandomId('bizPerson'),
  155. 'title' => 'someevent'.$i,
  156. );
  157. $iTicket = $this->CreateObject('bizIncidentTicket', $aData, $oChange);
  158. // Incident/Infra
  159. //
  160. $iInfraCount = rand(0, 6);
  161. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  162. {
  163. $aData = array(
  164. 'infra_id' => $this->RandomId('bizServer'),
  165. 'ticket_id' => $iTicket,
  166. 'impact' => 'info on impact '.$iLinked,
  167. );
  168. $this->CreateObject('lnkInfraTicket', $aData, $oChange);
  169. }
  170. // Incident/Contact
  171. //
  172. $iInfraCount = rand(0, 6);
  173. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  174. {
  175. $aData = array(
  176. 'contact_id' => $this->RandomId('bizPerson'),
  177. 'ticket_id' => $iTicket,
  178. 'role' => 'role '.$iLinked,
  179. );
  180. $this->CreateObject('lnkContactTicket', $aData, $oChange);
  181. }
  182. }
  183. $this->MakeFeedback($oP, 'bizIncidentTicket');
  184. // 7 - Change Tickets
  185. //
  186. for($i = 0 ; $i < $this->m_aPlanned['Changes'] ; $i++)
  187. {
  188. $aData = array(
  189. 'org_id' => $iOrg,
  190. 'requestor_id' => $this->RandomId('bizPerson'),
  191. 'workgroup_id' => $this->RandomId('bizWorkgroup'),
  192. 'agent_id' => $this->RandomId('bizPerson'),
  193. 'supervisorgroup_id' => $this->RandomId('bizWorkgroup'),
  194. 'supervisor_id' => $this->RandomId('bizPerson'),
  195. 'managergroup_id' => $this->RandomId('bizWorkgroup'),
  196. 'manager_id' => $this->RandomId('bizPerson'),
  197. 'title' => "change$i",
  198. );
  199. $iTicket = $this->CreateObject('bizChangeTicket', $aData, $oChange);
  200. // Change/Infra
  201. //
  202. $iInfraCount = rand(0, 6);
  203. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  204. {
  205. $aData = array(
  206. 'infra_id' => $this->RandomId('bizServer'),
  207. 'ticket_id' => $iTicket,
  208. 'impact' => 'info on impact '.$iLinked,
  209. );
  210. $this->CreateObject('lnkInfraChangeTicket', $aData, $oChange);
  211. }
  212. // Change/Contact
  213. //
  214. $iInfraCount = rand(0, 6);
  215. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  216. {
  217. $aData = array(
  218. 'contact_id' => $this->RandomId('bizPerson'),
  219. 'change_id' => $iTicket,
  220. 'role' => 'role '.$iLinked,
  221. );
  222. $this->CreateObject('lnkContactChange', $aData, $oChange);
  223. }
  224. }
  225. $this->MakeFeedback($oP, 'bizChangeTicket');
  226. // 8 - Service calls
  227. //
  228. for($i = 0 ; $i < $this->m_aPlanned['ServiceCalls'] ; $i++)
  229. {
  230. $aData = array(
  231. 'org_id' => $iOrg,
  232. 'caller_id' => $this->RandomId('bizPerson'),
  233. 'workgroup_id' => $this->RandomId('bizWorkgroup'),
  234. 'agent_id' => $this->RandomId('bizPerson'),
  235. 'title' => "call$i",
  236. );
  237. $iTicket = $this->CreateObject('bizServiceCall', $aData, $oChange);
  238. // Call/Infra
  239. //
  240. $iInfraCount = rand(0, 6);
  241. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  242. {
  243. $aData = array(
  244. 'infra_id' => $this->RandomId('bizServer'),
  245. 'call_id' => $iTicket,
  246. 'impact' => 'info on impact '.$iLinked,
  247. );
  248. $this->CreateObject('lnkInfraCall', $aData, $oChange);
  249. }
  250. }
  251. $this->MakeFeedback($oP, 'bizServiceCall');
  252. // 8 - Documents
  253. //
  254. $sMyDoc = '';
  255. for($i = 0 ; $i < 1000 ; $i++)
  256. {
  257. // 100 chars
  258. $sMyDoc .= "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n";
  259. }
  260. $oRefDoc = new ormDocument($sMyDoc, 'text/plain');
  261. for($i = 0 ; $i < $this->m_aPlanned['Documents'] ; $i++)
  262. {
  263. $aData = array(
  264. 'org_id' => $iOrg,
  265. 'name' => "document$i",
  266. 'contents' => $oRefDoc,
  267. );
  268. $this->CreateObject('bizDocument', $aData, $oChange);
  269. }
  270. $this->MakeFeedback($oP, 'bizDocument');
  271. }
  272. }
  273. /**
  274. * Ask the user what are the settings for the data load
  275. */
  276. function DisplayStep1(SetupWebPage $oP)
  277. {
  278. $sNextOperation = 'step2';
  279. $oP->add("<h1>iTop benchmarking</h1>\n");
  280. $oP->add("<h2>Please specify the requested volumes</h2>\n");
  281. $oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Evaluating real plans...', 10)\">\n");
  282. $oP->add("<fieldset><legend>Data load configuration</legend>\n");
  283. $aForm = array();
  284. $aForm[] = array(
  285. 'label' => "Main CIs:",
  286. 'input' => "<input id=\"to\" type=\"text\" name=\"plannedcis\" value=\"70\">",
  287. 'help' => ' exclude interfaces, subnets or any other type of secondary CI',
  288. );
  289. $aForm[] = array(
  290. 'label' => "Contacts:",
  291. 'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontacts\" value=\"100\">",
  292. 'help' => '',
  293. );
  294. $aForm[] = array(
  295. 'label' => "Contracts:",
  296. 'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontracts\" value=\"10\">",
  297. 'help' => '',
  298. );
  299. $oP->form($aForm);
  300. $oP->add("</fieldset>\n");
  301. $oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
  302. $oP->add("<button type=\"submit\">Next >></button>\n");
  303. $oP->add("</form>\n");
  304. }
  305. /**
  306. * Inform the user how many items will be created
  307. */
  308. function DisplayStep2(SetupWebPage $oP, $oDataCreation)
  309. {
  310. $sNextOperation = 'step3';
  311. $oP->add("<h1>iTop benchmarking</h1>\n");
  312. $oP->add("<h2>Step 2: review planned volumes</h2>\n");
  313. $aPlanned = $oDataCreation->GetPlan();
  314. $aForm = array();
  315. foreach ($aPlanned as $sKey => $iCount)
  316. {
  317. $aForm[] = array(
  318. 'label' => $sKey,
  319. 'input' => $iCount,
  320. );
  321. }
  322. $oP->form($aForm);
  323. $oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Loading data...', 10)\">\n");
  324. $oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
  325. $oP->add("<input type=\"hidden\" name=\"plannedcis\" value=\"".$aPlanned['CIs']."\">\n");
  326. $oP->add("<input type=\"hidden\" name=\"plannedcontacts\" value=\"".$aPlanned['Contacts']."\">\n");
  327. $oP->add("<input type=\"hidden\" name=\"plannedcontracts\" value=\"".$aPlanned['Contracts']."\">\n");
  328. $oP->add("<button type=\"submit\">Next >></button>\n");
  329. $oP->add("</form>\n");
  330. }
  331. /**
  332. * Do create the data set... could take some time to execute
  333. */
  334. function DisplayStep3(SetupWebPage $oP, $oDataCreation)
  335. {
  336. // $sNextOperation = 'step3';
  337. $oMyChange = MetaModel::NewObject("CMDBChange");
  338. $oMyChange->Set("date", time());
  339. $oMyChange->Set("userinfo", "Administrator");
  340. $iChangeId = $oMyChange->DBInsertNoReload();
  341. $oDataCreation->Go($oP, $oMyChange);
  342. }
  343. /**
  344. * Main program
  345. */
  346. LoginWebPage::DoLogin(); // Check user rights and prompt if needed
  347. $sOperation = Utils::ReadParam('operation', 'step1');
  348. $oP = new SetupWebPage('iTop benchmark utility');
  349. try
  350. {
  351. switch($sOperation)
  352. {
  353. case 'step1':
  354. DisplayStep1($oP);
  355. break;
  356. case 'step2':
  357. $oP->no_cache();
  358. $iPlannedCIs = Utils::ReadParam('plannedcis');
  359. $iPlannedContacts = Utils::ReadParam('plannedcontacts');
  360. $iPlannedContracts = Utils::ReadParam('plannedcontracts');
  361. $oDataCreation = new BenchmarkDataCreation($iPlannedCIs, $iPlannedContacts, $iPlannedContracts);
  362. DisplayStep2($oP, $oDataCreation);
  363. break;
  364. case 'step3':
  365. $oP->no_cache();
  366. $iPlannedCIs = Utils::ReadParam('plannedcis');
  367. $iPlannedContacts = Utils::ReadParam('plannedcontacts');
  368. $iPlannedContracts = Utils::ReadParam('plannedcontracts');
  369. $oDataCreation = new BenchmarkDataCreation($iPlannedCIs, $iPlannedContacts, $iPlannedContracts);
  370. DisplayStep3($oP, $oDataCreation);
  371. break;
  372. default:
  373. $oP->error("Error: unsupported operation '$sOperation'");
  374. }
  375. }
  376. catch(ZZException $e)
  377. {
  378. $oP->error("Error: '".$e->getMessage()."'");
  379. }
  380. catch(ZZCoreException $e)
  381. {
  382. $oP->error("Error: '".$e->getHtmlDesc()."'");
  383. }
  384. $oP->output();
  385. ?>