impuls/lib/python3.11/site-packages/pymemcache/test/test_rendezvous.py
2023-11-06 16:54:45 +01:00

204 lines
5.1 KiB
Python

from pymemcache.client.rendezvous import RendezvousHash
import pytest
@pytest.mark.unit()
def test_init_no_options():
rendezvous = RendezvousHash()
assert 0 == len(rendezvous.nodes)
assert 1361238019 == rendezvous.hash_function("6666")
@pytest.mark.unit()
def test_init():
nodes = ["0", "1", "2"]
rendezvous = RendezvousHash(nodes=nodes)
assert 3 == len(rendezvous.nodes)
assert 1361238019 == rendezvous.hash_function("6666")
@pytest.mark.unit()
def test_seed():
rendezvous = RendezvousHash(seed=10)
assert 2981722772 == rendezvous.hash_function("6666")
@pytest.mark.unit()
def test_add_node():
rendezvous = RendezvousHash()
rendezvous.add_node("1")
assert 1 == len(rendezvous.nodes)
rendezvous.add_node("1")
assert 1 == len(rendezvous.nodes)
rendezvous.add_node("2")
assert 2 == len(rendezvous.nodes)
rendezvous.add_node("1")
assert 2 == len(rendezvous.nodes)
@pytest.mark.unit()
def test_remove_node():
nodes = ["0", "1", "2"]
rendezvous = RendezvousHash(nodes=nodes)
rendezvous.remove_node("2")
assert 2 == len(rendezvous.nodes)
with pytest.raises(ValueError):
rendezvous.remove_node("2")
assert 2 == len(rendezvous.nodes)
rendezvous.remove_node("1")
assert 1 == len(rendezvous.nodes)
rendezvous.remove_node("0")
assert 0 == len(rendezvous.nodes)
@pytest.mark.unit()
def test_get_node():
nodes = ["0", "1", "2"]
rendezvous = RendezvousHash(nodes=nodes)
assert "0" == rendezvous.get_node("ok")
assert "1" == rendezvous.get_node("mykey")
assert "2" == rendezvous.get_node("wat")
@pytest.mark.unit()
def test_get_node_after_removal():
nodes = ["0", "1", "2"]
rendezvous = RendezvousHash(nodes=nodes)
rendezvous.remove_node("1")
assert "0" == rendezvous.get_node("ok")
assert "0" == rendezvous.get_node("mykey")
assert "2" == rendezvous.get_node("wat")
@pytest.mark.unit()
def test_get_node_after_addition():
nodes = ["0", "1", "2"]
rendezvous = RendezvousHash(nodes=nodes)
assert "0" == rendezvous.get_node("ok")
assert "1" == rendezvous.get_node("mykey")
assert "2" == rendezvous.get_node("wat")
assert "2" == rendezvous.get_node("lol")
rendezvous.add_node("3")
assert "0" == rendezvous.get_node("ok")
assert "1" == rendezvous.get_node("mykey")
assert "2" == rendezvous.get_node("wat")
assert "3" == rendezvous.get_node("lol")
@pytest.mark.unit()
def test_grow():
rendezvous = RendezvousHash()
placements = {}
for i in range(10):
rendezvous.add_node(str(i))
placements[str(i)] = []
for i in range(1000):
node = rendezvous.get_node(str(i))
placements[node].append(i)
new_placements = {}
for i in range(20):
rendezvous.add_node(str(i))
new_placements[str(i)] = []
for i in range(1000):
node = rendezvous.get_node(str(i))
new_placements[node].append(i)
keys = [k for sublist in placements.values() for k in sublist]
new_keys = [k for sublist in new_placements.values() for k in sublist]
assert sorted(keys) == sorted(new_keys)
added = 0
removed = 0
for node, assignments in new_placements.items():
after = set(assignments)
before = set(placements.get(node, []))
removed += len(before.difference(after))
added += len(after.difference(before))
assert added == removed
assert 1062 == (added + removed)
@pytest.mark.unit()
def test_shrink():
rendezvous = RendezvousHash()
placements = {}
for i in range(10):
rendezvous.add_node(str(i))
placements[str(i)] = []
for i in range(1000):
node = rendezvous.get_node(str(i))
placements[node].append(i)
rendezvous.remove_node("9")
new_placements = {}
for i in range(9):
new_placements[str(i)] = []
for i in range(1000):
node = rendezvous.get_node(str(i))
new_placements[node].append(i)
keys = [k for sublist in placements.values() for k in sublist]
new_keys = [k for sublist in new_placements.values() for k in sublist]
assert sorted(keys) == sorted(new_keys)
added = 0
removed = 0
for node, assignments in placements.items():
after = set(assignments)
before = set(new_placements.get(node, []))
removed += len(before.difference(after))
added += len(after.difference(before))
assert added == removed
assert 202 == (added + removed)
def collide(key, seed):
return 1337
@pytest.mark.unit()
def test_rendezvous_collision():
nodes = ["c", "b", "a"]
rendezvous = RendezvousHash(nodes, hash_function=collide)
for i in range(1000):
assert "c" == rendezvous.get_node(i)
@pytest.mark.unit()
def test_rendezvous_names():
nodes = [1, 2, 3, "a", "b", "lol.wat.com"]
rendezvous = RendezvousHash(nodes, hash_function=collide)
for i in range(10):
assert "lol.wat.com" == rendezvous.get_node(i)
nodes = [1, "a", "0"]
rendezvous = RendezvousHash(nodes, hash_function=collide)
for i in range(10):
assert "a" == rendezvous.get_node(i)