Y2038TimestampUpdateTest.php

Same filename and directory in other branches
  1. 10 core/modules/system/tests/src/Functional/Update/Y2038TimestampUpdateTest.php

Namespace

Drupal\Tests\system\Functional\Update

File

core/modules/system/tests/src/Functional/Update/Y2038TimestampUpdateTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\system\Functional\Update;

use Drupal\FunctionalTests\Update\UpdatePathTestBase;
use Drupal\Tests\UpdatePathTestTrait;

/**
 * Tests update of timestamp fields to bigint.
 *
 * @group system
 */
class Y2038TimestampUpdateTest extends UpdatePathTestBase {
    use UpdatePathTestTrait;
    
    /**
     * {@inheritdoc}
     */
    protected static $modules = [
        'forum',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'stark';
    
    /**
     * The tables and column name of the time fields.
     *
     * The key is the table name and the values are the names of the time fields.
     *
     * @var string[][]
     */
    protected $tables = [
        'comment_entity_statistics' => [
            'last_comment_timestamp',
        ],
        'forum_index' => [
            'created',
            'last_comment_timestamp',
        ],
        'history' => [
            'timestamp',
        ],
        'locale_file' => [
            'timestamp',
            'last_checked',
        ],
        'node_counter' => [
            'timestamp',
        ],
        'sessions' => [
            'timestamp',
        ],
        'tracker_node' => [
            'changed',
        ],
        'tracker_user' => [
            'changed',
        ],
        'watchdog' => [
            'timestamp',
        ],
        'batch' => [
            'timestamp',
        ],
        'queue' => [
            'created',
            'expire',
        ],
        'flood' => [
            'expiration',
            'timestamp',
        ],
    ];
    
    /**
     * The database.
     *
     * @var \Drupal\Core\Database\Connection
     */
    protected $connection;
    
    /**
     * The name of the test database.
     *
     * @var string
     */
    protected $databaseName;
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        
        /** @var \Drupal\Core\Database\Connection $connection */
        $this->connection = \Drupal::service('database');
        if ($this->connection
            ->databaseType() == 'pgsql') {
            $this->databaseName = 'public';
        }
        else {
            $this->databaseName = $this->connection
                ->getConnectionOptions()['database'];
        }
    }
    
    /**
     * {@inheritdoc}
     */
    protected function setDatabaseDumpFiles() {
        $this->databaseDumpFiles = [
            // Start with a standard install of Drupal 9.3.0 with the following
            // enabled modules: forum, language, locale, statistics and tracker.
DRUPAL_ROOT . '/core/modules/system/tests/fixtures/update/drupal-9.4.0.filled.standard.php.gz',
            DRUPAL_ROOT . '/core/modules/system/tests/fixtures/update/Y2038-timestamp.php',
        ];
    }
    
    /**
     * Tests update of time fields.
     */
    public function testUpdate() {
        if (\Drupal::service('database')->databaseType() == 'sqlite') {
            $this->markTestSkipped("This test does not support the SQLite database driver.");
        }
        // Create a table starting with cache that is not a cache bin.
        \Drupal::service('database')->schema()
            ->createTable('cache_bogus', [
            'fields' => [
                'id' => [
                    'type' => 'int',
                    'not null' => TRUE,
                ],
            ],
            'primary key' => [
                'id',
            ],
        ]);
        $this->collectTimestampFieldsFromDatabase();
        // PostgreSQL returns the value 'integer' instead of 'int' when queried
        // about the column type. Some PostgreSQL tables are already of the type
        // 'bigint'.
        $this->assertTimestampFields([
            'int',
            'integer',
            'bigint',
        ]);
        $this->runUpdates();
        $this->assertTimestampFields([
            'bigint',
        ]);
    }
    
    /**
     * Collect the timestamp fields from the database and update table list.
     */
    public function collectTimestampFieldsFromDatabase() {
        
        /** @var \Drupal\Core\Database\Connection $connection */
        $connection = \Drupal::service('database');
        // Build list of all tables and fields to check.
        $tables = $connection->schema()
            ->findTables('migrate_map_%');
        foreach ($tables as $table) {
            $this->tables[$table] = [
                'last_imported',
            ];
        }
        $tables = $connection->schema()
            ->findTables('cache_%');
        $tables = array_filter($tables, function ($table) {
            return str_starts_with($table, 'cache_') && $table !== 'cache_bogus';
        });
        $this->assertNotEmpty($tables);
        foreach ($tables as $table) {
            $this->tables[$table] = [
                'expire',
            ];
        }
    }
    
    /**
     * Asserts the size of the timestamp fields.
     */
    public function assertTimestampFields($expected_values) {
        // Check the size of all the fields.
        foreach ($this->tables as $table => $column_names) {
            $table_name = $this->connection
                ->getPrefix() . $table;
            foreach ($column_names as $column_name) {
                $result = $this->connection
                    ->query("SELECT data_type FROM information_schema.columns WHERE table_schema = '{$this->databaseName}' and table_name = '{$table_name}' and column_name = '{$column_name}';")
                    ->fetchField();
                $this->assertContains($result, $expected_values, "Failed for '{$table_name}' column '{$column_name}'");
            }
        }
    }

}

Classes

Title Deprecated Summary
Y2038TimestampUpdateTest Tests update of timestamp fields to bigint.

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