Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ f59dce3e

History | View | Annotate | Download (8.7 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

    
32
import testutils
33

    
34

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

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

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

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

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

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

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

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

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

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

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

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

    
144

    
145
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
146

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

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

    
159
  def handle_error(self):
160
    self.error_count += 1
161

    
162

    
163
class TestAsyncUDPSocket(testutils.GanetiTestCase):
164
  """Test daemon.AsyncUDPSocket"""
165

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

    
174
  def tearDown(self):
175
    self.server.close()
176
    self.client.close()
177
    testutils.GanetiTestCase.tearDown(self)
178

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

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

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

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

    
210
  def testErrorHandling(self):
211
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
212
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
213
    self.client.enqueue_send("127.0.0.1", self.port, "error")
214
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
215
    self.client.enqueue_send("127.0.0.1", self.port, "error")
216
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
217
    self.mainloop.Run()
218
    self.assertEquals(self.server.received,
219
                      ["p1", "p2", "error", "p3", "error", "terminate"])
220
    self.assertEquals(self.server.error_count, 2)
221

    
222

    
223
if __name__ == "__main__":
224
  testutils.GanetiTestProgram()