testlist.inc.php 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780
  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. * Core test list
  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. class TestSQLQuery extends TestScenarioOnDB
  25. {
  26. static public function GetName() {return 'SQLQuery';}
  27. 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';}
  28. static public function GetDBHost() {return 'localhost';}
  29. static public function GetDBUser() {return 'root';}
  30. static public function GetDBPwd() {return '';}
  31. static public function GetDBName() {return 'TestSQLQuery';}
  32. static public function GetDBSubName() {return 'taratata';}
  33. protected function DoPrepare()
  34. {
  35. parent::DoPrepare();
  36. cmdbSource::CreateTable('CREATE TABLE `myTable` (myKey INT(11) NOT NULL auto_increment, column1 VARCHAR(255), column2 VARCHAR(255), PRIMARY KEY (`myKey`)) ENGINE = innodb');
  37. 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');
  38. 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');
  39. }
  40. protected function DoExecute()
  41. {
  42. $oQuery = new SQLQuery(
  43. $sTable = 'myTable',
  44. $sTableAlias = 'myTableAlias',
  45. $aFields = array('column1'=>new FieldExpression('column1', 'myTableAlias'), 'column2'=>new FieldExpression('column2', 'myTableAlias')),
  46. $oCondition = new BinaryExpression(new FieldExpression('column1', 'myTableAlias'), 'LIKE', new ScalarExpression('trash')),
  47. $aFullTextNeedles = array('column1'),
  48. $bToDelete = false,
  49. $aValues = array()
  50. );
  51. $oQuery->AddCondition(Expression::FromOQL('DATE(NOW() - 1200 * 2) > \'2008-07-31\''));
  52. $oSubQuery1 = new SQLQuery(
  53. $sTable = 'myTable1',
  54. $sTableAlias = 'myTable1Alias',
  55. $aFields = array('column1_1'=>new FieldExpression('column1', 'myTableAlias'), 'column1_2'=>new FieldExpression('column1', 'myTableAlias')),
  56. $oCondition = new TrueSQLExpression,
  57. $aFullTextNeedles = array(),
  58. $bToDelete = false,
  59. $aValues = array()
  60. );
  61. $oSubQuery2 = new SQLQuery(
  62. $sTable = 'myTable2',
  63. $sTableAlias = 'myTable2Alias',
  64. $aFields = array('column2_1'=>new FieldExpression('column2', 'myTableAlias'), 'column2_2'=>new FieldExpression('column2', 'myTableAlias')),
  65. $oCondition = new TrueSQLExpression,
  66. $aFullTextNeedles = array(),
  67. $bToDelete = false,
  68. $aValues = array()
  69. );
  70. $oQuery->AddInnerJoin($oSubQuery1, 'column1', 'column1_1');
  71. $oQuery->AddLeftJoin($oSubQuery2, 'column2', 'column2_2');
  72. $oQuery->DisplayHtml();
  73. $oQuery->RenderDelete();
  74. $oQuery->RenderUpdate();
  75. echo '<p>'.$oQuery->RenderSelect().'</p>';
  76. $oQuery->RenderSelect(array('column1'));
  77. $oQuery->RenderSelect(array('column1', 'column2'));
  78. }
  79. }
  80. class TestOQLParser extends TestFunction
  81. {
  82. static public function GetName() {return 'Check OQL parsing';}
  83. static public function GetDescription() {return 'Attempts a series of queries, and in particular those with a bad syntax';}
  84. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  85. {
  86. $oOql = new OqlInterpreter($sQuery);
  87. try
  88. {
  89. $oTrash = $oOql->Parse(); // Not expecting a given format, otherwise use ParseExpression/ParseObjectQuery/ParseValueSetQuery
  90. MyHelpers::var_dump_html($oTrash, true);
  91. }
  92. catch (OQLException $OqlException)
  93. {
  94. if ($bIsCorrectQuery)
  95. {
  96. echo "<p>More info on this unexpected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  97. throw $OqlException;
  98. return false;
  99. }
  100. else
  101. {
  102. // Everything is fine :-)
  103. echo "<p>More info on this expected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  104. return true;
  105. }
  106. }
  107. // The query was correctly parsed, was it expected to be correct ?
  108. if ($bIsCorrectQuery)
  109. {
  110. return true;
  111. }
  112. else
  113. {
  114. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  115. return false;
  116. }
  117. }
  118. protected function TestQuery($sQuery, $bIsCorrectQuery)
  119. {
  120. if (!$this->CheckQuery($sQuery, $bIsCorrectQuery))
  121. {
  122. return false;
  123. }
  124. return true;
  125. }
  126. public function DoExecute()
  127. {
  128. $aQueries = array(
  129. 'SELECT toto' => true,
  130. 'SELECT toto WHERE toto.a = 1' => true,
  131. 'SELECT toto WHERE toto.a=1' => true,
  132. 'SELECT toto WHERE toto.a = "1"' => true,
  133. 'SELECT toto WHHHERE toto.a = "1"' => false,
  134. 'SELECT toto WHERE toto.a == "1"' => false,
  135. 'SELECT toto WHERE toto.a % 1' => false,
  136. //'SELECT toto WHERE toto.a LIKE 1' => false,
  137. 'SELECT toto WHERE toto.a like \'arg\'' => false,
  138. 'SELECT toto WHERE toto.a NOT LIKE "That\'s it"' => true,
  139. 'SELECT toto WHERE toto.a NOT LIKE "That\'s "it""' => false,
  140. 'SELECT toto WHERE toto.a NOT LIKE "That\'s \\"it\\""' => true,
  141. 'SELECT toto WHERE toto.a NOT LIKE \'That"s it\'' => true,
  142. 'SELECT toto WHERE toto.a NOT LIKE \'That\'s it\'' => false,
  143. 'SELECT toto WHERE toto.a NOT LIKE \'That\\\'s it\'' => true,
  144. 'SELECT toto WHERE toto.a NOT LIKE "blah \\ truc"' => false,
  145. 'SELECT toto WHERE toto.a NOT LIKE "blah \\\\ truc"' => true,
  146. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\ truc\'' => false,
  147. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\\\ truc\'' => true,
  148. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  149. 'SELECT toto WHERE toto.a NOT LIKE "\\""' => true,
  150. 'SELECT toto WHERE toto.a NOT LIKE "\\"\\\\"' => true,
  151. 'SELECT toto WHERE toto.a NOT LIKE "\\\\\\""' => true,
  152. 'SELECT toto WHERE toto.a NOT LIKE ""' => true,
  153. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  154. "SELECT UserRightsMatrixClassGrant WHERE UserRightsMatrixClassGrant.class = 'lnkContactRealObject' AND UserRightsMatrixClassGrant.action = 'modify' AND UserRightsMatrixClassGrant.login = 'Denis'" => true,
  155. "SELECT A WHERE A.col1 = 'lit1' AND A.col2 = 'lit2' AND A.col3 = 'lit3'" => true,
  156. 'SELECT toto WHERE toto.a NOT LIKE "blah" AND toto.b LIKE "foo"' => true,
  157. //'SELECT toto WHERE toto.a > \'asd\'' => false,
  158. 'SELECT toto WHERE toto.a = 1 AND toto.b LIKE "x" AND toto.f >= 12345' => true,
  159. 'SELECT Device JOIN Site ON Device.site = Site.id' => true,
  160. 'SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id' => true,
  161. "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,
  162. "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,
  163. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + B.col2 * B.col1 = A.col2" => true,
  164. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + (B.col2 * B.col1) = A.col2" => true,
  165. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 + B.col2) * B.col1 = A.col2" => true,
  166. 'SELECT Device AS D_ JOIN Site AS S_ ON D_.site = S_.id WHERE S_.country = "Francia"' => true,
  167. // Several objects in a row...
  168. //
  169. 'SELECT A FROM A' => true,
  170. 'SELECT A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  171. 'SELECT A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  172. 'SELECT B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  173. 'SELECT A,B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  174. 'SELECT A, B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  175. 'SELECT B,A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => true,
  176. 'SELECT A, B,C FROM A JOIN B ON A.myB = B.id' => false,
  177. 'SELECT C FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2' => false,
  178. );
  179. $iErrors = 0;
  180. foreach($aQueries as $sQuery => $bIsCorrectQuery)
  181. {
  182. $sIsOk = $bIsCorrectQuery ? 'good' : 'bad';
  183. echo "<h4>Testing query: $sQuery ($sIsOk)</h4>\n";
  184. $bRet = $this->TestQuery($sQuery, $bIsCorrectQuery);
  185. if (!$bRet) $iErrors++;
  186. }
  187. return ($iErrors == 0);
  188. }
  189. }
  190. class TestCSVParser extends TestFunction
  191. {
  192. static public function GetName() {return 'Check CSV parsing';}
  193. static public function GetDescription() {return 'Loads a set of CSV data';}
  194. public function DoExecute()
  195. {
  196. $sDataFile = '"field1","field2","field3"
  197. "a","b","c"
  198. a,b,c
  199. "","",""
  200. ,,
  201. "a""","b","c"
  202. "a1
  203. a2","b","c"
  204. "a1,a2","b","c"
  205. "a","b","c1,"",c2
  206. ,c3"
  207. "a","b","ouf !"
  208. ';
  209. $sDataFile = '?field1?;?field2?;?field3?
  210. ?a?;?b?;?c?
  211. a;b;c
  212. ??;??;??
  213. ;;
  214. ?a"?;?b?;?c?
  215. ?a1
  216. a2?;?b?;?c?
  217. ?a1,a2?;?b?;?c?
  218. ?a?;?b?;?c1,",c2
  219. ,c3?
  220. ?a?;?b?;?ouf !?
  221. ';
  222. echo "<pre style=\"font-style:italic;\">\n";
  223. print_r($sDataFile);
  224. echo "</pre>\n";
  225. $aExpectedResult = array(
  226. //array('field1', 'field2', 'field3'),
  227. array('a', 'b', 'c'),
  228. array('a', 'b', 'c'),
  229. array('', '', ''),
  230. array('', '', ''),
  231. array('a"', 'b', 'c'),
  232. array("a1\na2", 'b', 'c'),
  233. array('a1,a2', 'b', 'c'),
  234. array('a', 'b', "c1,\",c2\n,c3"),
  235. array('a', 'b', 'ouf !'),
  236. array('a', 'b', 'a'),
  237. );
  238. $oCSVParser = new CSVParser($sDataFile, ';', '?');
  239. $aData = $oCSVParser->ToArray(1, null, 0);
  240. $iIssues = 0;
  241. echo "<table border=\"1\">\n";
  242. foreach ($aData as $iRow => $aRow)
  243. {
  244. echo "<tr>\n";
  245. foreach ($aRow as $iCol => $sCell)
  246. {
  247. if (empty($sCell))
  248. {
  249. $sCellValue = '&nbsp;';
  250. }
  251. else
  252. {
  253. $sCellValue = htmlentities($sCell);
  254. }
  255. if (!isset($aExpectedResult[$iRow][$iCol]))
  256. {
  257. $iIssues++;
  258. $sCellValue = "<span style =\"color: red; background-color: grey;\">$sCellValue</span>";
  259. }
  260. elseif ($aExpectedResult[$iRow][$iCol] != $sCell)
  261. {
  262. $iIssues++;
  263. $sCellValue = "<span style =\"color: red; background-color: lightgrey;\">$sCellValue</span>, expecting '<span style =\"color: green; background-color: lightgrey;\">".$aExpectedResult[$iRow][$iCol]."</span>'";
  264. }
  265. echo "<td><pre>$sCellValue</pre></td>";
  266. }
  267. echo "</tr>\n";
  268. }
  269. echo "</table>\n";
  270. return ($iIssues > 0);
  271. }
  272. }
  273. class TestGenericItoMyModel extends TestBizModelGeneric
  274. {
  275. static public function GetName()
  276. {
  277. return 'Generic RO test on '.self::GetConfigFile();
  278. }
  279. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  280. }
  281. class TestGenericItopBigModel extends TestBizModelGeneric
  282. {
  283. static public function GetName()
  284. {
  285. return 'Generic RO test on '.self::GetConfigFile();
  286. }
  287. static public function GetConfigFile() {return '../config-test-itopv06.php';}
  288. }
  289. class TestUserRightsMatrixItop extends TestUserRights
  290. {
  291. static public function GetName()
  292. {
  293. return 'User rights test on user rights matrix';
  294. }
  295. static public function GetDescription()
  296. {
  297. return 'blah blah blah';
  298. }
  299. public function DoPrepare()
  300. {
  301. parent::DoPrepare();
  302. MetaModel::Startup('../config-test-itopv06.php');
  303. }
  304. protected function DoExecute()
  305. {
  306. $sUser = 'Romain';
  307. echo "<p>Totor: ".(UserRights::Login('Totor', 'toto') ? 'ok' : 'NO')."</p>\n";
  308. echo "<p>Romain: ".(UserRights::Login('Romain', 'toto') ? 'ok' : 'NO')."</p>\n";
  309. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  310. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  311. echo "<p>Denis (impersonate) : ".(UserRights::Impersonate('Denis', 'tutu') ? 'ok' : 'NO')."</p>\n";
  312. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  313. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  314. UserRights::GetFilter('bizOrganization'); // returns a filter object
  315. $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT bizOrganization"));
  316. echo "<p>IsActionAllowed...".(UserRights::IsActionAllowed('bizOrganization', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  317. echo "<p>IsStimulusAllowed...".(UserRights::IsStimulusAllowed('bizOrganization', 'myStimulus', $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  318. echo "<p>IsActionAllowedOnAttribute...".(UserRights::IsActionAllowedOnAttribute('bizOrganization', 'myattribute', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  319. return true;
  320. }
  321. }
  322. ///////////////////////////////////////////////////////////////////////////
  323. // Test a complex biz model on the fly
  324. ///////////////////////////////////////////////////////////////////////////
  325. class TestMyBizModel extends TestBizModel
  326. {
  327. static public function GetName()
  328. {
  329. return 'A series of tests on a weird business model';
  330. }
  331. static public function GetDescription()
  332. {
  333. return 'Attempts various operations and build complex queries';
  334. }
  335. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  336. function test_linksinfo()
  337. {
  338. echo "<h4>Enum links</h4>";
  339. MyHelpers::var_dump_html(MetaModel::EnumReferencedClasses("cmdbTeam"));
  340. MyHelpers::var_dump_html(MetaModel::EnumReferencingClasses("Organization"));
  341. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses());
  342. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdbContact"));
  343. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdWorkshop"));
  344. MyHelpers::var_dump_html(MetaModel::GetLinkLabel("Liens_entre_contacts_et_workshop", "toworkshop"));
  345. }
  346. function test_list_attributes()
  347. {
  348. echo "<h4>List attributes</h4>";
  349. foreach(MetaModel::ListAttributeDefs("cmdbTeam") as $sAttCode=>$oAttDef)
  350. {
  351. echo $oAttDef->GetLabel()." / ".$oAttDef->GetDescription()." / ".$oAttDef->GetType()."</br>\n";
  352. }
  353. }
  354. function test_search()
  355. {
  356. echo "<h4>Two searches</h4>";
  357. $oFilterAllDevs = new DBObjectSearch("cmdbTeam");
  358. $oAllDevs = new DBObjectSet($oFilterAllDevs);
  359. echo "Found ".$oAllDevs->Count()." items.</br>\n";
  360. while ($oDev = $oAllDevs->Fetch())
  361. {
  362. $aValues = array();
  363. foreach(MetaModel::GetAttributesList($oAllDevs->GetClass()) as $sAttCode)
  364. {
  365. $aValues[] = MetaModel::GetLabel(get_class($oDev), $sAttCode)." (".MetaModel::GetDescription(get_class($oDev), $sAttCode).") = ".$oDev->GetAsHTML($sAttCode);
  366. }
  367. echo $oDev->GetKey()." => ".implode(", ", $aValues)."</br>\n";
  368. }
  369. // a second one
  370. $oMyFilter = new DBObjectSearch("cmdbContact");
  371. //$oMyFilter->AddCondition("name", "aii", "Finishes with");
  372. $oMyFilter->AddCondition("name", "aii");
  373. $this->search_and_show_list($oMyFilter);
  374. }
  375. function test_reload()
  376. {
  377. echo "<h4>Reload</h4>";
  378. $team = MetaModel::GetObject("cmdbContact", "2");
  379. echo "Chargement de l'attribut headcount: {$team->Get("headcount")}</br>\n";
  380. MyHelpers::var_dump_html($team);
  381. }
  382. function test_setattribute()
  383. {
  384. echo "<h4>Set attribute and update</h4>";
  385. $team = MetaModel::GetObject("cmdbTeam", "2");
  386. $team->Set("headcount", rand(1,1000));
  387. $team->Set("email", "Luis ".rand(9,250));
  388. MyHelpers::var_dump_html($team->ListChanges());
  389. echo "New headcount = {$team->Get("headcount")}</br>\n";
  390. echo "Computed name = {$team->Get("name")}</br>\n";
  391. $oMyChange = MetaModel::NewObject("CMDBChange");
  392. $oMyChange->Set("date", time());
  393. $oMyChange->Set("userinfo", "test_setattribute / Made by robot #".rand(1,100));
  394. $iChangeId = $oMyChange->DBInsert();
  395. //MetaModel::StartDebugQuery();
  396. $team->DBUpdateTracked($oMyChange);
  397. //MetaModel::StopDebugQuery();
  398. echo "<h4>Check the modified team</h4>";
  399. $oTeam = MetaModel::GetObject("cmdbTeam", "2");
  400. MyHelpers::var_dump_html($oTeam);
  401. }
  402. function test_newobject()
  403. {
  404. $oMyChange = MetaModel::NewObject("CMDBChange");
  405. $oMyChange->Set("date", time());
  406. $oMyChange->Set("userinfo", "test_newobject / Made by robot #".rand(1,100));
  407. $iChangeId = $oMyChange->DBInsert();
  408. echo "<h4>Create a new object (team)</h4>";
  409. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  410. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  411. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  412. $oNewTeam->Set("email", null);
  413. $oNewTeam->Set("owner", "ITOP");
  414. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  415. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  416. echo "Created new team: $iId</br>";
  417. echo "<h4>Delete team #$iId</h4>";
  418. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  419. $oTeam->DBDeleteTracked($oMyChange);
  420. echo "Deleted team: $iId</br>";
  421. MyHelpers::var_dump_html($oTeam);
  422. }
  423. function test_updatecolumn()
  424. {
  425. $oMyChange = MetaModel::NewObject("CMDBChange");
  426. $oMyChange->Set("date", time());
  427. $oMyChange->Set("userinfo", "test_updatecolumn / Made by robot #".rand(1,100));
  428. $iChangeId = $oMyChange->DBInsert();
  429. $sNewEmail = "updatecol".rand(9,250)."@quedlaballe.com";
  430. echo "<h4>Update a the email: set to '$sNewEmail'</h4>";
  431. $oMyFilter = new DBObjectSearch("cmdbContact");
  432. $oMyFilter->AddCondition("name", "o", "Contains");
  433. echo "Candidates before:</br>";
  434. $this->search_and_show_list($oMyFilter);
  435. MetaModel::BulkUpdateTracked($oMyChange, $oMyFilter, array("email" => $sNewEmail));
  436. echo "Candidates after:</br>";
  437. $this->search_and_show_list($oMyFilter);
  438. }
  439. function test_error()
  440. {
  441. trigger_error("Stop requested", E_USER_ERROR);
  442. }
  443. function test_changetracking()
  444. {
  445. echo "<h4>Create a change</h4>";
  446. $oMyChange = MetaModel::NewObject("CMDBChange");
  447. $oMyChange->Set("date", time());
  448. $oMyChange->Set("userinfo", "Made by robot #".rand(1,100));
  449. $iChangeId = $oMyChange->DBInsert();
  450. echo "Created new change: $iChangeId</br>";
  451. MyHelpers::var_dump_html($oMyChange);
  452. echo "<h4>Create a new object (team)</h4>";
  453. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  454. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  455. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  456. $oNewTeam->Set("email", null);
  457. $oNewTeam->Set("owner", "ITOP");
  458. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  459. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  460. echo "Created new team: $iId</br>";
  461. echo "<h4>Delete team #$iId</h4>";
  462. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  463. $oTeam->DBDeleteTracked($oMyChange);
  464. echo "Deleted team: $iId</br>";
  465. MyHelpers::var_dump_html($oTeam);
  466. }
  467. function test_zlist()
  468. {
  469. echo "<h4>Test ZLists</h4>";
  470. $aZLists = MetaModel::EnumZLists();
  471. foreach ($aZLists as $sListCode)
  472. {
  473. $aListInfos = MetaModel::GetZListInfo($sListCode);
  474. echo "<h4>List '".$sListCode."' (".$aListInfos["description"].") of type '".$aListInfos["type"]."'</h5>\n";
  475. foreach (MetaModel::GetSubclasses("cmdbObjectHomeMade") as $sKlass)
  476. {
  477. $aItems = MetaModel::GetZListItems($sKlass, $sListCode);
  478. if (count($aItems) == 0) continue;
  479. echo "$sKlass - $sListCode : {".implode(", ", $aItems)."}</br>\n";
  480. }
  481. }
  482. echo "<h4>IsAttributeInZList()... </h4>";
  483. echo "Liens_entre_contacts_et_workshop::ws_info in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "ws_info") ? "yes" : "no")."</br>\n";
  484. echo "Liens_entre_contacts_et_workshop::toworkshop in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "toworkshop") ? "yes" : "no")."</br>\n";
  485. }
  486. function test_pkey()
  487. {
  488. echo "<h4>Test search on pkey</h4>";
  489. $sExpr1 = "SELECT cmdbContact WHERE id IN (40, 42)";
  490. $sExpr2 = "SELECT cmdbContact WHERE IN NOT IN (40, 42)";
  491. $this->search_and_show_list_from_oql($sExpr1);
  492. $this->search_and_show_list_from_oql($sExpr2);
  493. echo "Et maintenant, on fusionne....</br>\n";
  494. $oSet1 = new CMDBObjectSet(DBObjectSearch::FromOQL($sExpr1));
  495. $oSet2 = new CMDBObjectSet(DBObjectSearch::FromOQL($sExpr2));
  496. $oIntersect = $oSet1->CreateIntersect($oSet2);
  497. $oDelta = $oSet1->CreateDelta($oSet2);
  498. $oMerge = clone $oSet1;
  499. $oMerge->Merge($oSet2);
  500. $oMerge->Merge($oSet2);
  501. echo "Set1 - Found ".$oSet1->Count()." items.</br>\n";
  502. echo "Set2 - Found ".$oSet2->Count()." items.</br>\n";
  503. echo "Intersect - Found ".$oIntersect->Count()." items.</br>\n";
  504. echo "Delta - Found ".$oDelta->Count()." items.</br>\n";
  505. echo "Merge - Found ".$oMerge->Count()." items.</br>\n";
  506. //$this->show_list($oObjSet);
  507. }
  508. function test_relations()
  509. {
  510. echo "<h4>Test relations</h4>";
  511. //MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbObjectHomeMade", "Potes"));
  512. MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbContact", "Potes"));
  513. $iMaxDepth = 9;
  514. echo "Max depth = $iMaxDepth</br>\n";
  515. $oObj = MetaModel::GetObject("cmdbContact", 18);
  516. $aRels = $oObj->GetRelatedObjects("Potes", $iMaxDepth);
  517. echo $oObj->Get('name')." has some 'Potes'...</br>\n";
  518. foreach ($aRels as $sClass => $aObjs)
  519. {
  520. echo "$sClass, count = ".count($aObjs)." =&gt; ".implode(', ', array_keys($aObjs))."</br>\n";
  521. $oObjectSet = CMDBObjectSet::FromArray($sClass, $aObjs);
  522. $this->show_list($oObjectSet);
  523. }
  524. echo "<h4>Test relations - same results, by the mean of a OQL</h4>";
  525. $this->search_and_show_list_from_oql("cmdbContact: RELATED (Potes, $iMaxDepth) TO (cmdbContact: pkey = 18)");
  526. }
  527. function test_linkedset()
  528. {
  529. echo "<h4>Linked set attributes</h4>\n";
  530. $oObj = MetaModel::GetObject("cmdbContact", 18);
  531. echo "<h5>Current workshops</h5>\n";
  532. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  533. $this->show_list($oSetWorkshopsCurr);
  534. echo "<h5>Setting workshops</h5>\n";
  535. $oNewLink = new cmdbLiens();
  536. $oNewLink->Set('toworkshop', 2);
  537. $oNewLink->Set('function', 'mafonctioooon');
  538. $oNewLink->Set('a1', 'tralala1');
  539. $oNewLink->Set('a2', 'F7M');
  540. $oSetWorkshops = CMDBObjectSet::FromArray("cmdbLiens", array($oNewLink));
  541. $oObj->Set("myworkshops", $oSetWorkshops);
  542. $this->show_list($oSetWorkshops);
  543. echo "<h5>New workshops</h5>\n";
  544. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  545. $this->show_list($oSetWorkshopsCurr);
  546. $oMyChange = MetaModel::NewObject("CMDBChange");
  547. $oMyChange->Set("date", time());
  548. $oMyChange->Set("userinfo", "test_linkedset / Made by robot #".rand(1,100));
  549. $iChangeId = $oMyChange->DBInsert();
  550. $oObj->DBUpdateTracked($oMyChange);
  551. $oObj = MetaModel::GetObject("cmdbContact", 18);
  552. echo "<h5>After the write</h5>\n";
  553. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  554. $this->show_list($oSetWorkshopsCurr);
  555. }
  556. function test_object_lifecycle()
  557. {
  558. echo "<h4>Test object lifecycle</h4>";
  559. MyHelpers::var_dump_html(MetaModel::GetStateAttributeCode("cmdbContact"));
  560. MyHelpers::var_dump_html(MetaModel::EnumStates("cmdbContact"));
  561. MyHelpers::var_dump_html(MetaModel::EnumStimuli("cmdbContact"));
  562. foreach(MetaModel::EnumStates("cmdbContact") as $sStateCode => $aStateDef)
  563. {
  564. echo "<p>Transition from <strong>$sStateCode</strong></p>\n";
  565. MyHelpers::var_dump_html(MetaModel::EnumTransitions("cmdbContact", $sStateCode));
  566. }
  567. $oObj = MetaModel::GetObject("cmdbContact", 18);
  568. echo "Current state: ".$oObj->GetState()."... let's go to school...";
  569. MyHelpers::var_dump_html($oObj->EnumTransitions());
  570. $oObj->ApplyStimulus("toschool");
  571. echo "New state: ".$oObj->GetState()."... let's get older...";
  572. MyHelpers::var_dump_html($oObj->EnumTransitions());
  573. $oObj->ApplyStimulus("raise");
  574. echo "New state: ".$oObj->GetState()."... let's try to go further... (should give an error)";
  575. MyHelpers::var_dump_html($oObj->EnumTransitions());
  576. $oObj->ApplyStimulus("raise"); // should give an error
  577. }
  578. protected function DoExecute()
  579. {
  580. // $this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  581. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  582. //$this->test_linksinfo();
  583. //$this->test_list_attributes();
  584. //$this->test_search();
  585. //$this->test_reload();
  586. //$this->test_newobject();
  587. $this->test_setattribute();
  588. //$this->test_updatecolumn();
  589. //$this->test_error();
  590. //$this->test_changetracking();
  591. $this->test_zlist();
  592. $this->test_OQL();
  593. //$this->test_pkey();
  594. $this->test_relations();
  595. $this->test_linkedset();
  596. $this->test_object_lifecycle();
  597. }
  598. }
  599. ///////////////////////////////////////////////////////////////////////////
  600. // Test a complex biz model on the fly
  601. ///////////////////////////////////////////////////////////////////////////
  602. abstract class MyFarm extends TestBizModel
  603. {
  604. static public function GetConfigFile() {return '../config-test-farm.php';}
  605. protected function DoPrepare()
  606. {
  607. parent::DoPrepare();
  608. $this->ResetDB();
  609. MetaModel::DBCheckIntegrity();
  610. }
  611. protected function InsertMammal($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $sName, $iHeight, $sBirth)
  612. {
  613. $oNew = MetaModel::NewObject('Mammal');
  614. $oNew->Set('species', $sSpecies);
  615. $oNew->Set('sex', $sSex);
  616. $oNew->Set('speed', $iSpeed);
  617. $oNew->Set('mother', $iMotherid);
  618. $oNew->Set('father', $iFatherId);
  619. $oNew->Set('name', $sName);
  620. $oNew->Set('height', $iHeight);
  621. $oNew->Set('birth', $sBirth);
  622. return $this->ObjectToDB($oNew);
  623. }
  624. protected function InsertBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId)
  625. {
  626. $oNew = MetaModel::NewObject('Bird');
  627. $oNew->Set('species', $sSpecies);
  628. $oNew->Set('sex', $sSex);
  629. $oNew->Set('speed', $iSpeed);
  630. $oNew->Set('mother', $iMotherid);
  631. $oNew->Set('father', $iFatherId);
  632. return $this->ObjectToDB($oNew);
  633. }
  634. protected function InsertFlyingBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $iFlyingSpeed)
  635. {
  636. $oNew = MetaModel::NewObject('FlyingBird');
  637. $oNew->Set('species', $sSpecies);
  638. $oNew->Set('sex', $sSex);
  639. $oNew->Set('speed', $iSpeed);
  640. $oNew->Set('mother', $iMotherid);
  641. $oNew->Set('father', $iFatherId);
  642. $oNew->Set('flyingspeed', $iFlyingSpeed);
  643. return $this->ObjectToDB($oNew);
  644. }
  645. private function InsertGroup($sName, $iLeaderId)
  646. {
  647. $oNew = MetaModel::NewObject('Group');
  648. $oNew->Set('name', $sName);
  649. $oNew->Set('leader', $iLeaderId);
  650. $iId = $oNew->DBInsertNoReload();
  651. return $iId;
  652. }
  653. }
  654. class TestQueriesOnFarm extends MyFarm
  655. {
  656. static public function GetName()
  657. {
  658. return 'Farm test';
  659. }
  660. static public function GetDescription()
  661. {
  662. return 'A series of tests on the farm business model (SQL generation)';
  663. }
  664. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  665. {
  666. if ($bIsCorrectQuery)
  667. {
  668. echo "<h4 style=\"color:green;\">$sQuery</h4>\n";
  669. }
  670. else
  671. {
  672. echo "<h4 style=\"color:red;\">$sQuery</h3>\n";
  673. }
  674. try
  675. {
  676. //$oOql = new OqlInterpreter($sQuery);
  677. //$oTrash = $oOql->ParseObjectQuery();
  678. //MyHelpers::var_dump_html($oTrash, true);
  679. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  680. }
  681. catch (OQLException $oOqlException)
  682. {
  683. if ($bIsCorrectQuery)
  684. {
  685. echo "<p>More info on this unexpected failure:<br/>".$oOqlException->getHtmlDesc()."</p>\n";
  686. throw $oOqlException;
  687. return false;
  688. }
  689. else
  690. {
  691. // Everything is fine :-)
  692. echo "<p>More info on this expected failure:\n";
  693. echo "<ul>\n";
  694. echo "<li>".get_class($oOqlException)."</li>\n";
  695. echo "<li>".$oOqlException->getMessage()."</li>\n";
  696. echo "<li>".$oOqlException->getHtmlDesc()."</li>\n";
  697. echo "</ul>\n";
  698. echo "</p>\n";
  699. return true;
  700. }
  701. }
  702. // The query was correctly parsed, was it expected to be correct ?
  703. if (!$bIsCorrectQuery)
  704. {
  705. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  706. return false;
  707. }
  708. echo "<p>To OQL: ".$oMyFilter->ToOQL()."</p>";
  709. $this->search_and_show_list($oMyFilter);
  710. //echo "<p>first pass<p>\n";
  711. //MyHelpers::var_dump_html($oMyFilter, true);
  712. $sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  713. //echo "<p>second pass<p>\n";
  714. //MyHelpers::var_dump_html($oMyFilter, true);
  715. //$sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  716. $sSerialize = $oMyFilter->serialize();
  717. echo "<p>Serialized:$sSerialize</p>\n";
  718. $oFilter2 = DBObjectSearch::unserialize($sSerialize);
  719. try
  720. {
  721. $sQuery2 = MetaModel::MakeSelectQuery($oFilter2);
  722. }
  723. catch (Exception $e)
  724. {
  725. echo "<p>Could not compute the query after unserialize</p>\n";
  726. echo "<p>Query 1: $sQuery1</p>\n";
  727. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  728. throw $e;
  729. }
  730. //if ($oFilter2 != $oMyFilter) no, they may differ while the resulting query is the same!
  731. if ($sQuery1 != $sQuery2)
  732. {
  733. echo "<p>serialize/unserialize mismatch :-(</p>\n";
  734. MyHelpers::var_cmp_html($sQuery1, $sQuery2);
  735. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  736. return false;
  737. }
  738. return true;
  739. }
  740. protected function DoExecute()
  741. {
  742. // $this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  743. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  744. echo "<h3>Create protagonists...</h3>";
  745. $iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
  746. $iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
  747. $this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
  748. $this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
  749. $this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
  750. $this->InsertBird('rooster', 'male', 12, 0, 0);
  751. $this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
  752. // Benchmarking
  753. //
  754. if (false)
  755. {
  756. define ('COUNT_BENCHMARK', 10);
  757. echo "<h3>Parsing a long query, ".COUNT_BENCHMARK." times</h3>";
  758. $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)";
  759. $fStart = MyHelpers::getmicrotime();
  760. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  761. {
  762. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  763. }
  764. $fDuration = MyHelpers::getmicrotime() - $fStart;
  765. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  766. echo "<p>Mean time by op: $fParsingDuration</p>";
  767. }
  768. echo "<h3>Test queries...</h3>";
  769. $aQueries = array(
  770. 'SELECT Animal' => true,
  771. 'SELECT Animal WHERE Animal.pkey = 1' => false,
  772. 'SELECT Animal WHERE Animal.id = 1' => true,
  773. 'SELECT Aniiimal' => false,
  774. 'SELECTe Animal' => false,
  775. 'SELECT * FROM Animal' => false,
  776. 'SELECT Animal AS zoo WHERE zoo.species = \'human\'' => true,
  777. 'SELECT Animal AS zoo WHERE species = \'human\'' => true,
  778. 'SELECT Animal AS zoo WHERE espece = \'human\'' => false,
  779. 'SELECT Animal AS zoo WHERE zoo.species IN (\'human\', "pig")' => true,
  780. 'SELECT Animal AS zoo WHERE CONCATENATION(zoo.species, zoo.sex) LIKE "hum%male"' => false,
  781. 'SELECT Animal AS zoo WHERE CONCAT(zoo.species, zoo.sex) LIKE "hum%male"' => true,
  782. 'SELECT Animal AS zoo WHERE zoo.species NOT IN (\'human\', "pig")' => true,
  783. 'SELECT Animal AS zoo WHERE zoo.kind = \'human\'' => false,
  784. 'SELECT Animal WHERE Animal.species = \'human\' AND Animal.sex = \'female\'' => true,
  785. 'SELECT Mammal AS x WHERE (x.species = \'human\' AND x.name LIKE \'ro%\') OR (x.species = \'donkey\' AND x.name LIKE \'po%\')' => true,
  786. 'SELECT Mammal AS x WHERE x.species = \'human\' AND x.name LIKE \'ro%\' OR x.species = \'donkey\' AND x.name LIKE \'po%\'' => true,
  787. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  788. 'SELECT Mammal AS m WHERE DAY(m.birth) = 19' => true,
  789. 'SELECT Mammal AS m WHERE YEAR(m.birth) = 1971' => true,
  790. 'SELECT Mammal AS m WHERE m.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR)' => true,
  791. 'SELECT Mammal AS m WHERE m.birth > DATE_SUB(NOW(), INTERVAL 2000 DAY)' => true,
  792. 'SELECT Mammal AS m WHERE (TO_DAYS(NOW()) - TO_DAYS(m.birth)) > 2000' => true,
  793. 'SELECT Mammal AS m WHERE m.name = IF(FLOOR(ROUND(m.height)) > 2, "pomme", "romain")' => true,
  794. 'SELECT Mammal AS m WHERE (1 + 2' => false,
  795. 'SELECT Mammal AS m WHERE (1 + 2 * 4 / 23) > 0' => true,
  796. 'SELECT Mammal AS m WHERE (4 / 23 * 2 + 1) > 0' => true,
  797. 'SELECT Mammal AS m WHERE 1/0' => true,
  798. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  799. 'SELECT Animal JOIN Group ON Group.leader = Animal.id' => true,
  800. 'SELECT Group JOIN Animal ON Group.leader = Animal.id' => true,
  801. 'SELECT Animal AS A JOIN Group AS G1 ON G1.leader = A.id' => true,
  802. 'SELECT Animal AS A JOIN Group AS G ON FooClass.leader = A.id' => false,
  803. 'SELECT Animal AS A JOIN Group AS G ON G.leader = FooClass.id' => false,
  804. 'SELECT Animal AS A JOIN Group AS G ON G.masterchief = A.id' => false,
  805. 'SELECT Animal AS A JOIN Group AS G ON A.id = G.leader' => false,
  806. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.qwerty = 123' => false,
  807. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.name LIKE "a%"' => true,
  808. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.id = 1' => true,
  809. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE id = 1' => false,
  810. 'SELECT Animal AS A JOIN Group AS G ON A.member = G.id' => false,
  811. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id' => true,
  812. 'SELECT Mammal AS M JOIN Group AS G ON A.member = G.id' => false,
  813. 'SELECT Mammal AS myAlias JOIN Group AS myAlias ON myAlias.member = myAlias.id' => false,
  814. 'SELECT Mammal AS Mammal JOIN Group AS Mammal ON Mammal.member = Mammal.id' => false,
  815. 'SELECT Group AS G WHERE G.leader_name LIKE "%"' => true,
  816. 'SELECT Group AS G WHERE G.leader_speed < 100000' => true,
  817. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  818. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_speed < 100000' => true,
  819. 'SELECT Mammal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  820. 'SELECT Mammal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  821. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  822. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  823. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id' => true,
  824. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  825. '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,
  826. '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,
  827. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  828. '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,
  829. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  830. 'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id' => true,
  831. '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,
  832. // Specifying multiple objects
  833. 'SELECT Animal FROM Animal' => true,
  834. 'SELECT yelele FROM Animal' => false,
  835. 'SELECT Animal FROM Animal AS A' => false,
  836. 'SELECT A FROM Animal AS A' => true,
  837. );
  838. //$aQueries = array(
  839. // 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  840. //);
  841. foreach($aQueries as $sQuery => $bIsCorrect)
  842. {
  843. $this->CheckQuery($sQuery, $bIsCorrect);
  844. }
  845. return true;
  846. }
  847. }
  848. ///////////////////////////////////////////////////////////////////////////
  849. // Test data load
  850. ///////////////////////////////////////////////////////////////////////////
  851. class TestBulkChangeOnFarm extends TestBizModel
  852. {
  853. static public function GetName()
  854. {
  855. return 'Farm test - data load';
  856. }
  857. static public function GetDescription()
  858. {
  859. return 'Bulk load';
  860. }
  861. static public function GetConfigFile() {return '../config-test-farm.php';}
  862. protected function DoPrepare()
  863. {
  864. parent::DoPrepare();
  865. $this->ResetDB();
  866. MetaModel::DBCheckIntegrity();
  867. }
  868. protected function DoExecute()
  869. {
  870. // $this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  871. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  872. $oParser = new CSVParser("denomination,hauteur,age
  873. suzy,123,2009-01-01
  874. chita,456,
  875. ");
  876. $aData = $oParser->ToArray(array('_name', '_height', '_birth'), ',');
  877. MyHelpers::var_dump_html($aData);
  878. $oBulk = new BulkChange(
  879. 'Mammal',
  880. $aData,
  881. // attributes
  882. array('name' => '_name', 'height' => '_height', 'birth' => '_birth'),
  883. // ext keys
  884. array(),
  885. // reconciliation
  886. array('name')
  887. );
  888. $oMyChange = MetaModel::NewObject("CMDBChange");
  889. $oMyChange->Set("date", time());
  890. $oMyChange->Set("userinfo", "Testor");
  891. $iChangeId = $oMyChange->DBInsert();
  892. // echo "Created new change: $iChangeId</br>";
  893. echo "<h3>Planned for loading...</h3>";
  894. $aRes = $oBulk->Process();
  895. print_r($aRes);
  896. echo "<h3>Go for loading...</h3>";
  897. $aRes = $oBulk->Process($oMyChange);
  898. print_r($aRes);
  899. return;
  900. $oRawData = array(
  901. 'Mammal',
  902. array('species', 'sex', 'speed', 'mother', 'father', 'name', 'height', 'birth'),
  903. "human,male,23,0,0,romulus,192,1971
  904. human,male,23,0,0,remus,154,-50
  905. human,male,23,0,0,julius,160,-49
  906. human,female,23,0,0,cleopatra,142,-50
  907. pig,female,23,0,0,confucius,50,2003"
  908. );
  909. }
  910. }
  911. ///////////////////////////////////////////////////////////////////////////
  912. // Test data load
  913. ///////////////////////////////////////////////////////////////////////////
  914. class TestFullTextSearchOnFarm extends MyFarm
  915. {
  916. static public function GetName()
  917. {
  918. return 'Farm test - full text search';
  919. }
  920. static public function GetDescription()
  921. {
  922. return 'Focus on the full text search feature';
  923. }
  924. protected function DoExecute()
  925. {
  926. echo "<h3>Create protagonists...</h3>";
  927. $iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
  928. $iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
  929. $this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
  930. $this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
  931. $this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
  932. $this->InsertBird('rooster', 'male', 12, 0, 0);
  933. $this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
  934. echo "<h3>Search...</h3>";
  935. $oSearch = new DBObjectSearch('Mammal');
  936. $oSearch->AddCondition_FullText('manof');
  937. //$oResultSet = new DBObjectSet($oSearch);
  938. $this->search_and_show_list($oSearch);
  939. }
  940. }
  941. ///////////////////////////////////////////////////////////////////////////
  942. // Benchmark queries
  943. ///////////////////////////////////////////////////////////////////////////
  944. class TestItopEfficiency extends TestBizModel
  945. {
  946. static public function GetName()
  947. {
  948. return 'Itop - benchmark';
  949. }
  950. static public function GetDescription()
  951. {
  952. return 'Measure time to perform the queries';
  953. }
  954. static public function GetConfigFile() {return '../config-itop.php';}
  955. protected function DoBenchmark($sOqlQuery)
  956. {
  957. echo "<h3>Testing query: $sOqlQuery</h3>";
  958. $fStart = MyHelpers::getmicrotime();
  959. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  960. {
  961. $oFilter = DBObjectSearch::FromOQL($sOqlQuery);
  962. }
  963. $fDuration = MyHelpers::getmicrotime() - $fStart;
  964. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  965. $fStart = MyHelpers::getmicrotime();
  966. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  967. {
  968. $sSQL = MetaModel::MakeSelectQuery($oFilter);
  969. }
  970. $fDuration = MyHelpers::getmicrotime() - $fStart;
  971. $fBuildDuration = $fDuration / COUNT_BENCHMARK;
  972. $fStart = MyHelpers::getmicrotime();
  973. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  974. {
  975. $res = CMDBSource::Query($sSQL);
  976. }
  977. $fDuration = MyHelpers::getmicrotime() - $fStart;
  978. $fQueryDuration = $fDuration / COUNT_BENCHMARK;
  979. // The fetch could not be repeated with the same results
  980. // But we've seen so far that is was very very quick to exec
  981. // So it makes sense to benchmark it a single time
  982. $fStart = MyHelpers::getmicrotime();
  983. $aRow = CMDBSource::FetchArray($res);
  984. $fDuration = MyHelpers::getmicrotime() - $fStart;
  985. $fFetchDuration = $fDuration;
  986. $fStart = MyHelpers::getmicrotime();
  987. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  988. {
  989. $sOql = $oFilter->ToOQL();
  990. }
  991. $fDuration = MyHelpers::getmicrotime() - $fStart;
  992. $fToOqlDuration = $fDuration / COUNT_BENCHMARK;
  993. echo "<ul>\n";
  994. echo "<li>Parsing: $fParsingDuration</li>\n";
  995. echo "<li>Build: $fBuildDuration</li>\n";
  996. echo "<li>Query: $fQueryDuration</li>\n";
  997. echo "<li>Fetch: $fFetchDuration</li>\n";
  998. echo "<li>ToOql: $fToOqlDuration</li>\n";
  999. echo "</ul>\n";
  1000. // Everything but the ToOQL (wich is interesting, anyhow)
  1001. $fTotal = $fParsingDuration + $fBuildDuration + $fQueryDuration + $fFetchDuration;
  1002. return array(
  1003. 'rows' => CMDBSource::NbRows($res),
  1004. 'duration (s)' => round($fTotal, 4),
  1005. 'parsing (%)' => round(100 * $fParsingDuration / $fTotal, 1),
  1006. 'build SQL (%)' => round(100 * $fBuildDuration / $fTotal, 1),
  1007. 'query exec (%)' => round(100 * $fQueryDuration / $fTotal, 1),
  1008. 'fetch (%)' => round(100 * $fFetchDuration / $fTotal, 1),
  1009. 'to OQL (%)' => round(100 * $fToOqlDuration / $fTotal, 1),
  1010. 'parsing+build (%)' => round(100 * ($fParsingDuration + $fBuildDuration) / $fTotal, 1),
  1011. );
  1012. }
  1013. protected function DoExecute()
  1014. {
  1015. define ('COUNT_BENCHMARK', 3);
  1016. echo "<p>The test will be repeated ".COUNT_BENCHMARK." times</p>";
  1017. $aQueries = array(
  1018. 'SELECT CMDBChangeOpSetAttribute',
  1019. 'SELECT CMDBChangeOpSetAttribute WHERE id=10',
  1020. 'SELECT CMDBChangeOpSetAttribute WHERE id=123456789',
  1021. 'SELECT CMDBChangeOpSetAttribute WHERE CMDBChangeOpSetAttribute.id=10',
  1022. 'SELECT bizIncidentTicket',
  1023. 'SELECT bizIncidentTicket WHERE id=1',
  1024. 'SELECT bizPerson',
  1025. 'SELECT bizPerson WHERE id=1',
  1026. 'SELECT bizIncidentTicket JOIN bizPerson ON bizIncidentTicket.agent_id = bizPerson.id WHERE bizPerson.id = 5',
  1027. );
  1028. $aStats = array();
  1029. foreach ($aQueries as $sOQL)
  1030. {
  1031. $aStats[$sOQL] = $this->DoBenchmark($sOQL);
  1032. }
  1033. $aData = array();
  1034. foreach ($aStats as $sOQL => $aResults)
  1035. {
  1036. $aValues = array();
  1037. $aValues['OQL'] = htmlentities($sOQL);
  1038. foreach($aResults as $sDesc => $sInfo)
  1039. {
  1040. $aValues[$sDesc] = htmlentities($sInfo);
  1041. }
  1042. $aData[] = $aValues;
  1043. }
  1044. echo MyHelpers::make_table_from_assoc_array($aData);
  1045. }
  1046. }
  1047. ///////////////////////////////////////////////////////////////////////////
  1048. // Test data load
  1049. ///////////////////////////////////////////////////////////////////////////
  1050. class TestItopWebServices extends TestWebServices
  1051. {
  1052. static public function GetName()
  1053. {
  1054. return 'Itop - web services';
  1055. }
  1056. static public function GetDescription()
  1057. {
  1058. return 'Bulk load and ???';
  1059. }
  1060. protected function DoExecSingleLoad($aLoadSpec)
  1061. {
  1062. $sTitle = 'Load: '.$aLoadSpec['class'];
  1063. $sClass = $aLoadSpec['class'];
  1064. $sCsvData = $aLoadSpec['csvdata'];
  1065. $aPostData = array('class' => $sClass, 'csvdata' => $sCsvData);
  1066. $sRes = self::DoPostRequestAuth('../webservices/import.php', $aPostData);
  1067. echo "<div><h3>$sTitle</h3><pre>$sCsvData</pre><div>$sRes</div></div>";
  1068. }
  1069. protected function DoExecute()
  1070. {
  1071. $aLoads = array(
  1072. array(
  1073. 'class' => 'bizOrganization',
  1074. 'csvdata' => "name;code\nWorldCompany;WCY"
  1075. ),
  1076. array(
  1077. 'class' => 'bizLocation',
  1078. 'csvdata' => "name;org_id;address\nParis;1;Centre de la Franca"
  1079. ),
  1080. array(
  1081. 'class' => 'bizPerson',
  1082. 'csvdata' => "email;name;first_name;org_id;phone\njohn.foo@starac.com;Foo;John;1;+33(1)23456789"
  1083. ),
  1084. array(
  1085. 'class' => 'bizTeam',
  1086. 'csvdata' => "name;org_id;location_name\nSquadra Azzura2;1;Paris"
  1087. ),
  1088. array(
  1089. 'class' => 'bizWorkgroup',
  1090. 'csvdata' => "name;org_id;team_id\ntravailleurs alpins;1;6"
  1091. ),
  1092. array(
  1093. 'class' => 'bizIncidentTicket',
  1094. '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"
  1095. ),
  1096. );
  1097. foreach ($aLoads as $aLoadSpec)
  1098. {
  1099. $this->DoExecSingleLoad($aLoadSpec);
  1100. }
  1101. }
  1102. }
  1103. $aWebServices = array(
  1104. array(
  1105. 'verb' => 'GetVersion',
  1106. 'expected result' => WebServices::GetVersion(),
  1107. 'explain result' => 'no comment!',
  1108. 'args' => array(),
  1109. ),
  1110. array(
  1111. 'verb' => 'CreateIncidentTicket',
  1112. 'expected result' => true,
  1113. 'explain result' => 'link attribute unknown + a CI not found',
  1114. 'args' => array(
  1115. 'admin', /* sLogin */
  1116. 'admin', /* sPassword */
  1117. 'desc of ticket', /* sDescription */
  1118. 'initial situation blah blah blah', /* sInitialSituation */
  1119. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1120. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1121. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1122. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1123. 'sub product of the service', /* sProduct */
  1124. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1125. array(
  1126. new SOAPLinkCreationSpec(
  1127. 'InfrastructureCI',
  1128. array(new SOAPSearchCondition('name', 'dbserver1.demo.com')),
  1129. array(new SOAPAttributeValue('impacting', 'very critical'))
  1130. ),
  1131. new SOAPLinkCreationSpec(
  1132. 'NetworkDevice',
  1133. array(new SOAPSearchCondition('name', 'switch01')),
  1134. array(new SOAPAttributeValue('impact', 'who cares'))
  1135. ),
  1136. new SOAPLinkCreationSpec(
  1137. 'Server',
  1138. array(new SOAPSearchCondition('name', 'thisone')),
  1139. array(new SOAPAttributeValue('impact', 'our lives'))
  1140. ),
  1141. ), /* aImpact */
  1142. '1', /* sImpact */
  1143. '1', /* sUrgency */
  1144. ),
  1145. ),
  1146. array(
  1147. 'verb' => 'CreateIncidentTicket',
  1148. 'expected result' => true,
  1149. 'explain result' => 'caller not specified',
  1150. 'args' => array(
  1151. 'admin', /* sLogin */
  1152. 'admin', /* sPassword */
  1153. 'PC burning', /* sDescription */
  1154. 'The power supply suddenly started to warm up', /* sInitialSituation */
  1155. new SOAPExternalKeySearch(), /* aCallerDesc */
  1156. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1157. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1158. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1159. 'sub product of the service', /* sProduct */
  1160. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1161. array(
  1162. new SOAPLinkCreationSpec(
  1163. 'InfrastructureCI',
  1164. array(new SOAPSearchCondition('name', 'dbserver1.demo.com')),
  1165. array()
  1166. ), /* aImpact */
  1167. ),
  1168. '1', /* sImpact */
  1169. '1', /* sUrgency */
  1170. ),
  1171. ),
  1172. array(
  1173. 'verb' => 'CreateIncidentTicket',
  1174. 'expected result' => false,
  1175. 'explain result' => 'wrong class on CI to attach',
  1176. 'args' => array(
  1177. 'admin', /* sLogin */
  1178. 'admin', /* sPassword */
  1179. 'PC burning', /* sDescription */
  1180. 'The power supply suddenly started to warm up', /* sInitialSituation */
  1181. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1182. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1183. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1184. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1185. 'sub product of the service', /* sProduct */
  1186. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1187. array(
  1188. new SOAPLinkCreationSpec(
  1189. 'logInfra',
  1190. array(new SOAPSearchCondition('dummyfiltercode', 2)),
  1191. array(new SOAPAttributeValue('impact', 'very critical'))
  1192. ),
  1193. ), /* aImpact */
  1194. '1', /* sImpact */
  1195. '1', /* sUrgency */
  1196. ),
  1197. ),
  1198. array(
  1199. 'verb' => 'CreateIncidentTicket',
  1200. 'expected result' => false,
  1201. 'explain result' => 'wrong search condition on CI to attach',
  1202. 'args' => array(
  1203. 'admin', /* sLogin */
  1204. 'admin', /* sPassword */
  1205. 'PC burning', /* sDescription */
  1206. 'The power supply suddenly started to warm up', /* sInitialSituation */
  1207. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1208. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1209. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1210. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1211. 'sub product of the service', /* sProduct */
  1212. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1213. array(
  1214. new SOAPLinkCreationSpec(
  1215. 'InfrastructureCI',
  1216. array(new SOAPSearchCondition('dummyfiltercode', 2)),
  1217. array(new SOAPAttributeValue('impact', 'very critical'))
  1218. ),
  1219. ), /* aImpact */
  1220. '1', /* sImpact */
  1221. '1', /* sUrgency */
  1222. ),
  1223. ),
  1224. array(
  1225. 'verb' => 'CreateIncidentTicket',
  1226. 'expected result' => true,
  1227. 'explain result' => 'no CI to attach (empty array)',
  1228. 'args' => array(
  1229. 'admin', /* sLogin */
  1230. 'admin', /* sPassword */
  1231. 'Houston not reachable', /* sDescription */
  1232. 'Tried to join the shuttle', /* sInitialSituation */
  1233. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1234. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1235. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1236. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1237. 'sub product of the service', /* sProduct */
  1238. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1239. array(
  1240. ), /* aImpact */
  1241. '1', /* sImpact */
  1242. '1', /* sUrgency */
  1243. ),
  1244. ),
  1245. array(
  1246. 'verb' => 'CreateIncidentTicket',
  1247. 'expected result' => true,
  1248. 'explain result' => 'no CI to attach (null)',
  1249. 'args' => array(
  1250. 'admin', /* sLogin */
  1251. 'admin', /* sPassword */
  1252. 'Houston not reachable', /* sDescription */
  1253. 'Tried to join the shuttle', /* sInitialSituation */
  1254. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1255. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1256. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1257. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1258. 'sub product of the service', /* sProduct */
  1259. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1260. null, /* aImpact */
  1261. '1', /* sImpact */
  1262. '1', /* sUrgency */
  1263. ),
  1264. ),
  1265. array(
  1266. 'verb' => 'CreateIncidentTicket',
  1267. 'expected result' => true,
  1268. 'explain result' => 'caller unknown',
  1269. 'args' => array(
  1270. 'admin', /* sLogin */
  1271. 'admin', /* sPassword */
  1272. 'Houston not reachable', /* sDescription */
  1273. 'Tried to join the shuttle', /* sInitialSituation */
  1274. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1000))), /* aCallerDesc */
  1275. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1276. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1277. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1278. 'sub product of the service', /* sProduct */
  1279. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1280. array(
  1281. ), /* aImpact */
  1282. '1', /* sImpact */
  1283. '1', /* sUrgency */
  1284. ),
  1285. ),
  1286. array(
  1287. 'verb' => 'CreateIncidentTicket',
  1288. 'expected result' => false,
  1289. 'explain result' => 'wrong values for impact and urgency',
  1290. 'args' => array(
  1291. 'admin', /* sLogin */
  1292. 'admin', /* sPassword */
  1293. 'Houston not reachable', /* sDescription */
  1294. 'Tried to join the shuttle', /* sInitialSituation */
  1295. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1296. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1297. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1298. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1299. 'sub product of the service', /* sProduct */
  1300. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1301. array(
  1302. ), /* aImpact */
  1303. '6', /* sImpact */
  1304. '7', /* sUrgency */
  1305. ),
  1306. ),
  1307. array(
  1308. 'verb' => 'CreateIncidentTicket',
  1309. 'expected result' => false,
  1310. 'explain result' => 'wrong password',
  1311. 'args' => array(
  1312. 'admin', /* sLogin */
  1313. 'xxxxx', /* sPassword */
  1314. 'Houston not reachable', /* sDescription */
  1315. 'Tried to join the shuttle', /* sInitialSituation */
  1316. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1317. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1318. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1319. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1320. 'sub product of the service', /* sProduct */
  1321. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1322. array(
  1323. ), /* aImpact */
  1324. '1', /* sImpact */
  1325. '1', /* sUrgency */
  1326. ),
  1327. ),
  1328. array(
  1329. 'verb' => 'CreateIncidentTicket',
  1330. 'expected result' => false,
  1331. 'explain result' => 'wrong login',
  1332. 'args' => array(
  1333. 'xxxxx', /* sLogin */
  1334. 'yyyyy', /* sPassword */
  1335. 'Houston not reachable', /* sDescription */
  1336. 'Tried to join the shuttle', /* sInitialSituation */
  1337. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aCallerDesc */
  1338. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Demo'))), /* aCustomerDesc */
  1339. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'HW Management'))), /* aServiceDesc */
  1340. new SOAPExternalKeySearch(array(new SOAPSearchCondition('id', 1))), /* aServiceSubcategoryDesc */
  1341. 'sub product of the service', /* sProduct */
  1342. new SOAPExternalKeySearch(array(new SOAPSearchCondition('name', 'Hardware support'))), /* aWorkgroupDesc */
  1343. array(
  1344. ), /* aImpact */
  1345. '1', /* sImpact */
  1346. '1', /* sUrgency */
  1347. ),
  1348. ),
  1349. );
  1350. class TestSoap extends TestSoapWebService
  1351. {
  1352. static public function GetName() {return 'Test SOAP';}
  1353. static public function GetDescription() {return 'Do basic stuff to test the SOAP capability';}
  1354. protected function DoExecute()
  1355. {
  1356. echo "<p>Note: You may also want to try the sample SOAP client <a href=\"../webservices/itopsoap.examples.php\">itopsoap.examples.php</a></p>\n";
  1357. global $aSOAPMapping;
  1358. // this file is generated dynamically with location = here
  1359. $sWsdlUri = 'http'.(empty($_SERVER['HTTPS']) ? '' : 's').'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].dirname($_SERVER['SCRIPT_NAME']).'/../webservices/itop.wsdl.php';
  1360. ini_set("soap.wsdl_cache_enabled","0");
  1361. $this->m_SoapClient = new SoapClient
  1362. (
  1363. $sWsdlUri,
  1364. array(
  1365. 'classmap' => $aSOAPMapping,
  1366. 'trace' => 1,
  1367. )
  1368. );
  1369. if (false)
  1370. {
  1371. print "<pre>\n";
  1372. print_r($this->m_SoapClient->__getTypes());
  1373. print "</pre>\n";
  1374. }
  1375. global $aWebServices;
  1376. foreach ($aWebServices as $iPos => $aWebService)
  1377. {
  1378. echo "<h2>SOAP call #$iPos - {$aWebService['verb']}</h2>\n";
  1379. echo "<p>{$aWebService['explain result']}</p>\n";
  1380. try
  1381. {
  1382. $oRes = call_user_func_array(array($this->m_SoapClient, $aWebService['verb']), $aWebService['args']);
  1383. }
  1384. catch(SoapFault $e)
  1385. {
  1386. print "<pre>\n";
  1387. print "Request: \n".htmlspecialchars($this->m_SoapClient->__getLastRequest()) ."\n";
  1388. print "Response: \n".htmlspecialchars($this->m_SoapClient->__getLastResponse())."\n";
  1389. print "</pre>";
  1390. print "Response in HTML: <p>".$this->m_SoapClient->__getLastResponse()."</p>";
  1391. throw $e;
  1392. }
  1393. echo "<pre>\n";
  1394. print_r($oRes);
  1395. echo "</pre>\n";
  1396. print "<pre>\n";
  1397. print "Request: \n".htmlspecialchars($this->m_SoapClient->__getLastRequest()) ."\n";
  1398. print "Response: \n".htmlspecialchars($this->m_SoapClient->__getLastResponse())."\n";
  1399. print "</pre>";
  1400. if ($oRes instanceof SOAPResult)
  1401. {
  1402. $res = $oRes->status;
  1403. }
  1404. else
  1405. {
  1406. $res = $oRes;
  1407. }
  1408. if ($res != $aWebService['expected result'])
  1409. {
  1410. echo "Expecting:<br/>\n";
  1411. var_dump($aWebService['expected result']);
  1412. echo "Obtained:<br/>\n";
  1413. var_dump($res);
  1414. throw new UnitTestException("Expecting result '{$aWebService['expected result']}', but got '$res'");
  1415. }
  1416. }
  1417. }
  1418. }
  1419. class TestWebServicesDirect extends TestBizModel
  1420. {
  1421. static public function GetName() {return 'Test web services locally';}
  1422. static public function GetDescription() {return 'Invoke the service directly (troubleshooting)';}
  1423. static public function GetConfigFile() {return '../config-itop.php';}
  1424. protected function DoExecute()
  1425. {
  1426. $oWebServices = new WebServices();
  1427. global $aWebServices;
  1428. foreach ($aWebServices as $iPos => $aWebService)
  1429. {
  1430. echo "<h2>SOAP call #$iPos - {$aWebService['verb']}</h2>\n";
  1431. echo "<p>{$aWebService['explain result']}</p>\n";
  1432. $oRes = call_user_func_array(array($oWebServices, $aWebService['verb']), $aWebService['args']);
  1433. echo "<pre>\n";
  1434. print_r($oRes);
  1435. echo "</pre>\n";
  1436. if ($oRes instanceof SOAPResult)
  1437. {
  1438. $res = $oRes->status;
  1439. }
  1440. else
  1441. {
  1442. $res = $oRes;
  1443. }
  1444. if ($res != $aWebService['expected result'])
  1445. {
  1446. echo "Expecting:<br/>\n";
  1447. var_dump($aWebService['expected result']);
  1448. echo "Obtained:<br/>\n";
  1449. var_dump($res);
  1450. throw new UnitTestException("Expecting result '{$aWebService['expected result']}', but got '$res'");
  1451. }
  1452. }
  1453. return true;
  1454. }
  1455. }
  1456. class TestTriggerAndEmail extends TestBizModel
  1457. {
  1458. static public function GetName() {return 'Test trigger and email';}
  1459. static public function GetDescription() {return 'Create a trigger and an email, then activates the trigger';}
  1460. static public function GetConfigFile() {return '../config-itop.php';}
  1461. protected function CreateEmailSpec($oTrigger, $sStatus, $sTo, $sCC, $sTesterEmail)
  1462. {
  1463. $oAction = MetaModel::NewObject("ActionEmail");
  1464. $oAction->Set("status", $sStatus);
  1465. $oAction->Set("name", "New server");
  1466. $oAction->Set("test_recipient", $sTesterEmail);
  1467. $oAction->Set("from", $sTesterEmail);
  1468. $oAction->Set("reply_to", $sTesterEmail);
  1469. $oAction->Set("to", $sTo);
  1470. $oAction->Set("cc", $sCC);
  1471. $oAction->Set("bcc", "");
  1472. $oAction->Set("subject", "New server: '\$this->name()$'");
  1473. $oAction->Set("body", "<html><body><p>Dear customer,</p><p>We have created the server \$this->hyperlink()$ in the IT infrastructure database.</p><p>You will be further notified when it is in <strong>Production</strong>.</p><p>The IT infrastructure management team.</p><p>Here are some accentuated characters for french people: 'ééà'</p></body></html>");
  1474. $oAction->Set("importance", "low");
  1475. $iActionId = $this->ObjectToDB($oAction, true);
  1476. $oLink = MetaModel::NewObject("lnkTriggerAction");
  1477. $oLink->Set("trigger_id", $oTrigger->GetKey());
  1478. $oLink->Set("action_id", $iActionId);
  1479. $oLink->Set("order", "1");
  1480. $iLink = $this->ObjectToDB($oLink, true);
  1481. }
  1482. protected function DoExecute()
  1483. {
  1484. $oMyPerson = MetaModel::NewObject("bizPerson");
  1485. $oMyPerson->Set("name", "testemail1");
  1486. $oMyPerson->Set("org_id", "1");
  1487. $oMyPerson->Set("email", "romain.quetiez@hp.com");
  1488. $iPersonId = $this->ObjectToDB($oMyPerson, true);
  1489. $oMyPerson = MetaModel::NewObject("bizPerson");
  1490. $oMyPerson->Set("name", "testemail2");
  1491. $oMyPerson->Set("org_id", "1");
  1492. $oMyPerson->Set("email", "denis.flaven@hp.com");
  1493. $iPersonId = $this->ObjectToDB($oMyPerson, true);
  1494. $oMyPerson = MetaModel::NewObject("bizPerson");
  1495. $oMyPerson->Set("name", "testemail3");
  1496. $oMyPerson->Set("org_id", "1");
  1497. $oMyPerson->Set("email", "erwan.taloc@hp.com");
  1498. $iPersonId = $this->ObjectToDB($oMyPerson, true);
  1499. $oMyServer = MetaModel::NewObject("bizServer");
  1500. $oMyServer->Set("name", "wfr.terminator.com");
  1501. $oMyServer->Set("severity", "low");
  1502. $oMyServer->Set("status", "production");
  1503. $oMyServer->Set("org_id", 2);
  1504. $oMyServer->Set("location_id", 2);
  1505. $iServerId = $this->ObjectToDB($oMyServer, true);
  1506. $oMyTrigger = MetaModel::NewObject("TriggerOnStateEnter");
  1507. $oMyTrigger->Set("description", "Testor");
  1508. $oMyTrigger->Set("target_class", "bizServer");
  1509. $oMyTrigger->Set("state", "Shipped");
  1510. $iTriggerId = $this->ObjectToDB($oMyTrigger, true);
  1511. // Error in OQL field(s)
  1512. //
  1513. $this->CreateEmailSpec
  1514. (
  1515. $oMyTrigger,
  1516. 'test',
  1517. "SELECT bizPerson WHERE naime = 'Dali'",
  1518. "SELECT bizServer",
  1519. 'romain.quetiez@hp.com'
  1520. );
  1521. // Error: no recipient
  1522. //
  1523. $this->CreateEmailSpec
  1524. (
  1525. $oMyTrigger,
  1526. 'test',
  1527. "",
  1528. "",
  1529. 'romain.quetiez@hp.com'
  1530. );
  1531. // Test
  1532. //
  1533. $this->CreateEmailSpec
  1534. (
  1535. $oMyTrigger,
  1536. 'test',
  1537. "SELECT bizPerson WHERE name LIKE 'testemail%'",
  1538. "SELECT bizPerson",
  1539. 'romain.quetiez@hp.com'
  1540. );
  1541. // Test failing because of a wrong test recipient address
  1542. //
  1543. $this->CreateEmailSpec
  1544. (
  1545. $oMyTrigger,
  1546. 'test',
  1547. "SELECT bizPerson WHERE name LIKE 'testemail%'",
  1548. "",
  1549. 'toto@walibi.bg'
  1550. );
  1551. // Normal behavior
  1552. //
  1553. $this->CreateEmailSpec
  1554. (
  1555. $oMyTrigger,
  1556. 'enabled',
  1557. "SELECT bizPerson WHERE name LIKE 'testemail%'",
  1558. "",
  1559. 'romain.quetiez@hp.com'
  1560. );
  1561. // Does nothing, because it is disabled
  1562. //
  1563. $this->CreateEmailSpec
  1564. (
  1565. $oMyTrigger,
  1566. 'disabled',
  1567. "SELECT bizPerson WHERE name = 'testemail%'",
  1568. "",
  1569. 'romain.quetiez@hp.com'
  1570. );
  1571. $oMyTrigger->DoActivate($oMyServer->ToArgs('this'));
  1572. return true;
  1573. }
  1574. }
  1575. ?>