DbTableTest.php 19 KB

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