Skip to content

Commit c10294e

Browse files
isapegoivandasch
andauthored
IGNITE-14240 Re-factor tests (#29)
Handle authentication error. Fix infinite recursion on failed connection on handshake. Skip affinity test if server doesn't support protocol. Remove travis. (cherry picked from commit b2030be) Co-authored-by: Ivan Dashchinskiy <ivandasch@gmail.com>
1 parent e62fbb9 commit c10294e

33 files changed

Lines changed: 581 additions & 515 deletions

pygridgain/connection/connection.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def read_response(self) -> Union[dict, OrderedDict]:
170170
('length', Int),
171171
('op_code', Byte),
172172
])
173-
with BinaryStream(self, self.recv()) as stream:
173+
with BinaryStream(self, self.recv(reconnect=False)) as stream:
174174
start_class = response_start.parse(stream)
175175
start = stream.read_ctype(start_class, direction=READ_BACKWARD)
176176
data = response_start.to_python(start)
@@ -266,7 +266,7 @@ def _connect_version(
266266

267267
with BinaryStream(self) as stream:
268268
hs_request.from_python(stream)
269-
self.send(stream.getbuffer())
269+
self.send(stream.getbuffer(), reconnect=False)
270270

271271
hs_response = self.read_response()
272272
if hs_response['op_code'] == 0:
@@ -314,12 +314,13 @@ def reconnect(self):
314314
except connection_errors:
315315
pass
316316

317-
def send(self, data: Union[bytes, bytearray, memoryview], flags=None):
317+
def send(self, data: Union[bytes, bytearray, memoryview], flags=None, reconnect=True):
318318
"""
319319
Send data down the socket.
320320
321321
:param data: bytes to send,
322322
:param flags: (optional) OS-specific flags.
323+
:param reconnect: (optional) reconnect on failure, default True.
323324
"""
324325
if self.closed:
325326
raise SocketError('Attempt to use closed connection.')
@@ -335,7 +336,13 @@ def send(self, data: Union[bytes, bytearray, memoryview], flags=None):
335336
self.reconnect()
336337
raise
337338

338-
def recv(self, flags=None) -> bytearray:
339+
def recv(self, flags=None, reconnect=True) -> bytearray:
340+
"""
341+
Receive data from the socket.
342+
343+
:param flags: (optional) OS-specific flags.
344+
:param reconnect: (optional) reconnect on failure, default True.
345+
"""
339346
def _recv(buffer, num_bytes):
340347
bytes_to_receive = num_bytes
341348
while bytes_to_receive > 0:
@@ -345,7 +352,8 @@ def _recv(buffer, num_bytes):
345352
raise SocketError('Connection broken.')
346353
except connection_errors:
347354
self.failed = True
348-
self.reconnect()
355+
if reconnect:
356+
self.reconnect()
349357
raise
350358

351359
buffer = buffer[bytes_rcvd:]

pygridgain/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
PROTOCOL_STRING_ENCODING = 'utf-8'
5353
PROTOCOL_CHAR_ENCODING = 'utf-16le'
5454

55-
SSL_DEFAULT_VERSION = ssl.PROTOCOL_TLSv1_1
55+
SSL_DEFAULT_VERSION = ssl.PROTOCOL_TLSv1_2
5656
SSL_DEFAULT_CIPHERS = ssl._DEFAULT_CIPHERS
5757

5858
FNV1_OFFSET_BASIS = 0x811c9dc5

requirements/install.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# these pip packages are necessary for the pygridgain to run
22

3-
attrs==18.1.0
3+
attrs==20.3.0
44
tzlocal==2.1

requirements/setup.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# additional package for integrating pytest in setuptools
22

3-
pytest-runner==4.2
3+
pytest-runner==5.3.0

requirements/tests.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# these packages are used for testing
22

3-
pytest==3.6.1
4-
pytest-cov==2.5.1
5-
teamcity-messages==1.21
6-
psutil==5.6.5
3+
pytest==6.2.2
4+
pytest-cov==2.11.1
5+
teamcity-messages==1.28
6+
psutil==5.8.0
77
jinja2==2.11.3

tests/affinity/conftest.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#
2+
# Copyright 2021 GridGain Systems, Inc. and Contributors.
3+
#
4+
# Licensed under the GridGain Community Edition License (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.gridgain.com/products/software/community-edition/gridgain-community-edition-license
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
import pytest
17+
18+
from pygridgain import Client
19+
from pygridgain.api import cache_create, cache_destroy
20+
from tests.util import start_ignite_gen
21+
22+
23+
@pytest.fixture(scope='module', autouse=True)
24+
def server1():
25+
yield from start_ignite_gen(1)
26+
27+
28+
@pytest.fixture(scope='module', autouse=True)
29+
def server2():
30+
yield from start_ignite_gen(2)
31+
32+
33+
@pytest.fixture(scope='module', autouse=True)
34+
def server3():
35+
yield from start_ignite_gen(3)
36+
37+
38+
@pytest.fixture
39+
def client():
40+
client = Client(partition_aware=True)
41+
42+
client.connect([('127.0.0.1', 10800 + i) for i in range(1, 4)])
43+
44+
yield client
45+
46+
client.close()
47+
48+
49+
@pytest.fixture
50+
def client_not_connected():
51+
client = Client(partition_aware=True)
52+
yield client
53+
client.close()
54+
55+
56+
@pytest.fixture
57+
def cache(connected_client):
58+
cache_name = 'my_bucket'
59+
conn = connected_client.random_node
60+
61+
cache_create(conn, cache_name)
62+
yield cache_name
63+
cache_destroy(conn, cache_name)
64+
65+
66+
@pytest.fixture(scope='module', autouse=True)
67+
def skip_if_no_affinity(request, server1):
68+
client = Client(partition_aware=True)
69+
client.connect('127.0.0.1', 10801)
70+
71+
if not client.partition_awareness_supported_by_protocol:
72+
pytest.skip(f'skipped {request.node.name}, partition awareness is not supported.')
Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@
2727
from pygridgain.datatypes.prop_codes import *
2828

2929

30-
def test_get_node_partitions(client_partition_aware):
30+
def test_get_node_partitions(client):
31+
conn = client.random_node
3132

32-
conn = client_partition_aware.random_node
33-
34-
cache_1 = client_partition_aware.get_or_create_cache('test_cache_1')
35-
cache_2 = client_partition_aware.get_or_create_cache({
33+
cache_1 = client.get_or_create_cache('test_cache_1')
34+
cache_2 = client.get_or_create_cache({
3635
PROP_NAME: 'test_cache_2',
3736
PROP_CACHE_KEY_CONFIGURATION: [
3837
{
@@ -41,9 +40,9 @@ def test_get_node_partitions(client_partition_aware):
4140
}
4241
],
4342
})
44-
cache_3 = client_partition_aware.get_or_create_cache('test_cache_3')
45-
cache_4 = client_partition_aware.get_or_create_cache('test_cache_4')
46-
cache_5 = client_partition_aware.get_or_create_cache('test_cache_5')
43+
client.get_or_create_cache('test_cache_3')
44+
client.get_or_create_cache('test_cache_4')
45+
client.get_or_create_cache('test_cache_5')
4746

4847
result = cache_get_node_partitions(
4948
conn,
@@ -115,9 +114,8 @@ def test_get_node_partitions(client_partition_aware):
115114
116115
],
117116
)
118-
def test_affinity(client_partition_aware, key, key_hint):
119-
120-
cache_1 = client_partition_aware.get_or_create_cache({
117+
def test_affinity(client, key, key_hint):
118+
cache_1 = client.get_or_create_cache({
121119
PROP_NAME: 'test_cache_1',
122120
PROP_CACHE_MODE: CacheMode.PARTITIONED,
123121
})
@@ -126,7 +124,7 @@ def test_affinity(client_partition_aware, key, key_hint):
126124

127125
best_node = cache_1.get_best_node(key, key_hint=key_hint)
128126

129-
for node in filter(lambda n: n.alive, client_partition_aware._nodes):
127+
for node in filter(lambda n: n.alive, client._nodes):
130128
result = cache_local_peek(
131129
node, cache_1.cache_id, key, key_hint=key_hint,
132130
)
@@ -142,9 +140,8 @@ def test_affinity(client_partition_aware, key, key_hint):
142140
cache_1.destroy()
143141

144142

145-
def test_affinity_for_generic_object(client_partition_aware):
146-
147-
cache_1 = client_partition_aware.get_or_create_cache({
143+
def test_affinity_for_generic_object(client):
144+
cache_1 = client.get_or_create_cache({
148145
PROP_NAME: 'test_cache_1',
149146
PROP_CACHE_MODE: CacheMode.PARTITIONED,
150147
})
@@ -166,7 +163,7 @@ class KeyClass(
166163

167164
best_node = cache_1.get_best_node(key, key_hint=BinaryObject)
168165

169-
for node in filter(lambda n: n.alive, client_partition_aware._nodes):
166+
for node in filter(lambda n: n.alive, client._nodes):
170167
result = cache_local_peek(
171168
node, cache_1.cache_id, key, key_hint=BinaryObject,
172169
)
@@ -182,16 +179,8 @@ class KeyClass(
182179
cache_1.destroy()
183180

184181

185-
def test_affinity_for_generic_object_without_type_hints(client_partition_aware):
186-
187-
if not client_partition_aware.partition_awareness_supported_by_protocol:
188-
pytest.skip(
189-
'Best effort affinity is not supported by the protocol {}.'.format(
190-
client_partition_aware.protocol_version
191-
)
192-
)
193-
194-
cache_1 = client_partition_aware.get_or_create_cache({
182+
def test_affinity_for_generic_object_without_type_hints(client):
183+
cache_1 = client.get_or_create_cache({
195184
PROP_NAME: 'test_cache_1',
196185
PROP_CACHE_MODE: CacheMode.PARTITIONED,
197186
})
@@ -213,7 +202,7 @@ class KeyClass(
213202

214203
best_node = cache_1.get_best_node(key)
215204

216-
for node in filter(lambda n: n.alive, client_partition_aware._nodes):
205+
for node in filter(lambda n: n.alive, client._nodes):
217206
result = cache_local_peek(
218207
node, cache_1.cache_id, key
219208
)

tests/test_affinity_bad_servers.py renamed to tests/affinity/test_affinity_bad_servers.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,20 @@
1616
import pytest
1717

1818
from pygridgain.exceptions import ReconnectError
19-
from tests.util import *
19+
from tests.util import start_ignite, kill_process_tree
2020

2121

22-
def test_client_with_multiple_bad_servers(start_client):
23-
client = start_client(partition_aware=True)
22+
def test_client_with_multiple_bad_servers(client_not_connected):
2423
with pytest.raises(ReconnectError) as e_info:
25-
client.connect([("127.0.0.1", 10900), ("127.0.0.1", 10901)])
24+
client_not_connected.connect([("127.0.0.1", 10900), ("127.0.0.1", 10901)])
2625
assert str(e_info.value) == "Can not connect."
2726

2827

29-
def test_client_with_failed_server(request, start_ignite_server, start_client):
30-
srv = start_ignite_server(4)
28+
def test_client_with_failed_server(request, client_not_connected):
29+
srv = start_ignite(idx=4)
3130
try:
32-
client = start_client()
33-
client.connect([("127.0.0.1", 10804)])
34-
cache = client.get_or_create_cache(request.node.name)
31+
client_not_connected.connect([("127.0.0.1", 10804)])
32+
cache = client_not_connected.get_or_create_cache(request.node.name)
3533
cache.put(1, 1)
3634
kill_process_tree(srv.pid)
3735
with pytest.raises(ConnectionResetError):
@@ -40,17 +38,16 @@ def test_client_with_failed_server(request, start_ignite_server, start_client):
4038
kill_process_tree(srv.pid)
4139

4240

43-
def test_client_with_recovered_server(request, start_ignite_server, start_client):
44-
srv = start_ignite_server(4)
41+
def test_client_with_recovered_server(request, client_not_connected):
42+
srv = start_ignite(idx=4)
4543
try:
46-
client = start_client()
47-
client.connect([("127.0.0.1", 10804)])
48-
cache = client.get_or_create_cache(request.node.name)
44+
client_not_connected.connect([("127.0.0.1", 10804)])
45+
cache = client_not_connected.get_or_create_cache(request.node.name)
4946
cache.put(1, 1)
5047

5148
# Kill and restart server
5249
kill_process_tree(srv.pid)
53-
srv = start_ignite_server(4)
50+
srv = start_ignite(idx=4)
5451

5552
# First request fails
5653
with pytest.raises(Exception):

tests/test_affinity_request_routing.py renamed to tests/affinity/test_affinity_request_routing.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ def check_grid_idx():
7070

7171
@pytest.mark.parametrize("key,grid_idx", [(1, 1), (2, 2), (3, 3), (4, 1), (5, 1), (6, 2), (11, 1), (13, 1), (19, 1)])
7272
@pytest.mark.parametrize("backups", [0, 1, 2, 3])
73-
def test_cache_operation_on_primitive_key_routes_request_to_primary_node(
74-
request, key, grid_idx, backups, client_partition_aware):
75-
76-
cache = client_partition_aware.get_or_create_cache({
73+
def test_cache_operation_on_primitive_key_routes_request_to_primary_node(request, key, grid_idx, backups, client):
74+
cache = client.get_or_create_cache({
7775
PROP_NAME: request.node.name + str(backups),
7876
PROP_BACKUPS_NUMBER: backups,
7977
})
@@ -132,8 +130,7 @@ def test_cache_operation_on_complex_key_routes_request_to_primary_node():
132130

133131
@pytest.mark.parametrize("key,grid_idx", [(1, 2), (2, 1), (3, 1), (4, 2), (5, 2), (6, 3)])
134132
@pytest.mark.skip(reason="GG-25823: Custom key objects are not supported yet")
135-
def test_cache_operation_on_custom_affinity_key_routes_request_to_primary_node(
136-
request, client_partition_aware, key, grid_idx):
133+
def test_cache_operation_on_custom_affinity_key_routes_request_to_primary_node(request, client, key, grid_idx):
137134
class AffinityTestType1(
138135
metaclass=GenericObjectMeta,
139136
type_name='AffinityTestType1',
@@ -153,7 +150,7 @@ class AffinityTestType1(
153150
},
154151
],
155152
}
156-
cache = client_partition_aware.create_cache(cache_config)
153+
cache = client.create_cache(cache_config)
157154

158155
# noinspection PyArgumentList
159156
key_obj = AffinityTestType1(
@@ -167,17 +164,18 @@ class AffinityTestType1(
167164
assert requests.pop() == grid_idx
168165

169166

170-
def test_cache_operation_routed_to_new_cluster_node(request, start_ignite_server, start_client):
171-
client = start_client(partition_aware=True)
172-
client.connect([("127.0.0.1", 10801), ("127.0.0.1", 10802), ("127.0.0.1", 10803), ("127.0.0.1", 10804)])
173-
cache = client.get_or_create_cache(request.node.name)
167+
def test_cache_operation_routed_to_new_cluster_node(request, client_not_connected):
168+
client_not_connected.connect(
169+
[("127.0.0.1", 10801), ("127.0.0.1", 10802), ("127.0.0.1", 10803), ("127.0.0.1", 10804)]
170+
)
171+
cache = client_not_connected.get_or_create_cache(request.node.name)
174172
key = 12
175173
wait_for_affinity_distribution(cache, key, 3)
176174
cache.put(key, key)
177175
cache.put(key, key)
178176
assert requests.pop() == 3
179177

180-
srv = start_ignite_server(4)
178+
srv = start_ignite(idx=4)
181179
try:
182180
# Wait for rebalance and partition map exchange
183181
wait_for_affinity_distribution(cache, key, 4)
@@ -190,8 +188,8 @@ def test_cache_operation_routed_to_new_cluster_node(request, start_ignite_server
190188
kill_process_tree(srv.pid)
191189

192190

193-
def test_replicated_cache_operation_routed_to_random_node(request, client_partition_aware):
194-
cache = client_partition_aware.get_or_create_cache({
191+
def test_replicated_cache_operation_routed_to_random_node(request, client):
192+
cache = client.get_or_create_cache({
195193
PROP_NAME: request.node.name,
196194
PROP_CACHE_MODE: CacheMode.REPLICATED,
197195
})

0 commit comments

Comments
 (0)