forked from mongodb/mongo-python-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_pooling_gevent.py
More file actions
182 lines (144 loc) · 6.15 KB
/
test_pooling_gevent.py
File metadata and controls
182 lines (144 loc) · 6.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# Copyright 2012 10gen, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you
# may not use this file except in compliance with the License. You
# may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
"""Tests for connection-pooling with greenlets and Gevent"""
import unittest
from nose.plugins.skip import SkipTest
from pymongo import pool
from test.utils import looplet
from test.test_connection import host, port
from test.test_pooling_base import (
_TestPooling, _TestMaxPoolSize, _TestPoolSocketSharing)
class TestPoolingGevent(_TestPooling, unittest.TestCase):
"""Apply all the standard pool tests with greenlets and Gevent"""
use_greenlets = True
class TestPoolingGeventSpecial(unittest.TestCase):
"""Do a few special greenlet tests that don't use TestPoolingBase"""
def test_greenlet_sockets(self):
# Check that Pool gives two sockets to two greenlets
try:
import greenlet
except ImportError:
raise SkipTest('greenlet not installed')
cx_pool = pool.Pool(
pair=(host,port),
max_size=10,
net_timeout=1000,
conn_timeout=1000,
use_ssl=False,
use_greenlets=True)
socks = []
def get_socket():
cx_pool.start_request()
socks.append(cx_pool.get_socket())
looplet([
greenlet.greenlet(get_socket),
greenlet.greenlet(get_socket),
])
self.assertEqual(2, len(socks))
self.assertNotEqual(socks[0], socks[1])
def test_greenlet_sockets_with_request(self):
# Verify two assumptions: that start_request() with two greenlets but
# not use_greenlets fails, meaning that the two greenlets will
# share one socket. Also check that start_request() with use_greenlets
# succeeds, meaning that two greenlets will get different sockets.
try:
import greenlet
except ImportError:
raise SkipTest('greenlet not installed')
pool_args = dict(
pair=(host,port),
max_size=10,
net_timeout=1000,
conn_timeout=1000,
use_ssl=False,
)
for use_greenlets, use_request, expect_success in [
(True, True, True),
(True, False, False),
(False, True, False),
(False, False, False),
]:
pool_args_cp = pool_args.copy()
pool_args_cp['use_greenlets'] = use_greenlets
cx_pool = pool.Pool(**pool_args_cp)
# Map: greenlet -> socket
greenlet2socks = {}
main = greenlet.getcurrent()
def get_socket_in_request():
# Get a socket from the pool twice, switching contexts each time
if use_request:
cx_pool.start_request()
main.switch()
for _ in range(2):
sock = cx_pool.get_socket()
cx_pool.maybe_return_socket(sock)
greenlet2socks.setdefault(
greenlet.getcurrent(), []
).append(id(sock))
main.switch()
cx_pool.end_request()
greenlets = [
greenlet.greenlet(get_socket_in_request),
greenlet.greenlet(get_socket_in_request),
]
# Run both greenlets to completion
looplet(greenlets)
socks_for_gr0 = greenlet2socks[greenlets[0]]
socks_for_gr1 = greenlet2socks[greenlets[1]]
# Whether we expect requests to work or not, we definitely expect
# greenlet2socks to have the same number of keys and values
self.assertEqual(2, len(greenlet2socks))
self.assertEqual(2, len(socks_for_gr0))
self.assertEqual(2, len(socks_for_gr1))
# If we started a request, then there was a point at which we had
# 2 active sockets, otherwise we always used one.
if use_request and use_greenlets:
self.assertEqual(2, len(cx_pool.sockets))
else:
self.assertEqual(1, len(cx_pool.sockets))
# Again, regardless of whether requests work, a greenlet will get
# the same socket each time it calls get_socket() within a request.
# What we're really testing is that the two *different* greenlets
# get *different* sockets from each other.
self.assertEqual(
socks_for_gr0[0], socks_for_gr0[1],
"Expected greenlet 0 to get the same socket for each call "
"to get_socket()"
)
self.assertEqual(
socks_for_gr1[0], socks_for_gr1[1],
"Expected greenlet 1 to get the same socket for each call "
"to get_socket()"
)
if expect_success:
# We passed use_greenlets=True, so start_request successfully
# distinguished between the two greenlets.
self.assertNotEqual(
socks_for_gr0[0], socks_for_gr1[0],
"Expected two greenlets to get two different sockets"
)
else:
# We passed use_greenlets=False, so start_request didn't
# distinguish between the two greenlets, and it gave them both
# the same socket.
self.assertEqual(
socks_for_gr0[0], socks_for_gr1[0],
"Expected two greenlets to get same socket"
)
class TestMaxPoolSizeGevent(_TestMaxPoolSize, unittest.TestCase):
use_greenlets = True
class TestPoolSocketSharingGevent(_TestPoolSocketSharing, unittest.TestCase):
use_greenlets = True
if __name__ == '__main__':
unittest.main()