we are moving to mongodb atlas and I've started using the mongodb/mongodb-atlas-local container for local development, it bound to ports 27017:27017. Now I wanted to update our integration tests to use the new container but I have some strange behaviour. This is my old code that worked, there is some extra code so it starts as a replica set so I can test functions that use transactions
@pytest.fixture(autouse=True, scope="session")def init_mongo_get_uri(): mongo_container = DockerContainer("mongo:latest") mongo_bind_port = randint(a=30000, b=40000) mongo_container.with_name("python_testing_mongodb") mongo_container.with_exposed_ports(mongo_bind_port) mongo_container.with_bind_ports(container=mongo_bind_port, host=mongo_bind_port) mongo_container.with_command(f"--port={mongo_bind_port} --replSet=rs") mongo_container.start() # normally the stuff above would be enough but we need to start the container with replica set to be able to test functions that use transactions # starting with replica set takes a second so we need to wait for the container to be ready mongo_uri = f"mongodb://localhost:{mongo_bind_port}/?replicaSet=rs" max_attempts = 10 for attempt in range(max_attempts): exit_code, output = mongo_container.exec("mongosh --quiet --eval=\"rs.initiate({_id:'rs',members:[{_id:0,host:'localhost:%s'}]})\" mongodb://localhost:%s" % ( mongo_bind_port, mongo_bind_port) ) if exit_code == 0: # If the command succeeds, break the loop break else: # Wait for 1 second before retrying sleep(1) if attempt == max_attempts - 1: # If we reach the last attempt and still fail, raise an error raise RuntimeError("Replica set didn't get setup properly after 10 seconds") yield mongo_uri mongo_container.stop()@pytest.fixture(scope="session")def test_app(init_mongo_get_uri): # Additional check to ensure the MongoDB container URI is not None if not init_mongo_get_uri: raise RuntimeError("MongoDB Testcontainer URI is None in test_app fixture.") # Setup the MongoDBSingleton with the container URI MongoDBSingleton._instance = None MongoDBSingleton(uri=init_mongo_get_uri, db_name="testdb") #start flask app
Now the mongodb/mongodb-atlas-local image uses replicasets by default so supposedly no need for all that extra stuff.
@pytest.fixture(autouse=True, scope="session")def init_mongo_get_uri(): mongo_container = DockerContainer("mongodb/mongodb-atlas-local") mongo_bind_port = randint(a=30000, b=40000) mongo_container.with_name("python_testing_mongodb") mongo_container.with_bind_ports(container=27017, host=mongo_bind_port) mongo_container.start() mongo_uri = f"mongodb://localhost:{mongo_bind_port}" yield mongo_uri mongo_container.stop()@pytest.fixture(scope="session")def test_app(init_mongo_get_uri):# same as before
Here my knowledge of either Mongo or docker or both are failing me because even if the new integration tests run against the testcontainer
on a different host port I still see the testdb
appear inside my local dev 27017:27017 container, and if I stop the tests with debug I can use compass to connect to the testcontainer
on say port 37017 and I'll see my local databases there as well.
I have tried binding the atlas testcontainer
to something other than 27017 but it seems that isn't allowed.
What am I missing so I can run the testcontainer
without it "polluting" my dev-container? I would have thought that having different host ports would be enough.
EDITIt seems when my local dev db is turned off I can't access the test one at all unless i run it on 27017:27017.