Skip to content

Commit 394cae7

Browse files
committed
ACP2E-4303: Reindexing stuck due to high memory usage
1 parent 74fcac9 commit 394cae7

File tree

8 files changed

+2318
-0
lines changed

8 files changed

+2318
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Test\Unit\Model\Indexer;
9+
10+
use Magento\CatalogRule\Model\Indexer\CatalogRuleInsertBatchSizeCalculator;
11+
use Magento\Framework\DB\Adapter\AdapterInterface;
12+
use Magento\Framework\Indexer\BatchSizeManagementInterface;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* Unit test for CatalogRuleInsertBatchSizeCalculator
18+
*/
19+
class CatalogRuleInsertBatchSizeCalculatorTest extends TestCase
20+
{
21+
/**
22+
* @var BatchSizeManagementInterface|MockObject
23+
*/
24+
private $batchSizeManagementMock;
25+
26+
/**
27+
* @var AdapterInterface|MockObject
28+
*/
29+
private $connectionMock;
30+
31+
/**
32+
* @var CatalogRuleInsertBatchSizeCalculator
33+
*/
34+
private $calculator;
35+
36+
/**
37+
* @inheritDoc
38+
*/
39+
protected function setUp(): void
40+
{
41+
$this->batchSizeManagementMock = $this->getMockForAbstractClass(BatchSizeManagementInterface::class);
42+
$this->connectionMock = $this->getMockForAbstractClass(AdapterInterface::class);
43+
}
44+
45+
public function testGetInsertBatchSizeWithDefaultBatchSize(): void
46+
{
47+
$defaultBatchSize = 5000;
48+
$this->calculator = new CatalogRuleInsertBatchSizeCalculator(
49+
$this->batchSizeManagementMock,
50+
$defaultBatchSize
51+
);
52+
53+
$this->batchSizeManagementMock->expects($this->once())
54+
->method('ensureBatchSize')
55+
->with($this->connectionMock, $defaultBatchSize);
56+
57+
$result = $this->calculator->getInsertBatchSize($this->connectionMock);
58+
$this->assertEquals($defaultBatchSize, $result);
59+
}
60+
61+
public function testGetInsertBatchSizeWithCustomBatchSize(): void
62+
{
63+
$customBatchSize = 10000;
64+
$this->calculator = new CatalogRuleInsertBatchSizeCalculator(
65+
$this->batchSizeManagementMock,
66+
$customBatchSize
67+
);
68+
69+
$this->batchSizeManagementMock->expects($this->once())
70+
->method('ensureBatchSize')
71+
->with($this->connectionMock, $customBatchSize);
72+
73+
$result = $this->calculator->getInsertBatchSize($this->connectionMock);
74+
$this->assertEquals($customBatchSize, $result);
75+
}
76+
77+
public function testGetInsertBatchSizeWithAdjustedBatchSize(): void
78+
{
79+
$defaultBatchSize = 5000;
80+
$this->calculator = new CatalogRuleInsertBatchSizeCalculator(
81+
$this->batchSizeManagementMock,
82+
$defaultBatchSize
83+
);
84+
85+
$this->batchSizeManagementMock->expects($this->once())
86+
->method('ensureBatchSize')
87+
->with($this->connectionMock, $defaultBatchSize);
88+
89+
$result = $this->calculator->getInsertBatchSize($this->connectionMock);
90+
$this->assertIsInt($result);
91+
$this->assertGreaterThan(0, $result);
92+
}
93+
94+
public function testGetInsertBatchSizeReturnsInteger(): void
95+
{
96+
$defaultBatchSize = 5000;
97+
$this->calculator = new CatalogRuleInsertBatchSizeCalculator(
98+
$this->batchSizeManagementMock,
99+
$defaultBatchSize
100+
);
101+
102+
$this->batchSizeManagementMock->expects($this->once())
103+
->method('ensureBatchSize')
104+
->with($this->connectionMock, $defaultBatchSize);
105+
106+
$result = $this->calculator->getInsertBatchSize($this->connectionMock);
107+
$this->assertIsInt($result);
108+
$this->assertGreaterThan(0, $result);
109+
}
110+
}
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Test\Unit\Model\Indexer;
9+
10+
use Magento\CatalogRule\Model\Indexer\CatalogRuleProductPriceRowSizeEstimator;
11+
use Magento\Framework\App\ResourceConnection;
12+
use Magento\Store\Model\StoreManagerInterface;
13+
use Magento\Store\Model\Website;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* Unit test for CatalogRuleProductPriceRowSizeEstimator
19+
*/
20+
class CatalogRuleProductPriceRowSizeEstimatorTest extends TestCase
21+
{
22+
/**
23+
* @var ResourceConnection|MockObject
24+
*/
25+
private $resourceConnectionMock;
26+
27+
/**
28+
* @var MockObject
29+
*/
30+
private $customerGroupCollectionFactoryMock;
31+
32+
/**
33+
* @var StoreManagerInterface|MockObject
34+
*/
35+
private $storeManagerMock;
36+
37+
/**
38+
* @var MockObject
39+
*/
40+
private $customerGroupCollectionMock;
41+
42+
/**
43+
* @var CatalogRuleProductPriceRowSizeEstimator
44+
*/
45+
private $estimator;
46+
47+
/**
48+
* @inheritDoc
49+
*/
50+
protected function setUp(): void
51+
{
52+
$this->resourceConnectionMock = $this->createMock(ResourceConnection::class);
53+
54+
$this->customerGroupCollectionMock = $this->getMockBuilder(\stdClass::class)
55+
->addMethods(['getSize'])
56+
->getMock();
57+
58+
$collectionFactoryClass = 'Magento\Customer\Model\ResourceModel\Group\CollectionFactory';
59+
60+
$this->customerGroupCollectionFactoryMock = $this->getMockBuilder($collectionFactoryClass)
61+
->disableOriginalConstructor()
62+
->onlyMethods(['create'])
63+
->getMock();
64+
65+
$this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
66+
67+
$this->customerGroupCollectionFactoryMock->method('create')
68+
->willReturn($this->customerGroupCollectionMock);
69+
70+
$this->estimator = new CatalogRuleProductPriceRowSizeEstimator(
71+
$this->resourceConnectionMock,
72+
$this->customerGroupCollectionFactoryMock,
73+
$this->storeManagerMock
74+
);
75+
}
76+
77+
/**
78+
* Test estimateRowSize with single website and single customer group
79+
*
80+
* @return void
81+
*/
82+
public function testEstimateRowSizeWithSingleWebsiteAndGroup(): void
83+
{
84+
$customerGroupCount = 1;
85+
$websiteCount = 1;
86+
87+
$this->customerGroupCollectionMock->expects($this->once())
88+
->method('getSize')
89+
->willReturn($customerGroupCount);
90+
91+
$website = $this->createMock(Website::class);
92+
$this->storeManagerMock->expects($this->once())
93+
->method('getWebsites')
94+
->willReturn([$website]);
95+
96+
$result = $this->estimator->estimateRowSize();
97+
98+
// Expected: 1 customer group * 1 website * 2 * 150 bytes = 300 bytes
99+
$this->assertEquals(300, $result);
100+
}
101+
102+
/**
103+
* Test estimateRowSize with multiple websites and customer groups
104+
*
105+
* @return void
106+
*/
107+
public function testEstimateRowSizeWithMultipleWebsitesAndGroups(): void
108+
{
109+
$customerGroupCount = 4;
110+
$websiteCount = 3;
111+
112+
$this->customerGroupCollectionMock->expects($this->once())
113+
->method('getSize')
114+
->willReturn($customerGroupCount);
115+
116+
$websites = [];
117+
for ($i = 0; $i < $websiteCount; $i++) {
118+
$websites[] = $this->createMock(Website::class);
119+
}
120+
121+
$this->storeManagerMock->expects($this->once())
122+
->method('getWebsites')
123+
->willReturn($websites);
124+
125+
$result = $this->estimator->estimateRowSize();
126+
127+
// Expected: 4 customer groups * 3 websites * 2 * 150 bytes = 3600 bytes
128+
$this->assertEquals(3600, $result);
129+
}
130+
131+
/**
132+
* Test estimateRowSize returns integer value
133+
*
134+
* @return void
135+
*/
136+
public function testEstimateRowSizeReturnsInteger(): void
137+
{
138+
$customerGroupCount = 3;
139+
$websiteCount = 2;
140+
141+
$this->customerGroupCollectionMock->expects($this->once())
142+
->method('getSize')
143+
->willReturn($customerGroupCount);
144+
145+
$websites = [];
146+
for ($i = 0; $i < $websiteCount; $i++) {
147+
$websites[] = $this->createMock(Website::class);
148+
}
149+
150+
$this->storeManagerMock->expects($this->once())
151+
->method('getWebsites')
152+
->willReturn($websites);
153+
154+
$result = $this->estimator->estimateRowSize();
155+
156+
$this->assertIsInt($result);
157+
// Expected: 3 customer groups * 2 websites * 2 * 150 bytes = 1800 bytes
158+
$this->assertEquals(1800, $result);
159+
}
160+
161+
/**
162+
* Test estimateRowSize with large number of groups and websites
163+
*
164+
* @return void
165+
*/
166+
public function testEstimateRowSizeWithLargeConfiguration(): void
167+
{
168+
$customerGroupCount = 10;
169+
$websiteCount = 5;
170+
171+
$this->customerGroupCollectionMock->expects($this->once())
172+
->method('getSize')
173+
->willReturn($customerGroupCount);
174+
175+
$websites = [];
176+
for ($i = 0; $i < $websiteCount; $i++) {
177+
$websites[] = $this->createMock(Website::class);
178+
}
179+
180+
$this->storeManagerMock->expects($this->once())
181+
->method('getWebsites')
182+
->willReturn($websites);
183+
184+
$result = $this->estimator->estimateRowSize();
185+
186+
// Expected: 10 customer groups * 5 websites * 2 * 150 bytes = 15000 bytes
187+
$this->assertEquals(15000, $result);
188+
}
189+
190+
/**
191+
* Test estimateRowSize with zero customer groups
192+
*
193+
* @return void
194+
*/
195+
public function testEstimateRowSizeWithZeroCustomerGroups(): void
196+
{
197+
$customerGroupCount = 0;
198+
$websiteCount = 3;
199+
200+
$this->customerGroupCollectionMock->expects($this->once())
201+
->method('getSize')
202+
->willReturn($customerGroupCount);
203+
204+
$websites = [];
205+
for ($i = 0; $i < $websiteCount; $i++) {
206+
$websites[] = $this->createMock(Website::class);
207+
}
208+
209+
$this->storeManagerMock->expects($this->once())
210+
->method('getWebsites')
211+
->willReturn($websites);
212+
213+
$result = $this->estimator->estimateRowSize();
214+
215+
// Expected: 0 customer groups * 3 websites * 2 * 150 bytes = 0 bytes
216+
$this->assertEquals(0, $result);
217+
}
218+
219+
/**
220+
* Test estimateRowSize with empty websites array
221+
*
222+
* @return void
223+
*/
224+
public function testEstimateRowSizeWithNoWebsites(): void
225+
{
226+
$customerGroupCount = 5;
227+
228+
$this->customerGroupCollectionMock->expects($this->once())
229+
->method('getSize')
230+
->willReturn($customerGroupCount);
231+
232+
$this->storeManagerMock->expects($this->once())
233+
->method('getWebsites')
234+
->willReturn([]);
235+
236+
$result = $this->estimator->estimateRowSize();
237+
238+
// Expected: 5 customer groups * 0 websites * 2 * 150 bytes = 0 bytes
239+
$this->assertEquals(0, $result);
240+
}
241+
}

0 commit comments

Comments
 (0)