Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.daemon_unittest.py @ 4db33137

History | View | Annotate | Download (6.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 1118ec44 Guido Trotter
98 4db33137 Guido Trotter
class _MyAsyncUDPSocket(daemon.AsyncUDPSocket):
99 4db33137 Guido Trotter
100 4db33137 Guido Trotter
  def __init__(self):
101 4db33137 Guido Trotter
    daemon.AsyncUDPSocket.__init__(self)
102 4db33137 Guido Trotter
    self.received = []
103 4db33137 Guido Trotter
    self.error_count = 0
104 4db33137 Guido Trotter
105 4db33137 Guido Trotter
  def handle_datagram(self, payload, ip, port):
106 4db33137 Guido Trotter
    self.received.append((payload))
107 4db33137 Guido Trotter
    if payload == "terminate":
108 4db33137 Guido Trotter
      os.kill(os.getpid(), signal.SIGTERM)
109 4db33137 Guido Trotter
    elif payload == "error":
110 4db33137 Guido Trotter
      raise errors.GenericError("error")
111 4db33137 Guido Trotter
112 4db33137 Guido Trotter
  def handle_error(self):
113 4db33137 Guido Trotter
    self.error_count += 1
114 4db33137 Guido Trotter
115 4db33137 Guido Trotter
116 4db33137 Guido Trotter
class TestAsyncUDPSocket(testutils.GanetiTestCase):
117 4db33137 Guido Trotter
  """Test daemon.AsyncUDPSocket"""
118 4db33137 Guido Trotter
119 4db33137 Guido Trotter
  def setUp(self):
120 4db33137 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
121 4db33137 Guido Trotter
    self.mainloop = daemon.Mainloop()
122 4db33137 Guido Trotter
    self.server = _MyAsyncUDPSocket()
123 4db33137 Guido Trotter
    self.client = _MyAsyncUDPSocket()
124 4db33137 Guido Trotter
    self.server.bind(("127.0.0.1", 0))
125 4db33137 Guido Trotter
    self.port = self.server.getsockname()[1]
126 4db33137 Guido Trotter
127 4db33137 Guido Trotter
  def tearDown(self):
128 4db33137 Guido Trotter
    self.server.close()
129 4db33137 Guido Trotter
    self.client.close()
130 4db33137 Guido Trotter
    testutils.GanetiTestCase.tearDown(self)
131 4db33137 Guido Trotter
132 4db33137 Guido Trotter
  def testNoDoubleBind(self):
133 4db33137 Guido Trotter
    self.assertRaises(socket.error, self.client.bind, ("127.0.0.1", self.port))
134 4db33137 Guido Trotter
135 4db33137 Guido Trotter
  def _ThreadedClient(self, payload):
136 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, payload)
137 4db33137 Guido Trotter
    print "sending %s" % payload
138 4db33137 Guido Trotter
    while self.client.writable():
139 4db33137 Guido Trotter
      self.client.handle_write()
140 4db33137 Guido Trotter
141 4db33137 Guido Trotter
  def testAsyncClientServer(self):
142 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
143 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
144 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
145 4db33137 Guido Trotter
    self.mainloop.Run()
146 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2", "terminate"])
147 4db33137 Guido Trotter
148 4db33137 Guido Trotter
  def testSyncClientServer(self):
149 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
150 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
151 4db33137 Guido Trotter
    while self.client.writable():
152 4db33137 Guido Trotter
      self.client.handle_write()
153 4db33137 Guido Trotter
    self.server.process_next_packet()
154 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1"])
155 4db33137 Guido Trotter
    self.server.process_next_packet()
156 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2"])
157 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
158 4db33137 Guido Trotter
    while self.client.writable():
159 4db33137 Guido Trotter
      self.client.handle_write()
160 4db33137 Guido Trotter
    self.server.process_next_packet()
161 4db33137 Guido Trotter
    self.assertEquals(self.server.received, ["p1", "p2", "p3"])
162 4db33137 Guido Trotter
163 4db33137 Guido Trotter
  def testErrorHandling(self):
164 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p1")
165 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p2")
166 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "error")
167 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "p3")
168 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "error")
169 4db33137 Guido Trotter
    self.client.enqueue_send("127.0.0.1", self.port, "terminate")
170 4db33137 Guido Trotter
    self.mainloop.Run()
171 4db33137 Guido Trotter
    self.assertEquals(self.server.received,
172 4db33137 Guido Trotter
                      ["p1", "p2", "error", "p3", "error", "terminate"])
173 4db33137 Guido Trotter
    self.assertEquals(self.server.error_count, 2)
174 4db33137 Guido Trotter
175 4db33137 Guido Trotter
176 1118ec44 Guido Trotter
if __name__ == "__main__":
177 1118ec44 Guido Trotter
  testutils.GanetiTestProgram()