root / test / py / ganeti.daemon_unittest.py @ 22b7f6f8
History | View | Annotate | Download (24.3 kB)
1 | 1118ec44 | Guido Trotter | #!/usr/bin/python
|
---|---|---|---|
2 | 1118ec44 | Guido Trotter | #
|
3 | 1118ec44 | Guido Trotter | |
4 | 1118ec44 | Guido Trotter | # Copyright (C) 2010 Google Inc.
|
5 | 1118ec44 | Guido Trotter | #
|
6 | 1118ec44 | Guido Trotter | # This program is free software; you can redistribute it and/or modify
|
7 | 1118ec44 | Guido Trotter | # it under the terms of the GNU General Public License as published by
|
8 | 1118ec44 | Guido Trotter | # the Free Software Foundation; either version 2 of the License, or
|
9 | 1118ec44 | Guido Trotter | # (at your option) any later version.
|
10 | 1118ec44 | Guido Trotter | #
|
11 | 1118ec44 | Guido Trotter | # This program is distributed in the hope that it will be useful, but
|
12 | 1118ec44 | Guido Trotter | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 1118ec44 | Guido Trotter | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 1118ec44 | Guido Trotter | # General Public License for more details.
|
15 | 1118ec44 | Guido Trotter | #
|
16 | 1118ec44 | Guido Trotter | # You should have received a copy of the GNU General Public License
|
17 | 1118ec44 | Guido Trotter | # along with this program; if not, write to the Free Software
|
18 | 1118ec44 | Guido Trotter | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 1118ec44 | Guido Trotter | # 02110-1301, USA.
|
20 | 1118ec44 | Guido Trotter | |
21 | 1118ec44 | Guido Trotter | |
22 | 1118ec44 | Guido Trotter | """Script for unittesting the daemon module"""
|
23 | 1118ec44 | Guido Trotter | |
24 | 1118ec44 | Guido Trotter | import unittest |
25 | 1118ec44 | Guido Trotter | import signal |
26 | 1118ec44 | Guido Trotter | import os |
27 | 4db33137 | Guido Trotter | import socket |
28 | 19ad29d2 | Guido Trotter | import time |
29 | 18215385 | Guido Trotter | import tempfile |
30 | 18215385 | Guido Trotter | import shutil |
31 | 1118ec44 | Guido Trotter | |
32 | 1118ec44 | Guido Trotter | from ganeti import daemon |
33 | e3cc4c69 | Guido Trotter | from ganeti import errors |
34 | e9de7da4 | Guido Trotter | from ganeti import constants |
35 | 6e7e58b4 | Guido Trotter | from ganeti import utils |
36 | 1118ec44 | Guido Trotter | |
37 | 1118ec44 | Guido Trotter | import testutils |
38 | 1118ec44 | Guido Trotter | |
39 | 1118ec44 | Guido Trotter | |
40 | 1118ec44 | Guido Trotter | class TestMainloop(testutils.GanetiTestCase): |
41 | 1118ec44 | Guido Trotter | """Test daemon.Mainloop"""
|
42 | 1118ec44 | Guido Trotter | |
43 | 1118ec44 | Guido Trotter | def setUp(self): |
44 | 1118ec44 | Guido Trotter | testutils.GanetiTestCase.setUp(self)
|
45 | 1118ec44 | Guido Trotter | self.mainloop = daemon.Mainloop()
|
46 | 1118ec44 | Guido Trotter | self.sendsig_events = []
|
47 | 1118ec44 | Guido Trotter | self.onsignal_events = []
|
48 | 1118ec44 | Guido Trotter | |
49 | 1118ec44 | Guido Trotter | def _CancelEvent(self, handle): |
50 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.cancel(handle)
|
51 | 1118ec44 | Guido Trotter | |
52 | 1118ec44 | Guido Trotter | def _SendSig(self, sig): |
53 | 1118ec44 | Guido Trotter | self.sendsig_events.append(sig)
|
54 | 1118ec44 | Guido Trotter | os.kill(os.getpid(), sig) |
55 | 1118ec44 | Guido Trotter | |
56 | 1118ec44 | Guido Trotter | def OnSignal(self, signum): |
57 | 1118ec44 | Guido Trotter | self.onsignal_events.append(signum)
|
58 | 1118ec44 | Guido Trotter | |
59 | 1118ec44 | Guido Trotter | def testRunAndTermBySched(self): |
60 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM]) |
61 | 1118ec44 | Guido Trotter | self.mainloop.Run() # terminates by _SendSig being scheduled |
62 | 1118ec44 | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGTERM]) |
63 | 1118ec44 | Guido Trotter | |
64 | f59dce3e | Guido Trotter | def testTerminatingSignals(self): |
65 | f59dce3e | Guido Trotter | self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD]) |
66 | f59dce3e | Guido Trotter | self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGINT]) |
67 | f59dce3e | Guido Trotter | self.mainloop.Run()
|
68 | f59dce3e | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT]) |
69 | f59dce3e | Guido Trotter | self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM]) |
70 | f59dce3e | Guido Trotter | self.mainloop.Run()
|
71 | f59dce3e | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT, |
72 | f59dce3e | Guido Trotter | signal.SIGTERM]) |
73 | f59dce3e | Guido Trotter | |
74 | 1118ec44 | Guido Trotter | def testSchedulerCancel(self): |
75 | 1118ec44 | Guido Trotter | handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig, |
76 | 1118ec44 | Guido Trotter | [signal.SIGTERM]) |
77 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.cancel(handle)
|
78 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD]) |
79 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM]) |
80 | 1118ec44 | Guido Trotter | self.mainloop.Run()
|
81 | 1118ec44 | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM]) |
82 | 1118ec44 | Guido Trotter | |
83 | 1118ec44 | Guido Trotter | def testRegisterSignal(self): |
84 | 1118ec44 | Guido Trotter | self.mainloop.RegisterSignal(self) |
85 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD]) |
86 | 1118ec44 | Guido Trotter | handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig, |
87 | 1118ec44 | Guido Trotter | [signal.SIGTERM]) |
88 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.cancel(handle)
|
89 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD]) |
90 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM]) |
91 | 1118ec44 | Guido Trotter | # ...not delievered because they are scheduled after TERM
|
92 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD]) |
93 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD]) |
94 | 1118ec44 | Guido Trotter | self.mainloop.Run()
|
95 | 1118ec44 | Guido Trotter | self.assertEquals(self.sendsig_events, |
96 | 1118ec44 | Guido Trotter | [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM]) |
97 | 1118ec44 | Guido Trotter | self.assertEquals(self.onsignal_events, self.sendsig_events) |
98 | 1118ec44 | Guido Trotter | |
99 | 1118ec44 | Guido Trotter | def testDeferredCancel(self): |
100 | 1118ec44 | Guido Trotter | self.mainloop.RegisterSignal(self) |
101 | 19ad29d2 | Guido Trotter | now = time.time() |
102 | 19ad29d2 | Guido Trotter | self.mainloop.scheduler.enterabs(now + 0.1, 1, self._SendSig, |
103 | 19ad29d2 | Guido Trotter | [signal.SIGCHLD]) |
104 | 19ad29d2 | Guido Trotter | handle1 = self.mainloop.scheduler.enterabs(now + 0.3, 2, self._SendSig, |
105 | 19ad29d2 | Guido Trotter | [signal.SIGCHLD]) |
106 | 19ad29d2 | Guido Trotter | handle2 = self.mainloop.scheduler.enterabs(now + 0.4, 2, self._SendSig, |
107 | 19ad29d2 | Guido Trotter | [signal.SIGCHLD]) |
108 | 19ad29d2 | Guido Trotter | self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent, |
109 | 19ad29d2 | Guido Trotter | [handle1]) |
110 | 19ad29d2 | Guido Trotter | self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent, |
111 | 19ad29d2 | Guido Trotter | [handle2]) |
112 | 1118ec44 | Guido Trotter | self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGTERM]) |
113 | 1118ec44 | Guido Trotter | self.mainloop.Run()
|
114 | 1118ec44 | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM]) |
115 | 1118ec44 | Guido Trotter | self.assertEquals(self.onsignal_events, self.sendsig_events) |
116 | 1118ec44 | Guido Trotter | |
117 | c6987b16 | Guido Trotter | def testReRun(self): |
118 | c6987b16 | Guido Trotter | self.mainloop.RegisterSignal(self) |
119 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD]) |
120 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD]) |
121 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM]) |
122 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD]) |
123 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD]) |
124 | c6987b16 | Guido Trotter | self.mainloop.Run()
|
125 | c6987b16 | Guido Trotter | self.assertEquals(self.sendsig_events, |
126 | c6987b16 | Guido Trotter | [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM]) |
127 | c6987b16 | Guido Trotter | self.assertEquals(self.onsignal_events, self.sendsig_events) |
128 | c6987b16 | Guido Trotter | self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM]) |
129 | c6987b16 | Guido Trotter | self.mainloop.Run()
|
130 | c6987b16 | Guido Trotter | self.assertEquals(self.sendsig_events, |
131 | c6987b16 | Guido Trotter | [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM, |
132 | c6987b16 | Guido Trotter | signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM]) |
133 | c6987b16 | Guido Trotter | self.assertEquals(self.onsignal_events, self.sendsig_events) |
134 | c6987b16 | Guido Trotter | |
135 | 85dbfd78 | Guido Trotter | def testPriority(self): |
136 | 85dbfd78 | Guido Trotter | # for events at the same time, the highest priority one executes first
|
137 | 85dbfd78 | Guido Trotter | now = time.time() |
138 | 85dbfd78 | Guido Trotter | self.mainloop.scheduler.enterabs(now + 0.1, 2, self._SendSig, |
139 | 85dbfd78 | Guido Trotter | [signal.SIGCHLD]) |
140 | 85dbfd78 | Guido Trotter | self.mainloop.scheduler.enterabs(now + 0.1, 1, self._SendSig, |
141 | 85dbfd78 | Guido Trotter | [signal.SIGTERM]) |
142 | 85dbfd78 | Guido Trotter | self.mainloop.Run()
|
143 | 85dbfd78 | Guido Trotter | self.assertEquals(self.sendsig_events, [signal.SIGTERM]) |
144 | 85dbfd78 | Guido Trotter | self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGTERM]) |
145 | 85dbfd78 | Guido Trotter | self.mainloop.Run()
|
146 | 85dbfd78 | Guido Trotter | self.assertEquals(self.sendsig_events, |
147 | 85dbfd78 | Guido Trotter | [signal.SIGTERM, signal.SIGCHLD, signal.SIGTERM]) |
148 | 85dbfd78 | Guido Trotter | |
149 | 1118ec44 | Guido Trotter | |
150 | 4db33137 | Guido Trotter | class _MyAsyncUDPSocket(daemon.AsyncUDPSocket): |
151 | 4db33137 | Guido Trotter | |
152 | d8bcfe21 | Manuel Franceschini | def __init__(self, family): |
153 | d8bcfe21 | Manuel Franceschini | daemon.AsyncUDPSocket.__init__(self, family)
|
154 | 4db33137 | Guido Trotter | self.received = []
|
155 | 4db33137 | Guido Trotter | self.error_count = 0 |
156 | 4db33137 | Guido Trotter | |
157 | 4db33137 | Guido Trotter | def handle_datagram(self, payload, ip, port): |
158 | 4db33137 | Guido Trotter | self.received.append((payload))
|
159 | 4db33137 | Guido Trotter | if payload == "terminate": |
160 | 4db33137 | Guido Trotter | os.kill(os.getpid(), signal.SIGTERM) |
161 | 4db33137 | Guido Trotter | elif payload == "error": |
162 | 4db33137 | Guido Trotter | raise errors.GenericError("error") |
163 | 4db33137 | Guido Trotter | |
164 | 4db33137 | Guido Trotter | def handle_error(self): |
165 | 4db33137 | Guido Trotter | self.error_count += 1 |
166 | e3cc4c69 | Guido Trotter | raise
|
167 | 4db33137 | Guido Trotter | |
168 | 4db33137 | Guido Trotter | |
169 | d8bcfe21 | Manuel Franceschini | class _BaseAsyncUDPSocketTest: |
170 | d8bcfe21 | Manuel Franceschini | """Base class for AsyncUDPSocket tests"""
|
171 | d8bcfe21 | Manuel Franceschini | |
172 | d8bcfe21 | Manuel Franceschini | family = None
|
173 | d8bcfe21 | Manuel Franceschini | address = None
|
174 | 4db33137 | Guido Trotter | |
175 | 4db33137 | Guido Trotter | def setUp(self): |
176 | 4db33137 | Guido Trotter | self.mainloop = daemon.Mainloop()
|
177 | d8bcfe21 | Manuel Franceschini | self.server = _MyAsyncUDPSocket(self.family) |
178 | d8bcfe21 | Manuel Franceschini | self.client = _MyAsyncUDPSocket(self.family) |
179 | d8bcfe21 | Manuel Franceschini | self.server.bind((self.address, 0)) |
180 | 4db33137 | Guido Trotter | self.port = self.server.getsockname()[1] |
181 | 6e7e58b4 | Guido Trotter | # Save utils.IgnoreSignals so we can do evil things to it...
|
182 | 6e7e58b4 | Guido Trotter | self.saved_utils_ignoresignals = utils.IgnoreSignals
|
183 | 4db33137 | Guido Trotter | |
184 | 4db33137 | Guido Trotter | def tearDown(self): |
185 | 4db33137 | Guido Trotter | self.server.close()
|
186 | 4db33137 | Guido Trotter | self.client.close()
|
187 | 6e7e58b4 | Guido Trotter | # ...and restore it as well
|
188 | 6e7e58b4 | Guido Trotter | utils.IgnoreSignals = self.saved_utils_ignoresignals
|
189 | 4db33137 | Guido Trotter | testutils.GanetiTestCase.tearDown(self)
|
190 | 4db33137 | Guido Trotter | |
191 | 4db33137 | Guido Trotter | def testNoDoubleBind(self): |
192 | d8bcfe21 | Manuel Franceschini | self.assertRaises(socket.error, self.client.bind, (self.address, self.port)) |
193 | 4db33137 | Guido Trotter | |
194 | 4db33137 | Guido Trotter | def testAsyncClientServer(self): |
195 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p1") |
196 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p2") |
197 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "terminate") |
198 | 4db33137 | Guido Trotter | self.mainloop.Run()
|
199 | 4db33137 | Guido Trotter | self.assertEquals(self.server.received, ["p1", "p2", "terminate"]) |
200 | 4db33137 | Guido Trotter | |
201 | 4db33137 | Guido Trotter | def testSyncClientServer(self): |
202 | 95ab227e | Guido Trotter | self.client.handle_write()
|
203 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p1") |
204 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p2") |
205 | 4db33137 | Guido Trotter | while self.client.writable(): |
206 | 4db33137 | Guido Trotter | self.client.handle_write()
|
207 | 4db33137 | Guido Trotter | self.server.process_next_packet()
|
208 | 4db33137 | Guido Trotter | self.assertEquals(self.server.received, ["p1"]) |
209 | 4db33137 | Guido Trotter | self.server.process_next_packet()
|
210 | 4db33137 | Guido Trotter | self.assertEquals(self.server.received, ["p1", "p2"]) |
211 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p3") |
212 | 4db33137 | Guido Trotter | while self.client.writable(): |
213 | 4db33137 | Guido Trotter | self.client.handle_write()
|
214 | 4db33137 | Guido Trotter | self.server.process_next_packet()
|
215 | 4db33137 | Guido Trotter | self.assertEquals(self.server.received, ["p1", "p2", "p3"]) |
216 | 4db33137 | Guido Trotter | |
217 | 4db33137 | Guido Trotter | def testErrorHandling(self): |
218 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p1") |
219 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p2") |
220 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "error") |
221 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p3") |
222 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "error") |
223 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "terminate") |
224 | e3cc4c69 | Guido Trotter | self.assertRaises(errors.GenericError, self.mainloop.Run) |
225 | e3cc4c69 | Guido Trotter | self.assertEquals(self.server.received, |
226 | e3cc4c69 | Guido Trotter | ["p1", "p2", "error"]) |
227 | e3cc4c69 | Guido Trotter | self.assertEquals(self.server.error_count, 1) |
228 | e3cc4c69 | Guido Trotter | self.assertRaises(errors.GenericError, self.mainloop.Run) |
229 | e3cc4c69 | Guido Trotter | self.assertEquals(self.server.received, |
230 | e3cc4c69 | Guido Trotter | ["p1", "p2", "error", "p3", "error"]) |
231 | e3cc4c69 | Guido Trotter | self.assertEquals(self.server.error_count, 2) |
232 | 4db33137 | Guido Trotter | self.mainloop.Run()
|
233 | 4db33137 | Guido Trotter | self.assertEquals(self.server.received, |
234 | 4db33137 | Guido Trotter | ["p1", "p2", "error", "p3", "error", "terminate"]) |
235 | 4db33137 | Guido Trotter | self.assertEquals(self.server.error_count, 2) |
236 | 4db33137 | Guido Trotter | |
237 | 6e7e58b4 | Guido Trotter | def testSignaledWhileReceiving(self): |
238 | 6e7e58b4 | Guido Trotter | utils.IgnoreSignals = lambda fn, *args, **kwargs: None |
239 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p1") |
240 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "p2") |
241 | 6e7e58b4 | Guido Trotter | self.server.handle_read()
|
242 | 6e7e58b4 | Guido Trotter | self.assertEquals(self.server.received, []) |
243 | d8bcfe21 | Manuel Franceschini | self.client.enqueue_send(self.address, self.port, "terminate") |
244 | 6e7e58b4 | Guido Trotter | utils.IgnoreSignals = self.saved_utils_ignoresignals
|
245 | 6e7e58b4 | Guido Trotter | self.mainloop.Run()
|
246 | 6e7e58b4 | Guido Trotter | self.assertEquals(self.server.received, ["p1", "p2", "terminate"]) |
247 | 6e7e58b4 | Guido Trotter | |
248 | e9de7da4 | Guido Trotter | def testOversizedDatagram(self): |
249 | e9de7da4 | Guido Trotter | oversized_data = (constants.MAX_UDP_DATA_SIZE + 1) * "a" |
250 | e9de7da4 | Guido Trotter | self.assertRaises(errors.UdpDataSizeError, self.client.enqueue_send, |
251 | d8bcfe21 | Manuel Franceschini | self.address, self.port, oversized_data) |
252 | d8bcfe21 | Manuel Franceschini | |
253 | d8bcfe21 | Manuel Franceschini | |
254 | d8bcfe21 | Manuel Franceschini | class TestAsyncIP4UDPSocket(testutils.GanetiTestCase, _BaseAsyncUDPSocketTest): |
255 | d8bcfe21 | Manuel Franceschini | """Test IP4 daemon.AsyncUDPSocket"""
|
256 | d8bcfe21 | Manuel Franceschini | |
257 | d8bcfe21 | Manuel Franceschini | family = socket.AF_INET |
258 | d8bcfe21 | Manuel Franceschini | address = "127.0.0.1"
|
259 | d8bcfe21 | Manuel Franceschini | |
260 | d8bcfe21 | Manuel Franceschini | def setUp(self): |
261 | d8bcfe21 | Manuel Franceschini | testutils.GanetiTestCase.setUp(self)
|
262 | d8bcfe21 | Manuel Franceschini | _BaseAsyncUDPSocketTest.setUp(self)
|
263 | d8bcfe21 | Manuel Franceschini | |
264 | d8bcfe21 | Manuel Franceschini | def tearDown(self): |
265 | d8bcfe21 | Manuel Franceschini | testutils.GanetiTestCase.tearDown(self)
|
266 | d8bcfe21 | Manuel Franceschini | _BaseAsyncUDPSocketTest.tearDown(self)
|
267 | d8bcfe21 | Manuel Franceschini | |
268 | d8bcfe21 | Manuel Franceschini | |
269 | d8bcfe21 | Manuel Franceschini | class TestAsyncIP6UDPSocket(testutils.GanetiTestCase, _BaseAsyncUDPSocketTest): |
270 | d8bcfe21 | Manuel Franceschini | """Test IP6 daemon.AsyncUDPSocket"""
|
271 | d8bcfe21 | Manuel Franceschini | |
272 | d8bcfe21 | Manuel Franceschini | family = socket.AF_INET6 |
273 | d8bcfe21 | Manuel Franceschini | address = "::1"
|
274 | d8bcfe21 | Manuel Franceschini | |
275 | d8bcfe21 | Manuel Franceschini | def setUp(self): |
276 | d8bcfe21 | Manuel Franceschini | testutils.GanetiTestCase.setUp(self)
|
277 | d8bcfe21 | Manuel Franceschini | _BaseAsyncUDPSocketTest.setUp(self)
|
278 | d8bcfe21 | Manuel Franceschini | |
279 | d8bcfe21 | Manuel Franceschini | def tearDown(self): |
280 | d8bcfe21 | Manuel Franceschini | testutils.GanetiTestCase.tearDown(self)
|
281 | d8bcfe21 | Manuel Franceschini | _BaseAsyncUDPSocketTest.tearDown(self)
|
282 | e9de7da4 | Guido Trotter | |
283 | 4db33137 | Guido Trotter | |
284 | 18215385 | Guido Trotter | class _MyAsyncStreamServer(daemon.AsyncStreamServer): |
285 | 18215385 | Guido Trotter | |
286 | 18215385 | Guido Trotter | def __init__(self, family, address, handle_connection_fn): |
287 | 18215385 | Guido Trotter | daemon.AsyncStreamServer.__init__(self, family, address)
|
288 | 18215385 | Guido Trotter | self.handle_connection_fn = handle_connection_fn
|
289 | 18215385 | Guido Trotter | self.error_count = 0 |
290 | 18215385 | Guido Trotter | self.expt_count = 0 |
291 | 18215385 | Guido Trotter | |
292 | 18215385 | Guido Trotter | def handle_connection(self, connected_socket, client_address): |
293 | 18215385 | Guido Trotter | self.handle_connection_fn(connected_socket, client_address)
|
294 | 18215385 | Guido Trotter | |
295 | 18215385 | Guido Trotter | def handle_error(self): |
296 | 18215385 | Guido Trotter | self.error_count += 1 |
297 | 18215385 | Guido Trotter | self.close()
|
298 | 18215385 | Guido Trotter | raise
|
299 | 18215385 | Guido Trotter | |
300 | 18215385 | Guido Trotter | def handle_expt(self): |
301 | 18215385 | Guido Trotter | self.expt_count += 1 |
302 | 18215385 | Guido Trotter | self.close()
|
303 | 18215385 | Guido Trotter | |
304 | 18215385 | Guido Trotter | |
305 | 18215385 | Guido Trotter | class _MyMessageStreamHandler(daemon.AsyncTerminatedMessageStream): |
306 | 18215385 | Guido Trotter | |
307 | 18215385 | Guido Trotter | def __init__(self, connected_socket, client_address, terminator, family, |
308 | 37e62cb9 | Guido Trotter | message_fn, client_id, unhandled_limit): |
309 | 18215385 | Guido Trotter | daemon.AsyncTerminatedMessageStream.__init__(self, connected_socket,
|
310 | 18215385 | Guido Trotter | client_address, |
311 | 37e62cb9 | Guido Trotter | terminator, family, |
312 | 37e62cb9 | Guido Trotter | unhandled_limit) |
313 | 18215385 | Guido Trotter | self.message_fn = message_fn
|
314 | 18215385 | Guido Trotter | self.client_id = client_id
|
315 | 18215385 | Guido Trotter | self.error_count = 0 |
316 | 18215385 | Guido Trotter | |
317 | 18215385 | Guido Trotter | def handle_message(self, message, message_id): |
318 | 18215385 | Guido Trotter | self.message_fn(self, message, message_id) |
319 | 18215385 | Guido Trotter | |
320 | 18215385 | Guido Trotter | def handle_error(self): |
321 | 18215385 | Guido Trotter | self.error_count += 1 |
322 | 18215385 | Guido Trotter | raise
|
323 | 18215385 | Guido Trotter | |
324 | 18215385 | Guido Trotter | |
325 | 18215385 | Guido Trotter | class TestAsyncStreamServerTCP(testutils.GanetiTestCase): |
326 | 18215385 | Guido Trotter | """Test daemon.AsyncStreamServer with a TCP connection"""
|
327 | 18215385 | Guido Trotter | |
328 | 18215385 | Guido Trotter | family = socket.AF_INET |
329 | 18215385 | Guido Trotter | |
330 | 18215385 | Guido Trotter | def setUp(self): |
331 | 18215385 | Guido Trotter | testutils.GanetiTestCase.setUp(self)
|
332 | 18215385 | Guido Trotter | self.mainloop = daemon.Mainloop()
|
333 | 18215385 | Guido Trotter | self.address = self.getAddress() |
334 | 18215385 | Guido Trotter | self.server = _MyAsyncStreamServer(self.family, self.address, |
335 | 18215385 | Guido Trotter | self.handle_connection)
|
336 | 18215385 | Guido Trotter | self.client_handler = _MyMessageStreamHandler
|
337 | 37e62cb9 | Guido Trotter | self.unhandled_limit = None |
338 | 18215385 | Guido Trotter | self.terminator = "\3" |
339 | 18215385 | Guido Trotter | self.address = self.server.getsockname() |
340 | 18215385 | Guido Trotter | self.clients = []
|
341 | 18215385 | Guido Trotter | self.connections = []
|
342 | 18215385 | Guido Trotter | self.messages = {}
|
343 | 18215385 | Guido Trotter | self.connect_terminate_count = 0 |
344 | 18215385 | Guido Trotter | self.message_terminate_count = 0 |
345 | 18215385 | Guido Trotter | self.next_client_id = 0 |
346 | 18215385 | Guido Trotter | # Save utils.IgnoreSignals so we can do evil things to it...
|
347 | 18215385 | Guido Trotter | self.saved_utils_ignoresignals = utils.IgnoreSignals
|
348 | 18215385 | Guido Trotter | |
349 | 18215385 | Guido Trotter | def tearDown(self): |
350 | 18215385 | Guido Trotter | for c in self.clients: |
351 | 18215385 | Guido Trotter | c.close() |
352 | 18215385 | Guido Trotter | for c in self.connections: |
353 | 18215385 | Guido Trotter | c.close() |
354 | 18215385 | Guido Trotter | self.server.close()
|
355 | 18215385 | Guido Trotter | # ...and restore it as well
|
356 | 18215385 | Guido Trotter | utils.IgnoreSignals = self.saved_utils_ignoresignals
|
357 | 18215385 | Guido Trotter | testutils.GanetiTestCase.tearDown(self)
|
358 | 18215385 | Guido Trotter | |
359 | 18215385 | Guido Trotter | def getAddress(self): |
360 | 18215385 | Guido Trotter | return ("127.0.0.1", 0) |
361 | 18215385 | Guido Trotter | |
362 | 18215385 | Guido Trotter | def countTerminate(self, name): |
363 | 18215385 | Guido Trotter | value = getattr(self, name) |
364 | 18215385 | Guido Trotter | if value is not None: |
365 | 18215385 | Guido Trotter | value -= 1
|
366 | 18215385 | Guido Trotter | setattr(self, name, value) |
367 | 18215385 | Guido Trotter | if value <= 0: |
368 | 18215385 | Guido Trotter | os.kill(os.getpid(), signal.SIGTERM) |
369 | 18215385 | Guido Trotter | |
370 | 18215385 | Guido Trotter | def handle_connection(self, connected_socket, client_address): |
371 | 18215385 | Guido Trotter | client_id = self.next_client_id
|
372 | 18215385 | Guido Trotter | self.next_client_id += 1 |
373 | 18215385 | Guido Trotter | client_handler = self.client_handler(connected_socket, client_address,
|
374 | 18215385 | Guido Trotter | self.terminator, self.family, |
375 | 18215385 | Guido Trotter | self.handle_message,
|
376 | 37e62cb9 | Guido Trotter | client_id, self.unhandled_limit)
|
377 | 18215385 | Guido Trotter | self.connections.append(client_handler)
|
378 | 18215385 | Guido Trotter | self.countTerminate("connect_terminate_count") |
379 | 18215385 | Guido Trotter | |
380 | 18215385 | Guido Trotter | def handle_message(self, handler, message, message_id): |
381 | 18215385 | Guido Trotter | self.messages.setdefault(handler.client_id, [])
|
382 | 18215385 | Guido Trotter | # We should just check that the message_ids are monotonically increasing.
|
383 | 18215385 | Guido Trotter | # If in the unit tests we never remove messages from the received queue,
|
384 | 18215385 | Guido Trotter | # though, we can just require that the queue length is the same as the
|
385 | 18215385 | Guido Trotter | # message id, before pushing the message to it. This forces a more
|
386 | 18215385 | Guido Trotter | # restrictive check, but we can live with this for now.
|
387 | 18215385 | Guido Trotter | self.assertEquals(len(self.messages[handler.client_id]), message_id) |
388 | 18215385 | Guido Trotter | self.messages[handler.client_id].append(message)
|
389 | 18215385 | Guido Trotter | if message == "error": |
390 | 18215385 | Guido Trotter | raise errors.GenericError("error") |
391 | 18215385 | Guido Trotter | self.countTerminate("message_terminate_count") |
392 | 18215385 | Guido Trotter | |
393 | 18215385 | Guido Trotter | def getClient(self): |
394 | 18215385 | Guido Trotter | client = socket.socket(self.family, socket.SOCK_STREAM)
|
395 | 18215385 | Guido Trotter | client.connect(self.address)
|
396 | 18215385 | Guido Trotter | self.clients.append(client)
|
397 | 18215385 | Guido Trotter | return client
|
398 | 18215385 | Guido Trotter | |
399 | 18215385 | Guido Trotter | def tearDown(self): |
400 | 18215385 | Guido Trotter | testutils.GanetiTestCase.tearDown(self)
|
401 | 18215385 | Guido Trotter | self.server.close()
|
402 | 18215385 | Guido Trotter | |
403 | 18215385 | Guido Trotter | def testConnect(self): |
404 | 18215385 | Guido Trotter | self.getClient()
|
405 | 18215385 | Guido Trotter | self.mainloop.Run()
|
406 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 1) |
407 | 18215385 | Guido Trotter | self.getClient()
|
408 | 18215385 | Guido Trotter | self.mainloop.Run()
|
409 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 2) |
410 | 18215385 | Guido Trotter | self.connect_terminate_count = 4 |
411 | 18215385 | Guido Trotter | self.getClient()
|
412 | 18215385 | Guido Trotter | self.getClient()
|
413 | 18215385 | Guido Trotter | self.getClient()
|
414 | 18215385 | Guido Trotter | self.getClient()
|
415 | 18215385 | Guido Trotter | self.mainloop.Run()
|
416 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 6) |
417 | 18215385 | Guido Trotter | |
418 | 18215385 | Guido Trotter | def testBasicMessage(self): |
419 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
420 | 18215385 | Guido Trotter | client = self.getClient()
|
421 | 18215385 | Guido Trotter | client.send("ciao\3")
|
422 | 18215385 | Guido Trotter | self.mainloop.Run()
|
423 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 1) |
424 | 18215385 | Guido Trotter | self.assertEquals(len(self.messages[0]), 1) |
425 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0][0], "ciao") |
426 | 18215385 | Guido Trotter | |
427 | 18215385 | Guido Trotter | def testDoubleMessage(self): |
428 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
429 | 18215385 | Guido Trotter | client = self.getClient()
|
430 | 18215385 | Guido Trotter | client.send("ciao\3")
|
431 | 18215385 | Guido Trotter | self.mainloop.Run()
|
432 | 18215385 | Guido Trotter | client.send("foobar\3")
|
433 | 18215385 | Guido Trotter | self.mainloop.Run()
|
434 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 1) |
435 | 18215385 | Guido Trotter | self.assertEquals(len(self.messages[0]), 2) |
436 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0][1], "foobar") |
437 | 18215385 | Guido Trotter | |
438 | 18215385 | Guido Trotter | def testComposedMessage(self): |
439 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
440 | 18215385 | Guido Trotter | self.message_terminate_count = 3 |
441 | 18215385 | Guido Trotter | client = self.getClient()
|
442 | 18215385 | Guido Trotter | client.send("one\3composed\3message\3")
|
443 | 18215385 | Guido Trotter | self.mainloop.Run()
|
444 | 18215385 | Guido Trotter | self.assertEquals(len(self.messages[0]), 3) |
445 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "message"]) |
446 | 18215385 | Guido Trotter | |
447 | 18215385 | Guido Trotter | def testLongTerminator(self): |
448 | 18215385 | Guido Trotter | self.terminator = "\0\1\2" |
449 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
450 | 18215385 | Guido Trotter | self.message_terminate_count = 3 |
451 | 18215385 | Guido Trotter | client = self.getClient()
|
452 | 18215385 | Guido Trotter | client.send("one\0\1\2composed\0\1\2message\0\1\2")
|
453 | 18215385 | Guido Trotter | self.mainloop.Run()
|
454 | 18215385 | Guido Trotter | self.assertEquals(len(self.messages[0]), 3) |
455 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "message"]) |
456 | 18215385 | Guido Trotter | |
457 | 18215385 | Guido Trotter | def testErrorHandling(self): |
458 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
459 | 18215385 | Guido Trotter | self.message_terminate_count = None |
460 | 18215385 | Guido Trotter | client = self.getClient()
|
461 | 18215385 | Guido Trotter | client.send("one\3two\3error\3three\3")
|
462 | 18215385 | Guido Trotter | self.assertRaises(errors.GenericError, self.mainloop.Run) |
463 | 18215385 | Guido Trotter | self.assertEquals(self.connections[0].error_count, 1) |
464 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "two", "error"]) |
465 | 18215385 | Guido Trotter | client.send("error\3")
|
466 | 18215385 | Guido Trotter | self.assertRaises(errors.GenericError, self.mainloop.Run) |
467 | 18215385 | Guido Trotter | self.assertEquals(self.connections[0].error_count, 2) |
468 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "two", "error", "three", |
469 | 18215385 | Guido Trotter | "error"])
|
470 | 18215385 | Guido Trotter | |
471 | 18215385 | Guido Trotter | def testDoubleClient(self): |
472 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
473 | 18215385 | Guido Trotter | self.message_terminate_count = 2 |
474 | 18215385 | Guido Trotter | client1 = self.getClient()
|
475 | 18215385 | Guido Trotter | client2 = self.getClient()
|
476 | 18215385 | Guido Trotter | client1.send("c1m1\3")
|
477 | 18215385 | Guido Trotter | client2.send("c2m1\3")
|
478 | 18215385 | Guido Trotter | self.mainloop.Run()
|
479 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["c1m1"]) |
480 | 18215385 | Guido Trotter | self.assertEquals(self.messages[1], ["c2m1"]) |
481 | 18215385 | Guido Trotter | |
482 | 18215385 | Guido Trotter | def testUnterminatedMessage(self): |
483 | 18215385 | Guido Trotter | self.connect_terminate_count = None |
484 | 18215385 | Guido Trotter | self.message_terminate_count = 3 |
485 | 18215385 | Guido Trotter | client1 = self.getClient()
|
486 | 18215385 | Guido Trotter | client2 = self.getClient()
|
487 | 18215385 | Guido Trotter | client1.send("message\3unterminated")
|
488 | 18215385 | Guido Trotter | client2.send("c2m1\3c2m2\3")
|
489 | 18215385 | Guido Trotter | self.mainloop.Run()
|
490 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["message"]) |
491 | 18215385 | Guido Trotter | self.assertEquals(self.messages[1], ["c2m1", "c2m2"]) |
492 | 18215385 | Guido Trotter | client1.send("message\3")
|
493 | 18215385 | Guido Trotter | self.mainloop.Run()
|
494 | 18215385 | Guido Trotter | self.assertEquals(self.messages[0], ["message", "unterminatedmessage"]) |
495 | 18215385 | Guido Trotter | |
496 | 18215385 | Guido Trotter | def testSignaledWhileAccepting(self): |
497 | 18215385 | Guido Trotter | utils.IgnoreSignals = lambda fn, *args, **kwargs: None |
498 | 18215385 | Guido Trotter | client1 = self.getClient()
|
499 | 18215385 | Guido Trotter | self.server.handle_accept()
|
500 | 18215385 | Guido Trotter | # When interrupted while accepting we don't have a connection, but we
|
501 | 18215385 | Guido Trotter | # didn't crash either.
|
502 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 0) |
503 | 18215385 | Guido Trotter | utils.IgnoreSignals = self.saved_utils_ignoresignals
|
504 | 18215385 | Guido Trotter | self.mainloop.Run()
|
505 | 18215385 | Guido Trotter | self.assertEquals(len(self.connections), 1) |
506 | 18215385 | Guido Trotter | |
507 | 1e063ccd | Guido Trotter | def testSendMessage(self): |
508 | 1e063ccd | Guido Trotter | self.connect_terminate_count = None |
509 | 1e063ccd | Guido Trotter | self.message_terminate_count = 3 |
510 | 1e063ccd | Guido Trotter | client1 = self.getClient()
|
511 | 1e063ccd | Guido Trotter | client2 = self.getClient()
|
512 | 1e063ccd | Guido Trotter | client1.send("one\3composed\3message\3")
|
513 | 1e063ccd | Guido Trotter | self.mainloop.Run()
|
514 | 1e063ccd | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "message"]) |
515 | 1e063ccd | Guido Trotter | self.assertFalse(self.connections[0].writable()) |
516 | 1e063ccd | Guido Trotter | self.assertFalse(self.connections[1].writable()) |
517 | 1e063ccd | Guido Trotter | self.connections[0].send_message("r0") |
518 | 1e063ccd | Guido Trotter | self.assert_(self.connections[0].writable()) |
519 | 1e063ccd | Guido Trotter | self.assertFalse(self.connections[1].writable()) |
520 | 1e063ccd | Guido Trotter | self.connections[0].send_message("r1") |
521 | 1e063ccd | Guido Trotter | self.connections[0].send_message("r2") |
522 | 1e063ccd | Guido Trotter | # We currently have no way to terminate the mainloop on write events, but
|
523 | 1e063ccd | Guido Trotter | # let's assume handle_write will be called if writable() is True.
|
524 | 1e063ccd | Guido Trotter | while self.connections[0].writable(): |
525 | 1e063ccd | Guido Trotter | self.connections[0].handle_write() |
526 | 1e063ccd | Guido Trotter | client1.setblocking(0)
|
527 | 1e063ccd | Guido Trotter | client2.setblocking(0)
|
528 | 1e063ccd | Guido Trotter | self.assertEquals(client1.recv(4096), "r0\3r1\3r2\3") |
529 | 1e063ccd | Guido Trotter | self.assertRaises(socket.error, client2.recv, 4096) |
530 | 1e063ccd | Guido Trotter | |
531 | 37e62cb9 | Guido Trotter | def testLimitedUnhandledMessages(self): |
532 | 37e62cb9 | Guido Trotter | self.connect_terminate_count = None |
533 | 37e62cb9 | Guido Trotter | self.message_terminate_count = 3 |
534 | 37e62cb9 | Guido Trotter | self.unhandled_limit = 2 |
535 | 37e62cb9 | Guido Trotter | client1 = self.getClient()
|
536 | 37e62cb9 | Guido Trotter | client2 = self.getClient()
|
537 | 37e62cb9 | Guido Trotter | client1.send("one\3composed\3long\3message\3")
|
538 | 37e62cb9 | Guido Trotter | client2.send("c2one\3")
|
539 | 37e62cb9 | Guido Trotter | self.mainloop.Run()
|
540 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed"]) |
541 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[1], ["c2one"]) |
542 | 37e62cb9 | Guido Trotter | self.assertFalse(self.connections[0].readable()) |
543 | 37e62cb9 | Guido Trotter | self.assert_(self.connections[1].readable()) |
544 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r0") |
545 | 37e62cb9 | Guido Trotter | self.message_terminate_count = None |
546 | 37e62cb9 | Guido Trotter | client1.send("another\3")
|
547 | 37e62cb9 | Guido Trotter | # when we write replies messages queued also get handled, but not the ones
|
548 | 37e62cb9 | Guido Trotter | # in the socket.
|
549 | 37e62cb9 | Guido Trotter | while self.connections[0].writable(): |
550 | 37e62cb9 | Guido Trotter | self.connections[0].handle_write() |
551 | 37e62cb9 | Guido Trotter | self.assertFalse(self.connections[0].readable()) |
552 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "long"]) |
553 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r1") |
554 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r2") |
555 | 37e62cb9 | Guido Trotter | while self.connections[0].writable(): |
556 | 37e62cb9 | Guido Trotter | self.connections[0].handle_write() |
557 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "long", "message"]) |
558 | 37e62cb9 | Guido Trotter | self.assert_(self.connections[0].readable()) |
559 | 37e62cb9 | Guido Trotter | |
560 | 37e62cb9 | Guido Trotter | def testLimitedUnhandledMessagesOne(self): |
561 | 37e62cb9 | Guido Trotter | self.connect_terminate_count = None |
562 | 37e62cb9 | Guido Trotter | self.message_terminate_count = 2 |
563 | 37e62cb9 | Guido Trotter | self.unhandled_limit = 1 |
564 | 37e62cb9 | Guido Trotter | client1 = self.getClient()
|
565 | 37e62cb9 | Guido Trotter | client2 = self.getClient()
|
566 | 37e62cb9 | Guido Trotter | client1.send("one\3composed\3message\3")
|
567 | 37e62cb9 | Guido Trotter | client2.send("c2one\3")
|
568 | 37e62cb9 | Guido Trotter | self.mainloop.Run()
|
569 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one"]) |
570 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[1], ["c2one"]) |
571 | 37e62cb9 | Guido Trotter | self.assertFalse(self.connections[0].readable()) |
572 | 37e62cb9 | Guido Trotter | self.assertFalse(self.connections[1].readable()) |
573 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r0") |
574 | 37e62cb9 | Guido Trotter | self.message_terminate_count = None |
575 | 37e62cb9 | Guido Trotter | while self.connections[0].writable(): |
576 | 37e62cb9 | Guido Trotter | self.connections[0].handle_write() |
577 | 37e62cb9 | Guido Trotter | self.assertFalse(self.connections[0].readable()) |
578 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed"]) |
579 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r2") |
580 | 37e62cb9 | Guido Trotter | self.connections[0].send_message("r3") |
581 | 37e62cb9 | Guido Trotter | while self.connections[0].writable(): |
582 | 37e62cb9 | Guido Trotter | self.connections[0].handle_write() |
583 | 37e62cb9 | Guido Trotter | self.assertEquals(self.messages[0], ["one", "composed", "message"]) |
584 | 37e62cb9 | Guido Trotter | self.assert_(self.connections[0].readable()) |
585 | 37e62cb9 | Guido Trotter | |
586 | 18215385 | Guido Trotter | |
587 | 18215385 | Guido Trotter | class TestAsyncStreamServerUnixPath(TestAsyncStreamServerTCP): |
588 | 18215385 | Guido Trotter | """Test daemon.AsyncStreamServer with a Unix path connection"""
|
589 | 18215385 | Guido Trotter | |
590 | 18215385 | Guido Trotter | family = socket.AF_UNIX |
591 | 18215385 | Guido Trotter | |
592 | 18215385 | Guido Trotter | def getAddress(self): |
593 | 18215385 | Guido Trotter | self.tmpdir = tempfile.mkdtemp()
|
594 | 18215385 | Guido Trotter | return os.path.join(self.tmpdir, "server.sock") |
595 | 18215385 | Guido Trotter | |
596 | 18215385 | Guido Trotter | def tearDown(self): |
597 | 18215385 | Guido Trotter | shutil.rmtree(self.tmpdir)
|
598 | 18215385 | Guido Trotter | TestAsyncStreamServerTCP.tearDown(self)
|
599 | 18215385 | Guido Trotter | |
600 | 18215385 | Guido Trotter | |
601 | 5c1ae836 | Guido Trotter | class TestAsyncStreamServerUnixAbstract(TestAsyncStreamServerTCP): |
602 | 5c1ae836 | Guido Trotter | """Test daemon.AsyncStreamServer with a Unix abstract connection"""
|
603 | 5c1ae836 | Guido Trotter | |
604 | 5c1ae836 | Guido Trotter | family = socket.AF_UNIX |
605 | 5c1ae836 | Guido Trotter | |
606 | 5c1ae836 | Guido Trotter | def getAddress(self): |
607 | 5c1ae836 | Guido Trotter | return "\0myabstractsocketaddress" |
608 | 5c1ae836 | Guido Trotter | |
609 | 5c1ae836 | Guido Trotter | |
610 | 495ba852 | Guido Trotter | class TestAsyncAwaker(testutils.GanetiTestCase): |
611 | 495ba852 | Guido Trotter | """Test daemon.AsyncAwaker"""
|
612 | 495ba852 | Guido Trotter | |
613 | 495ba852 | Guido Trotter | family = socket.AF_INET |
614 | 495ba852 | Guido Trotter | |
615 | 495ba852 | Guido Trotter | def setUp(self): |
616 | 495ba852 | Guido Trotter | testutils.GanetiTestCase.setUp(self)
|
617 | 495ba852 | Guido Trotter | self.mainloop = daemon.Mainloop()
|
618 | 495ba852 | Guido Trotter | self.awaker = daemon.AsyncAwaker(signal_fn=self.handle_signal) |
619 | 495ba852 | Guido Trotter | self.signal_count = 0 |
620 | 495ba852 | Guido Trotter | self.signal_terminate_count = 1 |
621 | 495ba852 | Guido Trotter | |
622 | 495ba852 | Guido Trotter | def tearDown(self): |
623 | 495ba852 | Guido Trotter | self.awaker.close()
|
624 | 495ba852 | Guido Trotter | |
625 | 495ba852 | Guido Trotter | def handle_signal(self): |
626 | 495ba852 | Guido Trotter | self.signal_count += 1 |
627 | 495ba852 | Guido Trotter | self.signal_terminate_count -= 1 |
628 | 495ba852 | Guido Trotter | if self.signal_terminate_count <= 0: |
629 | 495ba852 | Guido Trotter | os.kill(os.getpid(), signal.SIGTERM) |
630 | 495ba852 | Guido Trotter | |
631 | 495ba852 | Guido Trotter | def testBasicSignaling(self): |
632 | 495ba852 | Guido Trotter | self.awaker.signal()
|
633 | 495ba852 | Guido Trotter | self.mainloop.Run()
|
634 | 495ba852 | Guido Trotter | self.assertEquals(self.signal_count, 1) |
635 | 495ba852 | Guido Trotter | |
636 | 495ba852 | Guido Trotter | def testDoubleSignaling(self): |
637 | 495ba852 | Guido Trotter | self.awaker.signal()
|
638 | 495ba852 | Guido Trotter | self.awaker.signal()
|
639 | 495ba852 | Guido Trotter | self.mainloop.Run()
|
640 | 495ba852 | Guido Trotter | # The second signal is never delivered
|
641 | 495ba852 | Guido Trotter | self.assertEquals(self.signal_count, 1) |
642 | 495ba852 | Guido Trotter | |
643 | 495ba852 | Guido Trotter | def testReallyDoubleSignaling(self): |
644 | 495ba852 | Guido Trotter | self.assert_(self.awaker.readable()) |
645 | 495ba852 | Guido Trotter | self.awaker.signal()
|
646 | 495ba852 | Guido Trotter | # Let's suppose two threads overlap, and both find need_signal True
|
647 | 495ba852 | Guido Trotter | self.awaker.need_signal = True |
648 | 495ba852 | Guido Trotter | self.awaker.signal()
|
649 | 495ba852 | Guido Trotter | self.mainloop.Run()
|
650 | 495ba852 | Guido Trotter | # We still get only one signaling
|
651 | 495ba852 | Guido Trotter | self.assertEquals(self.signal_count, 1) |
652 | 495ba852 | Guido Trotter | |
653 | 495ba852 | Guido Trotter | def testNoSignalFnArgument(self): |
654 | 495ba852 | Guido Trotter | myawaker = daemon.AsyncAwaker() |
655 | 495ba852 | Guido Trotter | self.assertRaises(socket.error, myawaker.handle_read)
|
656 | 495ba852 | Guido Trotter | myawaker.signal() |
657 | 495ba852 | Guido Trotter | myawaker.handle_read() |
658 | 495ba852 | Guido Trotter | self.assertRaises(socket.error, myawaker.handle_read)
|
659 | 495ba852 | Guido Trotter | myawaker.signal() |
660 | 495ba852 | Guido Trotter | myawaker.signal() |
661 | 495ba852 | Guido Trotter | myawaker.handle_read() |
662 | 495ba852 | Guido Trotter | self.assertRaises(socket.error, myawaker.handle_read)
|
663 | 495ba852 | Guido Trotter | myawaker.close() |
664 | 495ba852 | Guido Trotter | |
665 | 495ba852 | Guido Trotter | def testWrongSignalFnArgument(self): |
666 | 495ba852 | Guido Trotter | self.assertRaises(AssertionError, daemon.AsyncAwaker, 1) |
667 | 495ba852 | Guido Trotter | self.assertRaises(AssertionError, daemon.AsyncAwaker, "string") |
668 | 495ba852 | Guido Trotter | self.assertRaises(AssertionError, daemon.AsyncAwaker, signal_fn=1) |
669 | 495ba852 | Guido Trotter | self.assertRaises(AssertionError, daemon.AsyncAwaker, signal_fn="string") |
670 | 495ba852 | Guido Trotter | |
671 | 495ba852 | Guido Trotter | |
672 | 1118ec44 | Guido Trotter | if __name__ == "__main__": |
673 | 1118ec44 | Guido Trotter | testutils.GanetiTestProgram() |