schireson / pytest-mock-resources

Pytest Fixtures that let you actually test against external resource (Postgres, Mongo, Redshift...) dependent code.
https://pytest-mock-resources.readthedocs.io/en/latest/quickstart.html
MIT License
183 stars 19 forks source link

Support non-session container fixtures for all docker resources #80

Closed DanCardin closed 2 years ago

DanCardin commented 4 years ago

Is your feature request related to a problem? Please describe. We should support non-session fixtures for all resources. In particular, we cannot model all possible usecases without this

A couple usecases that come to mind for databases are:

Given that all docker-based fixtures route through the same container-producing function, it feels like we can enable a common set of options available on all fixtures. As much this one, as the scope of the fixture you get, itself.

oakhan3 commented 4 years ago

uping/downing containers can be expensive and can get out of control, do you have an API in mind to make the setting (which would default to off) explicit?

I also think we will need some form of docker management here - some default value to make sure we don't go above x amount of containers or if we want to be stricter - ensure this can't be used in parallel testing. What are your thoughts?

If this is used in parallel testing we would also have to make sure ports do not conflict.

Another thing to note - CircleCI does not support accessing upped/downed containers with the machine executor without some additional work. If this is implemented and is to be tested we will have to work around this.

DanCardin commented 4 years ago

The port conflict avoidance is the main building block here. Imagine we had already have mechanism for finding available ports and binding to them dynamically.

I'd imagine the interface, generally for docker-based resources might look like

create_x_fixture(container_scope='function')

where container_scope would alter the "scope" of the container such that things within that scope would share the existing mechanism. I'm not sure if scope necessarily is the same thing as pytest scope, or if it's more like an arbitrary string and whatever shares that string shares the container

I think this would also allow an additional method of configuration like so:

pg9 = create_postgres_fixture(container_scope='function', config=PostgresConfig(image='postgres:9')
pg10 = create_postgres_fixture(container_scope='function', config=PostgresConfig(image='postgres:10')

We could add a max_single_resource_containers=4 to something, maybe a pytest config option, but if someone opts into this feature + xdist then i feel like they probably know what they're getting into. If you xdist -n 100 with a bunch of function scoped fixtures, i feel like that's on purpose and we should have no opinion about it?

Circle is the primary wrinkle here. Either we do some workaround in circle to go through machine executors, or it's just a matter of sequencing. the tests such that all tests of the same scope are executed together so it will have terminated the previous container before starting a new one (under the same port)