zonkyio / embedded-database-spring-test

A library for creating isolated embedded databases for Spring-powered integration tests.
Apache License 2.0
399 stars 37 forks source link

Updated Dependencies leads to different Integration test behaviour #245

Closed Mom0aut closed 1 year ago

Mom0aut commented 1 year ago

Hey,

we updated to the latest Versions of Spring Boot (3.1.1) compatible Flyway and the latest Zonkyio embedded (2.3.0). Our Integration Tests are all using an embedded database (Zonky-Provider) + Spring Context. But with the newest Dependencies the Flyway suddenly fails. It seems that on each Test the Flyway Migration is executed but not with a clean Database. Some Database-Roles are still there from the old Integration Tests, which now cant be created/dropped because they are used with old Test-Data.

I tried to use the RefreshMode.AFTER_CLASS but they Database still got Roles from the previous Tests.

Any tips how we can prevent that, or are there any know issues similar to ours?

Thanks!

tomix26 commented 1 year ago

Hi @Mom0aut, thanks for the report.

I've tested it on the embedded-database-demo project and it seemed working fine. Tested with Spring Boot 3.1.1, Flyway 9.16.3, Flyway Test Extension 9.5.0, Zonky Embedded Database 2.3.0.

What was your previous version of Zonky Embedded Database before the upgrade? If it was version 1.x, it is possible that you may see some changes in behavior in version 2.x. For example, the previous 1.x version supported using zonky.test.database.postgres.zonky-provider.preparer-isolation=cluster property, which offered a better level of data isolation but at the cost of lower performance.

Without this feature all database roles (and users and other global level objects) are shared across all test databases. So they are never cleaned, even when RefreshMode is used. To avoid this problem, you need to create the roles with conditional create role if not exists statements, then it should work fine.

But maybe it is a different kind of problem. In that case I would need some logs for further investigation. Or ideally a reproducer on which I could test the problem.

Mom0aut commented 1 year ago

Thanks for your fast response, we updated from 2.0.0 to 2.3.0, the problem is there no Create If not exists with Roles. So you have to use Drop If Exists and then again Create Role which leads to erros because you cant drop Roles if they got any connection to some Privilegs or Grants in the database.

So if we are using the property zonky.test.database.postgres.zonky-provider.preparer-isolation=cluster then the created roles wont be shared across the embedded databases?

tomix26 commented 1 year ago

This is the trick how to emulate create role if not exists statement: https://stackoverflow.com/a/8099557/9419105

If you are upgrading from version 2.0.0 and you didn't have any problems then the root cause would be somewhere else. Because there were no noticeable changes in library behavior between versions 2.0.0 and 2.3.0. So could you please provide me some logs? Both with the previous working version and with the latest one?

The zonky.test.database.postgres.zonky-provider.preparer-isolation=cluster property is available only in older 1.x.x versions. Note that with this feature enabled, there may be some performance degradation because template databases can only be used in limited cases.

Mom0aut commented 1 year ago

Again thanks for your great reply, we changed some Roles and Grants, thats why the migrations were failing. We already implemented the Create role if no exists workaround. I thought the embedded db is always a complete clean one (even with roles and so on).

There wont be any canche to have some flag like the old one zonky.test.database.postgres.zonky-provider.preparer-isolation=cluster ?

The upgrade was not the cause of the errors 😄

Thanks

tomix26 commented 1 year ago

we changed some Roles and Grants, thats why the migrations were failing

I'm glad that's been explained.

I thought the embedded db is always a complete clean one (even with roles and so on)

All database-related objects are cleaned up (schemas, tables, indexes, data, etc.), but global objects are kept untouched.

There wont be any canche to have some flag like the old one?

I have no plans to bring this functionality back, but maybe implementing #195 could address the issue too.

Mom0aut commented 1 year ago

Again thank you for your great communication