PerformanceTest.php
5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
declare(strict_types=1);
namespace Drupal\Tests\drupal_cms_starter\FunctionalJavascript;
use Composer\InstalledVersions;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait;
/**
* Tests the performance of the drupal_cms_starter recipe.
*
* Stark is used as the default theme so that this test is not Olivero specific.
*
* @group OpenTelemetry
* @group #slow
* @requires extension apcu
*/
class PerformanceTest extends PerformanceTestBase {
use RecipeTestTrait;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests performance of the starter recipe.
*/
public function testPerformance(): void {
$dir = InstalledVersions::getInstallPath('drupal/drupal_cms_starter');
$this->applyRecipe($dir);
// Applying the recipe installs automated cron, but we don't want cron to
// run in the middle of a performance test, so uninstall it.
\Drupal::service('module_installer')->uninstall(['automated_cron']);
$this->doTestAnonymousFrontPage();
$this->doTestEditorFrontPage();
}
/**
* Check the anonymous front page with a hot cache.
*/
protected function doTestAnonymousFrontPage(): void {
$this->drupalGet('');
$this->drupalGet('');
// Test frontpage.
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('');
}, 'drupalCMSAnonymousFrontPage');
$expected = [
'QueryCount' => 0,
'CacheGetCount' => 2,
'CacheSetCount' => 0,
'CacheTagLookupQueryCount' => 1,
// If there are small changes in the below limits, e.g. under 5kb, the
// ceiling can be raised without any investigation. However large increases
// indicate a large library is newly loaded for anonymous users.
'StylesheetCount' => 2,
'StylesheetBytes' => 80000,
'ScriptCount' => 1,
'ScriptBytes' => 23000,
];
$this->assertMetrics($expected, $performance_data);
$this->assertSession()->elementExists('css', 'article.node');
}
/**
* Log in with the editor role and visit the front page with a warm cache.
*/
protected function doTestEditorFrontPage(): void {
$editor = $this->drupalCreateUser();
$editor->addRole('content_editor')->save();
$this->drupalLogin($editor);
// Warm various caches.
$this->drupalGet('');
// Allow one second for post response tasks to write caches.
sleep(1);
$this->drupalGet('');
sleep(1);
// Test frontpage.
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('');
}, 'drupalCMSEditorFrontPage');
$assert_session = $this->assertSession();
$assert_session->elementAttributeContains('named', ['link', 'Dashboard'], 'class', 'toolbar-button--icon--navigation-dashboard');
$assert_session->elementExists('css', 'article.node');
// The following queries are the only database queries executed for editors on the
// front page.
$queries = [
'SELECT "session" FROM "sessions" WHERE "sid" = "SESSION_ID" LIMIT 0, 1',
'SELECT * FROM "users_field_data" "u" WHERE "u"."uid" = "2" AND "u"."default_langcode" = 1',
'SELECT "roles_target_id" FROM "user__roles" WHERE "entity_id" = "2"',
'SELECT "base_table"."id" AS "id", "base_table"."path" AS "path", "base_table"."alias" AS "alias", "base_table"."langcode" AS "langcode" FROM "path_alias" "base_table" WHERE ("base_table"."status" = 1) AND ("base_table"."alias" LIKE "/node/2" ESCAPE \'\\\\\') AND ("base_table"."langcode" IN ("en", "und")) ORDER BY "base_table"."langcode" ASC, "base_table"."id" DESC',
'SELECT rid FROM "redirect" WHERE hash IN ("NKzL8tFQHWuVsiKsKSy9LeHXQXJXBi02otuiixBL8TE", "hef6TjxChWEKH2Wao9m0dVOigdwgf67UkEGlfXcimoA") ORDER BY LENGTH(redirect_source__query) DESC',
'SELECT "config"."name" AS "name" FROM "config" "config" WHERE ("collection" = "") AND ("name" LIKE "klaro.klaro_app.%" ESCAPE \'\\\\\') ORDER BY "collection" ASC, "name" ASC',
'SELECT "session" FROM "sessions" WHERE "sid" = "SESSION_ID" LIMIT 0, 1',
'SELECT * FROM "users_field_data" "u" WHERE "u"."uid" = "2" AND "u"."default_langcode" = 1',
'SELECT "roles_target_id" FROM "user__roles" WHERE "entity_id" = "2"',
];
// To avoid a test failure when a database query is removed, check only
// that a new database query has not been added.
$query_diff = array_diff($performance_data->getQueries(), $queries);
$this->assertSame([], $query_diff);
$this->assertLessThanOrEqual(9, $performance_data->getQueryCount());
$expected = [
'QueryCount' => 9,
'CacheGetCount' => 70,
'CacheSetCount' => 0,
'CacheTagLookupQueryCount' => 9,
// If there are small changes in the below limits, e.g. under 5kb, the
// ceiling can be raised without any investigation. However large increases
// indicate a large library is newly loaded for authenticated users.
'StylesheetCount' => 3,
'StylesheetBytes' => 218000,
'ScriptCount' => 4,
'ScriptBytes' => 244800,
];
$this->assertMetrics($expected, $performance_data);
}
}