Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ 1a2eb2dc

History | View | Annotate | Download (24 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 495ba852 Guido Trotter
class TestAsyncAwaker(testutils.GanetiTestCase):
602 495ba852 Guido Trotter
  """Test daemon.AsyncAwaker"""
603 495ba852 Guido Trotter
604 495ba852 Guido Trotter
  family = socket.AF_INET
605 495ba852 Guido Trotter
606 495ba852 Guido Trotter
  def setUp(self):
607 495ba852 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
608 495ba852 Guido Trotter
    self.mainloop = daemon.Mainloop()
609 495ba852 Guido Trotter
    self.awaker = daemon.AsyncAwaker(signal_fn=self.handle_signal)
610 495ba852 Guido Trotter
    self.signal_count = 0
611 495ba852 Guido Trotter
    self.signal_terminate_count = 1
612 495ba852 Guido Trotter
613 495ba852 Guido Trotter
  def tearDown(self):
614 495ba852 Guido Trotter
    self.awaker.close()
615 495ba852 Guido Trotter
616 495ba852 Guido Trotter
  def handle_signal(self):
617 495ba852 Guido Trotter
    self.signal_count += 1
618 495ba852 Guido Trotter
    self.signal_terminate_count -= 1
619 495ba852 Guido Trotter
    if self.signal_terminate_count <= 0:
620 495ba852 Guido Trotter
      os.kill(os.getpid(), signal.SIGTERM)
621 495ba852 Guido Trotter
622 495ba852 Guido Trotter
  def testBasicSignaling(self):
623 495ba852 Guido Trotter
    self.awaker.signal()
624 495ba852 Guido Trotter
    self.mainloop.Run()
625 495ba852 Guido Trotter
    self.assertEquals(self.signal_count, 1)
626 495ba852 Guido Trotter
627 495ba852 Guido Trotter
  def testDoubleSignaling(self):
628 495ba852 Guido Trotter
    self.awaker.signal()
629 495ba852 Guido Trotter
    self.awaker.signal()
630 495ba852 Guido Trotter
    self.mainloop.Run()
631 495ba852 Guido Trotter
    # The second signal is never delivered
632 495ba852 Guido Trotter
    self.assertEquals(self.signal_count, 1)
633 495ba852 Guido Trotter
634 495ba852 Guido Trotter
  def testReallyDoubleSignaling(self):
635 495ba852 Guido Trotter
    self.assert_(self.awaker.readable())
636 495ba852 Guido Trotter
    self.awaker.signal()
637 495ba852 Guido Trotter
    # Let's suppose two threads overlap, and both find need_signal True
638 495ba852 Guido Trotter
    self.awaker.need_signal = True
639 495ba852 Guido Trotter
    self.awaker.signal()
640 495ba852 Guido Trotter
    self.mainloop.Run()
641 495ba852 Guido Trotter
    # We still get only one signaling
642 495ba852 Guido Trotter
    self.assertEquals(self.signal_count, 1)
643 495ba852 Guido Trotter
644 495ba852 Guido Trotter
  def testNoSignalFnArgument(self):
645 495ba852 Guido Trotter
    myawaker = daemon.AsyncAwaker()
646 495ba852 Guido Trotter
    self.assertRaises(socket.error, myawaker.handle_read)
647 495ba852 Guido Trotter
    myawaker.signal()
648 495ba852 Guido Trotter
    myawaker.handle_read()
649 495ba852 Guido Trotter
    self.assertRaises(socket.error, myawaker.handle_read)
650 495ba852 Guido Trotter
    myawaker.signal()
651 495ba852 Guido Trotter
    myawaker.signal()
652 495ba852 Guido Trotter
    myawaker.handle_read()
653 495ba852 Guido Trotter
    self.assertRaises(socket.error, myawaker.handle_read)
654 495ba852 Guido Trotter
    myawaker.close()
655 495ba852 Guido Trotter
656 495ba852 Guido Trotter
  def testWrongSignalFnArgument(self):
657 495ba852 Guido Trotter
    self.assertRaises(AssertionError, daemon.AsyncAwaker, 1)
658 495ba852 Guido Trotter
    self.assertRaises(AssertionError, daemon.AsyncAwaker, "string")
659 495ba852 Guido Trotter
    self.assertRaises(AssertionError, daemon.AsyncAwaker, signal_fn=1)
660 495ba852 Guido Trotter
    self.assertRaises(AssertionError, daemon.AsyncAwaker, signal_fn="string")
661 495ba852 Guido Trotter
662 495ba852 Guido Trotter
663 1118ec44 Guido Trotter
if __name__ == "__main__":
664 1118ec44 Guido Trotter
  testutils.GanetiTestProgram()