Skip to content

Commit 9e30cc4

Browse files
committed
added tests for delete, fix_node, fill_slots
1 parent 0d9aca4 commit 9e30cc4

File tree

4 files changed

+105
-3
lines changed

4 files changed

+105
-3
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,9 @@ ruskit slowlog 192.168.0.11:8000
103103
# ruskit peek <node belong to cluster>
104104
ruskit peek 192.168.0.11:8000
105105
```
106+
107+
## Test
108+
```
109+
pip install -r test_requirements.txt
110+
py.test tests/
111+
```

test_requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ pbr==1.10.0
55
python-igraph==0.7.1.post6
66
redis==2.10.5
77
six==1.10.0
8+
py==1.4.31
9+
pytest==2.9.2

tests/test_base.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import unittest
22

3-
from mock import MagicMock, patch
3+
from mock import MagicMock, patch, call
44

55
from ruskit.cluster import ClusterNode, Cluster
66

77

88
CLUSTER_NODES_RESP = \
99
'e925e492d37b4ac6125da32ad681896fdff7e7b3 host0:6000 ' \
10-
'{}master - 0 0 1 connected 0-5461\n' \
10+
'{}master - 0 0 1 connected 0-5461\n' \
1111
'ac4f2168f6ebd97aa54412260d27d3a49dd5eb8a host1:6001 ' \
12-
'{}master - 0 1469498603296 2 connected 5462-10922\n' \
12+
'{}master - 0 1469498603296 2 connected 5462-10922\n' \
1313
'81b76b0961fda365771f1952ab5ff2a2898fc45c host2:6002 ' \
1414
'{}master - 0 1469498602285 3 connected 10923-16383\n'
1515

@@ -101,3 +101,10 @@ def setUp(self):
101101

102102
def assert_exec_cmd(self, node, *args, **kwargs):
103103
node.r.execute_command.assert_any_call(*args, **kwargs)
104+
105+
def assert_no_exec(self, node, *args, **kwargs):
106+
func = node.r.execute_command
107+
self.assertNotIn(call(*args, **kwargs), func.mock_calls)
108+
109+
def assert_not_called_with(self, mock_func, *args, **kwargs):
110+
self.assertNotIn(call(*args, **kwargs), mock_func.mock_calls)

tests/test_cluster.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import mock
22
import redis
3+
from mock import patch
4+
5+
from test_base import TestCaseBase, MockNewNode
6+
from ruskit.cluster import Cluster, ClusterNode
37

48

59
class MockNode(object):
@@ -119,3 +123,86 @@ def test_distribute(monkeypatch):
119123

120124
for s in manager.slaves:
121125
assert master_map[s.unassigned_master].host != s.host
126+
127+
128+
def clear_slots(node):
129+
node._cached_node_info['slots'] = []
130+
return mock.MagicMock()
131+
132+
133+
class TestCluster(TestCaseBase):
134+
@patch.object(Cluster, 'migrate_node', side_effect=clear_slots)
135+
def test_delete(self, migrate_node):
136+
cluster = self.cluster
137+
a = cluster.nodes[0]
138+
b = cluster.nodes[1]
139+
c = cluster.nodes[2]
140+
cluster.delete_node(a)
141+
migrate_node.assert_called_with(a)
142+
self.assertEqual(cluster.get_node(a.name), None)
143+
self.assert_exec_cmd(a, 'CLUSTER RESET')
144+
self.assert_exec_cmd(b, 'CLUSTER FORGET', a.name)
145+
self.assert_exec_cmd(c, 'CLUSTER FORGET', a.name)
146+
147+
@patch.object(Cluster, 'migrate_slot')
148+
def test_fix_node_migrating(self, migrate_slot):
149+
cluster = self.cluster
150+
a = cluster.nodes[0]
151+
b = cluster.nodes[1]
152+
c = cluster.nodes[2]
153+
for n in cluster.nodes:
154+
n.node_info # gen node_info
155+
a._cached_node_info['migrating'] = {
156+
'233': b.name,
157+
'666': c.name,
158+
'99': 'name_not_in_cluster',
159+
}
160+
b._cached_node_info['importing'] = {'233': a.name}
161+
cluster.fix_node(a)
162+
self.assert_no_exec(a, 'CLUSTER SETSLOT', '233', 'STABLE')
163+
self.assert_no_exec(b, 'CLUSTER SETSLOT', '233', 'STABLE')
164+
self.assert_exec_cmd(a, 'CLUSTER SETSLOT', '666', 'STABLE')
165+
self.assert_exec_cmd(a, 'CLUSTER SETSLOT', '99', 'STABLE')
166+
migrate_slot.assert_called_with(a, b, '233')
167+
self.assert_not_called_with(a, c, '666')
168+
169+
@patch.object(Cluster, 'migrate_slot')
170+
def test_fix_node_importing(self, migrate_slot):
171+
cluster = self.cluster
172+
a = cluster.nodes[0]
173+
b = cluster.nodes[1]
174+
c = cluster.nodes[2]
175+
for n in cluster.nodes:
176+
n.node_info # gen node_info
177+
a._cached_node_info['importing'] = {
178+
'233': b.name,
179+
'666': c.name,
180+
'99': 'name_not_in_cluster',
181+
}
182+
b._cached_node_info['migrating'] = {'233': a.name}
183+
cluster.fix_node(a)
184+
self.assert_no_exec(a, 'CLUSTER SETSLOT', '233', 'STABLE')
185+
self.assert_no_exec(b, 'CLUSTER SETSLOT', '233', 'STABLE')
186+
self.assert_exec_cmd(a, 'CLUSTER SETSLOT', '666', 'STABLE')
187+
self.assert_exec_cmd(a, 'CLUSTER SETSLOT', '99', 'STABLE')
188+
migrate_slot.assert_called_with(b, a, '233')
189+
self.assert_not_called_with(migrate_slot, c, a, '666')
190+
191+
def test_fill_slots(self):
192+
cluster = self.cluster
193+
a = cluster.nodes[0]
194+
b = cluster.nodes[1]
195+
c = cluster.nodes[2]
196+
for n in cluster.nodes:
197+
n.node_info # gen node_info
198+
missing_slots = a._cached_node_info['slots'][-6:]
199+
a._cached_node_info['slots'] = a._cached_node_info['slots'][:-6]
200+
cluster.fill_slots()
201+
added_slots = []
202+
for n in cluster.nodes:
203+
added_slots.extend(
204+
[list(args[1:]) for args, kwargs \
205+
in n.r.execute_command.call_args_list \
206+
if args[0] == 'CLUSTER ADDSLOTS'])
207+
added_slots = sum(added_slots, [])
208+
self.assertEqual(set(added_slots), set(missing_slots))

0 commit comments

Comments
 (0)