1 # Copyright (c) 2001-2006 Twisted Matrix Laboratories.
3 # Permission is hereby granted, free of charge, to any person obtaining
4 # a copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish,
7 # distribute, sublicense, and/or sell copies of the Software, and to
8 # permit persons to whom the Software is furnished to do so, subject to
9 # the following conditions:
11 # The above copyright notice and this permission notice shall be
12 # included in all copies or substantial portions of the Software.
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Tests for epoll wrapper.
32 from test
import test_support
33 if not hasattr(select
, "epoll"):
34 raise unittest
.SkipTest("test works only on Linux 2.6")
39 if e
.errno
== errno
.ENOSYS
:
40 raise unittest
.SkipTest("kernel doesn't support epoll()")
42 class TestEPoll(unittest
.TestCase
):
45 self
.serverSocket
= socket
.socket()
46 self
.serverSocket
.bind(('127.0.0.1', 0))
47 self
.serverSocket
.listen(1)
48 self
.connections
= [self
.serverSocket
]
52 for skt
in self
.connections
:
55 def _connected_pair(self
):
56 client
= socket
.socket()
57 client
.setblocking(False)
59 client
.connect(('127.0.0.1', self
.serverSocket
.getsockname()[1]))
60 except socket
.error
, e
:
61 self
.assertEquals(e
.args
[0], errno
.EINPROGRESS
)
63 raise AssertionError("Connect should have raised EINPROGRESS")
64 server
, addr
= self
.serverSocket
.accept()
66 self
.connections
.extend((client
, server
))
69 def test_create(self
):
73 raise AssertionError(str(e
))
74 self
.assertTrue(ep
.fileno() > 0, ep
.fileno())
75 self
.assertTrue(not ep
.closed
)
77 self
.assertTrue(ep
.closed
)
78 self
.assertRaises(ValueError, ep
.fileno
)
80 def test_badcreate(self
):
81 self
.assertRaises(TypeError, select
.epoll
, 1, 2, 3)
82 self
.assertRaises(TypeError, select
.epoll
, 'foo')
83 self
.assertRaises(TypeError, select
.epoll
, None)
84 self
.assertRaises(TypeError, select
.epoll
, ())
85 self
.assertRaises(TypeError, select
.epoll
, ['foo'])
86 self
.assertRaises(TypeError, select
.epoll
, {})
89 server
, client
= self
._connected
_pair
()
93 ep
.register(server
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
)
94 ep
.register(client
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
)
98 # adding by object w/ fileno works, too.
101 ep
.register(server
, select
.EPOLLIN | select
.EPOLLOUT
)
102 ep
.register(client
, select
.EPOLLIN | select
.EPOLLOUT
)
108 # TypeError: argument must be an int, or have a fileno() method.
109 self
.assertRaises(TypeError, ep
.register
, object(),
110 select
.EPOLLIN | select
.EPOLLOUT
)
111 self
.assertRaises(TypeError, ep
.register
, None,
112 select
.EPOLLIN | select
.EPOLLOUT
)
113 # ValueError: file descriptor cannot be a negative integer (-1)
114 self
.assertRaises(ValueError, ep
.register
, -1,
115 select
.EPOLLIN | select
.EPOLLOUT
)
116 # IOError: [Errno 9] Bad file descriptor
117 self
.assertRaises(IOError, ep
.register
, 10000,
118 select
.EPOLLIN | select
.EPOLLOUT
)
119 # registering twice also raises an exception
120 ep
.register(server
, select
.EPOLLIN | select
.EPOLLOUT
)
121 self
.assertRaises(IOError, ep
.register
, server
,
122 select
.EPOLLIN | select
.EPOLLOUT
)
126 def test_fromfd(self
):
127 server
, client
= self
._connected
_pair
()
130 ep2
= select
.epoll
.fromfd(ep
.fileno())
132 ep2
.register(server
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
)
133 ep2
.register(client
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
)
135 events
= ep
.poll(1, 4)
136 events2
= ep2
.poll(0.9, 4)
137 self
.assertEqual(len(events
), 2)
138 self
.assertEqual(len(events2
), 2)
144 self
.assertEqual(e
.args
[0], errno
.EBADF
, e
)
146 self
.fail("epoll on closed fd didn't raise EBADF")
148 def test_control_and_wait(self
):
149 client
, server
= self
._connected
_pair
()
151 ep
= select
.epoll(16)
152 ep
.register(server
.fileno(),
153 select
.EPOLLIN | select
.EPOLLOUT | select
.EPOLLET
)
154 ep
.register(client
.fileno(),
155 select
.EPOLLIN | select
.EPOLLOUT | select
.EPOLLET
)
158 events
= ep
.poll(1, 4)
160 self
.assertFalse(then
- now
> 0.1, then
- now
)
163 expected
= [(client
.fileno(), select
.EPOLLOUT
),
164 (server
.fileno(), select
.EPOLLOUT
)]
167 self
.assertEquals(events
, expected
)
168 self
.assertFalse(then
- now
> 0.01, then
- now
)
171 events
= ep
.poll(timeout
=2.1, maxevents
=4)
173 self
.assertFalse(events
)
175 client
.send("Hello!")
176 server
.send("world!!!")
179 events
= ep
.poll(1, 4)
181 self
.assertFalse(then
- now
> 0.01)
184 expected
= [(client
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
),
185 (server
.fileno(), select
.EPOLLIN | select
.EPOLLOUT
)]
188 self
.assertEquals(events
, expected
)
190 ep
.unregister(client
.fileno())
191 ep
.modify(server
.fileno(), select
.EPOLLOUT
)
193 events
= ep
.poll(1, 4)
195 self
.assertFalse(then
- now
> 0.01)
197 expected
= [(server
.fileno(), select
.EPOLLOUT
)]
198 self
.assertEquals(events
, expected
)
200 def test_errors(self
):
201 self
.assertRaises(ValueError, select
.epoll
, -2)
202 self
.assertRaises(ValueError, select
.epoll().register
, -1,
205 def test_unregister_closed(self
):
206 server
, client
= self
._connected
_pair
()
208 ep
= select
.epoll(16)
212 events
= ep
.poll(1, 4)
214 self
.assertFalse(then
- now
> 0.01)
220 test_support
.run_unittest(TestEPoll
)
222 if __name__
== "__main__":