Commit 1debb398 authored by catch's avatar catch
Browse files

Issue #3375959 by znerol, catch, bradjones1: Add a way to delay executions in...

Issue #3375959 by znerol, catch, bradjones1: Add a way to delay executions in test runner until terminate event completed in the child site
parent aec9cf8c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
use Drupal\Core\Render\MainContent\MainContentRenderersPass;
use Drupal\Core\Site\Settings;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
@@ -142,6 +143,12 @@ protected function registerTest(ContainerBuilder $container) {
    $container
      ->register('test.http_client.middleware', 'Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware')
      ->addTag('http_client_middleware');
    // Add the wait terminate middleware which acquires a lock to signal request
    // termination to the test runner.
    $container
      ->register('test.http_middleware.wait_terminate_middleware', 'Drupal\Core\Test\StackMiddleware\TestWaitTerminateMiddleware')
      ->setArguments([new Reference('state'), new Reference('lock')])
      ->addTag('http_middleware', ['priority' => -1024]);
  }

}
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,13 @@ public function __invoke() {
            if (!drupal_valid_test_ua()) {
              return $response;
            }
            if (!empty($response->getHeader('X-Drupal-Wait-Terminate')[0])) {
              $lock = \Drupal::lock();
              if (!$lock->acquire('test_wait_terminate')) {
                $lock->wait('test_wait_terminate');
              }
              $lock->release('test_wait_terminate');
            }
            $headers = $response->getHeaders();
            foreach ($headers as $header_name => $header_values) {
              if (preg_match('/^X-Drupal-Assertion-[0-9]+$/', $header_name, $matches)) {
+50 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Test\StackMiddleware;

use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
 * Acquire a lock to signal request termination to the test runner.
 */
class TestWaitTerminateMiddleware implements HttpKernelInterface {

  /**
   * Constructs a test wait terminate stack middleware object.
   *
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $httpKernel
   *   The decorated kernel.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state server.
   * @param \Drupal\Core\Lock\LockBackendInterface $lock
   *   The lock backend.
   */
  public function __construct(
    protected HttpKernelInterface $httpKernel,
    protected StateInterface $state,
    protected LockBackendInterface $lock
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response {
    $result = $this->httpKernel->handle($request, $type, $catch);

    if ($this->state->get('drupal.test_wait_terminate')) {
      // Set a header on the response to instruct the test runner that it must
      // await the lock. Note that the lock acquired here is automatically
      // released from within a shutdown function.
      $this->lock->acquire('test_wait_terminate');
      $result->headers->set('X-Drupal-Wait-Terminate', '1');
    }

    return $result;
  }

}
+4 −4
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\jsonapi\Traits\CommonCollectionFilterAccessTestPatternsTrait;
use Drupal\Tests\WaitTerminateTestTrait;
use Drupal\user\Entity\User;
use GuzzleHttp\RequestOptions;

@@ -22,6 +23,7 @@
class NodeTest extends ResourceTestBase {

  use CommonCollectionFilterAccessTestPatternsTrait;
  use WaitTerminateTestTrait;

  /**
   * {@inheritdoc}
@@ -315,6 +317,8 @@ public function testPatchPath() {
   * {@inheritdoc}
   */
  public function testGetIndividual() {
    $this->setWaitForTerminate();

    parent::testGetIndividual();

    $this->assertCacheableNormalizations();
@@ -393,15 +397,11 @@ protected function assertCacheableNormalizations(): void {
    $request_options = $this->getAuthenticationRequestOptions();
    $request_options[RequestOptions::QUERY] = ['fields' => ['node--camelids' => 'title']];
    $this->request('GET', $url, $request_options);
    // Cacheable normalizations are written after the response is flushed to
    // the client; give the server a chance to complete this work.
    sleep(1);
    // Ensure the normalization cache is being incrementally built. After
    // requesting the title, only the title is in the cache.
    $this->assertNormalizedFieldsAreCached(['title']);
    $request_options[RequestOptions::QUERY] = ['fields' => ['node--camelids' => 'field_rest_test']];
    $this->request('GET', $url, $request_options);
    sleep(1);
    // After requesting an additional field, then that field is in the cache and
    // the old one is still there.
    $this->assertNormalizedFieldsAreCached(['title', 'field_rest_test']);
+5 −12
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\WaitTerminateTestTrait;

/**
 * Tests Language Negotiation.
@@ -21,6 +22,8 @@
 */
class ConfigurableLanguageManagerTest extends BrowserTestBase {

  use WaitTerminateTestTrait;

  /**
   * {@inheritdoc}
   */
@@ -45,6 +48,8 @@ class ConfigurableLanguageManagerTest extends BrowserTestBase {
  protected function setUp(): void {
    parent::setUp();

    $this->setWaitForTerminate();

    /** @var \Drupal\user\UserInterface $user */
    $user = $this->createUser([], '', TRUE);
    $this->drupalLogin($user);
@@ -266,16 +271,4 @@ public function testUserProfileTranslationWithPreferredAdminLanguage() {
    $assert_session->pageTextNotContains($field_label_es);
  }

  /**
   * {@inheritdoc}
   */
  protected function drupalGet($path, array $options = [], array $headers = []) {
    $response = parent::drupalGet($path, $options, $headers);
    // The \Drupal\locale\LocaleTranslation service clears caches after the
    // response is flushed to the client; wait for Drupal to perform its
    // termination work before continuing.
    sleep(1);
    return $response;
  }

}
Loading