1
# Copyright 2012 10gen, Inc.
3
# Licensed under the Apache License, Version 2.0 (the "License"); you
4
# may not use this file except in compliance with the License. You
5
# may obtain a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
# implied. See the License for the specific language governing
13
# permissions and limitations under the License.
15
"""Tests for connection-pooling with greenlets and Gevent"""
19
from nose.plugins.skip import SkipTest
21
from pymongo import pool
22
from test.test_connection import host, port
23
from test.test_pooling_base import (
24
_TestPooling, _TestMaxPoolSize, _TestPoolSocketSharing)
27
def looplet(greenlets):
28
"""World's smallest event loop; run until all greenlets are done
42
class TestPoolingGevent(_TestPooling, unittest.TestCase):
43
"""Apply all the standard pool tests to GreenletPool with Gevent"""
47
class TestPoolingGeventSpecial(unittest.TestCase):
48
"""Do a few special GreenletPool tests that don't use TestPoolingBase"""
49
def test_greenlet_sockets(self):
50
# Check that Pool gives two sockets to two greenlets
54
raise SkipTest('greenlet not installed')
56
cx_pool = pool.GreenletPool(
67
cx_pool.start_request()
68
socks.append(cx_pool.get_socket())
71
greenlet.greenlet(get_socket),
72
greenlet.greenlet(get_socket),
75
self.assertEqual(2, len(socks))
76
self.assertNotEqual(socks[0], socks[1])
78
def test_greenlet_sockets_with_request(self):
79
# Verify two assumptions: that start_request() with two greenlets and
80
# the regular pool will fail, meaning that the two greenlets will
81
# share one socket. Also check that start_request() with GreenletPool
82
# succeeds, meaning that two greenlets will get different sockets (this
83
# is exactly the reason for creating GreenletPool).
88
raise SkipTest('greenlet not installed')
98
for pool_class, use_request, expect_success in [
99
(pool.GreenletPool, True, True),
100
(pool.GreenletPool, False, False),
101
(pool.Pool, True, False),
102
(pool.Pool, False, False),
104
cx_pool = pool_class(**pool_args)
106
# Map: greenlet -> socket
108
main = greenlet.getcurrent()
110
def get_socket_in_request():
111
# Get a socket from the pool twice, switching contexts each time
113
cx_pool.start_request()
118
sock = cx_pool.get_socket()
119
cx_pool.return_socket(sock)
120
greenlet2socks.setdefault(
121
greenlet.getcurrent(), []
126
cx_pool.end_request()
129
greenlet.greenlet(get_socket_in_request),
130
greenlet.greenlet(get_socket_in_request),
133
# Run both greenlets to completion
136
socks_for_gr0 = greenlet2socks[greenlets[0]]
137
socks_for_gr1 = greenlet2socks[greenlets[1]]
139
# Whether we expect requests to work or not, we definitely expect
140
# greenlet2socks to have the same number of keys and values
141
self.assertEqual(2, len(greenlet2socks))
142
self.assertEqual(2, len(socks_for_gr0))
143
self.assertEqual(2, len(socks_for_gr1))
145
# If we started a request, then there was a point at which we had
146
# 2 active sockets, otherwise we always used one.
147
if use_request and pool_class is pool.GreenletPool:
148
self.assertEqual(2, len(cx_pool.sockets))
150
self.assertEqual(1, len(cx_pool.sockets))
152
# Again, regardless of whether requests work, a greenlet will get
153
# the same socket each time it calls get_socket() within a request.
154
# What we're really testing is that the two *different* greenlets
155
# get *different* sockets from each other.
157
socks_for_gr0[0], socks_for_gr0[1],
158
"Expected greenlet 0 to get the same socket for each call "
163
socks_for_gr1[0], socks_for_gr1[1],
164
"Expected greenlet 1 to get the same socket for each call "
169
# We used the proper pool class, so start_request successfully
170
# distinguished between the two greenlets.
172
socks_for_gr0[0], socks_for_gr1[0],
173
"Expected two greenlets to get two different sockets"
177
# We used the wrong pool class, so start_request didn't
178
# distinguish between the two greenlets, and it gave them both
181
socks_for_gr0[0], socks_for_gr1[0],
182
"Expected two greenlets to get same socket"
186
class TestMaxPoolSizeGevent(_TestMaxPoolSize, unittest.TestCase):
190
class TestPoolSocketSharingGevent(_TestPoolSocketSharing, unittest.TestCase):
194
if __name__ == '__main__':