Codeception / module-yii2

Codeception module for Yii2 framework
MIT License
16 stars 36 forks source link

Yii2 - Unit-testing - Too many connections #29

Closed hijhem closed 2 years ago

hijhem commented 5 years ago

What are you trying to achieve?

Running large suite of unit tests

What do you get instead?

[yii\db\Exception] SQLSTATE[HY000] [1040] Too many connections

After some investigation I found that ConnectionWatcher doesn't close connections initialized by the application.

- StudentWalletRepositoryTest: Persist existing wallet  Destroying application
  Starting application
  [ConnectionWatcher] watching new connections
  [Fixtures] Loading fixtures
  [Fixtures] Done
  [TransactionForcer] watching new connections
✔ StudentWalletRepositoryTest: Persist existing wallet (0.06s)
  [TransactionForcer] no longer watching new connections
  Destroying application
  [ConnectionWatcher] no longer watching new connections
  [ConnectionWatcher] closing all (0) connections

That happens because connection is being opened as soon as application starts (bootstraping some settings) and ConnectionWatcher doesn't catch it.

// src/Codeception/Module/Yii2.php:299
$this->recreateClient();
$this->client->startApp(); // connection has been initialized here

$this->connectionWatcher = new Yii2Connector\ConnectionWatcher();
$this->connectionWatcher->start(); // watcher did not catch it

However, if I place ConnectionWatcher initialization before the app initialization, problem disappears.

// src/Codeception/Module/Yii2.php:299
$this->connectionWatcher = new Yii2Connector\ConnectionWatcher();
$this->connectionWatcher->start();

$this->recreateClient();
$this->client->startApp(); // connection is caught by ConnectionWatcher

Details

SamMousa commented 5 years ago

Thanks for the report!

Are you up for creating a PR with a test case here https://github.com/codeception/yii2-tests? And a PR with the fix you propose here?

DmLapin commented 2 years ago

FYI. I have encountered with too many connections in functional tests. New DB connection opens on every test request like $tester->sendGet() and stay opened untill all tests finish.

I see that \Codeception\Module\Yii2::_after use connectionWatcher to close all connections in case of simple unit tests. But in case of functional tests \Codeception\Lib\Connector\Yii2::doRequest doesn't use connectionWatcher. I dont know why but connections here are not closed even if recreateApplication = true.

SamMousa commented 2 years ago

It works for functional tests as well. Are you having the same issue as OP? If not create a separate issue.

SamMousa commented 2 years ago

Closing this since OP has not been responsive and clearly it's only an issue in a small subset of cases.