-
Notifications
You must be signed in to change notification settings - Fork 45
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
[SF 5.3] Impossible to make functionnal test with SQLite: Operation 'AbstractPlatform::getListDatabasesSQL' is not supported by platform. #154
Comments
I looked at the source code reported by the error stacktrace. The The code from public function getListDatabasesSQL()
{
throw Exception::notSupported(__METHOD__);
} Called from the LiipTestFixturesBundle in the protected function createDatabaseIfNotExists(): void
{
$params = $this->connection->getParams();
if (isset($params['master'])) {
$params = $params['master'];
}
$dbName = $params['dbname'] ?? '';
unset($params['dbname'], $params['url']);
// Unset url to avoid issue:
// “An exception occurred in driver: SQLSTATE[HY000] [1049] Unknown database 'test'”
$tmpConnection = DriverManager::getConnection($params);
$tmpConnection->connect();
// The '->listDatabases' is the one that calls the AbstractPlatform::getListDatabasesSQL method
if (!\in_array($dbName, $tmpConnection->getSchemaManager()->listDatabases(), true)) {
$tmpConnection->getSchemaManager()->createDatabase($dbName);
}
$tmpConnection->close();
} However I have no idea how I could solve that myself unfortunately |
As SQLite seems to work on unique database this should not be possible to list databases. Thus a way to handle it could be creating the database anyway in a Sqlite context, kinda like this (that works in this specific case): protected function createDatabaseIfNotExists(): void
{
$params = $this->connection->getParams();
if (isset($params['master'])) {
$params = $params['master'];
}
$dbName = $params['dbname'] ?? '';
unset($params['dbname'], $params['url']);
// Unset url to avoid issue:
// “An exception occurred in driver: SQLSTATE[HY000] [1049] Unknown database 'test'”
$tmpConnection = DriverManager::getConnection($params);
$tmpConnection->connect();
$databases = $tmpConnection->getDatabasePlatform() instanceof SqlitePlatform
? ['']
: $tmpConnection->getSchemaManager()->listDatabases();
if (!\in_array($dbName, $databases, true)) {
$tmpConnection->getSchemaManager()->createDatabase($dbName);
}
$tmpConnection->close();
} EDIT: I ended testing it by forking the repo and it seems it does not break the actual tests suite |
What versions of |
Looking at |
3.1.3 is the version that was used to run tests 2 days ago: https://github.com/liip/LiipTestFixturesBundle/runs/3951469875?check_suite_focus=true#step:8:141 Maybe it works because the tests don't use an URL for sqlite: LiipTestFixturesBundle/tests/AppConfigSqlite/config.yml Lines 3 to 7 in b607d23
We can override |
If you think that's the way to go I can take time to submit a PR. But what I don't get is how this But this method is beeing overrided in the Also, I ran the SQLite tests with some dumping and it never reach the code in Edit: I'm really interested to understand the difference since it can means some working behavior isn't covered by tests... But I don't get why has the tests really looks like the one we write in a Symfony application (for an integration/functional test) |
I added tests with SQLite and URL in #155 |
@AlexandreGerault |
Yeah, I saw for this inheritance. But what I don't get is that the only place |
Right, I missed that |
Please add this check before $this->assertInstanceOf(
\Liip\TestFixturesBundle\Services\DatabaseTools\ORMSqliteDatabaseTool::class,
$this->databaseTool
); We'll probably see that the bundle returns the ORM database tool instead of the specific SQLite one. Could you please put the sources of your example on a GitHub repo? I followed the steps and it worked for me, I had to install |
Here is the basic sources to produce the error: https://github.com/AlexandreGerault/debug-liip-test-fixtures-bundle Now I'll make another branch with your test (it's failing): https://github.com/AlexandreGerault/debug-liip-test-fixtures-bundle/tree/debug/add-instance-of-sqlite-tool |
I put my test projet on GitHub, please try it:
I have no error on my local environment, it uses PHP 7.4, not 8.0, but I don't think it should cause issues. |
I missed that your project use DAMADoctrineTestBundle, please try this: https://github.com/liip/LiipTestFixturesBundle/blob/2.x/doc/caveats.md#damadoctrinetestbundle |
To put in the EDIT: Now I'e just the error telling I've no table |
I added a missing information on the doc, you have to create the database and schema before running your tests: https://github.com/liip/LiipTestFixturesBundle/blob/2.x/doc/configuration.md#configuration |
FYI I am having the same issue with:
Note that I'm not using DAMADoctrineBundle but changing liip_test_fixtures:
cache_db:
sqlite: 'Liip\TestFixturesBundle\Services\DatabaseBackup\SqliteDatabaseBackup'
keep_database_and_schema: true
cache_metadata: true |
@AlexandreGerault I was able to have another error message with your project by changing the doctrine config to this: doctrine:
dbal:
driver: pdo_sqlite
url: "%kernel.cache_dir%/test.db" (instead of this config) Could you please test and see if it gives you different results? |
Hi @alexislefebvre, I encountered the same issue. I applied the patch provided in the close pr to make my tests work on my computer for now (but they fail in the CI due to this issue but this is normal at this point) I tried the configuration you provide but ended in the same result. Here is my complete configuration in my doctrine:
dbal:
logging: false
schema_filter: ~
driver: pdo_sqlite
url: null
orm:
dql:
datetime_functions:
Year: DoctrineExtensions\Query\Sqlite\Year And the configuration in my doctrine:
dbal:
# backtrace queries in profiler (increases memory usage per request)
#profiling_collect_backtrace: '%kernel.debug%'
server_version: '8'
charset: utf8mb4
url: '%env(resolve:DATABASE_URL)%'
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# ... A lot of configuration related to the project [EDIT]: here is may configuration of liip_test_fixtures:
cache_db:
sqlite: Liip\TestFixturesBundle\Services\DatabaseBackup\SqliteDatabaseBackup Tell me if you need more information or tests. I am working on the project every day and can provide quick feedback. Thank you |
Sorry, I missed some part of the configuration... Here is the right errors with right configuration. Error (with PR patch applied, same previous error when patch not applied): Stack trace/symfony/server/vendor/liip/test-fixtures-bundle/src/Services/DatabaseBackup/SqliteDatabaseBackup.php:68 /symfony/server/vendor/liip/test-fixtures-bundle/src/Services/DatabaseBackup/SqliteDatabaseBackup.php:46 /symfony/server/vendor/liip/test-fixtures-bundle/src/Services/DatabaseTools/ORMDatabaseTool.php:124 /symfony/server/tests/Functional/WebTestCase.php:29 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestResult.php:726 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:670Note : as the project also have an Angular client, the Symfony app is in adding the configuration Stack trace/symfony/server/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php:42 /symfony/server/vendor/doctrine/dbal/src/Connection.php:325 /symfony/server/vendor/liip/test-fixtures-bundle/src/Services/DatabaseTools/ORMDatabaseTool.php:162 /symfony/server/vendor/liip/test-fixtures-bundle/src/Services/DatabaseTools/ORMDatabaseTool.php:61 /symfony/server/tests/Functional/WebTestCase.php:29 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestResult.php:726 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678 /symfony/server/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:670Just in case here this is the content of our custom Functional\Tests\WebTestCase<?php
namespace Functional\Tests;
use Doctrine\Common\DataFixtures\ReferenceRepository;
use Factory\Tests\Administration\User\AdminUserFactory;
use Fixtures\Tests\Entity\Administration\User\AdminUserFixtures;
use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
use Liip\TestFixturesBundle\Services\DatabaseTools\AbstractDatabaseTool;
use Symfony\Component\BrowserKit\Cookie;
use Zenstruck\Browser\KernelBrowser;
use Zenstruck\Browser\Response\JsonResponse;
use Zenstruck\Browser\Test\HasBrowser;
use Zenstruck\Foundry\Test\Factories;
class WebTestCase extends \Liip\FunctionalTestBundle\Test\WebTestCase
{
use Factories;
use HasBrowser;
protected AbstractDatabaseTool $databaseTool;
protected ReferenceRepository $fixtures;
protected function setUp(): void
{
parent::setUp();
$this->databaseTool = static::getContainer()->get(DatabaseToolCollection::class)->get();
$this->databaseTool->loadFixtures([
AdminUserFixtures::class,
]);
}
protected function loadFixtures(array $classNames): void
{
$this->fixtures = $this->databaseTool->loadFixtures($classNames, true)->getReferenceRepository();
}
protected function createAdminClient(): KernelBrowser
{
return $this->createAuthenticatedClient(AdminUserFactory::ADMIN_USERNAME, 'password');
}
protected function createAuthenticatedClient(string $username, string $password): KernelBrowser
{
$response = $this->browser()
->post('/api/login_check', [
'body' => [
'username' => $username,
'password' => $password,
],
])
->assertJson()
->use(function (JsonResponse $response) use ($username, $password) {
self::assertTrue($response->isSuccessful(), "Cannot login user with $username:$password");
$response->search('token');
})->response();
$browser = $this->browser();
$browser->cookies()->set(new Cookie('JWT', $response->json()['token']));
return $browser;
}
} |
It's not directly related to the minimal project configuration at the beginning of the ticket, but I found the cause for my project to be the getsentry/sentry-symfony tracing to cause the exact same error message. Disabling the tracing fixed the issue. |
@bjalt Hi Could you elaborate a bit more? I can't find this tracing option and don't understand what it is. Thank you |
@flohw This is only relevant if you have a dependency on Sentry can collect performance information which include database performance. To do this they need to decorate the database abstraction, which seems to cause the issue. # config/packages/sentry.yaml
sentry:
tracing:
enabled: false |
As soon as I've free time this week-end I'll test |
Which I use 😉 Your solution works for me too. I will keep an eye here to provide other information if needed et try to look on the sentry one for the same purpose. Thanks |
That's a very nice finding! Sentry can be disabled only in the # config/packages/test/sentry.yaml
sentry:
tracing:
enabled: false |
Same issue, but with
|
I'm having same issue now :( I dig into code and found doctrine/dbal 3.3.4 edit: It seems that Then can't we use DatabasePlatform not DriverName to resolve appropriate DatabaseTool here? |
@darthf1 and @77web please tell if the solution in this comment doesn't work for you. Do you use a package that decorate the connection to the database? |
@alexislefebvre no, I never use sentry. |
Nope, sentry is disabled for me in the |
It seems that dbal silently started using their logging middleware by default? 🤔️ |
maybe doctrine/doctrine-bundle v2.6.0 is the cause:
|
encountering the described error after upgrading to doctrine-bundle v2.6.0 today, for the first time. |
Temporarily solved my problem by downgrading doctrine/doctrine-bundle to 2.5.x. |
Maybe we can find a way to disable this middleware, if it can fix the issue. |
I found one difference while using different versions of
With v2.6.0 it returns With 2.6.0, it won't find the item for SQLite in the following nice, so it returns the default configuration, and the We have to rewrite how the type of database is detected, because |
@alexislefebvre
I'm not familiar with PHPCR and MongoDBODM, so I thought why not use DatabasePlatform to distinguish db type... |
I'm sorry I missed your comment. I'm not familiar with how the driver is loaded, it's still black magic for me. Feel free to submit a PR if you have an idea. |
It appears that DoctrineBundle 2.6.0 now injects middlewares all the time (https://github.com/doctrine/DoctrineBundle/pull/1472/files#diff-36d403fbfadb131317c08db172ddbb7844ce35323d45c6096043b97ed066b60a)? I stepped through the code and even though I have both I'm not sure that we need to rewrite how the database is detected as much as we need to figure out how to disable the middlewares in the test environment? From what I can see, there's no way to remove them. If a |
Ok, I lied. After a bit more investigation I've found another way we can detect the type of database. Created PR #176 to fix it. If you're having this issue please install my fork and let me know if it works for you. |
@ndench thanks, this PR was merged. Please try the last release: https://github.com/liip/LiipTestFixturesBundle/releases/tag/2.3.0 |
Preconditions
My dependencies on a fresh Symfony app are:
Steps to reproduce
app/tests/DummyFunctionnalTest.php
DATABASE_URL
in the.env.test
file :Expected result
Actual result
I got this error when I run tests:
The text was updated successfully, but these errors were encountered: