(improvement) unit tests for benchmarking query planning.#653
(improvement) unit tests for benchmarking query planning.#653mykaul wants to merge 4 commits intoscylladb:masterfrom
Conversation
b9a8faa to
a797262
Compare
|
Latest commit add Host policy. Now it looks like this: |
|
@mykaul , thanks looks great, can you implement them in pytest and mark with |
Not a very scientific one, but reasonable to get some measurements in terms of how different optimizations work. Example run (on scylladb#650 branch): ykaul@ykaul:~/github/python-driver$ pytest -s tests/unit/test_policy_performance.py /usr/lib/python3.14/site-packages/pytest_asyncio/plugin.py:211: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset. The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session" warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET)) ============================================================================================================ test session starts ============================================================================================================= platform linux -- Python 3.14.2, pytest-8.3.5, pluggy-1.6.0 rootdir: /home/ykaul/github/python-driver configfile: pyproject.toml plugins: asyncio-1.1.0, anyio-4.12.1 asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function collected 4 items tests/unit/test_policy_performance.py Pinned to CPU 0 .... === Performance Benchmarks === Policy | Ops | Time (s) | Kops/s ---------------------------------------------------------------------- DCAware | 100000 | 0.2328 | 429 RackAware | 100000 | 0.3637 | 274 TokenAware(DCAware) | 100000 | 1.5884 | 62 TokenAware(RackAware) | 100000 | 1.6816 | 59 ---------------------------------------------------------------------- Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
Signed-off-by: Yaniv Kaul <yaniv.kaul@scylldb.com>
1. Move to regular Pytest, within the performance subdir, as part of a benchmark module 2. Renamed tests/integration/standard/column_encryption/test_policies.py -> test_encrypted_policies.py - we had two test_policies.py which conflicted when trying to run all unit tests. Example run: (scylla-driver) ykaul@ykaul:~/github/python-driver$ SCYLLA_VERSION=release:2025.4.2 PROTOCOL_VRESION=4 pytest -s -m benchmark ============================================================================================================ test session starts ============================================================================================================= platform linux -- Python 3.14.2, pytest-8.4.2, pluggy-1.6.0 rootdir: /home/ykaul/github/python-driver configfile: pyproject.toml collected 1798 items / 1792 deselected / 6 selected tests/performance/test_policy_performance.py Pinned to CPU 0 DCAware | 100000 | 0.1176 | 850 Kops/s . RackAware | 100000 | 0.1774 | 563 Kops/s . TokenAware(DCAware) | 100000 | 0.6666 | 150 Kops/s . TokenAware(RackAware) | 100000 | 0.7195 | 138 Kops/s . Default(DCAware) | 100000 | 0.1481 | 675 Kops/s . HostFilter(DCAware) | 100000 | 0.2416 | 413 Kops/s . Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
a797262 to
d850f81
Compare
There is no pytest.ini, so I've added one. The tests were already in pytest, now they are in the right dir, in a follow-up commit. |
|
There is |
…cement The test_idle_heartbeat test was failing with a KeyError when connections were dynamically replaced during the test run in shard-aware environments. Root cause: The test captures connection object IDs at the start, sleeps for heartbeat intervals, then tries to validate those connections. In shard-aware ScyllaDB deployments, the driver may replace connections during this window. When a connection is replaced, the new connection object has a different Python ID, causing a KeyError on lookup. Fix: Skip validation for connections that weren't present in the initial snapshot. This preserves the test's intent (validating heartbeats on stable connections) while being robust to dynamic connection management in shard-aware mode. I'm not sure this is a great fix. I don't think it has anything to do with this branch. I'll push it and if it's OK, I'll also create a separate PR for it. Why it popped now? Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
dkropachev
left a comment
There was a problem hiding this comment.
I love it, have some comments though.
Also can you please take a look at pytest-benchmark, it looks like exactly what we need.
| "A micro-bechmark for performance of policies" | ||
|
|
There was a problem hiding this comment.
Is it a real commit ? there is real change here.
| replicas = [] | ||
| for r in range(3): | ||
| idx = (i + r) % len(hosts) | ||
| replicas.append(hosts[idx]) | ||
| replicas_map[key] = replicas |
There was a problem hiding this comment.
I don't think it is good idea to connect number of token ranges with number of queries, you may want to run 1k queries on setup with 100 token ranges.
Also this way you would split mock cluster initialization from query initialization, which would make fixture api more readable and flexiable at the same time, it would look like this:
def test_dc_aware(policy, vnode_cluster_1000, select_10000):
policy.populate(vnode_cluster_1000, vnode_cluster_1000.metadata.all_hosts())
for query in select_10000:
...
| @@ -0,0 +1,242 @@ | |||
| import time | |||
There was a problem hiding this comment.
Can you please merge these two commits, it looks you you just moved code to another place
| connections = [c for holders in cluster.get_connection_holders() for c in holders.get_connections()] | ||
|
|
||
| # make sure requests were sent on all connections | ||
| # Note: connections can be replaced in shard-aware environments, so we skip |
There was a problem hiding this comment.
Could you please create a separate pr for this change.
There was a problem hiding this comment.
I was going to, first wanted to see that it solves the issue - but it doesn't:
FAILED tests/integration/standard/test_cluster.py::ClusterTests::test_idle_heartbeat - assert not True
+ where True = any(<generator object ClusterTests.test_idle_heartbeat.<locals>.<genexpr> at 0x7f63c0292d40>)
I feel like I should git bisect it - if I can reproduce this locally first.
There was a problem hiding this comment.
Of course, it passes locally. Over and over, consistently. Not a single failure.
Not a very scientific one, but reasonable to get some measurements in terms of how different optimizations work. Example run (on #650 branch):
Pre-review checklist
./docs/source/.Fixes:annotations to PR description.