-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Allows to persist database connection between tests and only reset PDO in afterClassTearDown()
#49385
Conversation
@@ -39,7 +40,7 @@ public function __construct(Container $container) | |||
* @param string|null $name | |||
* @return \Illuminate\Database\Connection | |||
*/ | |||
public function make(array $config, $name = null) | |||
public function make(array $config, $name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$name
shouldn't accept null
since parseConfig()
can only accept string
for $name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseConfig()
is only restricted via doc-block documentation. Since the property isn't really strictly typed, it actually works fine by using $factory->make($config)
on userland code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I didn't see your reply here, unfortunately I don't get notifications on the Laravel repository anymore (GitHub bug).
Whether you change or not the default connection in that script it's irrelevant since the configuration is being explicitly passed to the $factory->make()
. The variable you hold is the one that is relevant to which database connection you have.
the getName()
method is returning exactly what was provided when constructing the connection (null
), which is my point about this breaking change. It works as intended and it doesn't seem relevant to break it
…s' into 11/persist-database-connections
Related to #49373? Please comment there |
Since this applies to code that falls outside the scope of Suggested change , I would like to comment on it separately. (I'm not familiar with MySQL, so I'd like to comment only on PostgreSQL. But I think MySQL probably has similar features as well.)
There is some changeable state that persists while a session is open, whether inside or outside a transaction, and whether commit or rollback. However, certain status also allow us to explicitly discard their state.
In order to preserve existing behavior, we should execute these (or other?) statements to return the session state to its initial state as much as possible. UPDATE: 2023-12-16 9:52 JST This problem can now be resolved by an option implemented after the first mention. Thank you!
|
@@ -106,7 +106,7 @@ | |||
"league/flysystem-sftp-v3": "^3.0", | |||
"mockery/mockery": "^1.5.1", | |||
"nyholm/psr7": "^1.2", | |||
"orchestra/testbench-core": "^9.0", | |||
"orchestra/testbench-core": "dev-persist-db-connections", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@crynobone should we put this PR in draft while this dependency isn't ready yet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't merge Testbench Core branch to stable unless Laravel commit with this changes.
Testbench will depends on the new Illuminate\Foundation\Testing\DatabaseConnectionFactory
added in this PR.
…s' into 11/persist-database-connections
I'd like to chime in on this since it seems like it may heavily affect me.
The reason I have is because I run a multi-database multi-tenant application and sometimes I have some critical features that need the extra level of security to ensure that:
From reading the PR, I see Taylor's point. I've been using Laravel since 5.0 and I have never had any max connection issues. I believe many Laravel users don't face this issue at all. Making a significantly drastic change to how the framework handles database connections affecting every Laravel/Phpunit Users to fix an edge case without a way to keep the existing behavior seems like an opportunity to invite many more issues/bug reports than the current situation. I'm all for reusing the same PDO connection across many tests which could improve performance and speed up tests, but I feel like users need to be able to better control this. While we're on this subject, a paper cut issue I've had with Laravel for many years is precisely how DatabaseManager is tied with Config Repository, making it unable to work without global state changes that causes confusion. If something like my personal desire could be implemented, then the disadvantage listed here would be way less relevant. From my understanding, the disadvantage listed is caused exactly by my "paper cut" mention that you need to manipulate a global state on Config Repository prior to establishing a connection with the DatabaseManager, otherwise any changes to the global Config Repository will not reflect on the DatabaseManager connections already established. If we expose a
This would also make it easier to use the Migrator class outside of Artisan and we could work out the ability to |
@mpyw If this problem mainly affects |
It all depends on the max connection configured locally and on CI, we did face this issue on Framework own tests a few years back: #39877
Welcome any suggestion on this, we did add ability to disconnect the database connection via a property flag in this PR.
If the approach is to disconnect all database during tearDown, this have been proposed and rejected, also potentially impacts performance (since we only disconnect database connectio via |
Would it be simpler and less breaking (particularly for the multi-tenant scenario) to just call |
Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
I guess my primary point is: I'm a user of the Perhaps the implemented solution to the problem can be more targeted at where the problem is and leave users that are outside the scope of it unaffected. The problem with the current proposal is that it completely hijacks the |
Is this the answer? |
Background
PDO connection doesn't automatically get closed when the application is unset but instead requires explicitly set to
null
to trigger connection close:https://www.php.net/manual/en/pdo.connections.php
Since PHPUnit is especially a long-running process when the application gets booted and terminated on each test the PDO may persist and eventually can cause max database connections. To solve we have two options:
Option A: We can explicitly disconnect the database between tests
Disadvantages:
Iluminate\Foundation\Testing\TestCase::tearDown()
has been called.PDO
will still prevent the database from being disconnected.Option B: Reuse
PDO
instances between tests (provided in this PR)Disadvantage:
To cover Option A, you can configure a base
TestCase
and set$disconnectDatabaseConnections
property totrue
:<?php namespace Tests; abstract class TestCase extends \Illuminate\Foundation\Testing\TestCase { use CreatesApplication; + protected $disconnectDatabaseConnections = true; }