88
99
1010@pytest .fixture (scope = "session" , autouse = True )
11- def redis_container ():
12- # Set the default Redis version if not already set
11+ def redis_container (request ):
12+ """
13+ Create a unique Compose project for each xdist worker by setting
14+ COMPOSE_PROJECT_NAME. That prevents collisions on container/volume names.
15+ """
16+ # In xdist, the config has "workerid" in workerinput. For the main (non-xdist)
17+ # process, 'workerid' is often 'master' or something similar.
18+ worker_id = request .config .workerinput .get ("workerid" , "master" )
19+
20+ # Set the Compose project name so containers do not clash across workers
21+ os .environ ["COMPOSE_PROJECT_NAME" ] = f"redis_test_{ worker_id } "
1322 os .environ .setdefault ("REDIS_VERSION" , "edge" )
1423
15- compose = DockerCompose ("tests" , compose_file_name = "docker-compose.yml" , pull = True )
24+ compose = DockerCompose (
25+ context = "tests" ,
26+ compose_file_name = "docker-compose.yml" ,
27+ pull = True ,
28+ )
29+
1630 compose .start ()
1731
32+ # If you mapped the container port 6379:6379 in docker-compose.yml,
33+ # you might have collisions across workers. If you rely on ephemeral
34+ # host ports, remove the `ports:` block in docker-compose.yml and do:
1835 redis_host , redis_port = compose .get_service_host_and_port ("redis" , 6379 )
19- redis_url = f"redis://{ redis_host } :{ redis_port } "
20- os .environ ["REDIS_URL" ] = redis_url
36+ # redis_url = f"redis://{redis_host}:{redis_port}"
37+ # os.environ["REDIS_URL"] = redis_url
2138
2239 yield compose
2340
2441 compose .stop ()
42+ # Optionally, clean up the COMPOSE_PROJECT_NAME you set:
43+ os .environ .pop ("COMPOSE_PROJECT_NAME" , None )
44+
2545
2646@pytest .fixture (scope = "session" )
27- def redis_url ():
28- return os .getenv ("REDIS_URL" , "redis://localhost:6379" )
47+ def redis_url (redis_container ):
48+ """
49+ Use the `DockerCompose` fixture to get host/port of the 'redis' service
50+ on container port 6379 (mapped to an ephemeral port on the host).
51+ """
52+ host , port = redis_container .get_service_host_and_port ("redis" , 6379 )
53+ return f"redis://{ host } :{ port } "
2954
3055@pytest .fixture
3156async def async_client (redis_url ):
57+ """
58+ An async Redis client that uses the dynamic `redis_url`.
59+ """
3260 client = await RedisConnectionFactory .get_async_redis_connection (redis_url )
3361 yield client
3462 try :
@@ -38,8 +66,11 @@ async def async_client(redis_url):
3866 raise
3967
4068@pytest .fixture
41- def client ():
42- conn = RedisConnectionFactory .get_redis_connection (os .environ ["REDIS_URL" ])
69+ def client (redis_url ):
70+ """
71+ A sync Redis client that uses the dynamic `redis_url`.
72+ """
73+ conn = RedisConnectionFactory .get_redis_connection (redis_url )
4374 yield conn
4475 conn .close ()
4576
0 commit comments