Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ c6987b16

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

    
29
from ganeti import daemon
30

    
31
import testutils
32

    
33

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

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

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

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

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

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

    
58
  def testSchedulerCancel(self):
59
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
60
                                           [signal.SIGTERM])
61
    self.mainloop.scheduler.cancel(handle)
62
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
63
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
64
    self.mainloop.Run()
65
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
66

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

    
83
  def testDeferredCancel(self):
84
    self.mainloop.RegisterSignal(self)
85
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
86
    handle1 = self.mainloop.scheduler.enter(0.3, 2, self._SendSig,
87
                                           [signal.SIGCHLD])
88
    handle2 = self.mainloop.scheduler.enter(0.4, 2, self._SendSig,
89
                                           [signal.SIGCHLD])
90
    self.mainloop.scheduler.enter(0, 1, self._CancelEvent, [handle1])
91
    self.mainloop.scheduler.enter(0, 1, self._CancelEvent, [handle2])
92
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGTERM])
93
    self.mainloop.Run()
94
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
95
    self.assertEquals(self.onsignal_events, self.sendsig_events)
96

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

    
115

    
116
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
117

    
118
  def __init__(self):
119
    daemon.AsyncUDPSocket.__init__(self)
120
    self.received = []
121
    self.error_count = 0
122

    
123
  def handle_datagram(self, payload, ip, port):
124
    self.received.append((payload))
125
    if payload == "terminate":
126
      os.kill(os.getpid(), signal.SIGTERM)
127
    elif payload == "error":
128
      raise errors.GenericError("error")
129

    
130
  def handle_error(self):
131
    self.error_count += 1
132

    
133

    
134
class TestAsyncUDPSocket(testutils.GanetiTestCase):
135
  """Test daemon.AsyncUDPSocket"""
136

    
137
  def setUp(self):
138
    testutils.GanetiTestCase.setUp(self)
139
    self.mainloop = daemon.Mainloop()
140
    self.server = _MyAsyncUDPSocket()
141
    self.client = _MyAsyncUDPSocket()
142
    self.server.bind(("127.0.0.1", 0))
143
    self.port = self.server.getsockname()[1]
144

    
145
  def tearDown(self):
146
    self.server.close()
147
    self.client.close()
148
    testutils.GanetiTestCase.tearDown(self)
149

    
150
  def testNoDoubleBind(self):
151
    self.assertRaises(socket.error, self.client.bind, ("127.0.0.1", self.port))
152

    
153
  def _ThreadedClient(self, payload):
154
    self.client.enqueue_send("127.0.0.1", self.port, payload)
155
    print "sending %s" % payload
156
    while self.client.writable():
157
      self.client.handle_write()
158

    
159
  def testAsyncClientServer(self):
160
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
161
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
162
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
163
    self.mainloop.Run()
164
    self.assertEquals(self.server.received, ["p1", "p2", "terminate"])
165

    
166
  def testSyncClientServer(self):
167
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
168
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
169
    while self.client.writable():
170
      self.client.handle_write()
171
    self.server.process_next_packet()
172
    self.assertEquals(self.server.received, ["p1"])
173
    self.server.process_next_packet()
174
    self.assertEquals(self.server.received, ["p1", "p2"])
175
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
176
    while self.client.writable():
177
      self.client.handle_write()
178
    self.server.process_next_packet()
179
    self.assertEquals(self.server.received, ["p1", "p2", "p3"])
180

    
181
  def testErrorHandling(self):
182
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
183
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
184
    self.client.enqueue_send("127.0.0.1", self.port, "error")
185
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
186
    self.client.enqueue_send("127.0.0.1", self.port, "error")
187
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
188
    self.mainloop.Run()
189
    self.assertEquals(self.server.received,
190
                      ["p1", "p2", "error", "p3", "error", "terminate"])
191
    self.assertEquals(self.server.error_count, 2)
192

    
193

    
194
if __name__ == "__main__":
195
  testutils.GanetiTestProgram()