Skip to content
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

Allow defining port (and maybe other configuration) at runtime #308

Open
guludo opened this issue Aug 3, 2021 · 5 comments
Open

Allow defining port (and maybe other configuration) at runtime #308

guludo opened this issue Aug 3, 2021 · 5 comments

Comments

@guludo
Copy link

guludo commented Aug 3, 2021

Hi there,

I have a use case where I will only know the port to a running instance of mongo at runtime (and I'm able to get that via a session-scoped fixture). I would like to be able to tell pytest-mongo to use such a port. By looking at the documentation, it seems that there isn't a supported way of passing the port (or other configuration) to pytest-mongo at runtime. That would really be useful.

A way I can think of providing such a feature is to allow users to override a fixture that will give the configuration necessary. For example:

@pyest.fixture(scope='session')
def pytest_mongo_conf(my, own, required, fixtures, here):
    ... # Get host and port from other fixtures
    # Options defined in the returned dictionary would override their previous (or default) values
    return {
        'host': host,
        'port': port,
    }
@guludo
Copy link
Author

guludo commented Aug 3, 2021

Just a quick note: I was able to get away with the following workaround: overriding the mongo_noproc fixture to mimic what the original source code does:

@pytest.fixture(scope='session')
def mongo_noproc(mongo_service):
    yield pytest_mongo.executor_noop.NoopExecutor(
        host=mongo_service['host'],
        port=mongo_service['port'],
    )

However, I see that as a workaround and I believe that having official way of configuring pytest-mongo at runtime would be a better solution.

@fizyk
Copy link
Member

fizyk commented Aug 4, 2021

🤔 how do you start the MongoDB for tests then? Do you have any snippet you could show me your use case here?

@guludo
Copy link
Author

guludo commented Aug 4, 2021

Do you have any snippet you could show me your use case here?

Sure! Here is a fragment of my current setup:

@pytest.fixture(scope='session')
def mongo_service():
    """
    Fixture that starts a mongo service and yields useful information in a
    dictionary.
    """
    container_id = subprocess.run(
        ['docker', 'run', '--rm', '-d', '-p', '27017', 'mongo:4'],
        check=True,
        stdout=subprocess.PIPE,
        text=True,
    ).stdout.strip()

    try:
        # Get published port
        port_lines = subprocess.run(
            ['docker', 'container', 'port', container_id, '27017/tcp'],
            stdout=subprocess.PIPE,
            text=True,
        ).stdout.splitlines()

        ip, port = port_lines[0].rsplit(':')

        info = {
            'exec_prefix': ['docker', 'exec', '-i', container_id],
            'host': ip,
            'port': int(port),
        }

        yield info
    finally:
        subprocess.run(
            ['docker', 'kill', container_id],
            check=True,
            stdout=subprocess.DEVNULL,
        )


@pytest.fixture(scope='session')
def mongo_noproc(mongo_service):
    yield pytest_mongo.executor_noop.NoopExecutor(
        host=mongo_service['host'],
        port=mongo_service['port'],
    )

What I think would be a nicer solution:

@pytest.fixture(scope='session')
def mongo_service():
   ... # Same as before

@pyest.fixture(scope='session')
def pytest_mongo_conf(mongo_service):
    return {
        'host': mongo_service['host'],
        'port': mongo_service['port'],
    }

@fizyk
Copy link
Member

fizyk commented Aug 4, 2021

Okay, had to check how does it the -p and the container port work actually.
I usually run tests within docker-compose setup in this case - container with code and mongo, they share network between them.
Or a CI pipeline, like github actions or bitbucket pipelines, that separate it tests, and I can have same, defined test port there and use it in configuration.

Here, I think the simplest and to be honest, the most elegant solution would be what you did, if you use that info from mongo_service anywhere else, or merge both within one fixture returning the NoopExecutor instead of info. It has both host and port attributes on itself, so you can use it as well anywhere you need host and port informations.

@guludo
Copy link
Author

guludo commented Aug 4, 2021

Here, I think the simplest and to be honest, the most elegant solution would be what you did, if you use that info from mongo_service anywhere else, or merge both within one fixture returning the NoopExecutor instead of info. It has both host and port attributes on itself, so you can use it as well anywhere you need host and port informations.

Great! Thanks. So I'll keep my code as is.

Would it be possible to have a note in the documentation about the possibility of overriding mongo_noproc to return a instance of pytest_mongo.executor_noop.NoopExecutor? Currently, it feels like I'm using an implementation detail that might change in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants