Skip to content

Commit 0d46f99

Browse files
committed
ACP2E-2222: EAV Indexer performance
- improved code testability - added unit test
1 parent 018d259 commit 0d46f99

File tree

4 files changed

+157
-15
lines changed

4 files changed

+157
-15
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/AbstractIndexer.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
namespace Magento\Catalog\Model\ResourceModel\Product\Indexer;
77

88
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Eav\Model\Config;
10+
use Magento\Framework\EntityManager\MetadataPool;
11+
use Magento\Framework\Indexer\Table\StrategyInterface;
12+
use Magento\Framework\Model\ResourceModel\Db\Context;
913

1014
/**
1115
* Catalog Product Indexer Abstract Resource Model
@@ -33,18 +37,22 @@ abstract class AbstractIndexer extends \Magento\Indexer\Model\ResourceModel\Abst
3337
/**
3438
* Class constructor
3539
*
36-
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
37-
* @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy
38-
* @param \Magento\Eav\Model\Config $eavConfig
39-
* @param string $connectionName
40+
* @param Context $context
41+
* @param StrategyInterface $tableStrategy
42+
* @param Config $eavConfig
43+
* @param null $connectionName
44+
* @param MetadataPool|null $metadataPool
4045
*/
4146
public function __construct(
4247
\Magento\Framework\Model\ResourceModel\Db\Context $context,
4348
\Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
4449
\Magento\Eav\Model\Config $eavConfig,
45-
$connectionName = null
50+
$connectionName = null,
51+
?\Magento\Framework\EntityManager\MetadataPool $metadataPool = null
4652
) {
4753
$this->_eavConfig = $eavConfig;
54+
$this->metadataPool = $metadataPool ?: \Magento\Framework\App\ObjectManager::getInstance()
55+
->get(\Magento\Framework\EntityManager\MetadataPool::class);
4856
parent::__construct($context, $tableStrategy, $connectionName);
4957
}
5058

@@ -239,10 +247,6 @@ public function getRelationsByParent($parentIds)
239247
*/
240248
protected function getMetadataPool()
241249
{
242-
if (null === $this->metadataPool) {
243-
$this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
244-
->get(\Magento\Framework\EntityManager\MetadataPool::class);
245-
}
246250
return $this->metadataPool;
247251
}
248252
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ public function __construct(
3535
\Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
3636
\Magento\Eav\Model\Config $eavConfig,
3737
\Magento\Framework\Event\ManagerInterface $eventManager,
38-
$connectionName = null
38+
$connectionName = null,
39+
?\Magento\Framework\EntityManager\MetadataPool $metadataPool = null
3940
) {
4041
$this->_eventManager = $eventManager;
41-
parent::__construct($context, $tableStrategy, $eavConfig, $connectionName);
42+
parent::__construct($context, $tableStrategy, $eavConfig, $connectionName, $metadataPool);
4243
}
4344

4445
/**

app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,18 @@ public function __construct(
5555
\Magento\Eav\Model\Config $eavConfig,
5656
\Magento\Framework\Event\ManagerInterface $eventManager,
5757
\Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
58-
$connectionName = null,
58+
?string $connectionName = null,
5959
\Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository = null,
60-
\Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder = null
60+
\Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder = null,
61+
?\Magento\Framework\EntityManager\MetadataPool $metadataPool = null
6162
) {
6263
parent::__construct(
6364
$context,
6465
$tableStrategy,
6566
$eavConfig,
6667
$eventManager,
67-
$connectionName
68+
$connectionName,
69+
$metadataPool
6870
);
6971
$this->_resourceHelper = $resourceHelper;
7072
$this->attributeRepository = $attributeRepository
@@ -218,7 +220,10 @@ protected function _prepareSelectIndex($entityIds = null, $attributeId = null)
218220
'cpe.entity_id AS source_id',
219221
]
220222
);
221-
$visibilityCondition = $connection->quoteInto('>?', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE);
223+
$visibilityCondition = $connection->quoteInto(
224+
'>?',
225+
\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE
226+
);
222227
$linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField();
223228
$this->_addAttributeToSelect(
224229
$select,
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product\Indexer\Eav;
9+
10+
use Magento\Catalog\Model\ResourceModel\Helper;
11+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\Source;
12+
use Magento\Eav\Api\AttributeRepositoryInterface;
13+
use Magento\Eav\Model\Config;
14+
use Magento\Framework\Api\SearchCriteriaBuilder;
15+
use Magento\Framework\App\ResourceConnection;
16+
use Magento\Framework\DB\Adapter\AdapterInterface;
17+
use Magento\Framework\EntityManager\EntityMetadataInterface;
18+
use Magento\Framework\Event\ManagerInterface;
19+
use Magento\Framework\Indexer\Table\StrategyInterface;
20+
use Magento\Framework\Model\ResourceModel\Db\Context;
21+
use Magento\ResourceConnections\DB\Select;
22+
use PHPUnit\Framework\MockObject\MockObject;
23+
use PHPUnit\Framework\TestCase;
24+
use Magento\Framework\EntityManager\MetadataPool;
25+
26+
class SourceTest extends TestCase
27+
{
28+
/**
29+
* @var Context|MockObject
30+
*/
31+
private Context $context;
32+
33+
/**
34+
* @var StrategyInterface|MockObject
35+
*/
36+
private StrategyInterface $tableStrategy;
37+
38+
/**
39+
* @var Config|MockObject
40+
*/
41+
private Config $eavConfig;
42+
43+
/**
44+
* @var ManagerInterface|MockObject
45+
*/
46+
private ManagerInterface $eventManager;
47+
48+
/**
49+
* @var Helper|MockObject
50+
*/
51+
private Helper $resourceHelper;
52+
53+
/**
54+
* @var AttributeRepositoryInterface|MockObject
55+
*/
56+
private AttributeRepositoryInterface $attributeRepository;
57+
58+
/**
59+
* @var SearchCriteriaBuilder|MockObject
60+
*/
61+
private SearchCriteriaBuilder $criteriaBuilder;
62+
63+
/**
64+
* @var MetadataPool|MockObject
65+
*/
66+
private MetadataPool $metadataPool;
67+
68+
/**
69+
* @var Source
70+
*/
71+
private Source $indexer;
72+
73+
/**
74+
* @return void
75+
*/
76+
protected function setUp(): void
77+
{
78+
$this->context = $this->createMock(Context::class);
79+
$this->tableStrategy = $this->createMock(StrategyInterface::class);
80+
$this->eavConfig = $this->createMock(Config::class);
81+
$this->eventManager = $this->createMock(ManagerInterface::class);
82+
$this->resourceHelper = $this->createMock(Helper::class);
83+
$this->attributeRepository = $this->createMock(AttributeRepositoryInterface::class);
84+
$this->criteriaBuilder = $this->createMock(SearchCriteriaBuilder::class);
85+
$this->metadataPool = $this->createMock(MetadataPool::class);
86+
87+
parent::setUp();
88+
}
89+
90+
/**
91+
* @return void
92+
* @throws \Exception
93+
*/
94+
public function testReindexEntities(): void
95+
{
96+
$products = [1, 2];
97+
$select = $this->createMock(Select::class);
98+
$select->expects($this->any())->method('from')->willReturn($select);
99+
$select->expects($this->any())->method('join')->willReturn($select);
100+
$select->expects($this->any())->method('where')->willReturn($select);
101+
$select->expects($this->any())->method('joinLeft')->willReturn($select);
102+
$select->expects($this->any())->method('joinLeft')->willReturn($select);
103+
$select->expects($this->any())->method('group')->willReturn($select);
104+
$select->expects($this->any())->method('columns')->willReturn($select);
105+
$connection = $this->createMock(AdapterInterface::class);
106+
$connection->expects($this->once())->method('delete');
107+
$connection->expects($this->any())->method('select')->willReturn($select);
108+
$resources = $this->createMock(ResourceConnection::class);
109+
$resources->expects($this->any())
110+
->method('getConnection')
111+
->with('test_connection_name')
112+
->willReturn($connection);
113+
$this->context->expects($this->any())->method('getResources')->willReturn($resources);
114+
$this->tableStrategy->expects($this->any())->method('getTableName')->willReturn('idx_table');
115+
$this->tableStrategy->expects($this->any())->method('getUseIdxTable')->willReturn(true);
116+
$metadata = $this->createMock(EntityMetadataInterface::class);
117+
$this->metadataPool->expects($this->any())->method('getMetadata')->willReturn($metadata);
118+
119+
$this->indexer = new Source(
120+
$this->context,
121+
$this->tableStrategy,
122+
$this->eavConfig,
123+
$this->eventManager,
124+
$this->resourceHelper,
125+
'test_connection_name',
126+
$this->attributeRepository,
127+
$this->criteriaBuilder,
128+
$this->metadataPool
129+
);
130+
$this->indexer->reindexEntities($products);
131+
}
132+
}

0 commit comments

Comments
 (0)