|
5 | 5 | from cachetools import TTLCache, LRUCache, LFUCache
|
6 | 6 |
|
7 | 7 | import redis
|
8 |
| -from redis import Redis, RedisCluster |
9 | 8 | from redis.utils import HIREDIS_AVAILABLE
|
10 | 9 | from tests.conftest import _get_client
|
11 | 10 |
|
@@ -113,8 +112,6 @@ def test_health_check_invalidate_cache_multithreaded(self, r, r2, cache):
|
113 | 112 | threading.Thread(target=r2.set, args=("bar", "bar")).start()
|
114 | 113 | # Wait for health check
|
115 | 114 | time.sleep(2)
|
116 |
| - # Trigger object destructor to shutdown health check thread |
117 |
| - del r |
118 | 115 | # Make sure that value was invalidated
|
119 | 116 | assert cache.get(("GET", "foo")) is None
|
120 | 117 | assert cache.get(("GET", "bar")) is None
|
@@ -492,17 +489,92 @@ def test_cache_flushed_on_server_flush(self, r, cache):
|
492 | 489 | @pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
|
493 | 490 | @pytest.mark.onlynoncluster
|
494 | 491 | class TestSentinelCache:
|
495 |
| - def test_get_from_cache(self, cache, master): |
| 492 | + @pytest.mark.parametrize( |
| 493 | + "sentinel_setup", |
| 494 | + [{"cache": LRUCache(maxsize=128), "use_cache": True, "force_master_ip": "localhost"}], |
| 495 | + indirect=True, |
| 496 | + ) |
| 497 | + @pytest.mark.onlynoncluster |
| 498 | + def test_get_from_cache(self, master, cache): |
| 499 | + master, cache = master |
496 | 500 | master.set("foo", "bar")
|
497 | 501 | # get key from redis and save in local cache
|
498 | 502 | assert master.get("foo") == b"bar"
|
499 | 503 | # get key from local cache
|
500 | 504 | assert cache.get(("GET", "foo")) == b"bar"
|
501 | 505 | # change key in redis (cause invalidation)
|
502 | 506 | master.set("foo", "barbar")
|
503 |
| - # send any command to redis (process invalidation in background) |
504 |
| - master.ping() |
505 |
| - # the command is not in the local cache anymore |
506 |
| - assert cache.get(("GET", "foo")) is None |
507 | 507 | # get key from redis
|
508 | 508 | assert master.get("foo") == b"barbar"
|
| 509 | + # Make sure that new value was cached |
| 510 | + assert cache.get(("GET", "foo")) == b"barbar" |
| 511 | + |
| 512 | + @pytest.mark.parametrize( |
| 513 | + "sentinel_setup", |
| 514 | + [{"cache": LRUCache(maxsize=128), "use_cache": True, "force_master_ip": "localhost"}], |
| 515 | + indirect=True, |
| 516 | + ) |
| 517 | + @pytest.mark.onlynoncluster |
| 518 | + def test_get_from_cache_multithreaded(self, master, cache): |
| 519 | + master, cache = master |
| 520 | + # Running commands over two threads |
| 521 | + threading.Thread(target=set_get, args=(master, "foo", "bar")).start() |
| 522 | + threading.Thread(target=set_get, args=(master, "bar", "foo")).start() |
| 523 | + |
| 524 | + # Wait for command execution to be finished |
| 525 | + time.sleep(0.1) |
| 526 | + |
| 527 | + # Make sure that both values was cached. |
| 528 | + assert cache.get(("GET", "foo")) == b"bar" |
| 529 | + assert cache.get(("GET", "bar")) == b"foo" |
| 530 | + |
| 531 | + # Running commands over two threads |
| 532 | + threading.Thread(target=set_get, args=(master, "foo", "baz")).start() |
| 533 | + threading.Thread(target=set_get, args=(master, "bar", "bar")).start() |
| 534 | + |
| 535 | + # Wait for command execution to be finished |
| 536 | + time.sleep(0.1) |
| 537 | + |
| 538 | + # Make sure that new values was cached. |
| 539 | + assert cache.get(("GET", "foo")) == b"baz" |
| 540 | + assert cache.get(("GET", "bar")) == b"bar" |
| 541 | + |
| 542 | + @pytest.mark.parametrize( |
| 543 | + "sentinel_setup", |
| 544 | + [{"cache": LRUCache(maxsize=128), "use_cache": True, "force_master_ip": "localhost"}], |
| 545 | + indirect=True, |
| 546 | + ) |
| 547 | + @pytest.mark.onlynoncluster |
| 548 | + def test_health_check_invalidate_cache(self, master, cache): |
| 549 | + master, cache = master |
| 550 | + # add key to redis |
| 551 | + master.set("foo", "bar") |
| 552 | + # get key from redis and save in local cache |
| 553 | + assert master.get("foo") == b"bar" |
| 554 | + # get key from local cache |
| 555 | + assert cache.get(("GET", "foo")) == b"bar" |
| 556 | + # change key in redis (cause invalidation) |
| 557 | + master.set("foo", "barbar") |
| 558 | + # Wait for health check |
| 559 | + time.sleep(2) |
| 560 | + # Make sure that value was invalidated |
| 561 | + assert cache.get(("GET", "foo")) is None |
| 562 | + |
| 563 | + @pytest.mark.parametrize( |
| 564 | + "sentinel_setup", |
| 565 | + [{"cache": LRUCache(maxsize=128), "use_cache": True, "force_master_ip": "localhost"}], |
| 566 | + indirect=True, |
| 567 | + ) |
| 568 | + @pytest.mark.onlynoncluster |
| 569 | + def test_cache_clears_on_disconnect(self, master, cache): |
| 570 | + master, cache = master |
| 571 | + # add key to redis |
| 572 | + master.set("foo", "bar") |
| 573 | + # get key from redis and save in local cache |
| 574 | + assert master.get("foo") == b"bar" |
| 575 | + # get key from local cache |
| 576 | + assert cache.get(("GET", "foo")) == b"bar" |
| 577 | + # Force disconnection |
| 578 | + master.connection_pool.get_connection('_').disconnect() |
| 579 | + # Make sure cache is empty |
| 580 | + assert cache.currsize == 0 |
0 commit comments