Skip to content

Commit 039de71

Browse files
pweyckswsrmes
authored andcommitted
NEXT-23166 - Allow overrides in phpbench bootstrap
1 parent 735ffc3 commit 039de71

16 files changed

+4159
-391
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: Add PHPBench compatibility for the Commercial plugin
3+
issue: NEXT-17583
4+
---
5+
# Core
6+
* Added additional pre-generated UUID data to the `FixtureLoader.php` fixture generator
7+
* Added `createProducts` and `createCustomer` methods in `BasicTestDataBehaviour` which utilise the `CustomerBuilder` and `ProductBuilder` fixture helpers
8+
___
9+
# Tests
10+
* Added 100 products to phpbench `data.json` to allow for improved load testing in bench tests
11+
* Added phpbench tests for `ProductListingRoute.php` and `ProductDetailRoute.php`
12+
* Adjusted phpbench bootstrapping (initial fixture creation) to allow the loading of custom fixtures from the commercial plugin (conditionally based upon the phpbench `--group` flag)
13+
* Allow `Fixtures.php` to load fixtures with only string input
14+
___

phpbench.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema":"./vendor/phpbench/phpbench/phpbench.schema.json",
33
"core.extensions": ["Shopware\\Tests\\Bench\\BenchExtension"],
44
"runner.bootstrap": "tests/performance/bench/BenchBootstrap.php",
5-
"runner.path": "tests/performance/bench/Cases",
5+
"runner.path": ["tests/performance/bench/Storefront", "tests/performance/bench/Administration"],
66
"runner.file_pattern": "*Bench.php",
77
"runner.iterations": 10,
88
"runner.revs": 3,

phpstan-baseline.neon

-15
Original file line numberDiff line numberDiff line change
@@ -27105,11 +27105,6 @@ parameters:
2710527105
count: 2
2710627106
path: src/Core/System/Test/StateMachine/StateMachineRegistryTest.php
2710727107

27108-
-
27109-
message: "#^Method Shopware\\\\Core\\\\System\\\\Test\\\\StateMachine\\\\StateMachineRegistryTest\\:\\:createStateMachineWithoutInitialState\\(\\) is unused\\.$#"
27110-
count: 1
27111-
path: src/Core/System/Test/StateMachine/StateMachineRegistryTest.php
27112-
2711327108
-
2711427109
message: "#^Method Shopware\\\\Core\\\\System\\\\Test\\\\SystemConfig\\\\Command\\\\ConfigGetCommandTest\\:\\:configFormatDefaultProvider\\(\\) return type has no value type specified in iterable type iterable\\.$#"
2711527110
count: 1
@@ -27260,11 +27255,6 @@ parameters:
2726027255
count: 1
2726127256
path: src/Core/System/User/UserEntity.php
2726227257

27263-
-
27264-
message: "#^Method Shopware\\\\Core\\\\Test\\\\FixtureLoader\\:\\:sync\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#"
27265-
count: 1
27266-
path: src/Core/Test/FixtureLoader.php
27267-
2726827258
-
2726927259
message: "#^Method Shopware\\\\Core\\\\Test\\\\Integration\\\\Helper\\\\MailEventListener\\:\\:__construct\\(\\) has parameter \\$mapping with no value type specified in iterable type array\\.$#"
2727027260
count: 1
@@ -29120,11 +29110,6 @@ parameters:
2912029110
count: 1
2912129111
path: src/Storefront/Test/Framework/Csrf/CsrfPlaceholderHandlerTest.php
2912229112

29123-
-
29124-
message: "#^Method Shopware\\\\Storefront\\\\Test\\\\Framework\\\\Csrf\\\\CsrfPlaceholderHandlerTest\\:\\:generateToken\\(\\) is unused\\.$#"
29125-
count: 1
29126-
path: src/Storefront/Test/Framework/Csrf/CsrfPlaceholderHandlerTest.php
29127-
2912829113
-
2912929114
message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#"
2913029115
count: 1

src/Core/Framework/Test/TestCaseBase/BasicTestDataBehaviour.php

+73
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
use Shopware\Core\Checkout\Order\OrderStates;
77
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
88
use Shopware\Core\Checkout\Shipping\ShippingMethodEntity;
9+
use Shopware\Core\Checkout\Test\Customer\CustomerBuilder;
10+
use Shopware\Core\Content\Test\Product\ProductBuilder;
911
use Shopware\Core\Defaults;
1012
use Shopware\Core\Framework\Context;
1113
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
1214
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
1315
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
1416
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
17+
use Shopware\Core\Framework\Test\IdsCollection;
1518
use Shopware\Core\Framework\Uuid\Uuid;
1619
use Shopware\Core\System\Language\LanguageEntity;
1720
use Shopware\Core\Test\TestDefaults;
@@ -290,4 +293,74 @@ protected function getCurrencyIdByIso(string $iso = 'EUR'): string
290293

291294
return Uuid::fromBytesToHex($connection->fetchOne('SELECT id FROM currency WHERE iso_code = :iso', ['iso' => $iso]));
292295
}
296+
297+
/**
298+
* @param array<string, mixed> $additionalData
299+
*
300+
* @return array<array<string, mixed>>
301+
*/
302+
private function createCustomers(
303+
IdsCollection &$idsCollection,
304+
int $numberOfCustomers,
305+
string $idPrefix = 'customer',
306+
array $additionalData = []
307+
): array {
308+
$builders = [];
309+
while ($numberOfCustomers-- > 0) {
310+
$builder = new CustomerBuilder($idsCollection, "$idPrefix-$numberOfCustomers");
311+
foreach ($additionalData as $key => $value) {
312+
if (method_exists($builder, $key)) {
313+
if (\is_array($value)) {
314+
$builder->{$key}(...$value);
315+
316+
continue;
317+
}
318+
319+
$builder->{$key}($value);
320+
}
321+
}
322+
$builders[] = $builder->build();
323+
}
324+
325+
if (!empty($builders)) {
326+
$this->getContainer()->get('customer.repository')->upsert($builders, Context::createDefaultContext());
327+
}
328+
329+
return $builders;
330+
}
331+
332+
/**
333+
* @param array<string, mixed> $additionalData
334+
*
335+
* @return array<array<string, mixed>>
336+
*/
337+
private function createProducts(
338+
IdsCollection &$idsCollection,
339+
int $numberOfProducts,
340+
string $idPrefix = 'product',
341+
array $additionalData = ['price' => 100]
342+
): array {
343+
$builders = [];
344+
while ($numberOfProducts-- > 0) {
345+
$builder = new ProductBuilder($idsCollection, "$idPrefix-$numberOfProducts");
346+
foreach ($additionalData as $key => $value) {
347+
if (method_exists($builder, $key)) {
348+
if (\is_array($value)) {
349+
$builder->{$key}(...$value);
350+
351+
continue;
352+
}
353+
354+
$builder->{$key}($value);
355+
}
356+
}
357+
$builders[] = $builder->build();
358+
}
359+
360+
if (!empty($builders)) {
361+
$this->getContainer()->get('product.repository')->upsert($builders, Context::createDefaultContext());
362+
}
363+
364+
return $builders;
365+
}
293366
}

src/Core/Test/FixtureLoader.php

+56-14
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,65 @@
22

33
namespace Shopware\Core\Test;
44

5+
use Doctrine\DBAL\Connection;
56
use Shopware\Core\Defaults;
67
use Shopware\Core\Framework\Api\Sync\SyncOperation;
78
use Shopware\Core\Framework\Context;
9+
use Shopware\Core\Framework\DataAbstractionLayer\Indexing\EntityIndexerRegistry;
10+
use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriter;
811
use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriterInterface;
912
use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext;
1013
use Shopware\Core\Framework\Test\IdsCollection;
14+
use Shopware\Core\Framework\Test\TestCaseBase\BasicTestDataBehaviour;
15+
use Symfony\Component\DependencyInjection\ContainerInterface;
1116

1217
/**
1318
* @internal
1419
*/
1520
class FixtureLoader
1621
{
22+
use BasicTestDataBehaviour;
23+
24+
private ContainerInterface $container;
25+
1726
private EntityWriterInterface $writer;
1827

19-
public function __construct(EntityWriterInterface $writer)
20-
{
21-
$this->writer = $writer;
28+
private Connection $connection;
29+
30+
public function __construct(
31+
ContainerInterface $container
32+
) {
33+
$this->container = $container;
34+
$this->connection = $container->get(Connection::class);
35+
$this->writer = $container->get(EntityWriter::class);
2236
}
2337

24-
public function load(string $file): IdsCollection
38+
public function load(string $content, ?IdsCollection $ids = null): IdsCollection
2539
{
26-
$content = (string) \file_get_contents($file);
27-
28-
$ids = new IdsCollection([
29-
'currency' => Defaults::CURRENCY,
30-
'api-type' => Defaults::SALES_CHANNEL_TYPE_API,
31-
'comparison-type' => Defaults::SALES_CHANNEL_TYPE_PRODUCT_COMPARISON,
32-
'storefront-type' => Defaults::SALES_CHANNEL_TYPE_STOREFRONT,
33-
'language' => Defaults::LANGUAGE_SYSTEM,
34-
]);
40+
if (!$ids) {
41+
$ids = new IdsCollection([
42+
'currency' => Defaults::CURRENCY,
43+
'api-type' => Defaults::SALES_CHANNEL_TYPE_API,
44+
'comparison-type' => Defaults::SALES_CHANNEL_TYPE_PRODUCT_COMPARISON,
45+
'storefront-type' => Defaults::SALES_CHANNEL_TYPE_STOREFRONT,
46+
'language' => Defaults::LANGUAGE_SYSTEM,
47+
'locale' => $this->getLocaleIdOfSystemLanguage(),
48+
'es-locale' => $this->getLocaleIdFromLocaleCode('es-ES'),
49+
]);
50+
}
3551

3652
$content = $this->replaceIds($ids, $content);
37-
3853
$this->sync(\json_decode($content, true, 512, \JSON_THROW_ON_ERROR));
54+
$this->container->get(EntityIndexerRegistry::class)->index(false);
3955

4056
return $ids;
4157
}
4258

59+
public function getContainer(): ContainerInterface
60+
{
61+
return $this->container;
62+
}
63+
4364
private function replaceIds(IdsCollection $ids, string $content): string
4465
{
4566
return (string) \preg_replace_callback('/"{.*}"/mU', function (array $match) use ($ids) {
@@ -49,6 +70,9 @@ private function replaceIds(IdsCollection $ids, string $content): string
4970
}, $content);
5071
}
5172

73+
/**
74+
* @param array<array<string, mixed>> $content
75+
*/
5276
private function sync(array $content): void
5377
{
5478
$operations = [];
@@ -58,4 +82,22 @@ private function sync(array $content): void
5882

5983
$this->writer->sync($operations, WriteContext::createFromContext(Context::createDefaultContext()));
6084
}
85+
86+
private function getLocaleIdOfSystemLanguage(): string
87+
{
88+
return $this->connection
89+
->fetchOne(
90+
'SELECT LOWER(HEX(locale_id)) FROM language WHERE id = UNHEX(:systemLanguageId)',
91+
['systemLanguageId' => Defaults::LANGUAGE_SYSTEM]
92+
);
93+
}
94+
95+
private function getLocaleIdFromLocaleCode(string $code): string
96+
{
97+
return $this->connection
98+
->fetchOne(
99+
'SELECT LOWER(HEX(id)) from locale WHERE code = :code',
100+
['code' => $code]
101+
);
102+
}
61103
}

tests/performance/bench/Administration/.gitkeep

Whitespace-only changes.

tests/performance/bench/BenchCase.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
namespace Shopware\Tests\Bench;
44

55
use Doctrine\DBAL\Connection;
6-
use PhpBench\Attributes\AfterMethods;
7-
use PhpBench\Attributes\BeforeMethods;
6+
use PhpBench\Attributes\Groups;
87
use Shopware\Core\Framework\Test\IdsCollection;
98
use Shopware\Core\Framework\Test\TestCaseBase\KernelLifecycleManager;
109
use Shopware\Core\System\SalesChannel\SalesChannelContext;
@@ -13,8 +12,7 @@
1312
/**
1413
* @internal - only for performance benchmarks
1514
*/
16-
#[BeforeMethods(['setup'])]
17-
#[AfterMethods(['tearDown'])]
15+
#[Groups(['base'])]
1816
abstract class BenchCase
1917
{
2018
protected IdsCollection $ids;

0 commit comments

Comments
 (0)