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

Option to keep containers running or use manually started ones #46

Open
languitar opened this issue Jun 4, 2020 · 5 comments
Open

Option to keep containers running or use manually started ones #46

languitar opened this issue Jun 4, 2020 · 5 comments

Comments

@languitar
Copy link
Contributor

I have a setup where spinning up the containers for tests is quite expensive. It would be nice if there was an option to either leave contains running after the first execution or to use a project started manually beforehand. That way, the expensive boot up of the containers can be avoided for subsequent tests.

@Luminaar
Copy link
Collaborator

Luminaar commented Jun 9, 2020

Hello,

I've run into this issue in the past myself. I solved it by temporarily removing the docker_services fixture from my tests. But that is not an elegant solution.

Do you have an idea of how this option could be implemented? What comes to mind is either some kind of environment variable or maybe looking at the names of containers running on the system.

I would prefer the first option because it would be less likely to cause strange issues.

@languitar
Copy link
Contributor Author

languitar commented Jun 9, 2020

Pytest has command line options and this is what, for instance, pytest-kind uses for this purpose. I think the easiest thing would be to switch to a predictable project name and to provide a command line switch that disables the docker-compose down call.

https://codeberg.org/hjacobs/pytest-kind#user-content-pytest-options

@languitar
Copy link
Contributor Author

@otetard
Copy link
Contributor

otetard commented Jul 27, 2021

It’s quite easy to implement a “keep alive” mode by defining/overriding a few pytest-docker fixtures.

By adding the following code, you’ll be able to run pytest with a new --keepalive option that won’t stop Docker containers. In order to avoid recreating containers in the next pytest run, this requires to have a predictable name for Dockers, which was done by overriding the docker_compose_project_name fixture.

def pytest_addoption(parser):
    """Add custom options to pytest.
    Add the --keepalive option for pytest.
    """

    parser.addoption("--keepalive", "-K", action="store_true", default=False, help="Keep Docker containers alive")


@pytest.fixture(scope="session")
def keepalive(request):
    """Check if user asked to keep Docker running after the test."""

    return request.config.option.keepalive


@pytest.fixture(scope="session")
def docker_compose_project_name(keepalive, docker_compose_project_name):
    """Override `docker_compose_project_name` to make sure that we have a
    unique project name if user asked to keep containers alive. This way
    we won’t create Docker container every time we will start pytest."""

    if keepalive:
        return "pytest-myproject"

    return docker_compose_project_name


@pytest.fixture(scope="session")
def docker_cleanup(keepalive, docker_cleanup):
    """If user asked to keep Docker alive, make `pytest-docker` execute
    the `docker-compose version` command. This way, Docker container won’t
    be shut down."""

    if keepalive:
        return "version"

    return docker_cleanup

@lundybernard
Copy link

I do this for development work. I start my local cluster manually, and manage it myself. When running automated testing, I want pytest-docker to manage the cluster.

The simplest solution was to add a flag so that pytest-docker only runs when we set --env=docker like so:

# Add optional flags to the commandline
def pytest_addoption(parser):
    parser.addoption("--env", action="store", default="default")
    parser.addoption("--compose", action="store", default="v2")

    # add optional marker flags
    for marker, info in default_skip_markers.items():
        parser.addoption(
            f"--{marker}",
            action="store_true",
            default=False,
            help=info["help"],
        )

@fixture(scope="session")
def my_service(request):
    if request.config.getoption("--env") == "docker":
        request.getfixturevalue("my_container")
        
@fixture(scope="session")
def my_container(docker_ip, docker_services):
    """Ensure that HTTP service is up and responsive."""
    ...

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

No branches or pull requests

4 participants