From aa440d96fe494518bba74995852146342463e753 Mon Sep 17 00:00:00 2001 From: Thomas Vargiu Date: Sat, 17 Oct 2020 16:34:05 +0200 Subject: [PATCH 1/5] Fix for DBAL 2.11 and functional tests --- .gitattributes | 9 ++ .github/workflows/continuous-integration.yml | 108 +++++++++++++++++ .gitignore | 11 +- .travis.yml | 40 ------- CHANGELOG.md | 11 ++ Dockerfile | 18 +++ README.md | 2 +- ci/github/phpunit/mysqli.xml | 32 +++++ ci/github/phpunit/pdo_mysql.xml | 32 +++++ composer.json | 18 +-- docker-compose.yml | 44 +++++++ phpunit.xml.dist | 34 +++--- src/Connection.php | 2 + src/ConnectionInterface.php | 2 + src/ConnectionTrait.php | 79 +++++------- src/Connections/MasterSlaveConnection.php | 2 + src/Driver/Mysqli/Driver.php | 2 + src/Driver/PDOMySql/Driver.php | 2 + ...ServerGoneAwayExceptionsAwareInterface.php | 12 +- .../ServerGoneAwayExceptionsAwareTrait.php | 10 +- src/Statement.php | 8 +- tests/functional/Connection.php | 19 +++ tests/functional/FunctionalTest.php | 112 ++++++++++++++++++ tests/unit/ConnectionTest.php | 21 ++-- tests/unit/StatementTest.php | 20 ++-- 25 files changed, 509 insertions(+), 141 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/continuous-integration.yml delete mode 100644 .travis.yml create mode 100644 Dockerfile create mode 100644 ci/github/phpunit/mysqli.xml create mode 100644 ci/github/phpunit/pdo_mysql.xml create mode 100644 docker-compose.yml create mode 100644 tests/functional/Connection.php create mode 100644 tests/functional/FunctionalTest.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..df38b80 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +/composer.lock export-ignore +/tests export-ignore +/ci export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.scrutinizer.yml export-ignore +/docker-compose.yml export-ignore +/Dockerfile export-ignore +/phpunit.xml.dist export-ignore \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..5994cf8 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,108 @@ +name: "Continuous Integration" + +on: + pull_request: + branches: + - "*.x" + - "master" + push: + branches: + - "*.x" + - "master" + schedule: + - cron: "42 3 * * *" + +jobs: + phpunit-mysql: + name: "PHPUnit with MySQL" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.3" + - "7.4" + mysql-version: + - "5.7" + - "8.0" + deps: + - "latest" + coverage: + - "false" + extension: + - "mysqli" + - "pdo_mysql" + include: + - php-version: "7.3" + mysql-version: "8.0" + extension: "mysqli" + custom-entrypoint: >- + --entrypoint sh mysql:8 -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" + - php-version: "7.3" + mysql-version: "8.0" + extension: "pdo_mysql" + custom-entrypoint: >- + --entrypoint sh mysql:8 -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" + - mysql-version: "5.7" + - mysql-version: "8.0" + # https://stackoverflow.com/questions/60902904/how-to-pass-mysql-native-password-to-mysql-service-in-github-actions + custom-entrypoint: >- + --entrypoint sh mysql:8 -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" + - deps: "lowest" + php-version: "7.3" + mysql-version: "5.7" + extension: "pdo_mysql" + coverage: "true" + + services: + mysql: + image: "mysql:${{ matrix.mysql-version }}" + + options: >- + --health-cmd "mysqladmin ping --silent" + -e MYSQL_ALLOW_EMPTY_PASSWORD=yes + -e MYSQL_DATABASE=test + ${{ matrix.custom-entrypoint }} + ports: + - "3306:3306" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 2 + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + coverage: "pcov" + ini-values: "zend.assertions=1" + extensions: "${{ matrix.extension }}" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2" + with: + path: "~/.composer/cache" + key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + + - name: "Install dependencies with composer" + run: "composer install --no-interaction --no-progress --no-suggest --prefer-dist" + if: "${{ matrix.deps != 'low' }}" + + - name: "Install lowest possible dependencies with composer" + run: "composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-lowest" + if: "${{ matrix.deps == 'low' }}" + + - name: "Run PHPUnit" + run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml" + if: "${{ matrix.coverage != 'true' }}" + + - name: "Run PHPUnit with coverage" + run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml" + if: "${{ matrix.coverage == 'true' }}" + + - name: "Upload coverage" + run: "wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover ./coverage.xml" + if: "${{ matrix.coverage == 'true' }}" diff --git a/.gitignore b/.gitignore index 73f8309..6d837c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -.idea -vendor -bin -composer.phar -composer.lock -phpunit.xml +/vendor +/composer.phar +/composer.lock +/phpunit.xml +/.phpunit.result.cache diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 90746e6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: php -sudo: false - -php: - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 -env: - - COMPOSER_FLAGS="--prefer-lowest" - - COMPOSER_FLAGS="" - -matrix: - fast_finish: true - include: - - php: 7.1 - env: - - TEST_COVERAGE=true - -cache: - directories: - - $HOME/.composer/cache/files - -before_install: - - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi; - - composer self-update - -install: - - composer update --prefer-dist --no-interaction ${COMPOSER_FLAGS} - -script: - - if [[ $TEST_COVERAGE ]]; then phpdbg -qrr bin/phpunit --coverage-clover clover.xml; else bin/phpunit; fi; - -after_success: - - if [[ $TEST_COVERAGE ]]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover ./clover.xml; fi - -notifications: - on_success: never - on_failure: always diff --git a/CHANGELOG.md b/CHANGELOG.md index bcf5664..78de96a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.9.0] - TBD +### Added + * Added compatibility with doctrine/dbal 2.11 + * Added Github Actions for CI +### Changed + * Bumped minimum PHP version to 7.3 + * Updated dependencies + * Added functional tests +### Fixed + * Fixed compatiblity with doctrine/dbal 2.11 + ## [1.8] - 2019-09-05 ### Fixed * Fixed issue about loss of state for Statement class on retry (#34) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6e61ccf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +ARG PHP_VERSION=7.4 +FROM php:${PHP_VERSION}-cli-alpine + +RUN docker-php-ext-install -j$(getconf _NPROCESSORS_ONLN) \ + pdo_mysql \ + mysqli + +RUN set -ex \ + && apk add --no-cache --virtual build-dependencies \ + autoconf \ + make \ + g++ \ + && pecl install -o xdebug-2.9.8 && docker-php-ext-enable xdebug \ + && apk del build-dependencies + +ARG COMPOSER_VERSION=1.10.15 +RUN curl -sS https://getcomposer.org/installer | php -- \ + --install-dir=/usr/local/bin --filename=composer --version=$COMPOSER_VERSION diff --git a/README.md b/README.md index 9d6a063..e4a97f2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Latest Unstable Version](https://poser.pugx.org/facile-it/doctrine-mysql-come-back/v/unstable.svg)](https://packagist.org/packages/facile-it/doctrine-mysql-come-back) [![Total Downloads](https://poser.pugx.org/facile-it/doctrine-mysql-come-back/downloads.svg)](https://packagist.org/packages/facile-it/doctrine-mysql-come-back) -[![Build status](https://travis-ci.org/facile-it/doctrine-mysql-come-back.svg)]( https://travis-ci.org/facile-it/doctrine-mysql-come-back) +[![Build status](https://github.com/facile-it/doctrine-mysql-come-back/workflows/Continuous%20Integration/badge.svg)]( https://github.com/facile-it/doctrine-mysql-come-back/actions?query=workflow%3A%22Continuous+Integration%22+branch%3Amaster) [![Scrutinizer score](https://scrutinizer-ci.com/g/facile-it/doctrine-mysql-come-back/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facile-it/doctrine-mysql-come-back/?branch=master) [![Test coverage](https://scrutinizer-ci.com/g/facile-it/doctrine-mysql-come-back/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/facile-it/doctrine-mysql-come-back/?branch=master) diff --git a/ci/github/phpunit/mysqli.xml b/ci/github/phpunit/mysqli.xml new file mode 100644 index 0000000..26c5bc7 --- /dev/null +++ b/ci/github/phpunit/mysqli.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + ../../../tests/ + + + + + + ../../../src + + + \ No newline at end of file diff --git a/ci/github/phpunit/pdo_mysql.xml b/ci/github/phpunit/pdo_mysql.xml new file mode 100644 index 0000000..cc2f139 --- /dev/null +++ b/ci/github/phpunit/pdo_mysql.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + ../../../tests/ + + + + + + ../../../src + + + \ No newline at end of file diff --git a/composer.json b/composer.json index 2a926d6..eded0e4 100644 --- a/composer.json +++ b/composer.json @@ -10,25 +10,29 @@ } ], "require": { - "php" : "^5.6 || ^7.0", - "doctrine/dbal": "^2.3" + "php" : "^7.3", + "doctrine/dbal": "^2.11" }, "require-dev": { - "phpunit/phpunit": "^5.4.3 || ^6.0", - "friendsofphp/php-cs-fixer": "^2.3" + "phpunit/phpunit": "^9.4", + "friendsofphp/php-cs-fixer": "^2.12.17", + "phpspec/prophecy-phpunit": "^2.0" }, "autoload": { "psr-4": { "Facile\\DoctrineMySQLComeBack\\Doctrine\\DBAL\\": "src/" } }, "autoload-dev": { - "psr-4": { "Facile\\DoctrineMySQLComeBack\\Doctrine\\DBAL\\": "tests/unit/" } + "psr-4": { + "Facile\\DoctrineMySQLComeBack\\Doctrine\\DBAL\\FunctionalTest\\": "tests/functional/", + "Facile\\DoctrineMySQLComeBack\\Doctrine\\DBAL\\": "tests/unit/" + } }, "config": { - "preferred-install": "dist", - "bin-dir": "bin" + "preferred-install": "dist" }, "minimum-stability": "stable", "scripts": { + "test": "phpunit", "phpcs": "php-cs-fixer fix --level=psr2 -v --diff --dry-run src/", "phpcs-fix": "php-cs-fixer fix --level=psr2 -v --diff src/" } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6d653be --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +version: "3.5" + +x-mysql-props: &mysql-props + environment: + MYSQL_DATABASE: test + MYSQL_USER: root + MYSQL_PASSWORD: "" + MYSQL_ROOT_PASSWORD: "" + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + +x-php-props: &php-props + build: + context: . + args: + PHP_VERSION: 7.3 + volumes: + - ./:/app + working_dir: /app + command: [ "vendor/bin/phpunit" ] + environment: + MYSQL_DATABASE: test + MYSQL_USER: root + MYSQL_PASS: "" + +services: + mysql57: + image: mysql:5.7 + <<: *mysql-props + + mysql80: + image: mysql:8.0 + <<: *mysql-props + + php: + <<: *php-props + build: + context: . + args: + PHP_VERSION: 7.3 + depends_on: + - mysql57 + environment: + MYSQL_HOST: mysql57 + MYSQL_DRIVER: pdo_mysql \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ff278f0..d4e6a37 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,28 +1,32 @@ - - + + + + + + + - + ./tests/ - - - ./src/ - - ./tests - ./vendor - - - + + + ./src + + \ No newline at end of file diff --git a/src/Connection.php b/src/Connection.php index 3bb66c9..e36e8a4 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -1,5 +1,7 @@ canTryAgain($attempt) && $this->isRetryableException($e, $query)) { $this->close(); ++$attempt; @@ -84,7 +90,7 @@ public function executeQuery($query, array $params = array(), $types = array(), /** * @return \Doctrine\DBAL\Driver\Statement - * @throws \Exception + * @throws Exception */ public function query() { @@ -95,23 +101,8 @@ public function query() while ($retry) { $retry = false; try { - switch (count($args)) { - case 1: - $stmt = parent::query($args[0]); - break; - case 2: - $stmt = parent::query($args[0], $args[1]); - break; - case 3: - $stmt = parent::query($args[0], $args[1], $args[2]); - break; - case 4: - $stmt = parent::query($args[0], $args[1], $args[2], $args[3]); - break; - default: - $stmt = parent::query(); - } - } catch (\Exception $e) { + $stmt = parent::query(...$args); + } catch (Exception $e) { if ($this->canTryAgain($attempt) && $this->isRetryableException($e, $args[0])) { $this->close(); ++$attempt; @@ -125,18 +116,9 @@ public function query() return $stmt; } - /** - * @param string $query - * @param array $params - * @param array $types - * - * @return integer The number of affected rows. - * - * @throws \Exception - */ - public function executeUpdate($query, array $params = [], array $types = []) + public function executeUpdate($sql, array $params = [], array $types = []) { - return $this->executeStatement($query, $params, $types); + return $this->executeStatement($sql, $params, $types); } /** @@ -163,9 +145,12 @@ public function executeStatement($sql, array $params = [], array $types = []) while ($retry) { $retry = false; try { - // use parent::executeUpdate() for RC - $stmt = parent::executeUpdate($sql, $params, $types); - } catch (\Exception $e) { + if (is_callable('parent::executeStatement')) { + $stmt = parent::executeStatement($sql, $params, $types); + } else { + $stmt = parent::executeUpdate($sql, $params, $types); + } + } catch (Exception $e) { if ($this->canTryAgain($attempt) && $this->isRetryableException($e)) { $this->close(); ++$attempt; @@ -181,7 +166,7 @@ public function executeStatement($sql, array $params = [], array $types = []) /** * @return void - * @throws \Exception + * @throws Exception */ public function beginTransaction() { @@ -195,7 +180,7 @@ public function beginTransaction() $retry = false; try { parent::beginTransaction(); - } catch (\Exception $e) { + } catch (Exception $e) { if ($this->canTryAgain($attempt, true) && $this->_driver->isGoneAwayException($e)) { $this->close(); if (0 < $this->getTransactionNestingLevel()) { @@ -247,7 +232,7 @@ public function prepareUnwrapped($sql) /** * Forces reconnection by doing a dummy query. * - * @throws \Exception + * @throws Exception */ public function refresh() { @@ -269,12 +254,12 @@ public function canTryAgain($attempt, $ignoreTransactionLevel = false) } /** - * @param \Exception $e + * @param Exception $e * @param string|null $query * * @return bool */ - public function isRetryableException(\Exception $e, $query = null) + public function isRetryableException(Exception $e, ?string $query = null) { if (null === $query || $this->isUpdateQuery($query)) { return $this->_driver->isGoneAwayInUpdateException($e); @@ -290,8 +275,8 @@ public function isRetryableException(\Exception $e, $query = null) */ private function resetTransactionNestingLevel() { - if (!$this->selfReflectionNestingLevelProperty instanceof \ReflectionProperty) { - $reflection = new \ReflectionClass(DBALConnection::class); + if (!$this->selfReflectionNestingLevelProperty instanceof ReflectionProperty) { + $reflection = new ReflectionClass(DBALConnection::class); // Private property has been renamed in DBAL 2.9.0+ if ($reflection->hasProperty('transactionNestingLevel')) { diff --git a/src/Connections/MasterSlaveConnection.php b/src/Connections/MasterSlaveConnection.php index 6d62f01..970d46b 100644 --- a/src/Connections/MasterSlaveConnection.php +++ b/src/Connections/MasterSlaveConnection.php @@ -1,5 +1,7 @@ getMessage(); @@ -37,11 +39,11 @@ public function isGoneAwayException(\Exception $exception) } /** - * @param \Exception $exception + * @param Exception $exception * * @return bool */ - public function isGoneAwayInUpdateException(\Exception $exception) + public function isGoneAwayInUpdateException(Exception $exception): bool { $message = $exception->getMessage(); diff --git a/src/Statement.php b/src/Statement.php index bc85c98..8e696ef 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -1,14 +1,18 @@ isConnected()) { + ++$this->connectCount; + } + + return parent::connect(); + } +} diff --git a/tests/functional/FunctionalTest.php b/tests/functional/FunctionalTest.php new file mode 100644 index 0000000..71164ba --- /dev/null +++ b/tests/functional/FunctionalTest.php @@ -0,0 +1,112 @@ + getenv('MYSQL_DRIVER') ?: $GLOBALS['db_driver'] ?? 'pdo_mysql', + 'dbname' => getenv('MYSQL_DBNAME') ?: $GLOBALS['db_dbname'] ?? 'test', + 'user' => getenv('MYSQL_USER') ?: $GLOBALS['db_user'] ?? 'root', + 'password' => getenv('MYSQL_PASS') ?: $GLOBALS['db_pass'] ?? '', + 'host' => getenv('MYSQL_HOST') ?: $GLOBALS['db_host'] ?? 'localhost', + 'port' => (int) (getenv('MYSQL_PORT') ?: $GLOBALS['db_port'] ?? 3306), + ]; + } + + private function createConnection(int $attempts): Connection + { + /** @var Connection $connection */ + $connection = DriverManager::getConnection(array_merge( + $this->getConnectionParams(), + [ + 'wrapperClass' => Connection::class, + 'driverClass' => Driver::class, + 'driverOptions' => array( + 'x_reconnect_attempts' => $attempts + ) + ] + )); + + $connection->executeStatement(<<<'TABLE' +CREATE TABLE IF NOT EXISTS test ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +TRUNCATE test; +INSERT INTO test (id) VALUES (1); +TABLE + ); + + return $connection; + } + + private function setConnectionTimeout(\Doctrine\DBAL\Connection $connection, int $timeout): void + { + $connection->executeStatement('SET SESSION wait_timeout=' . $timeout); + $connection->executeStatement('SET SESSION interactive_timeout=' . $timeout); + } + + public function testExecuteQueryShouldNotReconnect(): void + { + $this->expectException(DBALException::class); + + $connection = $this->createConnection(0); + $this->assertSame(1, $connection->connectCount); + $this->setConnectionTimeout($connection, 2); + sleep(3); + $connection->executeQuery('SELECT 1'); + } + + public function testExecuteQueryShouldReconnect(): void + { + $connection = $this->createConnection(1); + $this->assertSame(1, $connection->connectCount); + $this->setConnectionTimeout($connection, 2); + sleep(3); + $connection->executeQuery('SELECT 1')->execute(); + $this->assertSame(2, $connection->connectCount); + } + + public function testQueryShouldReconnect(): void + { + $connection = $this->createConnection(1); + $this->assertSame(1, $connection->connectCount); + $this->setConnectionTimeout($connection, 2); + sleep(3); + $connection->query('SELECT 1')->execute(); + $this->assertSame(2, $connection->connectCount); + } + + public function testExecuteUpdateShouldReconnect(): void + { + $connection = $this->createConnection(1); + $this->assertSame(1, $connection->connectCount); + $this->setConnectionTimeout($connection, 2); + sleep(3); + $connection->executeUpdate('UPDATE test SET updatedAt = CURRENT_TIMESTAMP WHERE id = 1'); + $this->assertSame(2, $connection->connectCount); + } + + public function testExecuteStatementShouldReconnect(): void + { + $connection = $this->createConnection(1); + $this->assertSame(1, $connection->connectCount); + $this->setConnectionTimeout($connection, 2); + sleep(3); + $connection->executeStatement('UPDATE test SET updatedAt = CURRENT_TIMESTAMP WHERE id = 1'); + $this->assertSame(2, $connection->connectCount); + } +} diff --git a/tests/unit/ConnectionTest.php b/tests/unit/ConnectionTest.php index bec622f..5f19d25 100644 --- a/tests/unit/ConnectionTest.php +++ b/tests/unit/ConnectionTest.php @@ -1,5 +1,7 @@ prophesize(Driver::class) ->willImplement(ServerGoneAwayExceptionsAwareInterface::class); @@ -37,7 +43,7 @@ public function setUp() ); } - public function testConstructor() + public function testConstructor(): void { $driver = $this->prophesize(Driver::class) ->willImplement(ServerGoneAwayExceptionsAwareInterface::class); @@ -62,11 +68,10 @@ public function testConstructor() static::assertInstanceOf(Connection::class, $connection); } - /** - * @expectedException \InvalidArgumentException - */ - public function testConstructorWithInvalidDriver() + public function testConstructorWithInvalidDriver(): void { + $this->expectException(InvalidArgumentException::class); + $driver = $this->prophesize(Driver::class); $configuration = $this->prophesize(Configuration::class); $eventManager = $this->prophesize(EventManager::class); @@ -95,12 +100,12 @@ public function testConstructorWithInvalidDriver() * @param string $query * @param boolean $expected */ - public function testIsUpdateQuery($query, $expected) + public function testIsUpdateQuery(string $query, bool $expected): void { static::assertEquals($expected, $this->connection->isUpdateQuery($query)); } - public function isUpdateQueryDataProvider() + public function isUpdateQueryDataProvider(): array { return [ ['UPDATE ', true], diff --git a/tests/unit/StatementTest.php b/tests/unit/StatementTest.php index a5600af..9020375 100644 --- a/tests/unit/StatementTest.php +++ b/tests/unit/StatementTest.php @@ -1,16 +1,22 @@ prophesize(Connection::class); @@ -23,7 +29,7 @@ public function test_construction() $this->assertInstanceOf(Statement::class, $statement); } - public function test_retry() + public function test_retry(): void { $sql = 'SELECT :param'; /** @var DriverStatement|ObjectProphecy $driverStatement1 */ @@ -52,7 +58,7 @@ public function test_retry() $this->assertTrue($statement->execute(['param' => 'value'])); } - public function test_retry_with_state() + public function test_retry_with_state(): void { $sql = 'SELECT :value, :param'; /** @var DriverStatement|ObjectProphecy $driverStatement1 */ @@ -93,7 +99,7 @@ public function test_retry_with_state() $this->assertTrue($statement->execute()); } - public function test_retry_fails() + public function test_retry_fails(): void { $sql = 'SELECT 1'; /** @var DriverStatement|ObjectProphecy $driverStatement1 */ @@ -129,7 +135,7 @@ public function test_retry_fails() $this->assertTrue($statement->execute()); } - public function test_state_cache_only_changed_on_success() + public function test_state_cache_only_changed_on_success(): void { $sql = 'SELECT :value, :param'; /** @var DriverStatement|ObjectProphecy $driverStatement1 */ From 764d1601943e91bfcbb0757a6aa99003c1565c42 Mon Sep 17 00:00:00 2001 From: Thomas Vargiu Date: Mon, 19 Oct 2020 11:46:54 +0200 Subject: [PATCH 2/5] Removed previous dbal versions compatibility --- src/ConnectionTrait.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/ConnectionTrait.php b/src/ConnectionTrait.php index 16eb9e3..bc9c583 100644 --- a/src/ConnectionTrait.php +++ b/src/ConnectionTrait.php @@ -116,11 +116,6 @@ public function query() return $stmt; } - public function executeUpdate($sql, array $params = [], array $types = []) - { - return $this->executeStatement($sql, $params, $types); - } - /** * Executes an SQL statement with the given parameters and returns the number of affected rows. * @@ -145,11 +140,7 @@ public function executeStatement($sql, array $params = [], array $types = []) while ($retry) { $retry = false; try { - if (is_callable('parent::executeStatement')) { - $stmt = parent::executeStatement($sql, $params, $types); - } else { - $stmt = parent::executeUpdate($sql, $params, $types); - } + $stmt = parent::executeStatement($sql, $params, $types); } catch (Exception $e) { if ($this->canTryAgain($attempt) && $this->isRetryableException($e)) { $this->close(); From c0b294822a9b1d4d46a6fdefa32375e13e1edf5a Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 30 Oct 2020 09:34:45 +0100 Subject: [PATCH 3/5] Run cron only on monday --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 5994cf8..67e8490 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -10,7 +10,7 @@ on: - "*.x" - "master" schedule: - - cron: "42 3 * * *" + - cron: "42 3 * * 1" jobs: phpunit-mysql: From 44f41ba00eca3349916f703c4e84b3565e4cf3e1 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 30 Oct 2020 09:35:33 +0100 Subject: [PATCH 4/5] Use Composer 2 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6e61ccf..187279f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,6 @@ RUN set -ex \ && pecl install -o xdebug-2.9.8 && docker-php-ext-enable xdebug \ && apk del build-dependencies -ARG COMPOSER_VERSION=1.10.15 +ARG COMPOSER_VERSION=2.0.3 RUN curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/local/bin --filename=composer --version=$COMPOSER_VERSION From 07326c12b7567e2b4dd712e155cf24737e8d7290 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 30 Oct 2020 09:42:48 +0100 Subject: [PATCH 5/5] Fix test in respect of expected exceptions --- tests/functional/FunctionalTest.php | 5 +++-- tests/unit/ConnectionTest.php | 8 +++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/functional/FunctionalTest.php b/tests/functional/FunctionalTest.php index 71164ba..ed82a3f 100644 --- a/tests/functional/FunctionalTest.php +++ b/tests/functional/FunctionalTest.php @@ -61,12 +61,13 @@ private function setConnectionTimeout(\Doctrine\DBAL\Connection $connection, int public function testExecuteQueryShouldNotReconnect(): void { - $this->expectException(DBALException::class); - $connection = $this->createConnection(0); $this->assertSame(1, $connection->connectCount); $this->setConnectionTimeout($connection, 2); sleep(3); + + $this->expectException(DBALException::class); + $connection->executeQuery('SELECT 1'); } diff --git a/tests/unit/ConnectionTest.php b/tests/unit/ConnectionTest.php index 5f19d25..8be4fee 100644 --- a/tests/unit/ConnectionTest.php +++ b/tests/unit/ConnectionTest.php @@ -70,8 +70,6 @@ public function testConstructor(): void public function testConstructorWithInvalidDriver(): void { - $this->expectException(InvalidArgumentException::class); - $driver = $this->prophesize(Driver::class); $configuration = $this->prophesize(Configuration::class); $eventManager = $this->prophesize(EventManager::class); @@ -84,14 +82,14 @@ public function testConstructorWithInvalidDriver(): void 'platform' => $platform->reveal() ]; - $connection = new Connection( + $this->expectException(InvalidArgumentException::class); + + new Connection( $params, $driver->reveal(), $configuration->reveal(), $eventManager->reveal() ); - - static::assertInstanceOf(Connection::class, $connection); } /**