You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

433 lines
15 KiB

  1. <?php
  2. /*
  3. * @copyright NetMonsters <team@netmonsters.ru>
  4. * @link http://netmonsters.ru
  5. * @package Majestic
  6. * @subpackage UnitTests
  7. * @since 2011-11-10
  8. *
  9. * Unit tests for MongoDriver class
  10. */
  11. require_once dirname(__FILE__) . '/../../model/Db.php';
  12. require_once dirname(__FILE__) . '/../../model/DbDriver.php';
  13. require_once dirname(__FILE__) . '/../../model/NoSqlDbDriver.php';
  14. require_once dirname(__FILE__) . '/../../model/MongoDbCommand.php';
  15. require_once dirname(__FILE__) . '/../../model/DbStatement.php';
  16. require_once dirname(__FILE__) . '/../../model/MongoStatement.php';
  17. require_once dirname(__FILE__) . '/../../model/MongoDriver.php';
  18. require_once dirname(__FILE__) . '/../../exception/GeneralException.php';
  19. class MongoDriverTest extends PHPUnit_Framework_TestCase
  20. {
  21. private $conf = array();
  22. public function setUp()
  23. {
  24. $this->conf = array(
  25. 'hostname' => 'localhost',
  26. 'database' => 'test',
  27. 'username' => 'test',
  28. 'password' => '1234',
  29. 'port' => 27017
  30. );
  31. $data = array(
  32. array(
  33. 'name' => 'bread',
  34. 'price' => 3.2,
  35. 'quantity' => 10
  36. ),
  37. array(
  38. 'name' => 'eggs',
  39. 'price' => 2.1,
  40. 'quantity' => 20
  41. ),
  42. array(
  43. 'name' => 'fish',
  44. 'price' => 13.2,
  45. 'quantity' => 2
  46. ),
  47. array(
  48. 'name' => 'milk',
  49. 'price' => 3.8,
  50. 'quantity' => 1
  51. ),
  52. array(
  53. 'name' => 'eggs',
  54. 'price' => 2.3,
  55. 'quantity' => 5
  56. )
  57. );
  58. $connection = new Mongo('mongodb://' . $this->conf['hostname'] . ':' . $this->conf['port']);
  59. $db = $connection->selectDB($this->conf['database']);
  60. $db->authenticate($this->conf['username'], $this->conf['password']);
  61. $collection = 'items';
  62. $db->dropCollection($collection);
  63. $collection = $db->selectCollection($collection);
  64. foreach ($data as $document) {
  65. $collection->insert($document);
  66. }
  67. }
  68. /**
  69. * @group Mongo
  70. */
  71. public function testGetConnectionNoHostname()
  72. {
  73. unset($this->conf['hostname']);
  74. $this->setExpectedException('GeneralException', 'Configuration must have a "hostname"');
  75. $mongo = new MongoDriver($this->conf);
  76. }
  77. /**
  78. * @group Mongo
  79. */
  80. public function testGetConnectionWrongPassword()
  81. {
  82. $this->conf['password'] = 'nopass';
  83. $mongo = new MongoDriver($this->conf);
  84. $this->setExpectedException('MongoConnectionException', 'Couldn\'t authenticate with database');
  85. $this->assertInstanceOf('MongoDB', $mongo->getConnection());
  86. }
  87. /**
  88. * @group Mongo
  89. */
  90. public function testGetConnection()
  91. {
  92. $mongo = new MongoDriver($this->conf);
  93. $this->assertFalse($mongo->isConnected());
  94. $this->assertInstanceOf('Mongo', $mongo->getConnection());
  95. $this->assertTrue($mongo->isConnected());
  96. $mongo->getConnection();
  97. $mongo->disconnect();
  98. $this->assertFalse($mongo->isConnected());
  99. }
  100. /**
  101. * @runInSeparateProcess
  102. * @group Mongo
  103. */
  104. public function testFind()
  105. {
  106. if (!defined('DEBUG')) {
  107. define('DEBUG', false);
  108. }
  109. $mongo = new MongoDriver($this->conf);
  110. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  111. $this->assertEquals(2, $mongo->find('items', array('name' => 'eggs'))->numRows());
  112. $eggs = $mongo->find('items', array('name' => 'eggs'));
  113. $egg = $eggs->fetch();
  114. $this->assertEquals(20, $egg->quantity);
  115. $egg = $eggs->fetchObject();
  116. $this->assertEquals('eggs', $egg->name);
  117. $this->assertFalse($eggs->fetchObject());
  118. $this->assertEquals(3, $mongo->find('items', array('price' => array('$lt' => 3.5)))->numRows());
  119. $data = $mongo->find('items', array('price' => array('$lt' => 3.5)));
  120. $count = 0;
  121. while ($row = $data->fetch(Db::FETCH_ASSOC)) {
  122. $count++;
  123. $this->assertLessThan(3.5, $row['price']);
  124. }
  125. $this->assertEquals(3, $count);
  126. $this->assertEquals(5, $mongo->find('items', array())->numRows());
  127. }
  128. /**
  129. * @runInSeparateProcess
  130. * @group Mongo
  131. */
  132. public function testOrderSkipLimit()
  133. {
  134. if (!defined('DEBUG')) {
  135. define('DEBUG', false);
  136. }
  137. $mongo = new MongoDriver($this->conf);
  138. $count = $mongo->find('items', array())->numRows();
  139. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  140. $this->assertEquals(2, $mongo->find('items', array('name' => 'eggs'))->numRows());
  141. $mongo->insert('items', array('name' => 'fdsbssc'));
  142. $mongo->insert('items', array('name' => 'boc'));
  143. $mongo->insert('items', array('name' => 'abc'));
  144. $mongo->insert('items', array('name' => 'vcxxc'));
  145. $mongo->insert('items', array('name' => 'abbc'));
  146. $mongo->insert('items', array('name' => 'dsbssc'));
  147. $mongo->insert('items', array('name' => 'bssc'));
  148. $data = $mongo->find('items', array());
  149. $this->assertEquals($count + 7, $data->numRows());
  150. $data->order(array('name' => 1));
  151. $this->assertEquals('abbc', $data->fetch()->name);
  152. $this->assertEquals('abc', $data->fetch()->name);
  153. $this->assertEquals('boc', $data->fetch()->name);
  154. $data = $mongo->find('items', array());
  155. $data->order(array('name' => -1));
  156. $data->skip(3);
  157. $data->limit(1);
  158. while ($row = $data->fetch()) {
  159. $this->assertEquals('fdsbssc', $row->name);
  160. }
  161. }
  162. /**
  163. * @runInSeparateProcess
  164. * @group Mongo
  165. */
  166. public function testCount()
  167. {
  168. if (!defined('DEBUG')) {
  169. define('DEBUG', false);
  170. }
  171. $mongo = new MongoDriver($this->conf);
  172. $this->assertEquals(5, $mongo->count('items'));
  173. $this->assertEquals(2, $mongo->count('items', array('name' => 'eggs')));
  174. $this->assertEquals(1, $mongo->count('items', array('name' => 'eggs'), 1));
  175. }
  176. /**
  177. * @runInSeparateProcess
  178. * @group Mongo
  179. */
  180. public function testCursorCount()
  181. {
  182. if (!defined('DEBUG')) {
  183. define('DEBUG', false);
  184. }
  185. $mongo = new MongoDriver($this->conf);
  186. $this->assertEquals(5, $mongo->find('items')->count(5));
  187. $this->assertCount(3, $mongo->find('items')->limit(3)->fetchAll());
  188. $this->assertEquals(5, $mongo->count('items'));
  189. }
  190. /**
  191. * @runInSeparateProcess
  192. * @group Mongo
  193. */
  194. public function testGet()
  195. {
  196. if (!defined('DEBUG')) {
  197. define('DEBUG', false);
  198. }
  199. $mongo = new MongoDriver($this->conf);
  200. $eggs = $mongo->get('items', array('name' => 'eggs'))->fetchObject();
  201. $this->assertEquals(20, $eggs->quantity);
  202. $eggs = $mongo->get('items', array('name' => 'eggs'))->fetch();
  203. $this->assertEquals('eggs', $eggs->name);
  204. $this->assertInstanceOf('MongoId', $eggs->_id);
  205. }
  206. /**
  207. * @runInSeparateProcess
  208. * @group Mongo
  209. */
  210. public function testRemove()
  211. {
  212. if (!defined('DEBUG')) {
  213. define('DEBUG', false);
  214. }
  215. $mongo = new MongoDriver($this->conf);
  216. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  217. $this->assertEquals(0, $mongo->delete('items', array('name' => 'esggs')));
  218. $this->assertEquals(2, $mongo->delete('items', array('name' => 'eggs')));
  219. $this->assertEquals(1, $mongo->delete('items', array('name' => 'bread')));
  220. $this->assertEquals(0, $mongo->find('items', array('name' => 'bread'))->numRows());
  221. }
  222. /**
  223. * @runInSeparateProcess
  224. * @group Mongo
  225. */
  226. public function testInsert()
  227. {
  228. if (!defined('DEBUG')) {
  229. define('DEBUG', false);
  230. }
  231. $mongo = new MongoDriver($this->conf);
  232. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  233. $this->assertEquals(0, $mongo->insert('items', array('name' => 'bread')));
  234. $this->assertNotEmpty($mongo->getInsertId());
  235. $this->assertEquals(2, $mongo->find('items', array('name' => 'bread'))->numRows());
  236. $this->assertEquals(0, $mongo->insert('items', array('name' => 'meat', 'weight' => 230)));
  237. $this->assertEquals(230, $mongo->get('items', array('name' => 'meat'))->fetch()->weight);
  238. }
  239. /**
  240. * @runInSeparateProcess
  241. * @group Mongo
  242. */
  243. public function testBatchInsert()
  244. {
  245. if (!defined('DEBUG')) {
  246. define('DEBUG', false);
  247. }
  248. $data = array(
  249. array('name' => 'first object'),
  250. array('name' => 'second object'),
  251. array('name' => 'equal object'),
  252. array('name' => 'equal object')
  253. );
  254. $mongo = new MongoDriver($this->conf);
  255. $mongo->insert('items', $data, true);
  256. $this->assertEquals(1, $mongo->find('items', array('name' => 'first object'))->numRows());
  257. $this->assertEquals(1, $mongo->find('items', array('name' => 'second object'))->numRows());
  258. $this->assertEquals(2, $mongo->find('items', array('name' => 'equal object'))->numRows());
  259. }
  260. /**
  261. * @runInSeparateProcess
  262. * @group Mongo
  263. */
  264. public function testGetInsertId()
  265. {
  266. if (!defined('DEBUG')) {
  267. define('DEBUG', false);
  268. }
  269. $mongo = new MongoDriver($this->conf);
  270. $this->assertEquals(0, $mongo->getInsertId());
  271. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  272. $this->assertEquals(0, $mongo->insert('items', array('name' => 'bread')));
  273. $this->assertEquals(2, $mongo->find('items', array('name' => 'bread'))->numRows());
  274. $id1 = $mongo->getInsertId();
  275. $this->assertNotEmpty($id1);
  276. $this->assertEquals(0, $mongo->insert('items', array('name' => 'bread')));
  277. $id2 = $mongo->getInsertId();
  278. $this->assertNotEmpty($id2);
  279. $this->assertNotEquals($id1, $id2);
  280. $this->assertEquals(3, $mongo->find('items', array('name' => 'bread'))->numRows());
  281. }
  282. /**
  283. * @runInSeparateProcess
  284. * @group Mongo
  285. */
  286. public function testUpdate()
  287. {
  288. if (!defined('DEBUG')) {
  289. define('DEBUG', false);
  290. }
  291. $mongo = new MongoDriver($this->conf);
  292. $this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows());
  293. $this->assertEquals(1, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'fish')));
  294. $this->assertEquals(2, $mongo->update('items', array('$set' => array('price' => 1)), array('name' => 'eggs')));
  295. $fish = $mongo->get('items', array('name' => 'fish'))->fetch();
  296. $this->assertEquals(200, $fish->price);
  297. $this->assertEquals('today', $fish->date);
  298. $this->assertEquals(0, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'ball')));
  299. }
  300. /**
  301. * @runInSeparateProcess
  302. * @group Mongo
  303. */
  304. public function testUpsert()
  305. {
  306. if (!defined('DEBUG')) {
  307. define('DEBUG', false);
  308. }
  309. $mongo = new MongoDriver($this->conf);
  310. $mongo->insert('items', array('name' => 'bread'));
  311. $this->assertEquals(1, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'ball'), true, true));
  312. $this->assertEquals('today', $mongo->get('items', array('name' => 'ball'))->fetch()->date);
  313. }
  314. /**
  315. * @runInSeparateProcess
  316. * @group Mongo
  317. */
  318. public function testFindAndModify()
  319. {
  320. if (!defined('DEBUG')) {
  321. define('DEBUG', false);
  322. }
  323. $mongo = new MongoDriver($this->conf);
  324. $this->assertEquals(10, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity);
  325. $result = $mongo->findAndModify('items', array('name' => 'bread'), array('$set' => array('quantity' => 20)));
  326. $this->assertEquals(10, $result->fetch()->quantity);
  327. $this->assertEquals(20, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity);
  328. }
  329. /**
  330. * @runInSeparateProcess
  331. * @group Mongo
  332. */
  333. public function testFindAndModifyNoItem()
  334. {
  335. if (!defined('DEBUG')) {
  336. define('DEBUG', false);
  337. }
  338. $mongo = new MongoDriver($this->conf);
  339. $this->assertEquals(10, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity);
  340. $result = $mongo->findAndModify('items', array('name' => 'breading'), array('$set' => array('quantity' => 20)))->fetch();
  341. $this->assertFalse($result);
  342. $this->assertEquals(10, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity);
  343. }
  344. /**
  345. * @runInSeparateProcess
  346. * @group Mongo
  347. */
  348. public function testEvalCommand()
  349. {
  350. if (!defined('DEBUG')) {
  351. define('DEBUG', false);
  352. }
  353. $mongo = new MongoDriver($this->conf);
  354. $result = $mongo->command('items', array('$eval' => 'function() { return db.items.count();}'));
  355. $this->assertEquals(5, $result->fetch());
  356. $this->assertEquals(5, $mongo->count('items'));
  357. $result = $mongo->command('items', array('$eval' => 'function() { return "HELLO!";}'));
  358. $this->assertEquals("HELLO!", $result->fetch());
  359. }
  360. /**
  361. * @runInSeparateProcess
  362. * @group Mongo
  363. */
  364. public function testEval()
  365. {
  366. if (!defined('DEBUG')) {
  367. define('DEBUG', false);
  368. }
  369. $mongo = new MongoDriver($this->conf);
  370. $result = $mongo->command('items', array('$eval' => 'function() {return true; }'));
  371. $this->assertTrue($result->fetch());
  372. $result = $mongo->command('items', array('$eval' => 'function() {return "Hello"; }'));
  373. $this->assertSame('Hello', $result->fetch());
  374. $result = $mongo->command('items', array('$eval' => 'function() {return db.items.count(); }'));
  375. $this->assertEquals(5, $result->fetch());
  376. }
  377. /**
  378. * @runInSeparateProcess
  379. * @group Mongo
  380. */
  381. public function testCommand()
  382. {
  383. if (!defined('DEBUG')) {
  384. define('DEBUG', false);
  385. }
  386. $mongo = new MongoDriver($this->conf);
  387. $result = $mongo->command('items', array('distinct' => 'items', 'key' => 'name'));
  388. $this->assertEquals(4, count($result->fetch(DB::FETCH_ASSOC)));
  389. }
  390. }