function DirectoryTest::testMultiplePrepareDirectory

Same name in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php \Drupal\KernelTests\Core\File\DirectoryTest::testMultiplePrepareDirectory()
  2. 11.x core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php \Drupal\KernelTests\Core\File\DirectoryTest::testMultiplePrepareDirectory()

Tests asynchronous directory creation.

Image style generation can result in many calls to create similar directory paths. This test forks the process to create the same situation.

File

core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php, line 209

Class

DirectoryTest
Tests operations dealing with directories.

Namespace

Drupal\KernelTests\Core\File

Code

public function testMultiplePrepareDirectory() : void {
    if (!function_exists('pcntl_fork')) {
        $this->markTestSkipped('Requires the pcntl_fork() function');
    }
    $directories = [];
    for ($i = 1; $i <= 10; $i++) {
        $directories[] = 'public://a/b/c/d/e/f/g/h/' . $i;
    }
    $file_system = $this->container
        ->get('file_system');
    $time_to_start = microtime(TRUE) + 0.1;
    // This loop creates a new fork to create each directory.
    foreach ($directories as $directory) {
        $pid = pcntl_fork();
        if ($pid == -1) {
            $this->fail("Error forking");
        }
        elseif ($pid == 0) {
            // Sleep so that all the forks start preparing the directory at the same
            // time.
            usleep((int) (($time_to_start - microtime(TRUE)) * 1000000));
            $file_system->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);
            exit;
        }
    }
    // This while loop holds the parent process until all the child threads
    // are complete - at which point the script continues to execute.
    while (pcntl_waitpid(0, $status) != -1) {
    }
    foreach ($directories as $directory) {
        $this->assertDirectoryExists($directory);
    }
    // Remove the database connection because it will have been destroyed when
    // the forks exited. This allows
    // \Drupal\KernelTests\KernelTestBase::tearDown() to reopen it.
    Database::removeConnection('default');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.