testlist.inc.php 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. <?php
  2. class TestSQLQuery extends TestScenarioOnDB
  3. {
  4. static public function GetName() {return 'SQLQuery';}
  5. static public function GetDescription() {return 'SQLQuery does not depend on the rest of the framework, therefore it makes sense to have a separate test framework for it';}
  6. static public function GetDBHost() {return 'localhost';}
  7. static public function GetDBUser() {return 'RomainDBLogin';}
  8. static public function GetDBPwd() {return '';}
  9. static public function GetDBName() {return 'TestSQLQuery';}
  10. static public function GetDBSubName() {return 'taratata';}
  11. protected function DoPrepare()
  12. {
  13. parent::DoPrepare();
  14. cmdbSource::CreateTable('CREATE TABLE `myTable` (myKey INT(11) NOT NULL auto_increment, column1 VARCHAR(255), column2 VARCHAR(255), PRIMARY KEY (`myKey`)) ENGINE = innodb');
  15. cmdbSource::CreateTable('CREATE TABLE `myTable1` (myKey1 INT(11) NOT NULL auto_increment, column1_1 VARCHAR(255), column1_2 VARCHAR(255), PRIMARY KEY (`myKey1`)) ENGINE = innodb');
  16. cmdbSource::CreateTable('CREATE TABLE `myTable2` (myKey2 INT(11) NOT NULL auto_increment, column2_1 VARCHAR(255), column2_2 VARCHAR(255), PRIMARY KEY (`myKey2`)) ENGINE = innodb');
  17. }
  18. protected function DoExecute()
  19. {
  20. $oQuery = new SQLQuery(
  21. $sTable = 'myTable',
  22. $sTableAlias = 'myTableAlias',
  23. $aFields = array('column1'=>new FieldExpression('column1', 'myTableAlias'), 'column2'=>new FieldExpression('column2', 'myTableAlias')),
  24. $oCondition = new BinaryExpression(new FieldExpression('column1', 'myTableAlias'), 'LIKE', new ScalarExpression('trash')),
  25. $aFullTextNeedles = array('column1'),
  26. $bToDelete = false,
  27. $aValues = array()
  28. );
  29. $oQuery->AddCondition(Expression::FromOQL('DATE(NOW() - 1200 * 2) > \'2008-07-31\''));
  30. $oSubQuery1 = new SQLQuery(
  31. $sTable = 'myTable1',
  32. $sTableAlias = 'myTable1Alias',
  33. $aFields = array('column1_1'=>new FieldExpression('column1', 'myTableAlias'), 'column1_2'=>new FieldExpression('column1', 'myTableAlias')),
  34. $oCondition = new TrueSQLExpression,
  35. $aFullTextNeedles = array(),
  36. $bToDelete = false,
  37. $aValues = array()
  38. );
  39. $oSubQuery2 = new SQLQuery(
  40. $sTable = 'myTable2',
  41. $sTableAlias = 'myTable2Alias',
  42. $aFields = array('column2_1'=>new FieldExpression('column2', 'myTableAlias'), 'column2_2'=>new FieldExpression('column2', 'myTableAlias')),
  43. $oCondition = new TrueSQLExpression,
  44. $aFullTextNeedles = array(),
  45. $bToDelete = false,
  46. $aValues = array()
  47. );
  48. $oQuery->AddInnerJoin($oSubQuery1, 'column1', 'column1_1');
  49. $oQuery->AddLeftJoin($oSubQuery2, 'column2', 'column2_2');
  50. $oQuery->DisplayHtml();
  51. $oQuery->RenderDelete();
  52. $oQuery->RenderUpdate();
  53. echo '<p>'.$oQuery->RenderSelect().'</p>';
  54. $oQuery->RenderSelect(array('column1'));
  55. $oQuery->RenderSelect(array('column1', 'column2'));
  56. }
  57. }
  58. class TestOQLParser extends TestFunction
  59. {
  60. static public function GetName() {return 'Check OQL parsing';}
  61. static public function GetDescription() {return 'Attempts a series of queries, and in particular those with a bad syntax';}
  62. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  63. {
  64. $oOql = new OqlInterpreter($sQuery);
  65. try
  66. {
  67. $oTrash = $oOql->Parse(); // Not expecting a given format, otherwise use ParseExpression/ParseObjectQuery/ParseValueSetQuery
  68. MyHelpers::var_dump_html($oTrash, true);
  69. }
  70. catch (OQLException $OqlException)
  71. {
  72. if ($bIsCorrectQuery)
  73. {
  74. echo "<p>More info on this unexpected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  75. throw $OqlException;
  76. return false;
  77. }
  78. else
  79. {
  80. // Everything is fine :-)
  81. echo "<p>More info on this expected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  82. return true;
  83. }
  84. }
  85. // The query was correctly parsed, was it expected to be correct ?
  86. if ($bIsCorrectQuery)
  87. {
  88. return true;
  89. }
  90. else
  91. {
  92. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  93. return false;
  94. }
  95. }
  96. protected function TestQuery($sQuery, $bIsCorrectQuery)
  97. {
  98. if (!$this->CheckQuery($sQuery, $bIsCorrectQuery))
  99. {
  100. return false;
  101. }
  102. return true;
  103. }
  104. public function DoExecute()
  105. {
  106. $aQueries = array(
  107. 'SELECT toto' => true,
  108. 'SELECT toto WHERE toto.a = 1' => true,
  109. 'SELECT toto WHERE toto.a=1' => true,
  110. 'SELECT toto WHERE toto.a = "1"' => true,
  111. 'SELECT toto WHHHERE toto.a = "1"' => false,
  112. 'SELECT toto WHERE toto.a == "1"' => false,
  113. 'SELECT toto WHERE toto.a % 1' => false,
  114. //'SELECT toto WHERE toto.a LIKE 1' => false,
  115. 'SELECT toto WHERE toto.a like \'arg\'' => false,
  116. 'SELECT toto WHERE toto.a NOT LIKE "That\'s it"' => true,
  117. 'SELECT toto WHERE toto.a NOT LIKE "That\'s "it""' => false,
  118. 'SELECT toto WHERE toto.a NOT LIKE "That\'s \\"it\\""' => true,
  119. 'SELECT toto WHERE toto.a NOT LIKE \'That"s it\'' => true,
  120. 'SELECT toto WHERE toto.a NOT LIKE \'That\'s it\'' => false,
  121. 'SELECT toto WHERE toto.a NOT LIKE \'That\\\'s it\'' => true,
  122. 'SELECT toto WHERE toto.a NOT LIKE "blah \\ truc"' => false,
  123. 'SELECT toto WHERE toto.a NOT LIKE "blah \\\\ truc"' => true,
  124. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\ truc\'' => false,
  125. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\\\ truc\'' => true,
  126. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  127. 'SELECT toto WHERE toto.a NOT LIKE "\\""' => true,
  128. 'SELECT toto WHERE toto.a NOT LIKE "\\"\\\\"' => true,
  129. 'SELECT toto WHERE toto.a NOT LIKE "\\\\\\""' => true,
  130. 'SELECT toto WHERE toto.a NOT LIKE ""' => true,
  131. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  132. "SELECT UserRightsMatrixClassGrant WHERE UserRightsMatrixClassGrant.class = 'lnkContactRealObject' AND UserRightsMatrixClassGrant.action = 'modify' AND UserRightsMatrixClassGrant.login = 'Denis'" => true,
  133. "SELECT A WHERE A.col1 = 'lit1' AND A.col2 = 'lit2' AND A.col3 = 'lit3'" => true,
  134. 'SELECT toto WHERE toto.a NOT LIKE "blah" AND toto.b LIKE "foo"' => true,
  135. //'SELECT toto WHERE toto.a > \'asd\'' => false,
  136. 'SELECT toto WHERE toto.a = 1 AND toto.b LIKE "x" AND toto.f >= 12345' => true,
  137. 'SELECT Device JOIN Site ON Device.site = Site.id' => true,
  138. 'SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id' => true,
  139. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = 123 AND B.col1 = 'aa') OR (A.col3 = 'zzz' AND B.col4 > 100)" => true,
  140. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = B.col2 AND B.col1 = A.col2) OR (A.col3 = '' AND B.col4 > 100)" => true,
  141. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + B.col2 * B.col1 = A.col2" => true,
  142. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + (B.col2 * B.col1) = A.col2" => true,
  143. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 + B.col2) * B.col1 = A.col2" => true,
  144. 'SELECT Device AS D_ JOIN Site AS S_ ON D_.site = S_.id WHERE S_.country = "Francia"' => true,
  145. );
  146. $iErrors = 0;
  147. foreach($aQueries as $sQuery => $bIsCorrectQuery)
  148. {
  149. $sIsOk = $bIsCorrectQuery ? 'good' : 'bad';
  150. echo "<h4>Testing query: $sQuery ($sIsOk)</h4>\n";
  151. $bRet = $this->TestQuery($sQuery, $bIsCorrectQuery);
  152. if (!$bRet) $iErrors++;
  153. }
  154. return ($iErrors == 0);
  155. }
  156. }
  157. class TestGenericItoMyModel extends TestBizModelGeneric
  158. {
  159. static public function GetName()
  160. {
  161. return 'Generic RO test on '.self::GetConfigFile();
  162. }
  163. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  164. }
  165. class TestGenericItopBigModel extends TestBizModelGeneric
  166. {
  167. static public function GetName()
  168. {
  169. return 'Generic RO test on '.self::GetConfigFile();
  170. }
  171. static public function GetConfigFile() {return '../config-test-itopv06.php';}
  172. }
  173. class TestUserRightsMatrixItop extends TestUserRights
  174. {
  175. static public function GetName()
  176. {
  177. return 'User rights test on user rights matrix';
  178. }
  179. static public function GetDescription()
  180. {
  181. return 'blah blah blah';
  182. }
  183. public function DoPrepare()
  184. {
  185. parent::DoPrepare();
  186. MetaModel::Startup('../config-test-itopv06.php');
  187. }
  188. protected function DoExecute()
  189. {
  190. $sUser = 'Romain';
  191. echo "<p>Totor: ".(UserRights::Login('Totor', 'toto') ? 'ok' : 'NO')."</p>\n";
  192. echo "<p>Romain: ".(UserRights::Login('Romain', 'toto') ? 'ok' : 'NO')."</p>\n";
  193. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  194. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  195. echo "<p>Denis (impersonate) : ".(UserRights::Impersonate('Denis', 'tutu') ? 'ok' : 'NO')."</p>\n";
  196. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  197. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  198. UserRights::GetFilter('bizOrganization'); // returns a filter object
  199. $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT bizOrganization"));
  200. echo "<p>IsActionAllowed...".(UserRights::IsActionAllowed('bizOrganization', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  201. echo "<p>IsStimulusAllowed...".(UserRights::IsStimulusAllowed('bizOrganization', 'myStimulus', $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  202. echo "<p>IsActionAllowedOnAttribute...".(UserRights::IsActionAllowedOnAttribute('bizOrganization', 'myattribute', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  203. return true;
  204. }
  205. }
  206. ///////////////////////////////////////////////////////////////////////////
  207. // Test a complex biz model on the fly
  208. ///////////////////////////////////////////////////////////////////////////
  209. class TestMyBizModel extends TestBizModel
  210. {
  211. static public function GetName()
  212. {
  213. return 'A series of tests on a weird business model';
  214. }
  215. static public function GetDescription()
  216. {
  217. return 'Attempts various operations and build complex queries';
  218. }
  219. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  220. function test_linksinfo()
  221. {
  222. echo "<h4>Enum links</h4>";
  223. MyHelpers::var_dump_html(MetaModel::EnumReferencedClasses("cmdbTeam"));
  224. MyHelpers::var_dump_html(MetaModel::EnumReferencingClasses("Organization"));
  225. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses());
  226. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdbContact"));
  227. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdWorkshop"));
  228. MyHelpers::var_dump_html(MetaModel::GetLinkLabel("Liens_entre_contacts_et_workshop", "toworkshop"));
  229. }
  230. function test_list_attributes()
  231. {
  232. echo "<h4>List attributes</h4>";
  233. foreach(MetaModel::ListAttributeDefs("cmdbTeam") as $sAttCode=>$oAttDef)
  234. {
  235. echo $oAttDef->GetLabel()." / ".$oAttDef->GetDescription()." / ".$oAttDef->GetType()."</br>\n";
  236. }
  237. }
  238. function test_search()
  239. {
  240. echo "<h4>Two searches</h4>";
  241. $oFilterAllDevs = new DBObjectSearch("cmdbTeam");
  242. $oAllDevs = new DBObjectSet($oFilterAllDevs);
  243. echo "Found ".$oAllDevs->Count()." items.</br>\n";
  244. while ($oDev = $oAllDevs->Fetch())
  245. {
  246. $aValues = array();
  247. foreach(MetaModel::GetAttributesList($oAllDevs->GetClass()) as $sAttCode)
  248. {
  249. $aValues[] = MetaModel::GetLabel(get_class($oDev), $sAttCode)." (".MetaModel::GetDescription(get_class($oDev), $sAttCode).") = ".$oDev->GetAsHTML($sAttCode);
  250. }
  251. echo $oDev->GetKey()." => ".implode(", ", $aValues)."</br>\n";
  252. }
  253. // a second one
  254. $oMyFilter = new DBObjectSearch("cmdbContact");
  255. //$oMyFilter->AddCondition("name", "aii", "Finishes with");
  256. $oMyFilter->AddCondition("name", "aii");
  257. $this->search_and_show_list($oMyFilter);
  258. }
  259. function test_reload()
  260. {
  261. echo "<h4>Reload</h4>";
  262. $team = MetaModel::GetObject("cmdbContact", "2");
  263. echo "Chargement de l'attribut headcount: {$team->Get("headcount")}</br>\n";
  264. MyHelpers::var_dump_html($team);
  265. }
  266. function test_setattribute()
  267. {
  268. echo "<h4>Set attribute and update</h4>";
  269. $team = MetaModel::GetObject("cmdbTeam", "2");
  270. $team->Set("headcount", rand(1,1000));
  271. $team->Set("email", "Luis ".rand(9,250));
  272. MyHelpers::var_dump_html($team->ListChanges());
  273. echo "New headcount = {$team->Get("headcount")}</br>\n";
  274. echo "Computed name = {$team->Get("name")}</br>\n";
  275. $oMyChange = MetaModel::NewObject("CMDBChange");
  276. $oMyChange->Set("date", time());
  277. $oMyChange->Set("userinfo", "test_setattribute / Made by robot #".rand(1,100));
  278. $iChangeId = $oMyChange->DBInsert();
  279. //MetaModel::StartDebugQuery();
  280. $team->DBUpdateTracked($oMyChange);
  281. //MetaModel::StopDebugQuery();
  282. echo "<h4>Check the modified team</h4>";
  283. $oTeam = MetaModel::GetObject("cmdbTeam", "2");
  284. MyHelpers::var_dump_html($oTeam);
  285. }
  286. function test_newobject()
  287. {
  288. $oMyChange = MetaModel::NewObject("CMDBChange");
  289. $oMyChange->Set("date", time());
  290. $oMyChange->Set("userinfo", "test_newobject / Made by robot #".rand(1,100));
  291. $iChangeId = $oMyChange->DBInsert();
  292. echo "<h4>Create a new object (team)</h4>";
  293. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  294. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  295. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  296. $oNewTeam->Set("email", null);
  297. $oNewTeam->Set("owner", "ITOP");
  298. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  299. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  300. echo "Created new team: $iId</br>";
  301. echo "<h4>Delete team #$iId</h4>";
  302. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  303. $oTeam->DBDeleteTracked($oMyChange);
  304. echo "Deleted team: $iId</br>";
  305. MyHelpers::var_dump_html($oTeam);
  306. }
  307. function test_updatecolumn()
  308. {
  309. $oMyChange = MetaModel::NewObject("CMDBChange");
  310. $oMyChange->Set("date", time());
  311. $oMyChange->Set("userinfo", "test_updatecolumn / Made by robot #".rand(1,100));
  312. $iChangeId = $oMyChange->DBInsert();
  313. $sNewEmail = "updatecol".rand(9,250)."@quedlaballe.com";
  314. echo "<h4>Update a the email: set to '$sNewEmail'</h4>";
  315. $oMyFilter = new DBObjectSearch("cmdbContact");
  316. $oMyFilter->AddCondition("name", "o", "Contains");
  317. echo "Candidates before:</br>";
  318. $this->search_and_show_list($oMyFilter);
  319. MetaModel::BulkUpdateTracked($oMyChange, $oMyFilter, array("email" => $sNewEmail));
  320. echo "Candidates after:</br>";
  321. $this->search_and_show_list($oMyFilter);
  322. }
  323. function test_error()
  324. {
  325. trigger_error("Stop requested", E_USER_ERROR);
  326. }
  327. function test_changetracking()
  328. {
  329. echo "<h4>Create a change</h4>";
  330. $oMyChange = MetaModel::NewObject("CMDBChange");
  331. $oMyChange->Set("date", time());
  332. $oMyChange->Set("userinfo", "Made by robot #".rand(1,100));
  333. $iChangeId = $oMyChange->DBInsert();
  334. echo "Created new change: $iChangeId</br>";
  335. MyHelpers::var_dump_html($oMyChange);
  336. echo "<h4>Create a new object (team)</h4>";
  337. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  338. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  339. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  340. $oNewTeam->Set("email", null);
  341. $oNewTeam->Set("owner", "ITOP");
  342. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  343. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  344. echo "Created new team: $iId</br>";
  345. echo "<h4>Delete team #$iId</h4>";
  346. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  347. $oTeam->DBDeleteTracked($oMyChange);
  348. echo "Deleted team: $iId</br>";
  349. MyHelpers::var_dump_html($oTeam);
  350. }
  351. function test_zlist()
  352. {
  353. echo "<h4>Test ZLists</h4>";
  354. $aZLists = MetaModel::EnumZLists();
  355. foreach ($aZLists as $sListCode)
  356. {
  357. $aListInfos = MetaModel::GetZListInfo($sListCode);
  358. echo "<h4>List '".$sListCode."' (".$aListInfos["description"].") of type '".$aListInfos["type"]."'</h5>\n";
  359. foreach (MetaModel::GetSubclasses("cmdbObjectHomeMade") as $sKlass)
  360. {
  361. $aItems = MetaModel::GetZListItems($sKlass, $sListCode);
  362. if (count($aItems) == 0) continue;
  363. echo "$sKlass - $sListCode : {".implode(", ", $aItems)."}</br>\n";
  364. }
  365. }
  366. echo "<h4>IsAttributeInZList()... </h4>";
  367. echo "Liens_entre_contacts_et_workshop::ws_info in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "ws_info") ? "yes" : "no")."</br>\n";
  368. echo "Liens_entre_contacts_et_workshop::toworkshop in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "toworkshop") ? "yes" : "no")."</br>\n";
  369. }
  370. function test_SibuSQL()
  371. {
  372. echo "<h4>Simple But Structured Query Language</h4>";
  373. $oMyFilter = new DBObjectSearch("cmdbContact");
  374. echo "Tous les contacts: ".$oMyFilter->ToSibuSQL()."<br/>\n";
  375. $oNewFilter = DBObjectSearch::FromSibuSQL($oMyFilter->ToSibuSQL());
  376. echo "En passant par un filtre, ca revient en : ".$oNewFilter->ToSibuSQL()."</br>\n";
  377. $this->search_and_show_list($oNewFilter);
  378. $sFilterDesc = "cmdbContact: name Begins with '$[debutnom:as:debut du nom]' AND ownername NotLike $[ddd::]";
  379. echo "Construction d'un filtre a partir de sa description en SibuSQL: $sFilterDesc<br/>\n";
  380. MyHelpers::var_dump_html(DBObjectSearch::ListSibusQLParams($sFilterDesc));
  381. $oNewFilter = DBObjectSearch::FromSibuSQL($sFilterDesc, array('ddd'=>123));
  382. echo "Ca revient en: ".$oNewFilter->ToSibuSQL();
  383. }
  384. function test_pkey()
  385. {
  386. echo "<h4>Test search on pkey</h4>";
  387. $sExpr1 = "cmdbContact: pkey IN {40, 42}";
  388. $sExpr2 = "cmdbContact: pkey NOTIN {40, 42}";
  389. $this->search_and_show_list_from_sibusql($sExpr1);
  390. $this->search_and_show_list_from_sibusql($sExpr2);
  391. echo "Et maintenant, on fusionne....</br>\n";
  392. $oSet1 = new CMDBObjectSet(DBObjectSearch::FromSibuSQL($sExpr1));
  393. $oSet2 = new CMDBObjectSet(DBObjectSearch::FromSibuSQL($sExpr2));
  394. $oIntersect = $oSet1->CreateIntersect($oSet2);
  395. $oDelta = $oSet1->CreateDelta($oSet2);
  396. $oMerge = clone $oSet1;
  397. $oMerge->Merge($oSet2);
  398. $oMerge->Merge($oSet2);
  399. echo "Set1 - Found ".$oSet1->Count()." items.</br>\n";
  400. echo "Set2 - Found ".$oSet2->Count()." items.</br>\n";
  401. echo "Intersect - Found ".$oIntersect->Count()." items.</br>\n";
  402. echo "Delta - Found ".$oDelta->Count()." items.</br>\n";
  403. echo "Merge - Found ".$oMerge->Count()." items.</br>\n";
  404. //$this->show_list($oObjSet);
  405. }
  406. function test_relations()
  407. {
  408. echo "<h4>Test relations</h4>";
  409. //MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbObjectHomeMade", "Potes"));
  410. MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbContact", "Potes"));
  411. $iMaxDepth = 9;
  412. echo "Max depth = $iMaxDepth</br>\n";
  413. $oObj = MetaModel::GetObject("cmdbContact", 18);
  414. $aRels = $oObj->GetRelatedObjects("Potes", $iMaxDepth);
  415. echo $oObj->Get('name')." has some 'Potes'...</br>\n";
  416. foreach ($aRels as $sClass => $aObjs)
  417. {
  418. echo "$sClass, count = ".count($aObjs)." =&gt; ".implode(', ', array_keys($aObjs))."</br>\n";
  419. $oObjectSet = CMDBObjectSet::FromArray($sClass, $aObjs);
  420. $this->show_list($oObjectSet);
  421. }
  422. echo "<h4>Test relations - same results, by the mean of a SibuSQL</h4>";
  423. $this->search_and_show_list_from_sibusql("cmdbContact: RELATED (Potes, $iMaxDepth) TO (cmdbContact: pkey = 18)");
  424. }
  425. function test_linkedset()
  426. {
  427. echo "<h4>Linked set attributes</h4>\n";
  428. $oObj = MetaModel::GetObject("cmdbContact", 18);
  429. echo "<h5>Current workshops</h5>\n";
  430. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  431. $this->show_list($oSetWorkshopsCurr);
  432. echo "<h5>Setting workshops</h5>\n";
  433. $oNewLink = new cmdbLiens();
  434. $oNewLink->Set('toworkshop', 2);
  435. $oNewLink->Set('function', 'mafonctioooon');
  436. $oNewLink->Set('a1', 'tralala1');
  437. $oNewLink->Set('a2', 'F7M');
  438. $oSetWorkshops = CMDBObjectSet::FromArray("cmdbLiens", array($oNewLink));
  439. $oObj->Set("myworkshops", $oSetWorkshops);
  440. $this->show_list($oSetWorkshops);
  441. echo "<h5>New workshops</h5>\n";
  442. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  443. $this->show_list($oSetWorkshopsCurr);
  444. $oMyChange = MetaModel::NewObject("CMDBChange");
  445. $oMyChange->Set("date", time());
  446. $oMyChange->Set("userinfo", "test_linkedset / Made by robot #".rand(1,100));
  447. $iChangeId = $oMyChange->DBInsert();
  448. $oObj->DBUpdateTracked($oMyChange);
  449. $oObj = MetaModel::GetObject("cmdbContact", 18);
  450. echo "<h5>After the write</h5>\n";
  451. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  452. $this->show_list($oSetWorkshopsCurr);
  453. }
  454. function test_object_lifecycle()
  455. {
  456. echo "<h4>Test object lifecycle</h4>";
  457. MyHelpers::var_dump_html(MetaModel::GetStateAttributeCode("cmdbContact"));
  458. MyHelpers::var_dump_html(MetaModel::EnumStates("cmdbContact"));
  459. MyHelpers::var_dump_html(MetaModel::EnumStimuli("cmdbContact"));
  460. foreach(MetaModel::EnumStates("cmdbContact") as $sStateCode => $aStateDef)
  461. {
  462. echo "<p>Transition from <strong>$sStateCode</strong></p>\n";
  463. MyHelpers::var_dump_html(MetaModel::EnumTransitions("cmdbContact", $sStateCode));
  464. }
  465. $oObj = MetaModel::GetObject("cmdbContact", 18);
  466. echo "Current state: ".$oObj->GetState()."... let's go to school...";
  467. MyHelpers::var_dump_html($oObj->EnumTransitions());
  468. $oObj->ApplyStimulus("toschool");
  469. echo "New state: ".$oObj->GetState()."... let's get older...";
  470. MyHelpers::var_dump_html($oObj->EnumTransitions());
  471. $oObj->ApplyStimulus("raise");
  472. echo "New state: ".$oObj->GetState()."... let's try to go further... (should give an error)";
  473. MyHelpers::var_dump_html($oObj->EnumTransitions());
  474. $oObj->ApplyStimulus("raise"); // should give an error
  475. }
  476. protected function DoExecute()
  477. {
  478. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  479. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  480. //$this->test_linksinfo();
  481. //$this->test_list_attributes();
  482. //$this->test_search();
  483. //$this->test_reload();
  484. //$this->test_newobject();
  485. $this->test_setattribute();
  486. //$this->test_updatecolumn();
  487. //$this->test_error();
  488. //$this->test_changetracking();
  489. $this->test_zlist();
  490. $this->test_SibuSQL();
  491. //$this->test_pkey();
  492. $this->test_relations();
  493. $this->test_linkedset();
  494. $this->test_object_lifecycle();
  495. return true;
  496. }
  497. }
  498. ///////////////////////////////////////////////////////////////////////////
  499. // Test a complex biz model on the fly
  500. ///////////////////////////////////////////////////////////////////////////
  501. abstract class MyFarm extends TestBizModel
  502. {
  503. static public function GetConfigFile() {return '../config-test-farm.php';}
  504. protected function DoPrepare()
  505. {
  506. parent::DoPrepare();
  507. $this->ResetDB();
  508. MetaModel::DBCheckIntegrity();
  509. }
  510. protected $m_oChange;
  511. protected function ObjectToDB(CMDBObject $oNew)
  512. {
  513. if (!isset($this->m_oChange))
  514. {
  515. new CMDBChange();
  516. $oMyChange = MetaModel::NewObject("CMDBChange");
  517. $oMyChange->Set("date", time());
  518. $oMyChange->Set("userinfo", "Administrator");
  519. $iChangeId = $oMyChange->DBInsertNoReload();
  520. $this->m_oChange = $oMyChange;
  521. }
  522. $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange);
  523. return $iId;
  524. }
  525. protected function InsertMammal($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $sName, $iHeight, $sBirth)
  526. {
  527. $oNew = MetaModel::NewObject('Mammal');
  528. $oNew->Set('species', $sSpecies);
  529. $oNew->Set('sex', $sSex);
  530. $oNew->Set('speed', $iSpeed);
  531. $oNew->Set('mother', $iMotherid);
  532. $oNew->Set('father', $iFatherId);
  533. $oNew->Set('name', $sName);
  534. $oNew->Set('height', $iHeight);
  535. $oNew->Set('birth', $sBirth);
  536. return $this->ObjectToDB($oNew);
  537. }
  538. protected function InsertBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId)
  539. {
  540. $oNew = MetaModel::NewObject('Bird');
  541. $oNew->Set('species', $sSpecies);
  542. $oNew->Set('sex', $sSex);
  543. $oNew->Set('speed', $iSpeed);
  544. $oNew->Set('mother', $iMotherid);
  545. $oNew->Set('father', $iFatherId);
  546. return $this->ObjectToDB($oNew);
  547. }
  548. protected function InsertFlyingBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $iFlyingSpeed)
  549. {
  550. $oNew = MetaModel::NewObject('FlyingBird');
  551. $oNew->Set('species', $sSpecies);
  552. $oNew->Set('sex', $sSex);
  553. $oNew->Set('speed', $iSpeed);
  554. $oNew->Set('mother', $iMotherid);
  555. $oNew->Set('father', $iFatherId);
  556. $oNew->Set('flyingspeed', $iFlyingSpeed);
  557. return $this->ObjectToDB($oNew);
  558. }
  559. private function InsertGroup($sName, $iLeaderId)
  560. {
  561. $oNew = MetaModel::NewObject('Group');
  562. $oNew->Set('name', $sName);
  563. $oNew->Set('leader', $iLeaderId);
  564. $iId = $oNew->DBInsertNoReload();
  565. return $iId;
  566. }
  567. }
  568. class TestQueriesOnFarm extends MyFarm
  569. {
  570. static public function GetName()
  571. {
  572. return 'Farm test';
  573. }
  574. static public function GetDescription()
  575. {
  576. return 'A series of tests on the farm business model (SQL generation)';
  577. }
  578. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  579. {
  580. if ($bIsCorrectQuery)
  581. {
  582. echo "<h4 style=\"color:green;\">$sQuery</h4>\n";
  583. }
  584. else
  585. {
  586. echo "<h4 style=\"color:red;\">$sQuery</h3>\n";
  587. }
  588. try
  589. {
  590. //$oOql = new OqlInterpreter($sQuery);
  591. //$oTrash = $oOql->ParseObjectQuery();
  592. //MyHelpers::var_dump_html($oTrash, true);
  593. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  594. }
  595. catch (OQLException $oOqlException)
  596. {
  597. if ($bIsCorrectQuery)
  598. {
  599. echo "<p>More info on this unexpected failure:<br/>".$oOqlException->getHtmlDesc()."</p>\n";
  600. throw $oOqlException;
  601. return false;
  602. }
  603. else
  604. {
  605. // Everything is fine :-)
  606. echo "<p>More info on this expected failure:\n";
  607. echo "<ul>\n";
  608. echo "<li>".get_class($oOqlException)."</li>\n";
  609. echo "<li>".$oOqlException->getMessage()."</li>\n";
  610. echo "<li>".$oOqlException->getHtmlDesc()."</li>\n";
  611. echo "</ul>\n";
  612. echo "</p>\n";
  613. return true;
  614. }
  615. }
  616. // The query was correctly parsed, was it expected to be correct ?
  617. if (!$bIsCorrectQuery)
  618. {
  619. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  620. return false;
  621. }
  622. echo "<p>To OQL: ".$oMyFilter->ToOQL()."</p>";
  623. $this->search_and_show_list($oMyFilter);
  624. //echo "<p>first pass<p>\n";
  625. //MyHelpers::var_dump_html($oMyFilter, true);
  626. $sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  627. //echo "<p>second pass<p>\n";
  628. //MyHelpers::var_dump_html($oMyFilter, true);
  629. //$sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  630. $sSerialize = $oMyFilter->serialize();
  631. echo "<p>Serialized:$sSerialize</p>\n";
  632. $oFilter2 = DBObjectSearch::unserialize($sSerialize);
  633. try
  634. {
  635. $sQuery2 = MetaModel::MakeSelectQuery($oFilter2);
  636. }
  637. catch (Exception $e)
  638. {
  639. echo "<p>Could not compute the query after unserialize</p>\n";
  640. echo "<p>Query 1: $sQuery1</p>\n";
  641. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  642. throw $e;
  643. }
  644. //if ($oFilter2 != $oMyFilter) no, they may differ while the resulting query is the same!
  645. if ($sQuery1 != $sQuery2)
  646. {
  647. echo "<p>serialize/unserialize mismatch :-(</p>\n";
  648. MyHelpers::var_cmp_html($sQuery1, $sQuery2);
  649. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  650. return false;
  651. }
  652. return true;
  653. }
  654. protected function DoExecute()
  655. {
  656. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  657. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  658. echo "<h3>Create protagonists...</h3>";
  659. $iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
  660. $iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
  661. $this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
  662. $this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
  663. $this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
  664. $this->InsertBird('rooster', 'male', 12, 0, 0);
  665. $this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
  666. // Benchmarking
  667. //
  668. if (false)
  669. {
  670. define ('COUNT_BENCHMARK', 10);
  671. echo "<h3>Parsing a long query, ".COUNT_BENCHMARK." times</h3>";
  672. $sQuery = "SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR) AND Dad.height * 2 <= ROUND(TO_DAYS(Dad.birth) / (3 + 1) * 5 - 3)";
  673. $fStart = MyHelpers::getmicrotime();
  674. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  675. {
  676. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  677. }
  678. $fDuration = MyHelpers::getmicrotime() - $fStart;
  679. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  680. echo "<p>Mean time by op: $fParsingDuration</p>";
  681. }
  682. echo "<h3>Test queries...</h3>";
  683. $aQueries = array(
  684. 'SELECT Animal' => true,
  685. 'SELECT Animal WHERE Animal.pkey = 1' => false,
  686. 'SELECT Animal WHERE Animal.id = 1' => true,
  687. 'SELECT Aniiimal' => false,
  688. 'SELECTe Animal' => false,
  689. 'SELECT * FROM Animal' => false,
  690. 'SELECT Animal AS zoo WHERE zoo.species = \'human\'' => true,
  691. 'SELECT Animal AS zoo WHERE species = \'human\'' => true,
  692. 'SELECT Animal AS zoo WHERE espece = \'human\'' => false,
  693. 'SELECT Animal AS zoo WHERE zoo.species IN (\'human\', "pig")' => true,
  694. 'SELECT Animal AS zoo WHERE CONCATENATION(zoo.species, zoo.sex) LIKE "hum%male"' => false,
  695. 'SELECT Animal AS zoo WHERE CONCAT(zoo.species, zoo.sex) LIKE "hum%male"' => true,
  696. 'SELECT Animal AS zoo WHERE zoo.species NOT IN (\'human\', "pig")' => true,
  697. 'SELECT Animal AS zoo WHERE zoo.kind = \'human\'' => false,
  698. 'SELECT Animal WHERE Animal.species = \'human\' AND Animal.sex = \'female\'' => true,
  699. 'SELECT Mammal AS x WHERE (x.species = \'human\' AND x.name LIKE \'ro%\') OR (x.species = \'donkey\' AND x.name LIKE \'po%\')' => true,
  700. 'SELECT Mammal AS x WHERE x.species = \'human\' AND x.name LIKE \'ro%\' OR x.species = \'donkey\' AND x.name LIKE \'po%\'' => true,
  701. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  702. 'SELECT Mammal AS m WHERE DAY(m.birth) = 19' => true,
  703. 'SELECT Mammal AS m WHERE YEAR(m.birth) = 1971' => true,
  704. 'SELECT Mammal AS m WHERE m.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR)' => true,
  705. 'SELECT Mammal AS m WHERE m.birth > DATE_SUB(NOW(), INTERVAL 2000 DAY)' => true,
  706. 'SELECT Mammal AS m WHERE (TO_DAYS(NOW()) - TO_DAYS(m.birth)) > 2000' => true,
  707. 'SELECT Mammal AS m WHERE m.name = IF(FLOOR(ROUND(m.height)) > 2, "pomme", "romain")' => true,
  708. 'SELECT Mammal AS m WHERE (1 + 2' => false,
  709. 'SELECT Mammal AS m WHERE (1 + 2 * 4 / 23) > 0' => true,
  710. 'SELECT Mammal AS m WHERE (4 / 23 * 2 + 1) > 0' => true,
  711. 'SELECT Mammal AS m WHERE 1/0' => true,
  712. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  713. 'SELECT Animal JOIN Group ON Group.leader = Animal.id' => true,
  714. 'SELECT Group JOIN Animal ON Group.leader = Animal.id' => true,
  715. 'SELECT Animal AS A JOIN Group AS G1 ON G1.leader = A.id' => true,
  716. 'SELECT Animal AS A JOIN Group AS G ON FooClass.leader = A.id' => false,
  717. 'SELECT Animal AS A JOIN Group AS G ON G.leader = FooClass.id' => false,
  718. 'SELECT Animal AS A JOIN Group AS G ON G.masterchief = A.id' => false,
  719. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.pkey' => false,
  720. 'SELECT Animal AS A JOIN Group AS G ON A.id = G.leader' => false,
  721. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.qwerty = 123' => false,
  722. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.name LIKE "a%"' => true,
  723. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.id = 1' => true,
  724. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE id = 1' => false,
  725. 'SELECT Animal AS A JOIN Group AS G ON A.member = G.id' => false,
  726. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id' => true,
  727. 'SELECT Mammal AS M JOIN Group AS G ON A.member = G.id' => false,
  728. 'SELECT Mammal AS myAlias JOIN Group AS myAlias ON myAlias.member = myAlias.id' => false,
  729. 'SELECT Mammal AS Mammal JOIN Group AS Mammal ON Mammal.member = Mammal.id' => false,
  730. 'SELECT Group AS G WHERE G.leader_name LIKE "%"' => true,
  731. 'SELECT Group AS G WHERE G.leader_speed < 100000' => true,
  732. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  733. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_speed < 100000' => true,
  734. 'SELECT Mammal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  735. 'SELECT Mammal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  736. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  737. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  738. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id' => true,
  739. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  740. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.id = 1' => true,
  741. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\'' => false,
  742. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  743. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.speed = 0' => true,
  744. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  745. 'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id' => true,
  746. 'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id JOIN Mammal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.name=\'chloe\' OR Child.name=\'bizounours\'' => true,
  747. );
  748. //$aQueries = array(
  749. // 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  750. //);
  751. foreach($aQueries as $sQuery => $bIsCorrect)
  752. {
  753. $this->CheckQuery($sQuery, $bIsCorrect);
  754. }
  755. return true;
  756. }
  757. }
  758. ///////////////////////////////////////////////////////////////////////////
  759. // Test data load
  760. ///////////////////////////////////////////////////////////////////////////
  761. class TestBulkChangeOnFarm extends TestBizModel
  762. {
  763. static public function GetName()
  764. {
  765. return 'Farm test - data load';
  766. }
  767. static public function GetDescription()
  768. {
  769. return 'Bulk load';
  770. }
  771. static public function GetConfigFile() {return '../config-test-farm.php';}
  772. protected function DoPrepare()
  773. {
  774. parent::DoPrepare();
  775. $this->ResetDB();
  776. MetaModel::DBCheckIntegrity();
  777. }
  778. protected function DoExecute()
  779. {
  780. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  781. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  782. $oParser = new CSVParser("#denomination,hauteur,age
  783. suzy,123,2009-01-01
  784. chita,456,
  785. ");
  786. $oParser->SetSeparator(',');
  787. $aData = $oParser->ToArray(array('_name', '_height', '_birth'));
  788. MyHelpers::var_dump_html($aData);
  789. $oBulk = new BulkChange(
  790. 'Mammal',
  791. $aData,
  792. array('name' => '_name', 'height' => '_height', 'birth' => '_birth'),
  793. array('name'),
  794. array()
  795. );
  796. $oMyChange = MetaModel::NewObject("CMDBChange");
  797. $oMyChange->Set("date", time());
  798. $oMyChange->Set("userinfo", "Testor");
  799. $iChangeId = $oMyChange->DBInsert();
  800. // echo "Created new change: $iChangeId</br>";
  801. echo "<h3>Planned for loading...</h3>";
  802. $aRes = $oBulk->Process();
  803. print_r($aRes);
  804. echo "<h3>Go for loading...</h3>";
  805. $aRes = $oBulk->Process($oMyChange);
  806. print_r($aRes);
  807. return true;
  808. $oRawData = array(
  809. 'Mammal',
  810. array('species', 'sex', 'speed', 'mother', 'father', 'name', 'height', 'birth'),
  811. "human,male,23,0,0,romulus,192,1971
  812. human,male,23,0,0,remus,154,-50
  813. human,male,23,0,0,julius,160,-49
  814. human,female,23,0,0,cleopatra,142,-50
  815. pig,female,23,0,0,confucius,50,2003"
  816. );
  817. }
  818. }
  819. ///////////////////////////////////////////////////////////////////////////
  820. // Test data load
  821. ///////////////////////////////////////////////////////////////////////////
  822. class TestFullTextSearchOnFarm extends MyFarm
  823. {
  824. static public function GetName()
  825. {
  826. return 'Farm test - full text search';
  827. }
  828. static public function GetDescription()
  829. {
  830. return 'Focus on the full text search feature';
  831. }
  832. protected function DoExecute()
  833. {
  834. echo "<h3>Create protagonists...</h3>";
  835. $iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
  836. $iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
  837. $this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
  838. $this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
  839. $this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
  840. $this->InsertBird('rooster', 'male', 12, 0, 0);
  841. $this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
  842. echo "<h3>Search...</h3>";
  843. $oSearch = new DBObjectSearch('Mammal');
  844. $oSearch->AddCondition_FullText('manof');
  845. //$oResultSet = new DBObjectSet($oSearch);
  846. $this->search_and_show_list($oSearch);
  847. return true;
  848. }
  849. }
  850. ///////////////////////////////////////////////////////////////////////////
  851. // Benchmark queries
  852. ///////////////////////////////////////////////////////////////////////////
  853. class TestItopEfficiency extends TestBizModel
  854. {
  855. static public function GetName()
  856. {
  857. return 'Itop - benchmark';
  858. }
  859. static public function GetDescription()
  860. {
  861. return 'Measure time to perform the queries';
  862. }
  863. static public function GetConfigFile() {return '../config-itop.php';}
  864. protected function DoBenchmark($sOqlQuery)
  865. {
  866. echo "<h3>Testing query: $sOqlQuery</h3>";
  867. $fStart = MyHelpers::getmicrotime();
  868. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  869. {
  870. $oFilter = DBObjectSearch::FromOQL($sOqlQuery);
  871. }
  872. $fDuration = MyHelpers::getmicrotime() - $fStart;
  873. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  874. $fStart = MyHelpers::getmicrotime();
  875. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  876. {
  877. $sSQL = MetaModel::MakeSelectQuery($oFilter);
  878. }
  879. $fDuration = MyHelpers::getmicrotime() - $fStart;
  880. $fBuildDuration = $fDuration / COUNT_BENCHMARK;
  881. $fStart = MyHelpers::getmicrotime();
  882. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  883. {
  884. $res = CMDBSource::Query($sSQL);
  885. }
  886. $fDuration = MyHelpers::getmicrotime() - $fStart;
  887. $fQueryDuration = $fDuration / COUNT_BENCHMARK;
  888. // The fetch could not be repeated with the same results
  889. // But we've seen so far that is was very very quick to exec
  890. // So it makes sense to benchmark it a single time
  891. $fStart = MyHelpers::getmicrotime();
  892. $aRow = CMDBSource::FetchArray($res);
  893. $fDuration = MyHelpers::getmicrotime() - $fStart;
  894. $fFetchDuration = $fDuration;
  895. $fStart = MyHelpers::getmicrotime();
  896. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  897. {
  898. $sOql = $oFilter->ToOQL();
  899. }
  900. $fDuration = MyHelpers::getmicrotime() - $fStart;
  901. $fToOqlDuration = $fDuration / COUNT_BENCHMARK;
  902. echo "<ul>\n";
  903. echo "<li>Parsing: $fParsingDuration</li>\n";
  904. echo "<li>Build: $fBuildDuration</li>\n";
  905. echo "<li>Query: $fQueryDuration</li>\n";
  906. echo "<li>Fetch: $fFetchDuration</li>\n";
  907. echo "<li>ToOql: $fToOqlDuration</li>\n";
  908. echo "</ul>\n";
  909. // Everything but the ToOQL (wich is interesting, anyhow)
  910. $fTotal = $fParsingDuration + $fBuildDuration + $fQueryDuration + $fFetchDuration;
  911. return array(
  912. 'rows' => CMDBSource::NbRows($res),
  913. 'duration (s)' => round($fTotal, 4),
  914. 'parsing (%)' => round(100 * $fParsingDuration / $fTotal, 1),
  915. 'build SQL (%)' => round(100 * $fBuildDuration / $fTotal, 1),
  916. 'query exec (%)' => round(100 * $fQueryDuration / $fTotal, 1),
  917. 'fetch (%)' => round(100 * $fFetchDuration / $fTotal, 1),
  918. 'to OQL (%)' => round(100 * $fToOqlDuration / $fTotal, 1),
  919. 'parsing+build (%)' => round(100 * ($fParsingDuration + $fBuildDuration) / $fTotal, 1),
  920. );
  921. }
  922. protected function DoExecute()
  923. {
  924. define ('COUNT_BENCHMARK', 3);
  925. echo "<p>The test will be repeated ".COUNT_BENCHMARK." times</p>";
  926. $aQueries = array(
  927. 'SELECT CMDBChangeOpSetAttribute',
  928. 'SELECT CMDBChangeOpSetAttribute WHERE id=10',
  929. 'SELECT CMDBChangeOpSetAttribute WHERE id=123456789',
  930. 'SELECT CMDBChangeOpSetAttribute WHERE CMDBChangeOpSetAttribute.id=10',
  931. 'SELECT bizIncidentTicket',
  932. 'SELECT bizIncidentTicket WHERE id=1',
  933. 'SELECT bizPerson',
  934. 'SELECT bizPerson WHERE id=1',
  935. 'SELECT bizIncidentTicket JOIN bizPerson ON bizIncidentTicket.agent_id = bizPerson.id WHERE bizPerson.id = 5',
  936. );
  937. $aStats = array();
  938. foreach ($aQueries as $sOQL)
  939. {
  940. $aStats[$sOQL] = $this->DoBenchmark($sOQL);
  941. }
  942. $aData = array();
  943. foreach ($aStats as $sOQL => $aResults)
  944. {
  945. $aValues = array();
  946. $aValues['OQL'] = htmlentities($sOQL);
  947. foreach($aResults as $sDesc => $sInfo)
  948. {
  949. $aValues[$sDesc] = htmlentities($sInfo);
  950. }
  951. $aData[] = $aValues;
  952. }
  953. echo MyHelpers::make_table_from_assoc_array($aData);
  954. return true;
  955. }
  956. }
  957. ///////////////////////////////////////////////////////////////////////////
  958. // Test data load
  959. ///////////////////////////////////////////////////////////////////////////
  960. class TestItopWebServices extends TestWebServices
  961. {
  962. static public function GetName()
  963. {
  964. return 'Itop - web services';
  965. }
  966. static public function GetDescription()
  967. {
  968. return 'Bulk load and ???';
  969. }
  970. protected function DoExecSingleLoad($aLoadSpec)
  971. {
  972. $sTitle = 'Load: '.$aLoadSpec['class'];
  973. $sClass = $aLoadSpec['class'];
  974. $sCsvData = $aLoadSpec['csvdata'];
  975. $aPostData = array('class' => $sClass, 'csvdata' => $sCsvData);
  976. $sRes = self::DoPostRequestAuth('../webservices/import.php', $aPostData);
  977. echo "<div><h3>$sTitle</h3><pre>$sCsvData</pre><div>$sRes</div></div>";
  978. }
  979. protected function DoExecute()
  980. {
  981. $aLoads = array(
  982. array(
  983. 'class' => 'bizOrganization',
  984. 'csvdata' => "name;code\nWorldCompany;WCY"
  985. ),
  986. array(
  987. 'class' => 'bizLocation',
  988. 'csvdata' => "name;org_id;address\nParis;1;Centre de la Franca"
  989. ),
  990. array(
  991. 'class' => 'bizPerson',
  992. 'csvdata' => "email;name;first_name;org_id;phone\njohn.foo@starac.com;Foo;John;1;+33(1)23456789"
  993. ),
  994. array(
  995. 'class' => 'bizTeam',
  996. 'csvdata' => "name;org_id;location_name\nSquadra Azzura2;1;Paris"
  997. ),
  998. array(
  999. 'class' => 'bizWorkgroup',
  1000. 'csvdata' => "name;org_id;team_id\ntravailleurs alpins;1;6"
  1001. ),
  1002. array(
  1003. 'class' => 'bizIncidentTicket',
  1004. 'csvdata' => "name;title;type;org_id;initial_situation;start_date;next_update;caller_id;workgroup_id;agent_id\nOVSD-12345;server down;Network;1;server was found down;2009-04-10 12:00;2009-04-10 15:00;3;317;5"
  1005. ),
  1006. );
  1007. foreach ($aLoads as $aLoadSpec)
  1008. {
  1009. $this->DoExecSingleLoad($aLoadSpec);
  1010. }
  1011. return true;
  1012. }
  1013. }
  1014. $aWebServices = array(
  1015. array(
  1016. 'verb' => 'CreateIncidentTicket',
  1017. 'args' => array(
  1018. 'desc of ticket', /* sDescription */
  1019. 'initial situation blah blah blah', /* sInitialSituation */
  1020. array('id' => 1), /* aCallerDesc */
  1021. array('id' => 2), /* aCustomerDesc */
  1022. array('id' => 1), /* aWorkgroupDesc */
  1023. array(
  1024. array(
  1025. 'class' => 'logInfra',
  1026. 'search' => array('id' => 108),
  1027. 'link_values' => array('impactoche' => 'plus que critique'),
  1028. ),
  1029. array(
  1030. 'class' => 'bizDevice',
  1031. 'search' => array('name' => 'Router03'),
  1032. 'link_values' => array('impact' => 'ouais bof'),
  1033. ),
  1034. ), /* aImpact */
  1035. 'low' /* sSeverity */
  1036. ),
  1037. ),
  1038. );
  1039. class TestSoap extends TestSoapWebService
  1040. {
  1041. static public function GetName() {return 'Test SOAP';}
  1042. static public function GetDescription() {return 'Do basic stuff to test the SOAP capability';}
  1043. protected function DoExecute()
  1044. {
  1045. $this->m_SoapClient = new SoapClient(
  1046. // null,
  1047. "http://localhost:81/trunk/webservices/Itop.wsdl",
  1048. array(
  1049. //'location' => 'http://localhost:81/trunk/webservices/soapserver.php',
  1050. //'uri' => 'http://test-itop/',
  1051. 'login' => 'admin',
  1052. 'password' => 'admin',
  1053. // note: using the classmap functionality lead to APACHE fault on the server side
  1054. //'classmap' => array('stdClass' => 'ItopError'),
  1055. 'trace' => 1,
  1056. )
  1057. );
  1058. global $aWebServices;
  1059. $aWebService = $aWebServices[0];
  1060. // $oRes = $this->m_SoapClient->CreateIncidentTicket();
  1061. $oRes = call_user_func_array(array($this->m_SoapClient, $aWebService['verb']), $aWebService['args']);
  1062. echo "<pre>\n";
  1063. print_r($oRes);
  1064. echo "</pre>\n";
  1065. print "<pre>\n";
  1066. print "Request: \n".htmlspecialchars($this->m_SoapClient->__getLastRequest()) ."\n";
  1067. print "Response: \n".htmlspecialchars($this->m_SoapClient->__getLastResponse())."\n";
  1068. print "</pre>";
  1069. return true;
  1070. }
  1071. }
  1072. class TestWebServicesDirect extends TestBizModel
  1073. {
  1074. static public function GetName() {return 'Test web services locally';}
  1075. static public function GetDescription() {return 'Invoke the service directly (troubleshooting)';}
  1076. static public function GetConfigFile() {return '../config-itop.php';}
  1077. protected function DoExecute()
  1078. {
  1079. global $aWebServices;
  1080. $aWebService = $aWebServices[0];
  1081. $oWebServices = new WebServices();
  1082. $oRes = call_user_func_array(array($oWebServices, $aWebService['verb']), $aWebService['args']);
  1083. echo "<pre>\n";
  1084. print_r($oRes);
  1085. echo "</pre>\n";
  1086. return true;
  1087. }
  1088. }
  1089. ?>