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; } 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/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 aee07c053..d7f772e3f 100644 --- a/tests/Searcher/MongoTest.php +++ b/tests/Searcher/MongoTest.php @@ -183,4 +183,83 @@ public function testSaveRemove(): void $this->assertTrue($this->mongo->saveWatch($result[0])); $this->assertCount(0, $this->mongo->getAllWatches()); } + + public function testTruncateResultsPreserveIndexes(): void + { + $helper = new MongoHelper($this->mongodb); + + // dropping "results" collection using raw client + // (indexes are lost) + $helper->dropCollection('results'); + + // recreating collection "results" with indexes + $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]], + ]; + $helper->createCollection('results', $expectedIndexes); + + $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 + // compare result against expected indexes + foreach ($helper->getIndexes('results') as [$index, $name, $expectedIndex]) { + $this->assertEquals($expectedIndex[0], $index); + + $expectedName = $expectedIndex[1]['name']; + $this->assertEquals($expectedName, $name); + + if ($name === 'meta.request_ts') { + $this->assertArrayHasKey('expireAfterSeconds', $expectedIndex[1]); + $this->assertEquals(432000, $expectedIndex[1]['expireAfterSeconds']); + } + } + } + + public function testTruncateWatchesPreserveIndexes(): void + { + $helper = new MongoHelper($this->mongodb); + + // dropping "watches" collection using raw client + // (indexes are lost) + $helper->dropCollection('watches'); + + // recreating collection "watches" with indexes + $expectedIndexes = [ + [['_id' => 1], ['name' => '_id_']], + [['name' => -1], ['name' => 'test_name']], + ]; + $helper->createCollection('watches', $expectedIndexes); + + $this->searcher->saveWatch(['name' => 'strlen']); + + $result = $this->searcher->getAllWatches(); + $this->assertCount(1, $result); + + $this->mongo->truncateWatches(); + + $result = $this->searcher->getAllWatches(); + $this->assertEmpty($result); + + // compare result against expected indexes + foreach ($helper->getIndexes('watches') as [$index, $name, $expectedIndex]) { + $this->assertEquals($expectedIndex[0], $index); + $expectedName = $expectedIndex[1]['name']; + $this->assertEquals($expectedName, $name); + } + } }