Skip to content

Commit 18241a8

Browse files
authored
Make tests safer to run in parallel by changing the Redis key namespace (#6283)
2 parents 96eef0e + 0ebced6 commit 18241a8

File tree

11 files changed

+65
-23
lines changed

11 files changed

+65
-23
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Added
6969
working on StackStorm, improve our security posture, and improve CI reliability thanks in part
7070
to pants' use of PEX lockfiles. This is not a user-facing addition.
7171
#6118 #6141 #6133 #6120 #6181 #6183 #6200 #6237 #6229 #6240 #6241 #6244 #6251 #6253
72-
#6254 #6258 #6259 #6260 #6269 #6275 #6279 #6278 #6282
72+
#6254 #6258 #6259 #6260 #6269 #6275 #6279 #6278 #6282 #6283
7373
Contributed by @cognifloyd
7474
* Build of ST2 EL9 packages #6153
7575
Contributed by @amanda11

conf/st2.dev.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ protocol = udp
8787
# / cross server functionality
8888
#url = redis://localhost
8989
#url = kazoo://localhost
90-
url = redis://127.0.0.1:6379
90+
url = redis://127.0.0.1:6379?namespace=_st2_dev
9191

9292
[webui]
9393
# webui_base_url = https://mywebhost.domain

fixed-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ tooz==6.3.0
7272
# lockfiles/st2.lock has pip==24.2 wheel==0.44.0 setuptools==75.2.0
7373
virtualenv==20.27.0
7474
webob==1.8.9
75+
webtest==3.0.1
7576
zake==0.2.2
7677
# test requirements below
7778
bcrypt==4.2.0

pants-plugins/uses_services/redis_rules.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
rules as pex_rules,
2929
)
3030
from pants.core.goals.test import TestExtraEnv
31+
from pants.engine.env_vars import EnvironmentVars
3132
from pants.engine.fs import CreateDigest, Digest, FileContent
3233
from pants.engine.rules import collect_rules, Get, MultiGet, rule
3334
from pants.engine.process import FallibleProcessResult, ProcessCacheScope
@@ -54,16 +55,29 @@ class UsesRedisRequest:
5455

5556
# These config opts for integration tests are in:
5657
# conf/st2.dev.conf (copied to conf/st2.ci.conf)
57-
# TODO: for int tests: set url by either modifying st2.{dev,ci}.conf on the fly or via env vars.
58-
59-
# with our version of oslo.config (newer are slower) we can't directly override opts w/ environment variables.
58+
# These can also be updated via the ST2TESTS_REDIS_* env vars.
59+
# Integration tests should pass these changes onto subprocesses using the
60+
# ST2_COORDINATION__* env vars (which oslo_config reads).
6061

6162
host: str = "127.0.0.1"
62-
port: str = "6379"
63+
port: int = 6379
6364

6465
@property
6566
def coord_url(self) -> str:
66-
return f"redis://{self.host}:{self.port}"
67+
return f"redis://{self.host}:{self.port}?namespace=_st2_test"
68+
69+
@classmethod
70+
def from_env(cls, env: EnvironmentVars) -> UsesRedisRequest:
71+
default = cls()
72+
host = env.get("ST2TESTS_REDIS_HOST", default.host)
73+
port_raw = env.get("ST2TESTS_REDIS_PORT", str(default.port))
74+
75+
try:
76+
port = int(port_raw)
77+
except (TypeError, ValueError):
78+
port = default.port
79+
80+
return cls(host=host, port=port)
6781

6882

6983
@dataclass(frozen=True)
@@ -88,11 +102,8 @@ async def redis_is_running_for_pytest(
88102
request: PytestUsesRedisRequest,
89103
test_extra_env: TestExtraEnv,
90104
) -> PytestPluginSetup:
91-
redis_host = test_extra_env.env.get("ST2TESTS_REDIS_HOST", "127.0.0.1")
92-
redis_port = test_extra_env.env.get("ST2TESTS_REDIS_PORT", "6379")
93-
94105
# this will raise an error if redis is not running
95-
_ = await Get(RedisIsRunning, UsesRedisRequest(host=redis_host, port=redis_port))
106+
_ = await Get(RedisIsRunning, UsesRedisRequest.from_env(env=test_extra_env.env))
96107

97108
return PytestPluginSetup()
98109

@@ -161,7 +172,7 @@ async def redis_is_running(
161172
not_installed_clause_deb="this is one way to install it:",
162173
install_instructions_deb=dedent(
163174
"""\
164-
sudo apt-get install -y mongodb redis
175+
sudo apt-get install -y redis
165176
# Don't forget to start redis.
166177
"""
167178
),
@@ -170,7 +181,8 @@ async def redis_is_running(
170181
"""\
171182
You can also export the ST2TESTS_REDIS_HOST and ST2TESTS_REDIS_PORT
172183
env vars to automatically use any redis host, local or remote,
173-
while running unit and integration tests.
184+
while running unit and integration tests. Tests do not use any
185+
ST2_COORDINATION__* vars at this point.
174186
"""
175187
),
176188
),

pants-plugins/uses_services/redis_rules_test.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ def run_redis_is_running(
5151
"--backend-packages=uses_services",
5252
*(extra_args or ()),
5353
],
54-
env_inherit={"PATH", "PYENV_ROOT", "HOME"},
54+
env_inherit={
55+
"PATH",
56+
"PYENV_ROOT",
57+
"HOME",
58+
"ST2TESTS_REDIS_HOST",
59+
"ST2TESTS_REDIS_PORT",
60+
"ST2TESTS_PARALLEL_SLOT",
61+
},
5562
)
5663
result = rule_runner.request(
5764
RedisIsRunning,
@@ -62,7 +69,7 @@ def run_redis_is_running(
6269

6370
# Warning this requires that redis be running
6471
def test_redis_is_running(rule_runner: RuleRunner) -> None:
65-
request = UsesRedisRequest()
72+
request = UsesRedisRequest.from_env(env=rule_runner.environment)
6673
mock_platform = platform(os="TestMock")
6774

6875
# we are asserting that this does not raise an exception
@@ -74,7 +81,7 @@ def test_redis_is_running(rule_runner: RuleRunner) -> None:
7481
def test_redis_not_running(rule_runner: RuleRunner, mock_platform: Platform) -> None:
7582
request = UsesRedisRequest(
7683
host="127.100.20.7",
77-
port="10", # 10 is an unassigned port, unlikely to be used
84+
port=10, # 10 is an unassigned port, unlikely to be used
7885
)
7986

8087
with pytest.raises(ExecutionError) as exception_info:

pants-plugins/uses_services/scripts/is_redis_running.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ def _is_redis_running(coord_url: str) -> bool:
3939
if __name__ == "__main__":
4040
args = dict((k, v) for k, v in enumerate(sys.argv))
4141

42-
# unit tests do not use redis, they use use an in-memory coordinator: "zake://"
43-
# integration tests use this url with a conf file derived from conf/st2.dev.conf
44-
coord_url = args.get(1, "redis://127.0.0.1:6379")
42+
# unit and integration tests require a coordinator, and mostly use this redis url.
43+
# In some cases, unit tests can also use an in-memory coordinator: "zake://"
44+
coord_url = args.get(1, "redis://127.0.0.1:6379?namespace=_st2_test")
4545

4646
is_running = _is_redis_running(coord_url)
4747
exit_code = 0 if is_running else 1

pants.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ extra_env_vars = [
240240
# Use this so that the test system does not require the stanley user.
241241
# For example: export ST2TESTS_SYSTEM_USER=${USER}
242242
"ST2TESTS_SYSTEM_USER",
243+
"ST2_SYSTEM_USER__USER",
243244
# Use these to override MongoDB connection details
244245
# "ST2_DATABASE__HOST", # Tests override this with "127.0.0.1"
245246
"ST2_DATABASE__PORT",
@@ -250,9 +251,12 @@ extra_env_vars = [
250251
# Use these to override RabbitMQ connection details
251252
"ST2_MESSAGING__URL",
252253
"ST2_MESSAGING__PREFIX", # Tests will modify this to be "{prefix}{ST2TESTS_PARALLEL_SLOT}"
253-
# Use these to override the redis host and port
254+
# Use these to override Redis connection details
254255
"ST2TESTS_REDIS_HOST",
255256
"ST2TESTS_REDIS_PORT",
257+
# "ST2_COORDINATION__URL", # Tests will override this with one of:
258+
# "redis://{ST2TESTS_REDIS_HOST}:{ST2TESTS_REDIS_PORT}?namespace=_st2_test{ST2TESTS_PARALLEL_SLOT}
259+
# "zake://"
256260
]
257261
# 10 min should be more than enough even for integration tests.
258262
timeout_default = 600 # seconds

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ tooz==6.3.0
7676
typing-extensions==4.12.2
7777
unittest2
7878
webob==1.8.9
79-
webtest
79+
webtest==3.0.1
8080
zake==0.2.2
8181
zipp==3.20.2
8282
zstandard==0.23.0

st2tests/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ psutil==6.1.0
1414
pyrabbit
1515
rednose
1616
unittest2
17-
webtest
17+
webtest==3.0.1

st2tests/st2tests/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ def _override_coordinator_opts(noop=False):
174174
redis_host = os.environ.get("ST2TESTS_REDIS_HOST", False)
175175
if redis_host:
176176
redis_port = os.environ.get("ST2TESTS_REDIS_PORT", "6379")
177-
driver = f"redis://{redis_host}:{redis_port}"
177+
# namespace= is the tooz redis driver's key prefix (default is "_tooz")
178+
namespace = f"_st2_test{os.environ.get('ST2TESTS_PARALLEL_SLOT', '')}"
179+
driver = f"redis://{redis_host}:{redis_port}?namespace={namespace}"
178180

179181
CONF.set_override(name="url", override=driver, group="coordination")
180182
CONF.set_override(name="lock_timeout", override=1, group="coordination")

0 commit comments

Comments
 (0)