DbTableTest.php 19 KB

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