benchmark.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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_aRequested;
  34. var $m_aPlanned;
  35. var $m_aCreated = array();
  36. var $m_aStatsByClass = array();
  37. public function __construct($iPlannedCIs, $iPlannedContacts, $iPlannedContracts)
  38. {
  39. $this->m_aRequested = array(
  40. 'CIs' => $iPlannedCIs,
  41. 'Contacts' => $iPlannedContacts,
  42. 'Contracts' => $iPlannedContracts,
  43. );
  44. $this->m_aPlanned = array(
  45. 'Network devices' => ceil($iPlannedCIs / 2),
  46. 'Servers' => ceil($iPlannedCIs / 2),
  47. 'Interfaces' => 10 * $iPlannedCIs,
  48. 'Contacts' => $iPlannedContacts,
  49. 'Contracts' => $iPlannedContracts,
  50. 'Incidents' => 2 * 12 * $iPlannedCIs,
  51. 'ServiceCalls' => 1 * 12 * $iPlannedContacts,
  52. 'Changes' => 1 * 12 * $iPlannedCIs,
  53. 'Documents' => 12 * $iPlannedContracts + $iPlannedCIs,
  54. );
  55. }
  56. public function GetPlans()
  57. {
  58. return $this->m_aPlanned;
  59. }
  60. public function GetRequestInfo()
  61. {
  62. return $this->m_aRequested;
  63. }
  64. protected function CreateObject($sClass, $aData, $oChange)
  65. {
  66. $mu_t1 = MyHelpers::getmicrotime();
  67. $oMyObject = MetaModel::NewObject($sClass);
  68. foreach($aData as $sProp => $value)
  69. {
  70. $oMyObject->Set($sProp, $value);
  71. }
  72. $iId = $oMyObject->DBInsertTrackedNoReload($oChange);
  73. $this->m_aCreated[$sClass][] = $iId;
  74. $mu_t2 = MyHelpers::getmicrotime();
  75. $this->m_aStatsByClass[$sClass][] = $mu_t2 - $mu_t1;
  76. return $iId;
  77. }
  78. protected function RandomId($sClass)
  79. {
  80. return $this->m_aCreated[$sClass][array_rand($this->m_aCreated[$sClass])];
  81. }
  82. static protected function FindId($sClass)
  83. {
  84. $oSet = new DBObjectSet(new DBObjectSearch($sClass));
  85. if ($oSet->Count() < 1)
  86. {
  87. return null;
  88. }
  89. $oObj = $oSet->Fetch();
  90. return $oObj->GetKey();
  91. }
  92. static protected function FindIdFromOQL($sOQL)
  93. {
  94. $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL));
  95. if ($oSet->Count() < 1)
  96. {
  97. return null;
  98. }
  99. $oObj = $oSet->Fetch();
  100. return $oObj->GetKey();
  101. }
  102. protected function MakeFeedback($oP, $sClass)
  103. {
  104. $iSample = reset($this->m_aCreated[$sClass]);
  105. $sSample = "<a href=\"../pages/UI.php?operation=details&class=$sClass&id=$iSample\">sample</a>";
  106. $iDuration = number_format(array_sum($this->m_aStatsByClass[$sClass]), 3);
  107. $fDurationMin = number_format(min($this->m_aStatsByClass[$sClass]), 3);
  108. $fDurationMax = number_format(max($this->m_aStatsByClass[$sClass]), 3);
  109. $fDurationAverage = number_format(array_sum($this->m_aStatsByClass[$sClass]) / count($this->m_aStatsByClass[$sClass]), 3);
  110. $oP->add("<ul>");
  111. $oP->add("<li>");
  112. $oP->add("$sClass: ".count($this->m_aCreated[$sClass])." - $sSample<br/>");
  113. $oP->add("Duration: $fDurationMin =&gt; $fDurationMax; Avg:$fDurationAverage; Total: $iDuration");
  114. $oP->add("</li>");
  115. $oP->add("</ul>");
  116. }
  117. public function GoProjections(WebPage $oP, $oChange)
  118. {
  119. // User login
  120. //
  121. $aData = array(
  122. 'contactid' => self::FindId('Person'),
  123. 'login' => 'foo',
  124. 'password' => 'foo',
  125. 'language' => 'EN US',
  126. );
  127. $iLogin = $this->CreateObject('UserLocal', $aData, $oChange);
  128. // Assign profiles to the new login
  129. //
  130. $aData = array(
  131. 'userid' => $iLogin,
  132. 'profileid' => self::FindIdFromOQL("SELECT URP_Profiles WHERE name LIKE 'Configuration Manager'"),
  133. 'reason' => '',
  134. );
  135. $iFoo = $this->CreateObject('URP_UserProfile', $aData, $oChange);
  136. // Dimension
  137. //
  138. $aData = array(
  139. 'name' => 'location',
  140. 'description' => '',
  141. 'type' => 'Location',
  142. );
  143. $iDimLocation = $this->CreateObject('URP_Dimensions', $aData, $oChange);
  144. // Project classes
  145. //
  146. $aMyClassesToProject = array('NetworkDevice', 'Server');
  147. foreach($aMyClassesToProject as $sClass)
  148. {
  149. $aData = array(
  150. 'dimensionid' => $iDimLocation,
  151. 'class' => $sClass,
  152. 'value' => '<this>',
  153. 'attribute' => 'location_name',
  154. );
  155. $iFoo = $this->CreateObject('URP_ClassProjection', $aData, $oChange);
  156. }
  157. // Project profiles
  158. //
  159. $aProfilesToProject = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
  160. foreach($aProfilesToProject as $iProfileId)
  161. {
  162. $aData = array(
  163. 'dimensionid' => $iDimLocation,
  164. 'profileid' => $iProfileId,
  165. 'value' => 'Grenoble',
  166. 'attribute' => '',
  167. );
  168. $iFoo = $this->CreateObject('URP_ProfileProjection', $aData, $oChange);
  169. }
  170. $oP->p('Created projections (Cf. login "foo", pwd "foo")');
  171. }
  172. public function GoVolume(WebPage $oP, $oChange)
  173. {
  174. /////////////////////////
  175. //
  176. // Organizations
  177. //
  178. $aData = array(
  179. 'name' => 'Benchmark',
  180. );
  181. $iOrg = $this->CreateObject('Organization', $aData, $oChange);
  182. $this->MakeFeedback($oP, 'Organization');
  183. /////////////////////////
  184. //
  185. // Locations
  186. //
  187. $aData = array(
  188. 'org_id' => $iOrg,
  189. 'name' => 'Rio',
  190. );
  191. $iLoc = $this->CreateObject('Location', $aData, $oChange);
  192. $this->MakeFeedback($oP, 'Location');
  193. /////////////////////////
  194. //
  195. // Teams
  196. //
  197. $aData = array(
  198. 'org_id' => $iOrg,
  199. 'location_id' => $iLoc,
  200. 'name' => 'Fluminense',
  201. 'email' => 'fluminense@nowhere.fr',
  202. );
  203. $iTeam = $this->CreateObject('Team', $aData, $oChange);
  204. $this->MakeFeedback($oP, 'Team');
  205. /////////////////////////
  206. //
  207. // Persons
  208. //
  209. for($i = 0 ; $i < $this->m_aPlanned['Contacts'] ; $i++)
  210. {
  211. $aData = array(
  212. 'org_id' => $iOrg,
  213. 'location_id' => $iLoc,
  214. 'first_name' => 'Joaõ',
  215. 'name' => 'Ningem #'.$i,
  216. 'email' => 'foo'.$i.'@nowhere.fr',
  217. );
  218. $this->CreateObject('Person', $aData, $oChange);
  219. }
  220. $this->MakeFeedback($oP, 'Person');
  221. /////////////////////////
  222. //
  223. // Services
  224. //
  225. $aData = array(
  226. 'name' => 'My Service',
  227. );
  228. $iOrg = $this->CreateObject('Service', $aData, $oChange);
  229. $this->MakeFeedback($oP, 'Service');
  230. /////////////////////////
  231. //
  232. // Service subcategories
  233. //
  234. $aData = array(
  235. 'name' => 'My subcategory',
  236. );
  237. $iOrg = $this->CreateObject('ServiceSubcategory', $aData, $oChange);
  238. $this->MakeFeedback($oP, 'ServiceSubcategory');
  239. /////////////////////////
  240. //
  241. // Contracts
  242. //
  243. for($i = 0 ; $i < $this->m_aPlanned['Contracts'] ; $i++)
  244. {
  245. $aData = array(
  246. 'name' => "Contract #$i",
  247. 'description' => 'Created for benchmarking purposes',
  248. 'org_id' => $this->RandomId('Organization'),
  249. 'provider_id' => $this->RandomId('Organization'),
  250. 'start_date' => '2009-12-25',
  251. 'end_date' => '2019-08-01',
  252. 'support_team_id' => $this->RandomId('Team'),
  253. );
  254. $iContract = $this->CreateObject('CustomerContract', $aData, $oChange);
  255. }
  256. $this->MakeFeedback($oP, 'CustomerContract');
  257. /////////////////////////
  258. //
  259. // Servers
  260. //
  261. for($i = 0 ; $i < $this->m_aPlanned['Servers'] ; $i++)
  262. {
  263. $aData = array(
  264. 'org_id' => $iOrg,
  265. 'location_id' => $iLoc,
  266. 'name' => 'server'.$i,
  267. );
  268. $iServer = $this->CreateObject('Server', $aData, $oChange);
  269. // Contract/Infra
  270. //
  271. $iContractCount = 1;
  272. for($iLinked = 0 ; $iLinked < $iContractCount ; $iLinked++)
  273. {
  274. $aData = array(
  275. 'contract_id' => $this->RandomId('CustomerContract'),
  276. 'ci_id' => $iServer,
  277. );
  278. $this->CreateObject('lnkContractToCI', $aData, $oChange);
  279. }
  280. // Interfaces
  281. //
  282. $iInterfaceCount = 5; // See how aPlanned['Interfaces'] is computed
  283. for($iLinked = 0 ; $iLinked < $iInterfaceCount ; $iLinked++)
  284. {
  285. $aData = array(
  286. 'name' => "eth$iLinked",
  287. 'status' => 'implementation',
  288. 'org_id' => $iOrg,
  289. 'device_id' => $iServer,
  290. );
  291. $this->CreateObject('NetworkInterface', $aData, $oChange);
  292. }
  293. }
  294. $this->MakeFeedback($oP, 'Server');
  295. /////////////////////////
  296. //
  297. // Network devices
  298. //
  299. for($i = 0 ; $i < $this->m_aPlanned['Network devices'] ; $i++)
  300. {
  301. $aData = array(
  302. 'org_id' => $iOrg,
  303. 'location_id' => $iLoc,
  304. 'name' => 'server'.$i,
  305. );
  306. $iNWDevice = $this->CreateObject('NetworkDevice', $aData, $oChange);
  307. // Contract/Infra
  308. //
  309. $iContractCount = 1;
  310. for($iLinked = 0 ; $iLinked < $iContractCount ; $iLinked++)
  311. {
  312. $aData = array(
  313. 'contract_id' => $this->RandomId('CustomerContract'),
  314. 'ci_id' => $iNWDevice,
  315. );
  316. $this->CreateObject('lnkContractToCI', $aData, $oChange);
  317. }
  318. // Interfaces
  319. //
  320. $iInterfaceCount = 5; // See how aPlanned['Interfaces'] is computed
  321. for($iLinked = 0 ; $iLinked < $iInterfaceCount ; $iLinked++)
  322. {
  323. $aData = array(
  324. 'name' => "eth$iLinked",
  325. 'status' => 'implementation',
  326. 'org_id' => $iOrg,
  327. 'device_id' => $iNWDevice,
  328. );
  329. $this->CreateObject('NetworkInterface', $aData, $oChange);
  330. }
  331. }
  332. $this->MakeFeedback($oP, 'NetworkDevice');
  333. $this->MakeFeedback($oP, 'NetworkInterface');
  334. /////////////////////////
  335. //
  336. // Incident Tickets
  337. //
  338. for($i = 0 ; $i < $this->m_aPlanned['Incidents'] ; $i++)
  339. {
  340. $aData = array(
  341. 'org_id' => $iOrg,
  342. 'caller_id' => $this->RandomId('Person'),
  343. 'workgroup_id' => $this->RandomId('Team'),
  344. 'agent_id' => $this->RandomId('Person'),
  345. 'service_id' => $this->RandomId('Service'),
  346. 'servicesubcategory_id' => $this->RandomId('ServiceSubcategory'),
  347. 'title' => 'Incident #'.$i,
  348. 'ticket_log' => 'Testing...',
  349. );
  350. $iTicket = $this->CreateObject('Incident', $aData, $oChange);
  351. // Incident/Infra
  352. //
  353. $iInfraCount = rand(0, 6);
  354. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  355. {
  356. $aData = array(
  357. 'ci_id' => $this->RandomId('Server'),
  358. 'ticket_id' => $iTicket,
  359. );
  360. $this->CreateObject('lnkTicketToCI', $aData, $oChange);
  361. }
  362. // Incident/Contact
  363. //
  364. $iInfraCount = rand(0, 6);
  365. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  366. {
  367. $aData = array(
  368. 'contact_id' => $this->RandomId('Person'),
  369. 'ticket_id' => $iTicket,
  370. 'role' => 'role '.$iLinked,
  371. );
  372. $this->CreateObject('lnkTicketToContact', $aData, $oChange);
  373. }
  374. }
  375. $this->MakeFeedback($oP, 'Incident');
  376. /////////////////////////
  377. //
  378. // Change Tickets
  379. //
  380. for($i = 0 ; $i < $this->m_aPlanned['Changes'] ; $i++)
  381. {
  382. $aData = array(
  383. 'org_id' => $iOrg,
  384. 'requestor_id' => $this->RandomId('Person'),
  385. 'workgroup_id' => $this->RandomId('Team'),
  386. 'agent_id' => $this->RandomId('Person'),
  387. 'supervisor_group_id' => $this->RandomId('Team'),
  388. 'supervisor_id' => $this->RandomId('Person'),
  389. 'manager_group_id' => $this->RandomId('Team'),
  390. 'manager_id' => $this->RandomId('Person'),
  391. 'title' => 'change #'.$i,
  392. 'description' => "Let's do something there",
  393. );
  394. $iTicket = $this->CreateObject('NormalChange', $aData, $oChange);
  395. // Change/Infra
  396. //
  397. $iInfraCount = rand(0, 6);
  398. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  399. {
  400. $aData = array(
  401. 'ci_id' => $this->RandomId('Server'),
  402. 'ticket_id' => $iTicket,
  403. );
  404. $this->CreateObject('lnkTicketToCI', $aData, $oChange);
  405. }
  406. // Change/Contact
  407. //
  408. $iInfraCount = rand(0, 6);
  409. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  410. {
  411. $aData = array(
  412. 'contact_id' => $this->RandomId('Person'),
  413. 'ticket_id' => $iTicket,
  414. 'role' => 'role '.$iLinked,
  415. );
  416. $this->CreateObject('lnkTicketToContact', $aData, $oChange);
  417. }
  418. }
  419. $this->MakeFeedback($oP, 'NormalChange');
  420. /////////////////////////
  421. //
  422. // Service calls
  423. //
  424. for($i = 0 ; $i < $this->m_aPlanned['ServiceCalls'] ; $i++)
  425. {
  426. $aData = array(
  427. 'org_id' => $iOrg,
  428. 'caller_id' => $this->RandomId('Person'),
  429. 'workgroup_id' => $this->RandomId('Team'),
  430. 'agent_id' => $this->RandomId('Person'),
  431. 'service_id' => $this->RandomId('Service'),
  432. 'servicesubcategory_id' => $this->RandomId('ServiceSubcategory'),
  433. 'title' => 'Call #'.$i,
  434. 'ticket_log' => 'Testing...',
  435. );
  436. $iTicket = $this->CreateObject('UserRequest', $aData, $oChange);
  437. // Call/Infra
  438. //
  439. $iInfraCount = rand(0, 6);
  440. for($iLinked = 0 ; $iLinked < $iInfraCount ; $iLinked++)
  441. {
  442. $aData = array(
  443. 'ci_id' => $this->RandomId('Server'),
  444. 'ticket_id' => $iTicket,
  445. );
  446. $this->CreateObject('lnkTicketToCI', $aData, $oChange);
  447. }
  448. }
  449. $this->MakeFeedback($oP, 'UserRequest');
  450. /////////////////////////
  451. //
  452. // Documents
  453. //
  454. $sMyDoc = '';
  455. for($i = 0 ; $i < 1000 ; $i++)
  456. {
  457. // 100 chars
  458. $sMyDoc .= "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n";
  459. }
  460. $oRefDoc = new ormDocument($sMyDoc, 'text/plain');
  461. for($i = 0 ; $i < $this->m_aPlanned['Documents'] ; $i++)
  462. {
  463. $aData = array(
  464. //'org_id' => $iOrg,
  465. 'name' => "document$i",
  466. 'contents' => $oRefDoc,
  467. );
  468. $this->CreateObject('FileDoc', $aData, $oChange);
  469. }
  470. $this->MakeFeedback($oP, 'FileDoc');
  471. }
  472. }
  473. /**
  474. * Ask the user what are the settings for the data load
  475. */
  476. function DisplayStep1(SetupWebPage $oP)
  477. {
  478. $sNextOperation = 'step2';
  479. $oP->add("<h1>iTop benchmarking</h1>\n");
  480. $oP->add("<h2>Please specify the requested volumes</h2>\n");
  481. $oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Evaluating real plans...', 10)\">\n");
  482. $oP->add("<fieldset><legend>Data load configuration</legend>\n");
  483. $aForm = array();
  484. $aForm[] = array(
  485. 'label' => "Main CIs:",
  486. 'input' => "<input id=\"to\" type=\"text\" name=\"plannedcis\" value=\"70\">",
  487. 'help' => ' exclude interfaces, subnets or any other type of secondary CI',
  488. );
  489. $aForm[] = array(
  490. 'label' => "Contacts:",
  491. 'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontacts\" value=\"100\">",
  492. 'help' => '',
  493. );
  494. $aForm[] = array(
  495. 'label' => "Contracts:",
  496. 'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontracts\" value=\"10\">",
  497. 'help' => '',
  498. );
  499. $oP->form($aForm);
  500. $oP->add("</fieldset>\n");
  501. $oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
  502. $oP->add("<button type=\"submit\">Next >></button>\n");
  503. $oP->add("</form>\n");
  504. }
  505. /**
  506. * Inform the user how many items will be created
  507. */
  508. function DisplayStep2(SetupWebPage $oP, $oDataCreation)
  509. {
  510. $sNextOperation = 'step3';
  511. $oP->add("<h1>iTop benchmarking</h1>\n");
  512. $oP->add("<h2>Step 2: review planned volumes</h2>\n");
  513. $aPlanned = $oDataCreation->GetPlans();
  514. $aForm = array();
  515. foreach ($aPlanned as $sKey => $iCount)
  516. {
  517. $aForm[] = array(
  518. 'label' => $sKey,
  519. 'input' => $iCount,
  520. );
  521. }
  522. $oP->form($aForm);
  523. $aRequested = $oDataCreation->GetRequestInfo();
  524. $oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Loading data...', 10)\">\n");
  525. $oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
  526. $oP->add("<input type=\"hidden\" name=\"plannedcis\" value=\"".$aRequested['CIs']."\">\n");
  527. $oP->add("<input type=\"hidden\" name=\"plannedcontacts\" value=\"".$aRequested['Contacts']."\">\n");
  528. $oP->add("<input type=\"hidden\" name=\"plannedcontracts\" value=\"".$aRequested['Contracts']."\">\n");
  529. $oP->add("<button type=\"submit\">Next >></button>\n");
  530. $oP->add("</form>\n");
  531. }
  532. /**
  533. * Do create the data set... could take some time to execute
  534. */
  535. function DisplayStep3(SetupWebPage $oP, $oDataCreation)
  536. {
  537. // $sNextOperation = 'step3';
  538. $oMyChange = MetaModel::NewObject("CMDBChange");
  539. $oMyChange->Set("date", time());
  540. $oMyChange->Set("userinfo", "Administrator");
  541. $iChangeId = $oMyChange->DBInsertNoReload();
  542. $oDataCreation->GoProjections($oP, $oMyChange);
  543. $oDataCreation->GoVolume($oP, $oMyChange);
  544. }
  545. /**
  546. * Main program
  547. */
  548. LoginWebPage::DoLogin(); // Check user rights and prompt if needed
  549. $sOperation = Utils::ReadParam('operation', 'step1');
  550. $oP = new SetupWebPage('iTop benchmark utility');
  551. try
  552. {
  553. switch($sOperation)
  554. {
  555. case 'step1':
  556. DisplayStep1($oP);
  557. break;
  558. case 'step2':
  559. $oP->no_cache();
  560. $iPlannedCIs = Utils::ReadParam('plannedcis');
  561. $iPlannedContacts = Utils::ReadParam('plannedcontacts');
  562. $iPlannedContracts = Utils::ReadParam('plannedcontracts');
  563. $oDataCreation = new BenchmarkDataCreation($iPlannedCIs, $iPlannedContacts, $iPlannedContracts);
  564. DisplayStep2($oP, $oDataCreation);
  565. break;
  566. case 'step3':
  567. $oP->no_cache();
  568. $iPlannedCIs = Utils::ReadParam('plannedcis');
  569. $iPlannedContacts = Utils::ReadParam('plannedcontacts');
  570. $iPlannedContracts = Utils::ReadParam('plannedcontracts');
  571. $oDataCreation = new BenchmarkDataCreation($iPlannedCIs, $iPlannedContacts, $iPlannedContracts);
  572. DisplayStep3($oP, $oDataCreation);
  573. break;
  574. default:
  575. $oP->error("Error: unsupported operation '$sOperation'");
  576. }
  577. }
  578. catch(ZZException $e)
  579. {
  580. $oP->error("Error: '".$e->getMessage()."'");
  581. }
  582. catch(ZZCoreException $e)
  583. {
  584. $oP->error("Error: '".$e->getHtmlDesc()."'");
  585. }
  586. $oP->output();
  587. ?>