mirror of
https://github.com/nextcloud/server.git
synced 2026-06-09 00:32:29 -04:00
Merge pull request #57116 from nextcloud/php/8.5
ci(PHP): Test against 8.5 on CI
This commit is contained in:
commit
aec12f5b51
17 changed files with 72 additions and 62 deletions
2
.github/workflows/lint-php.yml
vendored
2
.github/workflows/lint-php.yml
vendored
|
|
@ -47,7 +47,7 @@ jobs:
|
|||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: [ '8.2', '8.3', '8.4' ]
|
||||
php-versions: [ '8.2', '8.3', '8.4', '8.5' ]
|
||||
|
||||
name: php-lint
|
||||
|
||||
|
|
|
|||
4
.github/workflows/phpunit-mariadb.yml
vendored
4
.github/workflows/phpunit-mariadb.yml
vendored
|
|
@ -60,13 +60,15 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.2']
|
||||
mariadb-versions: ['10.3', '10.6', '10.11', '11.4', '11.8']
|
||||
mariadb-versions: ['10.6', '10.11', '11.4', '11.8']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
mariadb-versions: '10.11'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
- php-versions: '8.4'
|
||||
mariadb-versions: '11.8'
|
||||
- php-versions: '8.5'
|
||||
mariadb-versions: '11.8'
|
||||
|
||||
name: MariaDB ${{ matrix.mariadb-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
|
|
|
|||
2
.github/workflows/phpunit-memcached.yml
vendored
2
.github/workflows/phpunit-memcached.yml
vendored
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.3', '8.4']
|
||||
php-versions: ['8.3', '8.4', '8.5']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
|
|
|||
2
.github/workflows/phpunit-mysql.yml
vendored
2
.github/workflows/phpunit-mysql.yml
vendored
|
|
@ -67,6 +67,8 @@ jobs:
|
|||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
- mysql-versions: '8.4'
|
||||
php-versions: '8.4'
|
||||
- mysql-versions: '8.4'
|
||||
php-versions: '8.5'
|
||||
|
||||
name: MySQL ${{ matrix.mysql-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
|
|
|
|||
2
.github/workflows/phpunit-nodb.yml
vendored
2
.github/workflows/phpunit-nodb.yml
vendored
|
|
@ -59,7 +59,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.3', '8.4']
|
||||
php-versions: ['8.3', '8.4', '8.5']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
|
|
|||
2
.github/workflows/phpunit-oci.yml
vendored
2
.github/workflows/phpunit-oci.yml
vendored
|
|
@ -69,6 +69,8 @@ jobs:
|
|||
php-versions: '8.3'
|
||||
- oracle-versions: '23'
|
||||
php-versions: '8.4'
|
||||
- oracle-versions: '23'
|
||||
php-versions: '8.5'
|
||||
|
||||
name: Oracle ${{ matrix.oracle-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
|
|
|
|||
2
.github/workflows/phpunit-pgsql.yml
vendored
2
.github/workflows/phpunit-pgsql.yml
vendored
|
|
@ -68,6 +68,8 @@ jobs:
|
|||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
- php-versions: '8.4'
|
||||
postgres-versions: '18'
|
||||
- php-versions: '8.5'
|
||||
postgres-versions: '18'
|
||||
|
||||
name: PostgreSQL ${{ matrix.postgres-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
|
|
|
|||
2
.github/workflows/phpunit-sqlite.yml
vendored
2
.github/workflows/phpunit-sqlite.yml
vendored
|
|
@ -59,7 +59,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.3', '8.4']
|
||||
php-versions: ['8.3', '8.4', '8.5']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
|
|
|||
|
|
@ -375,7 +375,6 @@ class SharedMountTest extends TestCase {
|
|||
$mountProvider = Server::get(MountProvider::class);
|
||||
$reflectionClass = new \ReflectionClass($mountProvider);
|
||||
$reflectionCacheFactory = $reflectionClass->getProperty('cacheFactory');
|
||||
$reflectionCacheFactory->setAccessible(true);
|
||||
$reflectionCacheFactory->setValue($mountProvider, $cacheFactory);
|
||||
|
||||
// share to user
|
||||
|
|
|
|||
|
|
@ -88,12 +88,23 @@ class ConnectionFactory {
|
|||
throw new \InvalidArgumentException("Unsupported type: $type");
|
||||
}
|
||||
$result = $this->defaultConnectionParams[$normalizedType];
|
||||
// \PDO::MYSQL_ATTR_FOUND_ROWS may not be defined, e.g. when the MySQL
|
||||
// driver is missing. In this case, we won't be able to connect anyway.
|
||||
if ($normalizedType === 'mysql' && defined('\PDO::MYSQL_ATTR_FOUND_ROWS')) {
|
||||
$result['driverOptions'] = [
|
||||
\PDO::MYSQL_ATTR_FOUND_ROWS => true,
|
||||
];
|
||||
/**
|
||||
* {@see \PDO::MYSQL_ATTR_FOUND_ROWS} may not be defined, e.g. when the MySQL
|
||||
* driver is missing. In this case, we won't be able to connect anyway.
|
||||
* In PHP 8.5 it's deprecated and {@see \Pdo\Mysql::ATTR_FOUND_ROWS} should be used,
|
||||
* but that is only available since PHP 8.4
|
||||
*/
|
||||
if ($normalizedType === 'mysql') {
|
||||
if (PHP_VERSION_ID >= 80500 && class_exists(\Pdo\Mysql::class)) {
|
||||
/** @psalm-suppress UndefinedClass */
|
||||
$result['driverOptions'] = [
|
||||
\Pdo\Mysql::ATTR_FOUND_ROWS => true,
|
||||
];
|
||||
} elseif (PHP_VERSION_ID < 80500 && defined('\PDO::MYSQL_ATTR_FOUND_ROWS')) {
|
||||
$result['driverOptions'] = [
|
||||
\PDO::MYSQL_ATTR_FOUND_ROWS => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,11 @@ class SQLiteSessionInit implements EventSubscriber {
|
|||
/** @var \Doctrine\DBAL\Driver\PDO\Connection $connection */
|
||||
$connection = $args->getConnection()->getWrappedConnection();
|
||||
$pdo = $connection->getWrappedConnection();
|
||||
$pdo->sqliteCreateFunction('md5', 'md5', 1);
|
||||
if (PHP_VERSION_ID >= 80500 && method_exists($pdo, 'createFunction')) {
|
||||
$pdo->createFunction('md5', 'md5', 1);
|
||||
} else {
|
||||
$pdo->sqliteCreateFunction('md5', 'md5', 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function getSubscribedEvents() {
|
||||
|
|
|
|||
|
|
@ -839,7 +839,6 @@ class Image implements IImage {
|
|||
return false;
|
||||
}
|
||||
$result = $this->resizeNew($maxSize);
|
||||
imagedestroy($this->resource);
|
||||
$this->resource = $result;
|
||||
return $this->valid();
|
||||
}
|
||||
|
|
@ -875,7 +874,6 @@ class Image implements IImage {
|
|||
return false;
|
||||
}
|
||||
$result = $this->preciseResizeNew($width, $height);
|
||||
imagedestroy($this->resource);
|
||||
$this->resource = $result;
|
||||
return $this->valid();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,14 +342,14 @@ class Log implements ILogger, IDataLogger {
|
|||
$this->error('Failed to load ExceptionSerializer serializer while trying to log ' . $exception->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
$context = array_map($this->normalizer->format(...), $context);
|
||||
$data = $context;
|
||||
unset($data['app']);
|
||||
unset($data['level']);
|
||||
unset($data['app'], $data['level']);
|
||||
|
||||
$data = array_merge($serializer->serializeException($exception), $data);
|
||||
$data = $this->interpolateMessage($data, isset($context['message']) && $context['message'] !== '' ? $context['message'] : ('Exception thrown: ' . get_class($exception)), 'CustomMessage');
|
||||
|
||||
array_walk($context, [$this->normalizer, 'format']);
|
||||
|
||||
$this->eventDispatcher?->dispatchTyped(new BeforeMessageLoggedEvent($app, $level, $data));
|
||||
|
||||
try {
|
||||
|
|
@ -374,8 +374,7 @@ class Log implements ILogger, IDataLogger {
|
|||
$level = $context['level'] ?? ILogger::ERROR;
|
||||
|
||||
$minLevel = $this->getLogLevel($context, $message);
|
||||
|
||||
array_walk($context, [$this->normalizer, 'format']);
|
||||
$data = array_map($this->normalizer->format(...), $data);
|
||||
|
||||
try {
|
||||
if ($level >= $minLevel) {
|
||||
|
|
@ -385,8 +384,6 @@ class Log implements ILogger, IDataLogger {
|
|||
}
|
||||
$this->writeLog($app, $data, $level);
|
||||
}
|
||||
|
||||
$context['level'] = $level;
|
||||
} catch (Throwable $e) {
|
||||
// make sure we dont hard crash if logging fails
|
||||
error_log('Error when trying to log exception: ' . $e->getMessage() . ' ' . $e->getTraceAsString());
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
// Show warning if a PHP version below 8.1 is used,
|
||||
// Show warning if a PHP version below 8.2 is used,
|
||||
if (PHP_VERSION_ID < 80200) {
|
||||
http_response_code(500);
|
||||
echo 'This version of Nextcloud requires at least PHP 8.2<br/>';
|
||||
|
|
@ -13,10 +13,10 @@ if (PHP_VERSION_ID < 80200) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// Show warning if >= PHP 8.5 is used as Nextcloud is not compatible with >= PHP 8.5 for now
|
||||
if (PHP_VERSION_ID >= 80500) {
|
||||
// Show warning if >= PHP 8.6 is used as Nextcloud is not compatible with >= PHP 8.6 for now
|
||||
if (PHP_VERSION_ID >= 80600) {
|
||||
http_response_code(500);
|
||||
echo 'This version of Nextcloud is not compatible with PHP>=8.5.<br/>';
|
||||
echo 'This version of Nextcloud is not compatible with PHP>=8.6.<br/>';
|
||||
echo 'You are currently running ' . PHP_VERSION . '.';
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1811,13 +1811,13 @@ class ViewTest extends \Test\TestCase {
|
|||
['touch', ['test.txt'], 'test.txt', 'touch', null, null, null],
|
||||
|
||||
// ---- no hooks, no locks ---
|
||||
['is_dir', ['dir'], 'dir', null],
|
||||
['is_file', ['dir'], 'dir', null],
|
||||
['is_dir', ['dir'], 'dir', ''],
|
||||
['is_file', ['dir'], 'dir', ''],
|
||||
[
|
||||
'stat',
|
||||
['dir'],
|
||||
'dir',
|
||||
null,
|
||||
'',
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
|
|
@ -1828,7 +1828,7 @@ class ViewTest extends \Test\TestCase {
|
|||
'filetype',
|
||||
['dir'],
|
||||
'dir',
|
||||
null,
|
||||
'',
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
|
|
@ -1839,7 +1839,7 @@ class ViewTest extends \Test\TestCase {
|
|||
'filesize',
|
||||
['dir'],
|
||||
'dir',
|
||||
null,
|
||||
'',
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
|
|
@ -1847,17 +1847,17 @@ class ViewTest extends \Test\TestCase {
|
|||
/* Return an int */
|
||||
100
|
||||
],
|
||||
['isCreatable', ['dir'], 'dir', null],
|
||||
['isReadable', ['dir'], 'dir', null],
|
||||
['isUpdatable', ['dir'], 'dir', null],
|
||||
['isDeletable', ['dir'], 'dir', null],
|
||||
['isSharable', ['dir'], 'dir', null],
|
||||
['file_exists', ['dir'], 'dir', null],
|
||||
['isCreatable', ['dir'], 'dir', ''],
|
||||
['isReadable', ['dir'], 'dir', ''],
|
||||
['isUpdatable', ['dir'], 'dir', ''],
|
||||
['isDeletable', ['dir'], 'dir', ''],
|
||||
['isSharable', ['dir'], 'dir', ''],
|
||||
['file_exists', ['dir'], 'dir', ''],
|
||||
[
|
||||
'filemtime',
|
||||
['dir'],
|
||||
'dir',
|
||||
null,
|
||||
'',
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
ILockingProvider::LOCK_SHARED,
|
||||
|
|
@ -1875,23 +1875,23 @@ class ViewTest extends \Test\TestCase {
|
|||
* @param array $operationArgs arguments for the operation
|
||||
* @param string $lockedPath path of the locked item to check
|
||||
* @param string $hookType hook type
|
||||
* @param int $expectedLockBefore expected lock during pre hooks
|
||||
* @param int $expectedLockDuring expected lock during operation
|
||||
* @param int $expectedLockAfter expected lock during post hooks
|
||||
* @param int $expectedStrayLock expected lock after returning, should
|
||||
* be null (unlock) for most operations
|
||||
* @param ?int $expectedLockBefore expected lock during pre hooks
|
||||
* @param ?int $expectedLockDuring expected lock during operation
|
||||
* @param ?int $expectedLockAfter expected lock during post hooks
|
||||
* @param ?int $expectedStrayLock expected lock after returning, should
|
||||
* be null (unlock) for most operations
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('basicOperationProviderForLocks')]
|
||||
public function testLockBasicOperation(
|
||||
$operation,
|
||||
$operationArgs,
|
||||
$lockedPath,
|
||||
$hookType,
|
||||
$expectedLockBefore = ILockingProvider::LOCK_SHARED,
|
||||
$expectedLockDuring = ILockingProvider::LOCK_SHARED,
|
||||
$expectedLockAfter = ILockingProvider::LOCK_SHARED,
|
||||
$expectedStrayLock = null,
|
||||
$returnValue = true,
|
||||
string $operation,
|
||||
array $operationArgs,
|
||||
string $lockedPath,
|
||||
string $hookType,
|
||||
?int $expectedLockBefore = ILockingProvider::LOCK_SHARED,
|
||||
?int $expectedLockDuring = ILockingProvider::LOCK_SHARED,
|
||||
?int $expectedLockAfter = ILockingProvider::LOCK_SHARED,
|
||||
?int $expectedStrayLock = null,
|
||||
mixed $returnValue = true,
|
||||
): void {
|
||||
$view = new View('/' . $this->user . '/files/');
|
||||
|
||||
|
|
@ -1931,7 +1931,7 @@ class ViewTest extends \Test\TestCase {
|
|||
// do operation
|
||||
call_user_func_array([$view, $operation], $operationArgs);
|
||||
|
||||
if ($hookType !== null) {
|
||||
if ($hookType !== '') {
|
||||
$this->assertEquals($expectedLockBefore, $lockTypePre, 'File locked properly during pre-hook');
|
||||
$this->assertEquals($expectedLockAfter, $lockTypePost, 'File locked properly during post-hook');
|
||||
$this->assertEquals($expectedLockDuring, $lockTypeDuring, 'File locked properly during operation');
|
||||
|
|
@ -2530,7 +2530,7 @@ class ViewTest extends \Test\TestCase {
|
|||
}
|
||||
);
|
||||
|
||||
if ($hookType !== null) {
|
||||
if ($hookType !== '') {
|
||||
Util::connectHook(
|
||||
Filesystem::CLASSNAME,
|
||||
$hookType,
|
||||
|
|
|
|||
|
|
@ -102,14 +102,12 @@ class HelperStorageTest extends \Test\TestCase {
|
|||
private function getIncludeExternalStorage(): bool {
|
||||
$class = new \ReflectionClass(\OC_Helper::class);
|
||||
$prop = $class->getProperty('quotaIncludeExternalStorage');
|
||||
$prop->setAccessible(true);
|
||||
return $prop->getValue(null) ?? false;
|
||||
}
|
||||
|
||||
private function setIncludeExternalStorage(bool $include) {
|
||||
$class = new \ReflectionClass(\OC_Helper::class);
|
||||
$prop = $class->getProperty('quotaIncludeExternalStorage');
|
||||
$prop->setAccessible(true);
|
||||
$prop->setValue(null, $include);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,15 +248,10 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase {
|
|||
|
||||
if ($reflection->hasMethod($methodName)) {
|
||||
$method = $reflection->getMethod($methodName);
|
||||
|
||||
$method->setAccessible(true);
|
||||
|
||||
return $method->invokeArgs($object, $parameters);
|
||||
} elseif ($reflection->hasProperty($methodName)) {
|
||||
$property = $reflection->getProperty($methodName);
|
||||
|
||||
$property->setAccessible(true);
|
||||
|
||||
if (!empty($parameters)) {
|
||||
if ($property->isStatic()) {
|
||||
$property->setValue(null, array_pop($parameters));
|
||||
|
|
|
|||
Loading…
Reference in a new issue