PageRenderTime 26ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/Symfony/Tests/Component/Security/Acl/Dbal/AclProviderBenchmarkTest.php

http://github.com/fabpot/symfony
PHP | 262 lines | 196 code | 46 blank | 20 comment | 21 complexity | ec29c9f2b67e070253c89d21b750c81f MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Tests\Component\Security\Acl\Dbal;
  11. use Symfony\Component\Security\Acl\Dbal\AclProvider;
  12. use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
  13. use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
  14. use Symfony\Component\Security\Acl\Dbal\Schema;
  15. use Doctrine\DBAL\DriverManager;
  16. /**
  17. * @group benchmark
  18. */
  19. class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
  20. {
  21. protected $con;
  22. protected $insertClassStmt;
  23. protected $insertSidStmt;
  24. protected $insertOidAncestorStmt;
  25. protected $insertOidStmt;
  26. protected $insertEntryStmt;
  27. protected function setUp()
  28. {
  29. $this->con = DriverManager::getConnection(array(
  30. 'driver' => 'pdo_mysql',
  31. 'host' => 'localhost',
  32. 'user' => 'root',
  33. 'dbname' => 'testdb',
  34. ));
  35. }
  36. protected function tearDown()
  37. {
  38. $this->con = null;
  39. }
  40. public function testFindAcls()
  41. {
  42. // $this->generateTestData();
  43. // get some random test object identities from the database
  44. $oids = array();
  45. $stmt = $this->con->executeQuery("SELECT object_identifier, class_type FROM acl_object_identities o INNER JOIN acl_classes c ON c.id = o.class_id ORDER BY RAND() LIMIT 25");
  46. foreach ($stmt->fetchAll() as $oid) {
  47. $oids[] = new ObjectIdentity($oid['object_identifier'], $oid['class_type']);
  48. }
  49. $provider = $this->getProvider();
  50. $start = microtime(true);
  51. $provider->findAcls($oids);
  52. $time = microtime(true) - $start;
  53. echo "Total Time: ".$time."s\n";
  54. }
  55. /**
  56. * This generates a huge amount of test data to be used mainly for benchmarking
  57. * purposes, not so much for testing. That's why it's not called by default.
  58. */
  59. protected function generateTestData()
  60. {
  61. $sm = $this->con->getSchemaManager();
  62. $sm->dropAndCreateDatabase('testdb');
  63. $this->con->exec("USE testdb");
  64. // import the schema
  65. $schema = new Schema($options = $this->getOptions());
  66. foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
  67. $this->con->exec($sql);
  68. }
  69. // setup prepared statements
  70. $this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
  71. $this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
  72. $this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
  73. $this->insertEntryStmt = $this->con->prepare('INSERT INTO acl_entries (id, class_id, object_identity_id, field_name, ace_order, security_identity_id, mask, granting, granting_strategy, audit_success, audit_failure) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
  74. $this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
  75. for ($i=0; $i<40000; $i++) {
  76. $this->generateAclHierarchy();
  77. }
  78. }
  79. protected function generateAclHierarchy()
  80. {
  81. $rootId = $this->generateAcl($this->chooseClassId(), null, array());
  82. $this->generateAclLevel(rand(1, 15), $rootId, array($rootId));
  83. }
  84. protected function generateAclLevel($depth, $parentId, $ancestors)
  85. {
  86. $level = count($ancestors);
  87. for ($i=0,$t=rand(1, 10); $i<$t; $i++) {
  88. $id = $this->generateAcl($this->chooseClassId(), $parentId, $ancestors);
  89. if ($level < $depth) {
  90. $this->generateAclLevel($depth, $id, array_merge($ancestors, array($id)));
  91. }
  92. }
  93. }
  94. protected function chooseClassId()
  95. {
  96. static $id = 1000;
  97. if ($id === 1000 || ($id < 1500 && rand(0, 1))) {
  98. $this->insertClassStmt->execute(array($id, $this->getRandomString(rand(20, 100), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\_')));
  99. $id += 1;
  100. return $id-1;
  101. } else {
  102. return rand(1000, $id-1);
  103. }
  104. }
  105. protected function generateAcl($classId, $parentId, $ancestors)
  106. {
  107. static $id = 1000;
  108. $this->insertOidStmt->execute(array(
  109. $id,
  110. $classId,
  111. $this->getRandomString(rand(20, 50)),
  112. $parentId,
  113. rand(0, 1),
  114. ));
  115. $this->insertOidAncestorStmt->execute(array($id, $id));
  116. foreach ($ancestors as $ancestor) {
  117. $this->insertOidAncestorStmt->execute(array($id, $ancestor));
  118. }
  119. $this->generateAces($classId, $id);
  120. $id += 1;
  121. return $id-1;
  122. }
  123. protected function chooseSid()
  124. {
  125. static $id = 1000;
  126. if ($id === 1000 || ($id < 11000 && rand(0, 1))) {
  127. $this->insertSidStmt->execute(array(
  128. $id,
  129. $this->getRandomString(rand(5, 30)),
  130. rand(0, 1)
  131. ));
  132. $id += 1;
  133. return $id-1;
  134. } else {
  135. return rand(1000, $id-1);
  136. }
  137. }
  138. protected function generateAces($classId, $objectId)
  139. {
  140. static $id = 1000;
  141. $sids = array();
  142. $fieldOrder = array();
  143. for ($i=0; $i<=30; $i++) {
  144. $fieldName = rand(0, 1) ? null : $this->getRandomString(rand(10, 20));
  145. do {
  146. $sid = $this->chooseSid();
  147. }
  148. while (array_key_exists($sid, $sids) && in_array($fieldName, $sids[$sid], true));
  149. $fieldOrder[$fieldName] = array_key_exists($fieldName, $fieldOrder) ? $fieldOrder[$fieldName]+1 : 0;
  150. if (!isset($sids[$sid])) {
  151. $sids[$sid] = array();
  152. }
  153. $sids[$sid][] = $fieldName;
  154. $strategy = rand(0, 2);
  155. if ($strategy === 0) {
  156. $strategy = PermissionGrantingStrategy::ALL;
  157. } else if ($strategy === 1) {
  158. $strategy = PermissionGrantingStrategy::ANY;
  159. } else {
  160. $strategy = PermissionGrantingStrategy::EQUAL;
  161. }
  162. // id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
  163. $this->insertEntryStmt->execute(array(
  164. $id,
  165. $classId,
  166. rand(0, 5) ? $objectId : null,
  167. $fieldName,
  168. $fieldOrder[$fieldName],
  169. $sid,
  170. $this->generateMask(),
  171. rand(0, 1),
  172. $strategy,
  173. rand(0, 1),
  174. rand(0, 1),
  175. ));
  176. $id += 1;
  177. }
  178. }
  179. protected function generateMask()
  180. {
  181. $i = rand(1, 30);
  182. $mask = 0;
  183. while ($i <= 30) {
  184. $mask |= 1 << rand(0, 30);
  185. $i++;
  186. }
  187. return $mask;
  188. }
  189. protected function getRandomString($length, $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
  190. {
  191. $s = '';
  192. $cLength = strlen($chars);
  193. while (strlen($s) < $length) {
  194. $s .= $chars[mt_rand(0, $cLength-1)];
  195. }
  196. return $s;
  197. }
  198. protected function getOptions()
  199. {
  200. return array(
  201. 'oid_table_name' => 'acl_object_identities',
  202. 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
  203. 'class_table_name' => 'acl_classes',
  204. 'sid_table_name' => 'acl_security_identities',
  205. 'entry_table_name' => 'acl_entries',
  206. );
  207. }
  208. protected function getStrategy()
  209. {
  210. return new PermissionGrantingStrategy();
  211. }
  212. protected function getProvider()
  213. {
  214. return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
  215. }
  216. }