Question

While running PHPUnit tests, a lot of connections are created but not closed. I can see this in

mysql> show processlist;

In my database class I create a db connection by implementing PHPUnit_Extensions_Database_TestCase#getConnection().

I make sure that in the teardown the connection gets closed. See snippet:

<?php

abstract class My_Tests_DatabaseTestCase extends \PHPUnit_Extensions_Database_TestCase
{

    static private $pdo = null;
    private $conn = null;

    /**
     * @throws RuntimeException
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    final public function getConnection()
    {
        $iniFilePath = __DIR__ . '/../../../db-config.ini';
        $iniFile = parse_ini_file($iniFilePath, true);

        $dsn = "mysql:dbname=".$iniFile['phpunit']['dbname'].";host=".$iniFile['phpunit']['host'];
        if ( $this->conn === null ) {
            if ( self::$pdo == null ) {
                self::$pdo = new \PDO($dsn, $iniFile['phpunit']['user'], $iniFile['phpunit']['password']);
            }
            $this->conn = $this->createDefaultDBConnection(self::$pdo, $iniFile['phpunit']['dbname']);
        }
        return $this->conn;
    }

    protected function getSetUpOperation()
    {
        return new \PHPUnit_Extensions_Database_Operation_Composite(array(
            new \TestsExtensions\TruncateDatabaseOperation(),
            \PHPUnit_Extensions_Database_Operation_Factory::INSERT()
        ));
    }

    protected function getTearDownOperation() {
        return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE();
    }

    protected function setUp()
    {
        parent::setUp();
        $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
        $em->clear();
    }

    protected function tearDown()
    {
        parent::tearDown();
        $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
        $em->getConnection()->close();
        if ($this->conn) {
            $this->conn->close();
        }
    }
}

Debugging showed that the connections were closed, but the processlist showed them with status "sleep". The amount of connections rises until I get the "too many connections" error.

I do not want to increase the number of connections. I want to close the connection.

What can I modify to make this happen?

Was it helpful?

Solution

Snippet from PDO Connection management:

Upon successful connection to the database, an instance of the PDO class is returned to your script. The connection remains active for the lifetime of that PDO object. To close the connection, you need to destroy the object by ensuring that all remaining references to it are deleted--you do this by assigning NULL to the variable that holds the object. If you don't do this explicitly, PHP will automatically close the connection when your script ends.

Don't store the PDO or set it to null in the teardown:

Remove static private $pdo = null;

or

protected function tearDown()
{
    parent::tearDown();
    $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
    $em->getConnection()->close();
    if ($this->conn) {
        $this->conn->close();
    }
    self::$pdo = null;
}

I don't think you need to store the PDO if you are going to pass it into the PHPUnit DB connection

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top