Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ e3cc4c69

History | View | Annotate | Download (9.2 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2010 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for unittesting the daemon module"""
23

    
24
import unittest
25
import signal
26
import os
27
import socket
28
import time
29

    
30
from ganeti import daemon
31
from ganeti import errors
32

    
33
import testutils
34

    
35

    
36
class TestMainloop(testutils.GanetiTestCase):
37
  """Test daemon.Mainloop"""
38

    
39
  def setUp(self):
40
    testutils.GanetiTestCase.setUp(self)
41
    self.mainloop = daemon.Mainloop()
42
    self.sendsig_events = []
43
    self.onsignal_events = []
44

    
45
  def _CancelEvent(self, handle):
46
    self.mainloop.scheduler.cancel(handle)
47

    
48
  def _SendSig(self, sig):
49
    self.sendsig_events.append(sig)
50
    os.kill(os.getpid(), sig)
51

    
52
  def OnSignal(self, signum):
53
    self.onsignal_events.append(signum)
54

    
55
  def testRunAndTermBySched(self):
56
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM])
57
    self.mainloop.Run() # terminates by _SendSig being scheduled
58
    self.assertEquals(self.sendsig_events, [signal.SIGTERM])
59

    
60
  def testTerminatingSignals(self):
61
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
62
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGINT])
63
    self.mainloop.Run()
64
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT])
65
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM])
66
    self.mainloop.Run()
67
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT,
68
                                            signal.SIGTERM])
69

    
70
  def testSchedulerCancel(self):
71
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
72
                                           [signal.SIGTERM])
73
    self.mainloop.scheduler.cancel(handle)
74
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
75
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
76
    self.mainloop.Run()
77
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
78

    
79
  def testRegisterSignal(self):
80
    self.mainloop.RegisterSignal(self)
81
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
82
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
83
                                           [signal.SIGTERM])
84
    self.mainloop.scheduler.cancel(handle)
85
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
86
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
87
    # ...not delievered because they are scheduled after TERM
88
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
89
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
90
    self.mainloop.Run()
91
    self.assertEquals(self.sendsig_events,
92
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
93
    self.assertEquals(self.onsignal_events, self.sendsig_events)
94

    
95
  def testDeferredCancel(self):
96
    self.mainloop.RegisterSignal(self)
97
    now = time.time()
98
    self.mainloop.scheduler.enterabs(now + 0.1, 1, self._SendSig,
99
                                     [signal.SIGCHLD])
100
    handle1 = self.mainloop.scheduler.enterabs(now + 0.3, 2, self._SendSig,
101
                                               [signal.SIGCHLD])
102
    handle2 = self.mainloop.scheduler.enterabs(now + 0.4, 2, self._SendSig,
103
                                               [signal.SIGCHLD])
104
    self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent,
105
                                     [handle1])
106
    self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent,
107
                                     [handle2])
108
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGTERM])
109
    self.mainloop.Run()
110
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
111
    self.assertEquals(self.onsignal_events, self.sendsig_events)
112

    
113
  def testReRun(self):
114
    self.mainloop.RegisterSignal(self)
115
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
116
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
117
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
118
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
119
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
120
    self.mainloop.Run()
121
    self.assertEquals(self.sendsig_events,
122
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
123
    self.assertEquals(self.onsignal_events, self.sendsig_events)
124
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
125
    self.mainloop.Run()
126
    self.assertEquals(self.sendsig_events,
127
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM,
128
                       signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
129
    self.assertEquals(self.onsignal_events, self.sendsig_events)
130

    
131
  def testPriority(self):
132
    # for events at the same time, the highest priority one executes first
133
    now = time.time()
134
    self.mainloop.scheduler.enterabs(now + 0.1, 2, self._SendSig,
135
                                     [signal.SIGCHLD])
136
    self.mainloop.scheduler.enterabs(now + 0.1, 1, self._SendSig,
137
                                     [signal.SIGTERM])
138
    self.mainloop.Run()
139
    self.assertEquals(self.sendsig_events, [signal.SIGTERM])
140
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGTERM])
141
    self.mainloop.Run()
142
    self.assertEquals(self.sendsig_events,
143
                      [signal.SIGTERM, signal.SIGCHLD, signal.SIGTERM])
144

    
145

    
146
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
147

    
148
  def __init__(self):
149
    daemon.AsyncUDPSocket.__init__(self)
150
    self.received = []
151
    self.error_count = 0
152

    
153
  def handle_datagram(self, payload, ip, port):
154
    self.received.append((payload))
155
    if payload == "terminate":
156
      os.kill(os.getpid(), signal.SIGTERM)
157
    elif payload == "error":
158
      raise errors.GenericError("error")
159

    
160
  def handle_error(self):
161
    self.error_count += 1
162
    raise
163

    
164

    
165
class TestAsyncUDPSocket(testutils.GanetiTestCase):
166
  """Test daemon.AsyncUDPSocket"""
167

    
168
  def setUp(self):
169
    testutils.GanetiTestCase.setUp(self)
170
    self.mainloop = daemon.Mainloop()
171
    self.server = _MyAsyncUDPSocket()
172
    self.client = _MyAsyncUDPSocket()
173
    self.server.bind(("127.0.0.1", 0))
174
    self.port = self.server.getsockname()[1]
175

    
176
  def tearDown(self):
177
    self.server.close()
178
    self.client.close()
179
    testutils.GanetiTestCase.tearDown(self)
180

    
181
  def testNoDoubleBind(self):
182
    self.assertRaises(socket.error, self.client.bind, ("127.0.0.1", self.port))
183

    
184
  def _ThreadedClient(self, payload):
185
    self.client.enqueue_send("127.0.0.1", self.port, payload)
186
    print "sending %s" % payload
187
    while self.client.writable():
188
      self.client.handle_write()
189

    
190
  def testAsyncClientServer(self):
191
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
192
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
193
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
194
    self.mainloop.Run()
195
    self.assertEquals(self.server.received, ["p1", "p2", "terminate"])
196

    
197
  def testSyncClientServer(self):
198
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
199
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
200
    while self.client.writable():
201
      self.client.handle_write()
202
    self.server.process_next_packet()
203
    self.assertEquals(self.server.received, ["p1"])
204
    self.server.process_next_packet()
205
    self.assertEquals(self.server.received, ["p1", "p2"])
206
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
207
    while self.client.writable():
208
      self.client.handle_write()
209
    self.server.process_next_packet()
210
    self.assertEquals(self.server.received, ["p1", "p2", "p3"])
211

    
212
  def testErrorHandling(self):
213
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
214
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
215
    self.client.enqueue_send("127.0.0.1", self.port, "error")
216
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
217
    self.client.enqueue_send("127.0.0.1", self.port, "error")
218
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
219
    self.assertRaises(errors.GenericError, self.mainloop.Run)
220
    self.assertEquals(self.server.received,
221
                      ["p1", "p2", "error"])
222
    self.assertEquals(self.server.error_count, 1)
223
    self.assertRaises(errors.GenericError, self.mainloop.Run)
224
    self.assertEquals(self.server.received,
225
                      ["p1", "p2", "error", "p3", "error"])
226
    self.assertEquals(self.server.error_count, 2)
227
    self.mainloop.Run()
228
    self.assertEquals(self.server.received,
229
                      ["p1", "p2", "error", "p3", "error", "terminate"])
230
    self.assertEquals(self.server.error_count, 2)
231

    
232

    
233
if __name__ == "__main__":
234
  testutils.GanetiTestProgram()