Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

max connection MySql reached during tests

When i launch my PHPUnit test suite i reached the max connection limit (200) for MySQL.

The hot fix was to set max_connection to 500, but i'm looking for a better solution in Zend Framework 2 context.

I tried to put some tearDown method, but no luck it seems to be useless or imcomplete solution.

This is a sample of code :

protected function tearDown()
{
    // i have two entitymanager
    $this->getObjectManager()->get('doctrine.connection.orm_alternate')->close();
    $this->getObjectManager()->get('doctrine.connection.orm_default')->close();
    $this->application = null;
    gc_collect_cycles();
    parent::tearDown();
}

I also tried to use processIsolation turn to true but some test are so long that i assumed that my console has froze or something like that....

With doctrine2 connection, and Zend Framework, how can I prevent this "Too many connection" during PHPunit tests ?

so far with tips of @awons i tried to modify $this->getObjectManager()->get('doctrine.connection.orm_alternate')->close();

to $this->getObjectManager()->get('doctrine.entitymanager.orm_alternate')->close();

I checked if teardown was called, yes.

Something i don't understand is : on each test, a new instance of my connections are created, why this is not the same instance ? (like singleton or Registry) ? But this instance is never closed even it's not used after the test passed.

I misse something but don't know what.

like image 482
Greco Jonathan Avatar asked Dec 15 '14 15:12

Greco Jonathan


4 Answers

I've solved a similar problem before doing it this way:

protected static $my_db_for_testing

public static function setUpBeforeClass()
{
    //create your DB connection once, here.
    $self::$my_db_for_testing = new DbConnectionWhatever()
}

protected function setUp()
{
    $this->my_obj_to_test = new MyObject();
    $this->my_obj_to_test->setDb($this->my_db_for_testing);
}



public function testOne()
{
    //normal test here
}

public static function tearDownAfterClass()
{
    //close the DB connection here
}

}

like image 152
STLMikey Avatar answered Nov 08 '22 09:11

STLMikey


We always configure with settings like:

set-variable = max_connections=1500

set-variable = max_user_connections=300

Where there are < 10 users that will connect to the server. This leaves connections open for super users. We typically have 2-3 application users for our mysql servers. So, with 3, only 900 connections could be used up by our users. You can additionally restrict per user connections if you want to tweak it even further.

like image 35
Abhishek Avatar answered Nov 08 '22 09:11

Abhishek


Do your tests need to be run against MySql?

With Doctrine, you can use a sqlite db for testing. Unless there is a specific need to use MySql, this is a method that can improve your testing process and isolate you from issues outside of your actual unit tests.

Additionally, you might potentially see speed gains by doing tests against an in memory DB.

like image 3
Tim Klever Avatar answered Nov 08 '22 10:11

Tim Klever


I'll recommend to read the chapter on fixtures. To avoid creating a new connection for each test, use setUpBeforeClass() to establish your DB connection once and reuse that connection for each of your tests.

<?php
  class DatabaseTest extends PHPUnit_Framework_TestCase
  {
     protected static $dbh;

     public static function setUpBeforeClass()
     {
       self::$dbh = new PDO('sqlite::memory:');
     }

     public static function tearDownAfterClass()
     {
       self::$dbh = NULL;
     }
  }
?>
like image 3
Kalenda Avatar answered Nov 08 '22 09:11

Kalenda