Skip to content

Commit

Permalink
api: try to test the performance of our endpoints against a larger da…
Browse files Browse the repository at this point in the history
…tabase

This failed because it takes too long to load the fixtures n times.
  • Loading branch information
BacLuc committed Mar 2, 2024
1 parent 754204e commit 2e35a86
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 51 deletions.
6 changes: 3 additions & 3 deletions api/fixtures/campCollaborations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ App\Entity\CampCollaboration:
campCollaboration4invited:
camp: '@camp1'
inviteKey: "myInviteKey"
inviteKeyHash: "sl3hC12VkIUzT89mMggYyoMmFuo="
inviteKeyHash: "<name()>"
inviteEmail: "[email protected]"
status: invited
role: member
Expand Down Expand Up @@ -54,7 +54,7 @@ App\Entity\CampCollaboration:
campCollaboration2invitedCampUnrelated:
camp: '@campUnrelated'
inviteKey: "myInviteKey2"
inviteKeyHash: "oNp2IShH2P5DIgvcdBZOwCqExZ0="
inviteKeyHash: "<name()>"
inviteEmail: "[email protected]"
status: invited
role: member
Expand All @@ -67,7 +67,7 @@ App\Entity\CampCollaboration:
user: '@user6invited'
camp: '@camp2'
inviteKey: "myInviteKeyCamp2"
inviteKeyHash: "ufVn1nkIodzMXLPB/ZI4JwNwSRg="
inviteKeyHash: "<name()>"
status: invited
role: member
campCollaboration1campPrototype:
Expand Down
16 changes: 8 additions & 8 deletions api/fixtures/contentTypes.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
App\Entity\ContentType:
contentTypeSafetyConcept:
name: 'SafetyConcept'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\SingleText'
contentTypeStoryContext:
name: 'Storycontext'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\SingleText'
contentTypeNotes:
name: 'Notes'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\SingleText'
contentTypeColumnLayout:
name: 'ColumnLayout'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\ColumnLayout'
contentTypeResponsiveLayout:
name: 'ResponsiveLayout'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\ResponsiveLayout'
contentTypeStoryboard:
name: 'Storyboard'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\Storyboard'
contentTypeMaterial:
name: 'Material'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\MaterialNode'
contentTypeMultiSelect:
name: 'LAThematicArea'
name: <name()>
active: true
entityClass: 'App\Entity\ContentNode\MultiSelect'
jsonConfig: { items: [ 'outdoorTechnique', 'security', 'natureAndEnvironment', 'pioneeringTechnique', 'campsiteAndSurroundings', 'preventionAndIntegration' ] }
4 changes: 2 additions & 2 deletions api/fixtures/profiles.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
App\Entity\Profile:
profile1manager:
user: '@user1manager'
email: [email protected]
email: <email()>
firstname: Robert
surname: Baden-Powell
nickname: Bi-Pi
Expand Down Expand Up @@ -65,7 +65,7 @@ App\Entity\Profile:
roles: [ 'ROLE_USER' ]
profileAdmin:
user: '@admin'
email: [email protected]
email: <email()>
firstname: Admi
surname: Nistrator
nickname: Administrator
Expand Down
15 changes: 3 additions & 12 deletions api/tests/Api/ECampApiTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\Entity\BaseEntity;
use App\Entity\Profile;
use App\Entity\User;
use App\Metadata\Resource\OperationHelper;
use App\Repository\ProfileRepository;
use App\Util\ArrayDeepSort;
use Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector;
use Doctrine\ORM\EntityManagerInterface;
Expand Down Expand Up @@ -81,16 +79,9 @@ public static function deepCloneArray(array $array): mixed {
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
protected static function createClientWithCredentials(?array $credentials = null, ?array $headers = null): Client {
protected static function createClientWithCredentials(string $userFixtureName = 'user1manager', ?array $headers = null): Client {
$client = static::createBasicClient($headers);

/** @var Profile $profile */
$profile = static::getContainer()->get(ProfileRepository::class)
->findOneBy(
array_diff_key($credentials ?: ['email' => '[email protected]'], ['password' => ''])
)
;
$user = $profile->user;
$user = self::getFixture($userFixtureName);

$jwtToken = static::getContainer()->get('lexik_jwt_authentication.jwt_manager')->create($user);
$lastPeriodPosition = strrpos($jwtToken, '.');
Expand All @@ -111,7 +102,7 @@ protected static function createClientWithCredentials(?array $credentials = null
* @throws TransportExceptionInterface
*/
protected static function createClientWithAdminCredentials(?array $headers = null): Client {
return static::createClientWithCredentials(['email' => '[email protected]']);
return static::createClientWithCredentials('user1admin', $headers);
}

protected static function createBasicClient(?array $headers = null): Client {
Expand Down
61 changes: 36 additions & 25 deletions api/tests/Api/SnapshotTests/EndpointQueryCountTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Tests\Api\ECampApiTestCase;
use App\Tests\Spatie\Snapshots\Driver\ECampYamlSnapshotDriver;
use Hautelook\AliceBundle\PhpUnit\FixtureStore;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseState;
use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
Expand All @@ -31,34 +32,40 @@ class EndpointQueryCountTest extends ECampApiTestCase {
* @throws TransportExceptionInterface
*/
public function testNumberOfQueriesDidNotChangeForStableEndpoints() {
$numberOfQueries = [];
$responseCodes = [];
$collectionEndpoints = self::getCollectionEndpoints();
foreach ($collectionEndpoints as $collectionEndpoint) {
if ('/users' !== $collectionEndpoint && !str_contains($collectionEndpoint, '/content_node')) {
list($statusCode, $queryCount, $executionTimeSeconds) = $this->measurePerformanceFor($collectionEndpoint);
$responseCodes[$collectionEndpoint] = $statusCode;
$numberOfQueries[$collectionEndpoint] = [
'queryCount' => $queryCount,
'executionTimeSeconds' => $executionTimeSeconds,
];
}

if (!str_contains($collectionEndpoint, '/content_node')) {
$fixtureFor = $this->getFixtureFor($collectionEndpoint);
list($statusCode, $queryCount, $executionTimeSeconds) = $this->measurePerformanceFor("{$collectionEndpoint}/{$fixtureFor->getId()}");
$responseCodes["{$collectionEndpoint}/item"] = $statusCode;
$numberOfQueries["{$collectionEndpoint}/item"] = [
'queryCount' => $queryCount,
'executionTimeSeconds' => $executionTimeSeconds,
];
RefreshDatabaseState::setDbPopulated(false);

try {
$numberOfQueries = [];
$responseCodes = [];
$collectionEndpoints = self::getCollectionEndpoints();
foreach ($collectionEndpoints as $collectionEndpoint) {
if ('/users' !== $collectionEndpoint && !str_contains($collectionEndpoint, '/content_node')) {
list($statusCode, $queryCount, $executionTimeSeconds) = $this->measurePerformanceFor($collectionEndpoint);
$responseCodes[$collectionEndpoint] = $statusCode;
$numberOfQueries[$collectionEndpoint] = [
'queryCount' => $queryCount,
'executionTimeSeconds' => $executionTimeSeconds,
];
}

if (!str_contains($collectionEndpoint, '/content_node')) {
$fixtureFor = $this->getFixtureFor($collectionEndpoint);
list($statusCode, $queryCount, $executionTimeSeconds) = $this->measurePerformanceFor("{$collectionEndpoint}/{$fixtureFor->getId()}");
$responseCodes["{$collectionEndpoint}/item"] = $statusCode;
$numberOfQueries["{$collectionEndpoint}/item"] = [
'queryCount' => $queryCount,
'executionTimeSeconds' => $executionTimeSeconds,
];
}
}
}

$not200Responses = array_filter($responseCodes, fn ($value) => 200 != $value);
assertThat($not200Responses, isEmpty());
$not200Responses = array_filter($responseCodes, fn ($value) => 200 != $value);
assertThat($not200Responses, isEmpty());

$this->assertMatchesSnapshot($numberOfQueries, new ECampYamlSnapshotDriver());
$this->assertMatchesSnapshot($numberOfQueries, new ECampYamlSnapshotDriver());
} finally {
RefreshDatabaseState::setDbPopulated(false);
}
}

/**
Expand Down Expand Up @@ -146,6 +153,10 @@ public static function getContentNodeEndpoints(): array {
});
}

protected static function getLoadFixturesNTimes($container): int {
return 1e4;
}

private static function getContentNodeEndpointQueryCountRanges(): array {
return [
'/content_nodes' => [8, 9],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
executionTimeSeconds: 0.01
/periods/item:
queryCount: 19
executionTimeSeconds: 0.03
executionTimeSeconds: 0.02
/profiles:
queryCount: 6
executionTimeSeconds: 0.01
Expand Down

0 comments on commit 2e35a86

Please sign in to comment.