Verified Commit 00de18c9 authored by Andrei Mateescu's avatar Andrei Mateescu
Browse files

task: #3426303 Move login performance testing to Umami

By: catch
By: kristiaanvandeneynde
By: berdir
By: amateescu
parent c13ef3fb
Loading
Loading
Loading
Loading
+170 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\demo_umami\FunctionalJavascript;

use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests demo_umami profile performance.
 */
#[Group('Performance')]
#[Group('#slow')]
#[RequiresPhpExtension('apcu')]
#[RunTestsInSeparateProcesses]
class MultipleRequestsPerformanceTest extends PerformanceTestBase {

  /**
   * {@inheritdoc}
   */
  protected $profile = 'demo_umami';

  /**
   * Test performance of various with various cache permutations.
   */
  public function testUmamiPerformance(): void {
    $this->doTestFrontAndRecipesPages();
    $this->doTestFrontAndRecipesPagesAuthenticated();
    $this->doTestFrontAndRecipesPagesEditor();
    $this->doTestNodeAddPagesAuthor();
    $this->doTestLogin();
  }

  /**
   * Checks the asset requests made when the front and recipe pages are visited.
   */
  protected function doTestFrontAndRecipesPages(): void {
    $performance_data = $this->collectPerformanceData(function () {
      $this->doRequests();
    }, 'umamiFrontAndRecipePages');

    $this->assertMetricsByName('umamiFrontAndRecipePages', $performance_data, [
      'ScriptCount',
      'ScriptBytes',
      'StylesheetCount',
      'StylesheetBytes',
    ]);
  }

  /**
   * Checks the front and recipe page asset requests as an authenticated user.
   */
  protected function doTestFrontAndRecipesPagesAuthenticated(): void {
    $user = $this->createUser();
    $this->drupalLogin($user);
    sleep(2);
    $performance_data = $this->collectPerformanceData(function () {
      $this->doRequests();
    }, 'umamiFrontAndRecipePagesAuthenticated');

    $this->assertMetricsByName('umamiFrontAndRecipePagesAuthenticated', $performance_data, [
      'ScriptCount',
      'ScriptBytes',
      'StylesheetCount',
      'StylesheetBytes',
    ]);
  }

  /**
   * Checks the front and recipe page asset requests as an editor.
   */
  protected function doTestFrontAndRecipesPagesEditor(): void {
    $user = $this->createUser();
    $user->addRole('editor');
    $user->save();
    $this->drupalLogin($user);
    sleep(2);
    $performance_data = $this->collectPerformanceData(function () {
      $this->doRequests();
    }, 'umamiFrontAndRecipePagesEditor');
    $this->assertMetricsByName('umamiFrontAndRecipePagesEditor', $performance_data, [
      'ScriptCount',
      'ScriptBytes',
      'StylesheetCount',
      'StylesheetBytes',
    ]);
  }

  /**
   * Checks the node/add page asset requests as an author.
   */
  protected function doTestNodeAddPagesAuthor(): void {
    $user = $this->createUser();
    $user->addRole('author');
    $user->save();
    $this->drupalLogin($user);
    $this->drupalGet('<front>');
    // Give additional time for the request and all assets to be returned
    // before making the next request.
    sleep(2);
    $performance_data = $this->collectPerformanceData(function () {
      $this->drupalGet('node/add/article');
      sleep(2);
      $this->drupalGet('node/add/recipe');
      sleep(2);
      $this->drupalGet('node/add/page');
    }, 'umamiNodeAddEditor');
    $this->assertMetricsByName('umamiNodeAddEditor', $performance_data, [
      'ScriptCount',
      'ScriptBytes',
      'StylesheetCount',
      'StylesheetBytes',
    ]);
  }

  /**
   * Tests the performance of logging in.
   */
  protected function doTestLogin(): void {
    $this->drupalLogout();
    $user = $this->createUser();
    // Create a user and log them in to warm all caches. Manually submit the
    // form so that we repeat the same steps when recording performance data. Do
    // this twice so that any caches which take two requests to warm are also
    // covered.
    for ($i = 0; $i < 2; $i++) {
      $this->drupalGet('user/login');
      $this->submitLoginForm($user);
      $this->drupalLogout();
    }

    $this->drupalGet('user/login');
    $performance_data = $this->collectPerformanceData(function () use ($user) {
      $this->submitLoginForm($user);
    }, 'umamiLogin');

    $this->assertQueriesByName('umamiLogin', $performance_data->getQueries());
    $this->assertMetricsByName('umamiLogin', $performance_data);
    $this->drupalLogout();
  }

  /**
   * Performs a common set of requests so the above test methods stay in sync.
   */
  protected function doRequests(): void {
    $this->drupalGet('<front>');
    // Give additional time for the request and all assets to be returned
    // before making the next request.
    sleep(2);
    $this->drupalGet('articles');
    sleep(2);
    $this->drupalGet('recipes');
    sleep(2);
    $this->drupalGet('recipes/deep-mediterranean-quiche');
  }

  /**
   * Submit the user login form.
   */
  protected function submitLoginForm($account): void {
    $this->submitForm([
      'name' => $account->getAccountName(),
      'pass' => $account->passRaw,
    ], 'Log in');
  }

}
+2 −2
Original line number Diff line number Diff line
ScriptCount: 3
ScriptBytes: 12006
ScriptBytes: 12091
StylesheetCount: 15
StylesheetBytes: 69836
StylesheetBytes: 69798
+2 −2
Original line number Diff line number Diff line
ScriptCount: 7
ScriptBytes: 74008
ScriptBytes: 74093
StylesheetCount: 12
StylesheetBytes: 55719
StylesheetBytes: 55681
+2 −2
Original line number Diff line number Diff line
ScriptCount: 12
ScriptBytes: 207377
ScriptBytes: 207462
StylesheetCount: 12
StylesheetBytes: 141838
StylesheetBytes: 141800
+9 −9
Original line number Diff line number Diff line
SELECT "name", "value" FROM "key_value" WHERE "name" IN ( "theme:stark" ) AND "collection" = "config.entity.key_store.block"
SELECT "name", "value" FROM "key_value_expire" WHERE "expire" > "NOW" AND "name" IN ( "KEY" ) AND "collection" = "form"
SELECT COUNT(*) AS "expression" FROM (SELECT 1 AS "expression" FROM "flood" "f" WHERE ("event" = "user.failed_login_ip") AND ("identifier" = "CLIENT_IP") AND ("timestamp" > "TIMESTAMP")) "subquery"
SELECT "base_table"."uid" AS "uid", "base_table"."uid" AS "base_table_uid" FROM "users" "base_table" INNER JOIN "users_field_data" "users_field_data" ON "users_field_data"."uid" = "base_table"."uid" WHERE ("users_field_data"."name" IN ("ACCOUNT_NAME")) AND ("users_field_data"."default_langcode" IN (1))
SELECT "base"."uid" AS "uid", "base"."uuid" AS "uuid", "base"."langcode" AS "langcode" FROM "users" "base" WHERE "base"."uid" IN (2)
SELECT "users_field_data".*, "users_field_data"."langcode" AS "users_field_data__langcode", "user__user_picture"."user_picture_target_id" AS "user_picture_target_id", "user__user_picture"."user_picture_alt" AS "user_picture_alt", "user__user_picture"."user_picture_title" AS "user_picture_title", "user__user_picture"."user_picture_width" AS "user_picture_width", "user__user_picture"."user_picture_height" AS "user_picture_height" FROM "users_field_data" "users_field_data" LEFT OUTER JOIN "user__user_picture" "user__user_picture" ON "user__user_picture"."entity_id" = "users_field_data"."uid" AND "user__user_picture"."langcode" = "users_field_data"."langcode" AND "user__user_picture"."deleted" = 0 WHERE "users_field_data"."uid" IN (2)
SELECT "user__roles"."entity_id" AS "id", "user__roles"."langcode" AS "langcode", "user__roles"."roles_target_id" AS "roles_target_id", "user__roles"."delta" AS "roles_delta" FROM "user__roles" "user__roles" WHERE ("user__roles"."entity_id" IN (2)) AND ("user__roles"."deleted" = 0) ORDER BY "user__roles"."delta" ASC
SELECT COUNT(*) AS "expression" FROM (SELECT 1 AS "expression" FROM "flood" "f" WHERE ("event" = "user.failed_login_user") AND ("identifier" = "CLIENT_IP") AND ("timestamp" > "TIMESTAMP")) "subquery"
INSERT INTO "watchdog" ("uid", "type", "message", "variables", "severity", "link", "location", "referer", "hostname", "timestamp") VALUES ("2", "user", "Session opened for %name.", "WATCHDOG_DATA", 6, "", "LOCATION", "REFERER", "CLIENT_IP", "TIMESTAMP")
UPDATE "users_field_data" SET "login"="TIMESTAMP" WHERE "uid" = "2"
INSERT INTO "watchdog" ("uid", "type", "message", "variables", "severity", "link", "location", "referer", "hostname", "timestamp") VALUES ("13", "user", "Session opened for %name.", "WATCHDOG_DATA", 6, "", "LOCATION", "REFERER", "CLIENT_IP", "TIMESTAMP")
UPDATE "users_field_data" SET "login"="TIMESTAMP" WHERE "uid" = "13"
SELECT "session" FROM "sessions" WHERE "sid" = "SESSION_ID" LIMIT 0, 1
INSERT INTO "sessions" ("sid", "uid", "hostname", "session", "timestamp") VALUES ("SESSION_ID", "2", "CLIENT_IP", "SESSION_DATA", "TIMESTAMP") ON DUPLICATE KEY UPDATE "uid" = VALUES("uid"), "hostname" = VALUES("hostname"), "session" = VALUES("session"), "timestamp" = VALUES("timestamp")
INSERT INTO "sessions" ("sid", "uid", "hostname", "session", "timestamp") VALUES ("SESSION_ID", "13", "CLIENT_IP", "SESSION_DATA", "TIMESTAMP") ON DUPLICATE KEY UPDATE "uid" = VALUES("uid"), "hostname" = VALUES("hostname"), "session" = VALUES("session"), "timestamp" = VALUES("timestamp")
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 * FROM "users_field_data" "u" WHERE "u"."uid" = "13" AND "u"."default_langcode" = 1
SELECT "roles_target_id" FROM "user__roles" WHERE "entity_id" = "13"
SELECT "base"."uid" AS "uid", "base"."uuid" AS "uuid", "base"."langcode" AS "langcode" FROM "users" "base" WHERE "base"."uid" IN (13)
SELECT "users_field_data".*, "users_field_data"."langcode" AS "users_field_data__langcode", "user__user_picture"."user_picture_target_id" AS "user_picture_target_id", "user__user_picture"."user_picture_alt" AS "user_picture_alt", "user__user_picture"."user_picture_title" AS "user_picture_title", "user__user_picture"."user_picture_width" AS "user_picture_width", "user__user_picture"."user_picture_height" AS "user_picture_height" FROM "users_field_data" "users_field_data" LEFT OUTER JOIN "user__user_picture" "user__user_picture" ON "user__user_picture"."entity_id" = "users_field_data"."uid" AND "user__user_picture"."langcode" = "users_field_data"."langcode" AND "user__user_picture"."deleted" = 0 WHERE "users_field_data"."uid" IN (13)
SELECT "user__roles"."entity_id" AS "id", "user__roles"."langcode" AS "langcode", "user__roles"."roles_target_id" AS "roles_target_id", "user__roles"."delta" AS "roles_delta" FROM "user__roles" "user__roles" WHERE ("user__roles"."entity_id" IN (13)) AND ("user__roles"."deleted" = 0) ORDER BY "user__roles"."delta" ASC
SELECT "name", "value" FROM "key_value" WHERE "name" IN ( "theme:umami" ) AND "collection" = "config.entity.key_store.block"
Loading