DbTableTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Session
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * Test helper
  24. */
  25. require_once dirname(__FILE__) . '/../../../TestHelper.php';
  26. /**
  27. * @see Zend_Session_SaveHandler_DbTable
  28. */
  29. require_once 'Zend/Session/SaveHandler/DbTable.php';
  30. /**
  31. * Unit testing for Zend_Session_SaveHandler_DbTable include all tests for
  32. * regular session handling
  33. *
  34. * @category Zend
  35. * @package Zend_Session
  36. * @subpackage UnitTests
  37. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  38. * @license http://framework.zend.com/license/new-bsd New BSD License
  39. * @group Zend_Session
  40. * @group Zend_Db_Table
  41. */
  42. class Zend_Session_SaveHandler_DbTableTest extends PHPUnit_Framework_TestCase
  43. {
  44. /**
  45. * @var array
  46. */
  47. protected $_saveHandlerTableConfig = array(
  48. 'name' => 'sessions',
  49. 'primary' => array(
  50. 'id',
  51. 'save_path',
  52. 'name',
  53. ),
  54. Zend_Session_SaveHandler_DbTable::MODIFIED_COLUMN => 'modified',
  55. Zend_Session_SaveHandler_DbTable::LIFETIME_COLUMN => 'lifetime',
  56. Zend_Session_SaveHandler_DbTable::DATA_COLUMN => 'data',
  57. Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT => array(
  58. Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_ID,
  59. Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_SAVE_PATH,
  60. Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_NAME,
  61. ),
  62. );
  63. /**
  64. * @var Zend_Db_Adapter_Abstract
  65. */
  66. protected $_db;
  67. /**
  68. * Array to collect used Zend_Session_SaveHandler_DbTable objects, so they are not
  69. * destroyed before all tests are done and session is not closed
  70. *
  71. * @var array
  72. */
  73. protected $_usedSaveHandlers = array();
  74. /**
  75. * Setup performed prior to each test method
  76. *
  77. * @return void
  78. */
  79. public function setUp()
  80. {
  81. $this->_setupDb($this->_saveHandlerTableConfig['primary']);
  82. }
  83. /**
  84. * Tear-down operations performed after each test method
  85. *
  86. * @return void
  87. */
  88. public function tearDown()
  89. {
  90. $this->_dropTable();
  91. }
  92. public function testConfigPrimaryAssignmentFullConfig()
  93. {
  94. $this->_usedSaveHandlers[] =
  95. $saveHandler = new Zend_Session_SaveHandler_DbTable($this->_saveHandlerTableConfig);
  96. /**
  97. * @todo Test something other than that an exception is not thrown
  98. */
  99. }
  100. public function testConstructorThrowsExceptionGivenConfigAsNull()
  101. {
  102. try {
  103. $this->_usedSaveHandlers[] =
  104. $saveHandler = new Zend_Session_SaveHandler_DbTable(null);
  105. $this->fail('Expected Zend_Session_SaveHandler_Exception not thrown');
  106. } catch (Zend_Session_SaveHandler_Exception $e) {
  107. $this->assertContains('$config must be', $e->getMessage());
  108. }
  109. }
  110. public function testTableNameSchema()
  111. {
  112. $config = $this->_saveHandlerTableConfig;
  113. $config['name'] = 'schema.session';
  114. $this->_usedSaveHandlers[] =
  115. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  116. }
  117. public function testTableEmptyNamePullFromSavePath()
  118. {
  119. $config = $this->_saveHandlerTableConfig;
  120. unset($config['name']);
  121. try {
  122. $savePath = ini_get('session.save_path');
  123. ini_set('session.save_path', dirname(__FILE__));
  124. $this->_usedSaveHandlers[] =
  125. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  126. $this->fail();
  127. } catch (Zend_Session_SaveHandler_Exception $e) {
  128. ini_set('session.save_path', $savePath);
  129. /**
  130. * @todo Test something other than that an exception is thrown
  131. */
  132. }
  133. }
  134. public function testPrimaryAssignmentIdNotSet()
  135. {
  136. $this->setExpectedException('Zend_Session_SaveHandler_Exception');
  137. $config = $this->_saveHandlerTableConfig;
  138. $config['primary'] = array('id');
  139. $config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]
  140. = Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_SAVE_PATH;
  141. $this->_usedSaveHandlers[] =
  142. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  143. /**
  144. * @todo Test something other than that an exception is thrown
  145. */
  146. }
  147. public function testPrimaryAssignmentNotArray()
  148. {
  149. $config = $this->_saveHandlerTableConfig;
  150. $config['primary'] = array('id');
  151. $config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]
  152. = Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_ID;
  153. $this->_usedSaveHandlers[] =
  154. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  155. /**
  156. * @todo Test something other than that an exception is not thrown
  157. */
  158. }
  159. public function testModifiedColumnNotSet()
  160. {
  161. $this->setExpectedException('Zend_Session_SaveHandler_Exception');
  162. $config = $this->_saveHandlerTableConfig;
  163. unset($config[Zend_Session_SaveHandler_DbTable::MODIFIED_COLUMN]);
  164. $this->_usedSaveHandlers[] =
  165. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  166. /**
  167. * @todo Test something other than that an exception is thrown
  168. */
  169. }
  170. public function testLifetimeColumnNotSet()
  171. {
  172. $this->setExpectedException('Zend_Session_SaveHandler_Exception');
  173. $config = $this->_saveHandlerTableConfig;
  174. unset($config[Zend_Session_SaveHandler_DbTable::LIFETIME_COLUMN]);
  175. $this->_usedSaveHandlers[] =
  176. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  177. /**
  178. * @todo Test something other than that an exception is thrown
  179. */
  180. }
  181. public function testDataColumnNotSet()
  182. {
  183. $this->setExpectedException('Zend_Session_SaveHandler_Exception');
  184. $config = $this->_saveHandlerTableConfig;
  185. unset($config[Zend_Session_SaveHandler_DbTable::DATA_COLUMN]);
  186. $this->_usedSaveHandlers[] =
  187. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  188. /**
  189. * @todo Test something other than that an exception is thrown
  190. */
  191. }
  192. public function testDifferentArraySize()
  193. {
  194. //different number of args between primary and primaryAssignment
  195. try {
  196. $config = $this->_saveHandlerTableConfig;
  197. array_pop($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  198. $this->_usedSaveHandlers[] =
  199. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  200. $this->fail();
  201. } catch (Zend_Session_SaveHandler_Exception $e) {
  202. /**
  203. * @todo Test something other than that an exception is thrown
  204. */
  205. }
  206. }
  207. public function testEmptyPrimaryAssignment()
  208. {
  209. //test the default - no primaryAssignment
  210. $config = $this->_saveHandlerTableConfig;
  211. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  212. $config['primary'] = $config['primary'][0];
  213. $this->_usedSaveHandlers[] =
  214. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  215. /**
  216. * @todo Test something other than that an exception is not thrown
  217. */
  218. }
  219. public function testSessionIdPresent()
  220. {
  221. //test that the session Id must be in the primary assignment config
  222. try {
  223. $config = $this->_saveHandlerTableConfig;
  224. $config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT] = array(
  225. Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT_SESSION_NAME,
  226. );
  227. $this->_usedSaveHandlers[] =
  228. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  229. $this->fail();
  230. } catch (Zend_Session_SaveHandler_Exception $e) {
  231. /**
  232. * @todo Test something other than that an exception is thrown
  233. */
  234. }
  235. }
  236. public function testModifiedColumnDefined()
  237. {
  238. //test the default - no primaryAssignment
  239. try {
  240. $config = $this->_saveHandlerTableConfig;
  241. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  242. unset($config[Zend_Session_SaveHandler_DbTable::MODIFIED_COLUMN]);
  243. $this->_usedSaveHandlers[] =
  244. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  245. $this->fail();
  246. } catch (Zend_Session_SaveHandler_Exception $e) {
  247. /**
  248. * @todo Test something other than that an exception is thrown
  249. */
  250. }
  251. }
  252. public function testLifetimeColumnDefined()
  253. {
  254. //test the default - no primaryAssignment
  255. try {
  256. $config = $this->_saveHandlerTableConfig;
  257. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  258. unset($config[Zend_Session_SaveHandler_DbTable::LIFETIME_COLUMN]);
  259. $this->_usedSaveHandlers[] =
  260. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  261. $this->fail();
  262. } catch (Zend_Session_SaveHandler_Exception $e) {
  263. /**
  264. * @todo Test something other than that an exception is thrown
  265. */
  266. }
  267. }
  268. public function testDataColumnDefined()
  269. {
  270. //test the default - no primaryAssignment
  271. try {
  272. $config = $this->_saveHandlerTableConfig;
  273. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  274. unset($config[Zend_Session_SaveHandler_DbTable::DATA_COLUMN]);
  275. $this->_usedSaveHandlers[] =
  276. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  277. $this->fail();
  278. } catch (Zend_Session_SaveHandler_Exception $e) {
  279. /**
  280. * @todo Test something other than that an exception is thrown
  281. */
  282. }
  283. }
  284. public function testLifetime()
  285. {
  286. $config = $this->_saveHandlerTableConfig;
  287. unset($config['lifetime']);
  288. $this->_usedSaveHandlers[] =
  289. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  290. $this->assertSame($saveHandler->getLifetime(), (int) ini_get('session.gc_maxlifetime'),
  291. 'lifetime must default to session.gc_maxlifetime'
  292. );
  293. $config = $this->_saveHandlerTableConfig;
  294. $lifetime = $config['lifetime'] = 1242;
  295. $this->_usedSaveHandlers[] =
  296. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  297. $this->assertSame($lifetime, $saveHandler->getLifetime());
  298. }
  299. public function testOverrideLifetime()
  300. {
  301. try {
  302. $config = $this->_saveHandlerTableConfig;
  303. $config['overrideLifetime'] = true;
  304. $this->_usedSaveHandlers[] =
  305. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  306. } catch (Zend_Session_SaveHandler_Exception $e) {
  307. /**
  308. * @todo Test something other than that an exception is thrown
  309. */
  310. }
  311. $this->assertTrue($saveHandler->getOverrideLifetime(), '');
  312. }
  313. public function testSessionSaving()
  314. {
  315. $this->_dropTable();
  316. $config = $this->_saveHandlerTableConfig;
  317. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  318. $config['primary'] = array($config['primary'][0]);
  319. $this->_setupDb($config['primary']);
  320. $this->_usedSaveHandlers[] =
  321. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  322. Zend_Session::setSaveHandler($saveHandler);
  323. Zend_Session::start();
  324. /**
  325. * @see Zend_Session_Namespace
  326. */
  327. require_once 'Zend/Session/Namespace.php';
  328. $session = new Zend_Session_Namespace('SaveHandler');
  329. $session->testArray = $this->_saveHandlerTableConfig;
  330. $tmp = array('SaveHandler' => serialize(array('testArray' => $this->_saveHandlerTableConfig)));
  331. $testAgainst = '';
  332. foreach ($tmp as $key => $val) {
  333. $testAgainst .= $key . "|" . $val;
  334. }
  335. session_write_close();
  336. foreach ($this->_db->query('SELECT * FROM Sessions')->fetchAll() as $row) {
  337. $this->assertSame($row[$config[Zend_Session_SaveHandler_DbTable::DATA_COLUMN]],
  338. $testAgainst, 'Data was not saved properly'
  339. );
  340. }
  341. }
  342. public function testReadWrite()
  343. {
  344. $config = $this->_saveHandlerTableConfig;
  345. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  346. $config['primary'] = array($config['primary'][0]);
  347. $this->_setupDb($config['primary']);
  348. $this->_usedSaveHandlers[] =
  349. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  350. $id = '242';
  351. $this->assertTrue($saveHandler->write($id, serialize($config)));
  352. $this->assertSame($config, unserialize($saveHandler->read($id)));
  353. }
  354. public function testReadWriteComplex()
  355. {
  356. $config = $this->_saveHandlerTableConfig;
  357. $this->_setupDb($config['primary']);
  358. $this->_usedSaveHandlers[] =
  359. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  360. $saveHandler->open('savepath', 'sessionname');
  361. $id = '242';
  362. $this->assertTrue($saveHandler->write($id, serialize($config)));
  363. $this->assertSame($config, unserialize($saveHandler->read($id)));
  364. }
  365. public function testReadWriteTwice()
  366. {
  367. $config = $this->_saveHandlerTableConfig;
  368. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  369. $config['primary'] = array($config['primary'][0]);
  370. $this->_setupDb($config['primary']);
  371. $this->_usedSaveHandlers[] =
  372. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  373. $id = '242';
  374. $this->assertTrue($saveHandler->write($id, serialize($config)));
  375. $this->assertSame($config, unserialize($saveHandler->read($id)));
  376. $this->assertTrue($saveHandler->write($id, serialize($config)));
  377. $this->assertSame($config, unserialize($saveHandler->read($id)));
  378. }
  379. public function testReadWriteTwiceAndExpire()
  380. {
  381. $config = $this->_saveHandlerTableConfig;
  382. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  383. $config['primary'] = array($config['primary'][0]);
  384. $config['lifetime'] = 1;
  385. $this->_setupDb($config['primary']);
  386. $this->_usedSaveHandlers[] =
  387. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  388. $id = '242';
  389. $this->assertTrue($saveHandler->write($id, serialize($config)));
  390. $this->assertSame($config, unserialize($saveHandler->read($id)));
  391. $this->assertTrue($saveHandler->write($id, serialize($config)));
  392. sleep(2);
  393. $this->assertSame(false, unserialize($saveHandler->read($id)));
  394. }
  395. public function testReadWriteThreeTimesAndGc()
  396. {
  397. $config = $this->_saveHandlerTableConfig;
  398. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  399. $config['primary'] = array($config['primary'][0]);
  400. $config['lifetime'] = 1;
  401. $this->_setupDb($config['primary']);
  402. $this->_usedSaveHandlers[] =
  403. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  404. $id = 242;
  405. $this->assertTrue($saveHandler->write($id, serialize($config)));
  406. $this->assertSame($config, unserialize($saveHandler->read($id)));
  407. $id++;
  408. $this->assertTrue($saveHandler->write($id, serialize($config)));
  409. $this->assertSame($config, unserialize($saveHandler->read($id)));
  410. $id++;
  411. $this->assertTrue($saveHandler->write($id, serialize($config)));
  412. $this->assertSame($config, unserialize($saveHandler->read($id)));
  413. foreach ($this->_db->query('SELECT * FROM Sessions')->fetchAll() as $row) {
  414. $this->assertSame($config, unserialize($row['data']));
  415. }
  416. sleep(2);
  417. $saveHandler->gc(false);
  418. foreach ($this->_db->query('SELECT * FROM Sessions')->fetchAll() as $row) {
  419. //should be empty!
  420. $this->fail();
  421. }
  422. }
  423. public function testSetLifetime()
  424. {
  425. $config = $this->_saveHandlerTableConfig;
  426. unset($config[Zend_Session_SaveHandler_DbTable::PRIMARY_ASSIGNMENT]);
  427. $config['primary'] = array($config['primary'][0]);
  428. $config['lifetime'] = 1;
  429. $this->_setupDb($config['primary']);
  430. $this->_usedSaveHandlers[] =
  431. $saveHandler = new Zend_Session_SaveHandler_DbTable($config);
  432. $this->assertSame(1, $saveHandler->getLifetime());
  433. $saveHandler->setLifetime(27);
  434. $this->assertSame(27, $saveHandler->getLifetime());
  435. }
  436. public function testZendConfig()
  437. {
  438. $this->_usedSaveHandlers[] =
  439. $saveHandler = new Zend_Session_SaveHandler_DbTable(new Zend_Config($this->_saveHandlerTableConfig));
  440. /**
  441. * @todo Test something other than that an exception is not thrown
  442. */
  443. }
  444. /**
  445. * Sets up the database connection and creates the table for session data
  446. *
  447. * @param array $primary
  448. * @return void
  449. */
  450. protected function _setupDb(array $primary)
  451. {
  452. if (!extension_loaded('pdo_sqlite')) {
  453. $this->markTestSkipped('The pdo_sqlite extension must be available and enabled for this test');
  454. }
  455. $this->_db = Zend_Db::factory('Pdo_Sqlite', array('dbname' => ':memory:'));
  456. Zend_Db_Table_Abstract::setDefaultAdapter($this->_db);
  457. $query = array();
  458. $query[] = 'CREATE TABLE `Sessions` ( ';
  459. $query[] = '`id` varchar(32) NOT NULL, ';
  460. if (in_array('save_path', $primary)) {
  461. $query[] = '`save_path` varchar(32) NOT NULL, ';
  462. }
  463. if (in_array('name', $primary)) {
  464. $query[] = '`name` varchar(32) NOT NULL, ';
  465. }
  466. $query[] = '`modified` int(11) default NULL, ';
  467. $query[] = '`lifetime` int(11) default NULL, ';
  468. $query[] = '`data` text, ';
  469. $query[] = 'PRIMARY KEY (' . implode(', ', $primary) . ') ';
  470. $query[] = ');';
  471. $this->_db->query(implode("\n", $query));
  472. }
  473. /**
  474. * Drops the database table for session data
  475. *
  476. * @return void
  477. */
  478. protected function _dropTable()
  479. {
  480. $this->_db->query('DROP TABLE Sessions');
  481. }
  482. }
  483. /**
  484. * This class is used by Zend_Session_SaveHandler_AllTests to produce one skip message when pdo_sqlite is unavailable
  485. */
  486. class Zend_Session_SaveHandler_DbTableTestSkip extends PHPUnit_Framework_TestCase
  487. {
  488. public function testNothing()
  489. {
  490. $this->markTestSkipped('The pdo_sqlite extension must be available and enabled for this test');
  491. }
  492. }