Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ c6987b16

History | View | Annotate | Download (7.4 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 1118ec44 Guido Trotter
29 1118ec44 Guido Trotter
from ganeti import daemon
30 1118ec44 Guido Trotter
31 1118ec44 Guido Trotter
import testutils
32 1118ec44 Guido Trotter
33 1118ec44 Guido Trotter
34 1118ec44 Guido Trotter
class TestMainloop(testutils.GanetiTestCase):
35 1118ec44 Guido Trotter
  """Test daemon.Mainloop"""
36 1118ec44 Guido Trotter
37 1118ec44 Guido Trotter
  def setUp(self):
38 1118ec44 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
39 1118ec44 Guido Trotter
    self.mainloop = daemon.Mainloop()
40 1118ec44 Guido Trotter
    self.sendsig_events = []
41 1118ec44 Guido Trotter
    self.onsignal_events = []
42 1118ec44 Guido Trotter
43 1118ec44 Guido Trotter
  def _CancelEvent(self, handle):
44 1118ec44 Guido Trotter
    self.mainloop.scheduler.cancel(handle)
45 1118ec44 Guido Trotter
46 1118ec44 Guido Trotter
  def _SendSig(self, sig):
47 1118ec44 Guido Trotter
    self.sendsig_events.append(sig)
48 1118ec44 Guido Trotter
    os.kill(os.getpid(), sig)
49 1118ec44 Guido Trotter
50 1118ec44 Guido Trotter
  def OnSignal(self, signum):
51 1118ec44 Guido Trotter
    self.onsignal_events.append(signum)
52 1118ec44 Guido Trotter
53 1118ec44 Guido Trotter
  def testRunAndTermBySched(self):
54 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM])
55 1118ec44 Guido Trotter
    self.mainloop.Run() # terminates by _SendSig being scheduled
56 1118ec44 Guido Trotter
    self.assertEquals(self.sendsig_events, [signal.SIGTERM])
57 1118ec44 Guido Trotter
58 1118ec44 Guido Trotter
  def testSchedulerCancel(self):
59 1118ec44 Guido Trotter
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
60 1118ec44 Guido Trotter
                                           [signal.SIGTERM])
61 1118ec44 Guido Trotter
    self.mainloop.scheduler.cancel(handle)
62 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
63 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
64 1118ec44 Guido Trotter
    self.mainloop.Run()
65 1118ec44 Guido Trotter
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
66 1118ec44 Guido Trotter
67 1118ec44 Guido Trotter
  def testRegisterSignal(self):
68 1118ec44 Guido Trotter
    self.mainloop.RegisterSignal(self)
69 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
70 1118ec44 Guido Trotter
    handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
71 1118ec44 Guido Trotter
                                           [signal.SIGTERM])
72 1118ec44 Guido Trotter
    self.mainloop.scheduler.cancel(handle)
73 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
74 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
75 1118ec44 Guido Trotter
    # ...not delievered because they are scheduled after TERM
76 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
77 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
78 1118ec44 Guido Trotter
    self.mainloop.Run()
79 1118ec44 Guido Trotter
    self.assertEquals(self.sendsig_events,
80 1118ec44 Guido Trotter
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
81 1118ec44 Guido Trotter
    self.assertEquals(self.onsignal_events, self.sendsig_events)
82 1118ec44 Guido Trotter
83 1118ec44 Guido Trotter
  def testDeferredCancel(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
    handle1 = self.mainloop.scheduler.enter(0.3, 2, self._SendSig,
87 1118ec44 Guido Trotter
                                           [signal.SIGCHLD])
88 1118ec44 Guido Trotter
    handle2 = self.mainloop.scheduler.enter(0.4, 2, self._SendSig,
89 1118ec44 Guido Trotter
                                           [signal.SIGCHLD])
90 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0, 1, self._CancelEvent, [handle1])
91 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0, 1, self._CancelEvent, [handle2])
92 1118ec44 Guido Trotter
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGTERM])
93 1118ec44 Guido Trotter
    self.mainloop.Run()
94 1118ec44 Guido Trotter
    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGTERM])
95 1118ec44 Guido Trotter
    self.assertEquals(self.onsignal_events, self.sendsig_events)
96 1118ec44 Guido Trotter
97 c6987b16 Guido Trotter
  def testReRun(self):
98 c6987b16 Guido Trotter
    self.mainloop.RegisterSignal(self)
99 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
100 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGCHLD])
101 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
102 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.4, 1, self._SendSig, [signal.SIGCHLD])
103 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.5, 1, self._SendSig, [signal.SIGCHLD])
104 c6987b16 Guido Trotter
    self.mainloop.Run()
105 c6987b16 Guido Trotter
    self.assertEquals(self.sendsig_events,
106 c6987b16 Guido Trotter
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
107 c6987b16 Guido Trotter
    self.assertEquals(self.onsignal_events, self.sendsig_events)
108 c6987b16 Guido Trotter
    self.mainloop.scheduler.enter(0.3, 1, self._SendSig, [signal.SIGTERM])
109 c6987b16 Guido Trotter
    self.mainloop.Run()
110 c6987b16 Guido Trotter
    self.assertEquals(self.sendsig_events,
111 c6987b16 Guido Trotter
                      [signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM,
112 c6987b16 Guido Trotter
                       signal.SIGCHLD, signal.SIGCHLD, signal.SIGTERM])
113 c6987b16 Guido Trotter
    self.assertEquals(self.onsignal_events, self.sendsig_events)
114 c6987b16 Guido Trotter
115 1118ec44 Guido Trotter
116 4db33137 Guido Trotter
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
117 4db33137 Guido Trotter
118 4db33137 Guido Trotter
  def __init__(self):
119 4db33137 Guido Trotter
    daemon.AsyncUDPSocket.__init__(self)
120 4db33137 Guido Trotter
    self.received = []
121 4db33137 Guido Trotter
    self.error_count = 0
122 4db33137 Guido Trotter
123 4db33137 Guido Trotter
  def handle_datagram(self, payload, ip, port):
124 4db33137 Guido Trotter
    self.received.append((payload))
125 4db33137 Guido Trotter
    if payload == "terminate":
126 4db33137 Guido Trotter
      os.kill(os.getpid(), signal.SIGTERM)
127 4db33137 Guido Trotter
    elif payload == "error":
128 4db33137 Guido Trotter
      raise errors.GenericError("error")
129 4db33137 Guido Trotter
130 4db33137 Guido Trotter
  def handle_error(self):
131 4db33137 Guido Trotter
    self.error_count += 1
132 4db33137 Guido Trotter
133 4db33137 Guido Trotter
134 4db33137 Guido Trotter
class TestAsyncUDPSocket(testutils.GanetiTestCase):
135 4db33137 Guido Trotter
  """Test daemon.AsyncUDPSocket"""
136 4db33137 Guido Trotter
137 4db33137 Guido Trotter
  def setUp(self):
138 4db33137 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
139 4db33137 Guido Trotter
    self.mainloop = daemon.Mainloop()
140 4db33137 Guido Trotter
    self.server = _MyAsyncUDPSocket()
141 4db33137 Guido Trotter
    self.client = _MyAsyncUDPSocket()
142 4db33137 Guido Trotter
    self.server.bind(("127.0.0.1", 0))
143 4db33137 Guido Trotter
    self.port = self.server.getsockname()[1]
144 4db33137 Guido Trotter
145 4db33137 Guido Trotter
  def tearDown(self):
146 4db33137 Guido Trotter
    self.server.close()
147 4db33137 Guido Trotter
    self.client.close()
148 4db33137 Guido Trotter
    testutils.GanetiTestCase.tearDown(self)
149 4db33137 Guido Trotter
150 4db33137 Guido Trotter
  def testNoDoubleBind(self):
151 4db33137 Guido Trotter
    self.assertRaises(socket.error, self.client.bind, ("127.0.0.1", self.port))
152 4db33137 Guido Trotter
153 4db33137 Guido Trotter
  def _ThreadedClient(self, payload):
154 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, payload)
155 4db33137 Guido Trotter
    print "sending %s" % payload
156 4db33137 Guido Trotter
    while self.client.writable():
157 4db33137 Guido Trotter
      self.client.handle_write()
158 4db33137 Guido Trotter
159 4db33137 Guido Trotter
  def testAsyncClientServer(self):
160 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
161 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
162 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
163 4db33137 Guido Trotter
    self.mainloop.Run()
164 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2", "terminate"])
165 4db33137 Guido Trotter
166 4db33137 Guido Trotter
  def testSyncClientServer(self):
167 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
168 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
169 4db33137 Guido Trotter
    while self.client.writable():
170 4db33137 Guido Trotter
      self.client.handle_write()
171 4db33137 Guido Trotter
    self.server.process_next_packet()
172 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1"])
173 4db33137 Guido Trotter
    self.server.process_next_packet()
174 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2"])
175 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
176 4db33137 Guido Trotter
    while self.client.writable():
177 4db33137 Guido Trotter
      self.client.handle_write()
178 4db33137 Guido Trotter
    self.server.process_next_packet()
179 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2", "p3"])
180 4db33137 Guido Trotter
181 4db33137 Guido Trotter
  def testErrorHandling(self):
182 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
183 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
184 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "error")
185 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
186 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "error")
187 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
188 4db33137 Guido Trotter
    self.mainloop.Run()
189 4db33137 Guido Trotter
    self.assertEquals(self.server.received,
190 4db33137 Guido Trotter
                      ["p1", "p2", "error", "p3", "error", "terminate"])
191 4db33137 Guido Trotter
    self.assertEquals(self.server.error_count, 2)
192 4db33137 Guido Trotter
193 4db33137 Guido Trotter
194 1118ec44 Guido Trotter
if __name__ == "__main__":
195 1118ec44 Guido Trotter
  testutils.GanetiTestProgram()