micronaut-projects / micronaut-test-resources

Test resources support
Apache License 2.0
8 stars 15 forks source link

Support multiple databases per container #111

Open melix opened 1 year ago

melix commented 1 year ago

Feature description

The feature was suggested during a talk about Micronaut Test Resources. It may be useful to have a single container used for multiple databases. For example, different microservices may use the same database server (e.g MySQL) but different database names.

Currently we spawn a separate container for each datasource.

MT-Jacobs commented 1 year ago

Note that this is true for SQL, but it's not true for every test resource type.

In a shared test resource server setup, you'll only get a single Elasticsearch container, even with multiple modules.

And with redis, you'll get one redis container per module.

This sounds like design problem; Micronaut Test Resources could have a more opinionated/standardized way to control whether or not a given missing configuration should use a new container or an existing container.

cosmin-marginean commented 1 year ago

An important use case here is running tests in parallel. We have certain tests that require a clean MongoDB or collection (wiped within @BeforeEach) for each test method. Currently running these tests in parallel is not possible as they share a database ("test"). So, at a minimum, having some way to dynamically pass a database name for a test would be very helpful.

melix commented 1 year ago

Note that test containers doesn't support multiple databases per container, so there's nothing we can do here. We also have an option to configure the database name, but it is not always taken into account by test containers, and in any case, not designed to trigger spawing separate containers either. I'm still contemplating how to mitigate this.

cosmin-marginean commented 1 year ago

Yes, I can see the limitations of the underlying test-containers have an impact here. It might be that workarounds are possible at least for some use cases (some storage engines). For example, with Elasticsearch this isn't a problem because the "instance" is the database, and dynamic indices can be created by tests at will. With Mongo or Postgress on the other hand, the database is usually setup as a connection component by tests (AFAIK).

But with Mongo for example (and maybe others), the painful thing is that it will let you create databases and collections dynamically which we're missing out on. First is the database name ("test") which can't be created dynamically although the engine supports it. Second, if you use something like Micronaut Data with Mongo, collection names are also immutable (inferred from entity name or configured -and that's fine!), which limits tests further.

To make matters worse, there are cases where multi-tenancy is part of the app requirements (and thus, test setup) so a dynamic database name is even more imperative. (Although, thinking about it, for some storage solutions like Mongo we can probably hack a TenantResolver to give us what we need in tests).

I know I'm not really providing solutions :) I just wanted to capture the breadth of the issue, and to make a case that a "unified" approach might not be what moves this forward. It could be in some cases we need to involve the test-containers contributors, other times to alter some Micronaut components, and lastly micronaut-test-resources.