diff --git a/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php b/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php index 54b4bc1d90a..b43f7371f43 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php @@ -9,10 +9,13 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\Tests\DbalFunctionalTestCase; use Throwable; +use const PHP_OS; use function array_merge; use function chmod; -use function defined; +use function exec; use function file_exists; +use function posix_geteuid; +use function posix_getpwuid; use function sprintf; use function sys_get_temp_dir; use function touch; @@ -284,25 +287,28 @@ public function testSyntaxErrorException() $this->connection->executeQuery($sql); } - /** - * @dataProvider getSqLiteOpenConnection - */ - public function testConnectionExceptionSqLite($mode, $exceptionClass) + public function testConnectionExceptionSqLite() { if ($this->connection->getDatabasePlatform()->getName() !== 'sqlite') { $this->markTestSkipped('Only fails this way on sqlite'); } + // mode 0 is considered read-only on Windows + $mode = PHP_OS === 'Linux' ? 0444 : 0000; + $filename = sprintf('%s/%s', sys_get_temp_dir(), 'doctrine_failed_connection_' . $mode . '.db'); if (file_exists($filename)) { - chmod($filename, 0200); // make the file writable again, so it can be removed on Windows - unlink($filename); + $this->cleanupReadOnlyFile($filename); } touch($filename); chmod($filename, $mode); + if ($this->isLinuxRoot()) { + exec(sprintf('chattr +i %s', $filename)); + } + $params = [ 'driver' => 'pdo_sqlite', 'path' => $filename, @@ -313,19 +319,21 @@ public function testConnectionExceptionSqLite($mode, $exceptionClass) $table = $schema->createTable('no_connection'); $table->addColumn('id', 'integer'); - $this->expectException($exceptionClass); - foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) { - $conn->exec($sql); - } - } + $this->expectException(Exception\ReadOnlyException::class); + $this->expectExceptionMessage(<<toSql($conn->getDatabasePlatform()) as $sql) { + $conn->exec($sql); + } + } finally { + $this->cleanupReadOnlyFile($filename); + } } /** @@ -395,4 +403,19 @@ private function tearDownForeignKeyConstraintViolationExceptionTest() $schemaManager->dropTable('owning_table'); $schemaManager->dropTable('constraint_error_table'); } + + private function isLinuxRoot() : bool + { + return PHP_OS === 'Linux' && posix_getpwuid(posix_geteuid())['name'] === 'root'; + } + + private function cleanupReadOnlyFile(string $filename) : void + { + if ($this->isLinuxRoot()) { + exec(sprintf('chattr -i %s', $filename)); + } + + chmod($filename, 0200); // make the file writable again, so it can be removed on Windows + unlink($filename); + } }