From e6db462c8dc93feb2bcb47a8634ff845b7c94c64 Mon Sep 17 00:00:00 2001 From: Marko Dobromirovic Date: Sat, 26 Dec 2020 00:51:57 +0100 Subject: [PATCH 1/4] MongoSearcher: replace drop() with remove() --- src/Searcher/MongoSearcher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Searcher/MongoSearcher.php b/src/Searcher/MongoSearcher.php index da515080e..e5bcd9a30 100644 --- a/src/Searcher/MongoSearcher.php +++ b/src/Searcher/MongoSearcher.php @@ -222,7 +222,7 @@ public function delete($id): void public function truncate() { - $this->_collection->drop(); + $this->_collection->remove(); return $this; } @@ -276,7 +276,7 @@ public function getAllWatches(): array public function truncateWatches() { - $this->_watches->drop(); + $this->_watches->remove(); return $this; } From 6c8c186988d5a7d5b8204de8bd6c42b66e21a6be Mon Sep 17 00:00:00 2001 From: Marko Dobromirovic Date: Sat, 26 Dec 2020 01:14:56 +0100 Subject: [PATCH 2/4] MongoTest: add tests for preserving indexes on truncate --- tests/Searcher/MongoTest.php | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tests/Searcher/MongoTest.php b/tests/Searcher/MongoTest.php index aee07c053..04ddfca29 100644 --- a/tests/Searcher/MongoTest.php +++ b/tests/Searcher/MongoTest.php @@ -2,7 +2,9 @@ namespace XHGui\Test\Searcher; +use ArrayIterator; use MongoDB; +use MultipleIterator; use XHGui\Options\SearchOptions; use XHGui\Profile; use XHGui\Test\LazyContainerProperties; @@ -183,4 +185,121 @@ public function testSaveRemove(): void $this->assertTrue($this->mongo->saveWatch($result[0])); $this->assertCount(0, $this->mongo->getAllWatches()); } + + public function testTruncateResultsPreserveIndexes(): void + { + $mongoDb = $this->getDi()[MongoDB::class]; + $collection = $mongoDb->results; + + // dropping "results" collection using raw client + // (indexes are lost) + $collection->drop(); + + // recreating collection "results" with indexes + $collection = $mongoDb->createCollection('results'); + $expectedIndexes = [ + [['_id' => 1], ['name' => '_id_']], + [['meta.SERVER.REQUEST_TIME' => -1], ['name' => 'meta_srv_req_t']], + [['profile.main().wt' => -1], ['name' => 'profile_wt']], + [['profile.main().mu' => -1], ['name' => 'profile_mu']], + [['profile.main().cpu' => -1], ['name' => 'profile_cpu']], + [['meta.url' => 1], ['name' => 'meta_url']], + [['meta.simple_url' => 1], ['name' => 'simple_url']], + [['meta.request_ts' => 1], ['name' => 'req_ts', 'expireAfterSeconds' => 432000]], + ]; + foreach ($expectedIndexes as $index) { + $collection->createIndex($index[0], $index[1]); + } + + $this->importFixture($this->saver); + + $result = $this->mongo->getAll(new SearchOptions()); + $this->assertCount(7, $result['results']); + + $this->mongo->truncate(); + + $result = $this->mongo->getAll(new SearchOptions()); + $this->assertEmpty($result['results']); + + // assert that all indexes are intact after truncating + // fetch indexes + $resultIndexInfo = $collection->getIndexInfo(); + $resultIndexes = array_column($resultIndexInfo, 'key'); + $resultIndexNames = array_column($resultIndexInfo, 'name'); + + // setup iterators + $iterator = new MultipleIterator(); + $iterator->attachIterator(new ArrayIterator($resultIndexes)); + $iterator->attachIterator(new ArrayIterator($resultIndexNames)); + $iterator->attachIterator(new ArrayIterator($expectedIndexes)); + + // compare result against expected indexes + foreach ($iterator as $item) { + $index = $item[0]; + $expectedIndex = $item[2][0]; + $this->assertEquals($expectedIndex, $index); + + $name = $item[1]; + $expectedName = $item[2][1]['name']; + $this->assertEquals($expectedName, $name); + + if ($name === 'meta.request_ts') { + $this->assertArrayHasKey('expireAfterSeconds', $item[2][1]); + $this->assertEquals(432000, $item[2][1]['expireAfterSeconds']); + } + } + } + + public function testTruncateWatchesPreserveIndexes(): void + { + $mongoDb = $this->getDi()[MongoDB::class]; + $collection = $mongoDb->watches; + + // dropping "watches" collection using raw client + // (indexes are lost) + $collection->drop(); + + // recreating collection "watches" with indexes + $collection = $mongoDb->createCollection('watches'); + $expectedIndexes = [ + [['_id' => 1], ['name' => '_id_']], + [['name' => -1], ['name' => 'test_name']], + ]; + foreach ($expectedIndexes as $index) { + $collection->createIndex($index[0], $index[1]); + } + + $this->searcher->saveWatch(['name' => 'strlen']); + + $result = $this->searcher->getAllWatches(); + $this->assertCount(1, $result); + + $this->mongo->truncateWatches(); + + $result = $this->searcher->getAllWatches(); + $this->assertEmpty($result); + + // assert that all indexes are intact after truncating + // fetch indexes + $resultIndexInfo = $collection->getIndexInfo(); + $resultIndexes = array_column($resultIndexInfo, 'key'); + $resultIndexNames = array_column($resultIndexInfo, 'name'); + + // setup iterators + $iterator = new MultipleIterator(); + $iterator->attachIterator(new ArrayIterator($resultIndexes)); + $iterator->attachIterator(new ArrayIterator($resultIndexNames)); + $iterator->attachIterator(new ArrayIterator($expectedIndexes)); + + // compare result against expected indexes + foreach ($iterator as $item) { + $index = $item[0]; + $expectedIndex = $item[2][0]; + $this->assertEquals($expectedIndex, $index); + + $name = $item[1]; + $expectedName = $item[2][1]['name']; + $this->assertEquals($expectedName, $name); + } + } } From feec5ade0142341eb7cfe9d666be75c20f4bc426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Sat, 26 Dec 2020 08:17:46 +0200 Subject: [PATCH 3/4] Tests: Add lazy-accessor for MongoDB --- tests/LazyContainerProperties.php | 9 +++++++++ tests/Searcher/MongoTest.php | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/LazyContainerProperties.php b/tests/LazyContainerProperties.php index f449ba2d8..d0996077d 100644 --- a/tests/LazyContainerProperties.php +++ b/tests/LazyContainerProperties.php @@ -3,6 +3,7 @@ namespace XHGui\Test; use LazyProperty\LazyPropertiesTrait; +use MongoDB; use Slim\Slim as App; use Slim\View; use XHGui\Controller\ImportController; @@ -24,6 +25,8 @@ trait LazyContainerProperties protected $import; /** @var MongoSearcher */ private $mongo; + /** @var MongoDB */ + protected $mongodb; /** @var RunController */ protected $runs; /** @var App */ @@ -44,6 +47,7 @@ protected function setupProperties(): void 'app', 'import', 'mongo', + 'mongodb', 'runs', 'saver', 'searcher', @@ -90,6 +94,11 @@ protected function getMongo() return $this->di['searcher.mongodb']; } + protected function getMongoDb() + { + return $this->di[MongoDB::class]; + } + protected function getSearcher() { return $this->di['searcher']; diff --git a/tests/Searcher/MongoTest.php b/tests/Searcher/MongoTest.php index 04ddfca29..6db4ce153 100644 --- a/tests/Searcher/MongoTest.php +++ b/tests/Searcher/MongoTest.php @@ -188,7 +188,7 @@ public function testSaveRemove(): void public function testTruncateResultsPreserveIndexes(): void { - $mongoDb = $this->getDi()[MongoDB::class]; + $mongoDb = $this->mongodb; $collection = $mongoDb->results; // dropping "results" collection using raw client @@ -252,7 +252,7 @@ public function testTruncateResultsPreserveIndexes(): void public function testTruncateWatchesPreserveIndexes(): void { - $mongoDb = $this->getDi()[MongoDB::class]; + $mongoDb = $this->mongodb; $collection = $mongoDb->watches; // dropping "watches" collection using raw client From c7afd2900deeac01473e5d10b226cbf6f27b269b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Sat, 26 Dec 2020 08:44:03 +0200 Subject: [PATCH 4/4] Add MongoHelper to reduce duplicaion in MongoTest --- tests/Searcher/MongoHelper.php | 53 ++++++++++++++++++++++++++ tests/Searcher/MongoTest.php | 68 +++++++--------------------------- 2 files changed, 67 insertions(+), 54 deletions(-) create mode 100644 tests/Searcher/MongoHelper.php diff --git a/tests/Searcher/MongoHelper.php b/tests/Searcher/MongoHelper.php new file mode 100644 index 000000000..776e97d20 --- /dev/null +++ b/tests/Searcher/MongoHelper.php @@ -0,0 +1,53 @@ +mongodb = $mongodb; + } + + public function dropCollection(string $collectionName): void + { + $collection = $this->mongodb->selectCollection($collectionName); + $collection->drop(); + } + + public function createCollection(string $collectionName, array $indexes): void + { + $collection = $this->mongodb->createCollection($collectionName); + + foreach ($indexes as [$keys, $options]) { + $collection->createIndex($keys, $options); + } + $this->indexes[$collectionName] = $indexes; + } + + public function getIndexes(string $collectionName): MultipleIterator + { + $collection = $this->mongodb->selectCollection($collectionName); + $expectedIndexes = $this->indexes[$collectionName]; + + $resultIndexInfo = $collection->getIndexInfo(); + $resultIndexes = array_column($resultIndexInfo, 'key'); + $resultIndexNames = array_column($resultIndexInfo, 'name'); + + $iterator = new MultipleIterator(); + $iterator->attachIterator(new ArrayIterator($resultIndexes)); + $iterator->attachIterator(new ArrayIterator($resultIndexNames)); + $iterator->attachIterator(new ArrayIterator($expectedIndexes)); + + return $iterator; + } +} diff --git a/tests/Searcher/MongoTest.php b/tests/Searcher/MongoTest.php index 6db4ce153..d7f772e3f 100644 --- a/tests/Searcher/MongoTest.php +++ b/tests/Searcher/MongoTest.php @@ -2,9 +2,7 @@ namespace XHGui\Test\Searcher; -use ArrayIterator; use MongoDB; -use MultipleIterator; use XHGui\Options\SearchOptions; use XHGui\Profile; use XHGui\Test\LazyContainerProperties; @@ -188,15 +186,13 @@ public function testSaveRemove(): void public function testTruncateResultsPreserveIndexes(): void { - $mongoDb = $this->mongodb; - $collection = $mongoDb->results; + $helper = new MongoHelper($this->mongodb); // dropping "results" collection using raw client // (indexes are lost) - $collection->drop(); + $helper->dropCollection('results'); // recreating collection "results" with indexes - $collection = $mongoDb->createCollection('results'); $expectedIndexes = [ [['_id' => 1], ['name' => '_id_']], [['meta.SERVER.REQUEST_TIME' => -1], ['name' => 'meta_srv_req_t']], @@ -207,9 +203,7 @@ public function testTruncateResultsPreserveIndexes(): void [['meta.simple_url' => 1], ['name' => 'simple_url']], [['meta.request_ts' => 1], ['name' => 'req_ts', 'expireAfterSeconds' => 432000]], ]; - foreach ($expectedIndexes as $index) { - $collection->createIndex($index[0], $index[1]); - } + $helper->createCollection('results', $expectedIndexes); $this->importFixture($this->saver); @@ -222,52 +216,34 @@ public function testTruncateResultsPreserveIndexes(): void $this->assertEmpty($result['results']); // assert that all indexes are intact after truncating - // fetch indexes - $resultIndexInfo = $collection->getIndexInfo(); - $resultIndexes = array_column($resultIndexInfo, 'key'); - $resultIndexNames = array_column($resultIndexInfo, 'name'); - - // setup iterators - $iterator = new MultipleIterator(); - $iterator->attachIterator(new ArrayIterator($resultIndexes)); - $iterator->attachIterator(new ArrayIterator($resultIndexNames)); - $iterator->attachIterator(new ArrayIterator($expectedIndexes)); - // compare result against expected indexes - foreach ($iterator as $item) { - $index = $item[0]; - $expectedIndex = $item[2][0]; - $this->assertEquals($expectedIndex, $index); + foreach ($helper->getIndexes('results') as [$index, $name, $expectedIndex]) { + $this->assertEquals($expectedIndex[0], $index); - $name = $item[1]; - $expectedName = $item[2][1]['name']; + $expectedName = $expectedIndex[1]['name']; $this->assertEquals($expectedName, $name); if ($name === 'meta.request_ts') { - $this->assertArrayHasKey('expireAfterSeconds', $item[2][1]); - $this->assertEquals(432000, $item[2][1]['expireAfterSeconds']); + $this->assertArrayHasKey('expireAfterSeconds', $expectedIndex[1]); + $this->assertEquals(432000, $expectedIndex[1]['expireAfterSeconds']); } } } public function testTruncateWatchesPreserveIndexes(): void { - $mongoDb = $this->mongodb; - $collection = $mongoDb->watches; + $helper = new MongoHelper($this->mongodb); // dropping "watches" collection using raw client // (indexes are lost) - $collection->drop(); + $helper->dropCollection('watches'); // recreating collection "watches" with indexes - $collection = $mongoDb->createCollection('watches'); $expectedIndexes = [ [['_id' => 1], ['name' => '_id_']], [['name' => -1], ['name' => 'test_name']], ]; - foreach ($expectedIndexes as $index) { - $collection->createIndex($index[0], $index[1]); - } + $helper->createCollection('watches', $expectedIndexes); $this->searcher->saveWatch(['name' => 'strlen']); @@ -279,26 +255,10 @@ public function testTruncateWatchesPreserveIndexes(): void $result = $this->searcher->getAllWatches(); $this->assertEmpty($result); - // assert that all indexes are intact after truncating - // fetch indexes - $resultIndexInfo = $collection->getIndexInfo(); - $resultIndexes = array_column($resultIndexInfo, 'key'); - $resultIndexNames = array_column($resultIndexInfo, 'name'); - - // setup iterators - $iterator = new MultipleIterator(); - $iterator->attachIterator(new ArrayIterator($resultIndexes)); - $iterator->attachIterator(new ArrayIterator($resultIndexNames)); - $iterator->attachIterator(new ArrayIterator($expectedIndexes)); - // compare result against expected indexes - foreach ($iterator as $item) { - $index = $item[0]; - $expectedIndex = $item[2][0]; - $this->assertEquals($expectedIndex, $index); - - $name = $item[1]; - $expectedName = $item[2][1]['name']; + foreach ($helper->getIndexes('watches') as [$index, $name, $expectedIndex]) { + $this->assertEquals($expectedIndex[0], $index); + $expectedName = $expectedIndex[1]['name']; $this->assertEquals($expectedName, $name); } }