Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ 19ad29d2

History | View | Annotate | Download (7.6 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 testSchedulerCancel(self):
60
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
61
                                           [signal.SIGTERM])
62
    self.mainloop.scheduler.cancel(handle)
63
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
64
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
65
    self.mainloop.Run()
66
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
67

    
68
  def testRegisterSignal(self):
69
    self.mainloop.RegisterSignal(self)
70
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
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
    # ...not delievered because they are scheduled after TERM
77
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
78
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
79
    self.mainloop.Run()
80
    self.assertEquals(self.sendsig_events,
81
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
82
    self.assertEquals(self.onsignal_events, self.sendsig_events)
83

    
84
  def testDeferredCancel(self):
85
    self.mainloop.RegisterSignal(self)
86
    now = time.time()
87
    self.mainloop.scheduler.enterabs(now + 0.1, 1, self._SendSig,
88
                                     [signal.SIGCHLD])
89
    handle1 = self.mainloop.scheduler.enterabs(now + 0.3, 2, self._SendSig,
90
                                               [signal.SIGCHLD])
91
    handle2 = self.mainloop.scheduler.enterabs(now + 0.4, 2, self._SendSig,
92
                                               [signal.SIGCHLD])
93
    self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent,
94
                                     [handle1])
95
    self.mainloop.scheduler.enterabs(now + 0.2, 1, self._CancelEvent,
96
                                     [handle2])
97
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGTERM])
98
    self.mainloop.Run()
99
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
100
    self.assertEquals(self.onsignal_events, self.sendsig_events)
101

    
102
  def testReRun(self):
103
    self.mainloop.RegisterSignal(self)
104
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
105
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
106
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
107
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
108
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
109
    self.mainloop.Run()
110
    self.assertEquals(self.sendsig_events,
111
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
112
    self.assertEquals(self.onsignal_events, self.sendsig_events)
113
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
114
    self.mainloop.Run()
115
    self.assertEquals(self.sendsig_events,
116
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM,
117
                       signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
118
    self.assertEquals(self.onsignal_events, self.sendsig_events)
119

    
120

    
121
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
122

    
123
  def __init__(self):
124
    daemon.AsyncUDPSocket.__init__(self)
125
    self.received = []
126
    self.error_count = 0
127

    
128
  def handle_datagram(self, payload, ip, port):
129
    self.received.append((payload))
130
    if payload == "terminate":
131
      os.kill(os.getpid(), signal.SIGTERM)
132
    elif payload == "error":
133
      raise errors.GenericError("error")
134

    
135
  def handle_error(self):
136
    self.error_count += 1
137

    
138

    
139
class TestAsyncUDPSocket(testutils.GanetiTestCase):
140
  """Test daemon.AsyncUDPSocket"""
141

    
142
  def setUp(self):
143
    testutils.GanetiTestCase.setUp(self)
144
    self.mainloop = daemon.Mainloop()
145
    self.server = _MyAsyncUDPSocket()
146
    self.client = _MyAsyncUDPSocket()
147
    self.server.bind(("127.0.0.1", 0))
148
    self.port = self.server.getsockname()[1]
149

    
150
  def tearDown(self):
151
    self.server.close()
152
    self.client.close()
153
    testutils.GanetiTestCase.tearDown(self)
154

    
155
  def testNoDoubleBind(self):
156
    self.assertRaises(socket.error, self.client.bind, ("127.0.0.1", self.port))
157

    
158
  def _ThreadedClient(self, payload):
159
    self.client.enqueue_send("127.0.0.1", self.port, payload)
160
    print "sending %s" % payload
161
    while self.client.writable():
162
      self.client.handle_write()
163

    
164
  def testAsyncClientServer(self):
165
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
166
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
167
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
168
    self.mainloop.Run()
169
    self.assertEquals(self.server.received, ["p1", "p2", "terminate"])
170

    
171
  def testSyncClientServer(self):
172
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
173
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
174
    while self.client.writable():
175
      self.client.handle_write()
176
    self.server.process_next_packet()
177
    self.assertEquals(self.server.received, ["p1"])
178
    self.server.process_next_packet()
179
    self.assertEquals(self.server.received, ["p1", "p2"])
180
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
181
    while self.client.writable():
182
      self.client.handle_write()
183
    self.server.process_next_packet()
184
    self.assertEquals(self.server.received, ["p1", "p2", "p3"])
185

    
186
  def testErrorHandling(self):
187
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
188
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
189
    self.client.enqueue_send("127.0.0.1", self.port, "error")
190
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
191
    self.client.enqueue_send("127.0.0.1", self.port, "error")
192
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
193
    self.mainloop.Run()
194
    self.assertEquals(self.server.received,
195
                      ["p1", "p2", "error", "p3", "error", "terminate"])
196
    self.assertEquals(self.server.error_count, 2)
197

    
198

    
199
if __name__ == "__main__":
200
  testutils.GanetiTestProgram()