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

Rerunning tests causes them to fail because the container is not cleaned up. #208

Closed
santiwanti opened this issue Sep 15, 2024 · 9 comments
Labels
question Further information is requested

Comments

@santiwanti
Copy link

I'm using the testcontainers-module Postgres container and all tests pass on the first run, but on the second run they fail because when trying to add the rows, the elements already exist causing problems with UNIQUE constraints. Is it expected behavior that the tests make permanent changes to the environment? I thought the whole point of testcontainers was that each test ran in isolation and the environment would be a clean one for each test.

@DDtKey
Copy link
Contributor

DDtKey commented Sep 15, 2024

No, this isn't the expected behavior. Each new container starts an independent instance (until any customizations are made - like mounting postgres data or reusing the same container)

because the container is not cleaned up

Even if it's not cleaned up (e.g TESTCONTAINERS_COMMAND=keep) - you should use the connection string for new container. But from the description it sounds like your code is connecting to the existing instance .

Could you share the code that causes the issue? How do you connect to postgres?

@DDtKey DDtKey transferred this issue from testcontainers/testcontainers-rs Sep 15, 2024
@santiwanti
Copy link
Author

While moving all the code to a single file, I noticed I was ignoring the get_host_port_ipv4 output. I thought there was no way that would be what would fix it, but I tested it and it did. 🙈
So for anyone that thinks you can ignore the port, as I did, because I thought obviously postgres is port 5432, think again. For some reason not specifying the port meant that every container was the same and all changes persisted through tests.

This works:

    let connection_string = &format!(
        "postgres://postgres:[email protected]:{}/postgres",
        node.get_host_port_ipv4(5432)?
    );

This does not work:

    let connection_string = "postgres://postgres:[email protected]/postgres";

@DDtKey
Copy link
Contributor

DDtKey commented Sep 15, 2024

For some reason not specifying the port meant that every container was the same and all changes persisted through tests.

Might that be that you have a local postgres instance? (i.e you started a container, but connected to the local one on your machine every time)

Because containers are always mapped to the random port (until customized) and that's why you need to use get_host_port_ipv4. You even may have many postgres containers spawned at the same time and it will work.

@DDtKey DDtKey added the question Further information is requested label Sep 15, 2024
@santiwanti
Copy link
Author

I don't think it was connecting to the local instance because deleting the postgres image manually would fix the tests and allow them to run properly again. I tried deleting all the images and containers so I only had one container and one image running, but the tests would still fail, due to UNIQUE constraints on the second run, when not specifying the port.

@DDtKey
Copy link
Contributor

DDtKey commented Sep 15, 2024

When you don't specify a port in connection string, in fact (depending on the client, ofc) all that happens is usually the default (5432) is used.
So to understand the reasons - you need to understand what was mapped to this port. (Test-)containers do not share state between themselves unless this is explicitly configured and get_host_port_ipv4 doesn't do any magic here, just tells which port to use for a connection to a particular container

@santiwanti
Copy link
Author

As you can probably tell I'm not much of an expert with docker and containers.

I used docker image ls to list all images and deleted them all with docker image rm. When rerunning the tests after that it worked the first time and then failed again until I deleted the image again. After using the port that I got back from get_host_port_ipv4 this problem stopped happening. Checking docker image ls again I only have 1 image which is what I would expect and the tests run properly no matter how many times I run them.

I'm not sure why using the port returned by get_host_port_ipv4 fixed the problem. I hadn't thought the port was the reason precisely because of what you mentioned of 5432 being the default already.

Btw, removing the port again from the connection string causes the issue to happen again.

If you want me to run any tests or try out anything let me know I would be happy to help.

@DDtKey
Copy link
Contributor

DDtKey commented Sep 15, 2024

docker images ls shows a list of images, not containers. You may have many containers using the same image - it's totally fine. You can check the documentation about image if you wish

When rerunning the tests after that it worked the first time and then failed again until I deleted the image again.

However this parts sounds interesting and weird.

Could you try to check what's bound to 5432 for you? For example:

lsof -i tcp:5432

Also, what you can check is docker container ls before and after running tests.
If you don't see any containers after test execution - it means they've been cleaned up. To double check - you can disable cleaning by setting export TESTCONTAINERS_COMMAND=keep before running and then try again.
You should see that the containers spawned are mapped to some random ports.

@santiwanti
Copy link
Author

I ran lsof -i tcp:5432 and didn't see any results and when checking docker container ls I don't see any containers, but as soon as I run it again without specifying the port the tests fail, but now deleting the image does not fix it. I have checked my local postgres databases and the database doesn't exist there either. So now I have no way to fix it so the tests run when not specifying a port.

@DDtKey
Copy link
Contributor

DDtKey commented Sep 25, 2024

I'm going to close the issue since using get_host_port_ipv4 solves the issue for you (and it's expected to be used)

However I'm not sure about underlying issues and can't reproduce. Please, feel free to re-open if you want to discuss the issue deeper, but it requires checking your case more deeply (it doesn't happen on 2 of my devices & some servers, so hard to help without allocating more time)

@DDtKey DDtKey closed this as completed Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants