Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.asyncnotifier_unittest.py @ 415feb2e

History | View | Annotate | Download (6.7 kB)

1 17496050 Guido Trotter
#!/usr/bin/python
2 17496050 Guido Trotter
#
3 17496050 Guido Trotter
4 0f85ebd9 Iustin Pop
# Copyright (C) 2010, 2012 Google Inc.
5 17496050 Guido Trotter
#
6 17496050 Guido Trotter
# This program is free software; you can redistribute it and/or modify
7 17496050 Guido Trotter
# it under the terms of the GNU General Public License as published by
8 17496050 Guido Trotter
# the Free Software Foundation; either version 2 of the License, or
9 17496050 Guido Trotter
# (at your option) any later version.
10 17496050 Guido Trotter
#
11 17496050 Guido Trotter
# This program is distributed in the hope that it will be useful, but
12 17496050 Guido Trotter
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 17496050 Guido Trotter
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 17496050 Guido Trotter
# General Public License for more details.
15 17496050 Guido Trotter
#
16 17496050 Guido Trotter
# You should have received a copy of the GNU General Public License
17 17496050 Guido Trotter
# along with this program; if not, write to the Free Software
18 17496050 Guido Trotter
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 17496050 Guido Trotter
# 02110-1301, USA.
20 17496050 Guido Trotter
21 17496050 Guido Trotter
22 17496050 Guido Trotter
"""Script for unittesting the asyncnotifier module"""
23 17496050 Guido Trotter
24 17496050 Guido Trotter
import unittest
25 17496050 Guido Trotter
import signal
26 17496050 Guido Trotter
import os
27 e543a42f Michael Hanselmann
import tempfile
28 e543a42f Michael Hanselmann
import shutil
29 17496050 Guido Trotter
30 17496050 Guido Trotter
try:
31 db859c7d Michael Hanselmann
  # pylint: disable=E0611
32 17496050 Guido Trotter
  from pyinotify import pyinotify
33 17496050 Guido Trotter
except ImportError:
34 17496050 Guido Trotter
  import pyinotify
35 17496050 Guido Trotter
36 17496050 Guido Trotter
from ganeti import asyncnotifier
37 17496050 Guido Trotter
from ganeti import daemon
38 17496050 Guido Trotter
from ganeti import utils
39 7678409f Guido Trotter
from ganeti import errors
40 17496050 Guido Trotter
41 17496050 Guido Trotter
import testutils
42 17496050 Guido Trotter
43 17496050 Guido Trotter
44 7678409f Guido Trotter
class _MyErrorLoggingAsyncNotifier(asyncnotifier.ErrorLoggingAsyncNotifier):
45 7678409f Guido Trotter
  def __init__(self, *args, **kwargs):
46 7678409f Guido Trotter
    asyncnotifier.ErrorLoggingAsyncNotifier.__init__(self, *args, **kwargs)
47 7678409f Guido Trotter
    self.error_count = 0
48 7678409f Guido Trotter
49 7678409f Guido Trotter
  def handle_error(self):
50 7678409f Guido Trotter
    self.error_count += 1
51 e3cc4c69 Guido Trotter
    raise
52 7678409f Guido Trotter
53 7678409f Guido Trotter
54 17496050 Guido Trotter
class TestSingleFileEventHandler(testutils.GanetiTestCase):
55 17496050 Guido Trotter
  """Test daemon.Mainloop"""
56 17496050 Guido Trotter
57 7678409f Guido Trotter
  NOTIFIERS = [NOTIFIER_TERM, NOTIFIER_NORM, NOTIFIER_ERR] = range(3)
58 49f986e7 Guido Trotter
59 17496050 Guido Trotter
  def setUp(self):
60 17496050 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
61 17496050 Guido Trotter
    self.mainloop = daemon.Mainloop()
62 49f986e7 Guido Trotter
    self.chk_files = [self._CreateTempFile() for i in self.NOTIFIERS]
63 49f986e7 Guido Trotter
    self.notified = [False for i in self.NOTIFIERS]
64 17496050 Guido Trotter
    # We need one watch manager per notifier, as those contain the file
65 17496050 Guido Trotter
    # descriptor which is monitored by asyncore
66 49f986e7 Guido Trotter
    self.wms = [pyinotify.WatchManager() for i in self.NOTIFIERS]
67 84ce674e Iustin Pop
    self.cbk = [self.OnInotifyCallback(self, i) for i in self.NOTIFIERS]
68 84ce674e Iustin Pop
    self.ihandler = [asyncnotifier.SingleFileEventHandler(wm, cb, cf)
69 84ce674e Iustin Pop
                     for (wm, cb, cf) in
70 84ce674e Iustin Pop
                     zip(self.wms, self.cbk, self.chk_files)]
71 84ce674e Iustin Pop
    self.notifiers = [_MyErrorLoggingAsyncNotifier(wm, ih)
72 84ce674e Iustin Pop
                      for (wm, ih) in zip(self.wms, self.ihandler)]
73 49f986e7 Guido Trotter
    # TERM notifier is enabled by default, as we use it to get out of the loop
74 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
75 17496050 Guido Trotter
76 0f85ebd9 Iustin Pop
  def tearDown(self):
77 0f85ebd9 Iustin Pop
    # disable the inotifiers, before removing the files
78 0f85ebd9 Iustin Pop
    for i in self.ihandler:
79 0f85ebd9 Iustin Pop
      i.disable()
80 0f85ebd9 Iustin Pop
    testutils.GanetiTestCase.tearDown(self)
81 0f85ebd9 Iustin Pop
    # and unregister the fd's being polled
82 0f85ebd9 Iustin Pop
    for n in self.notifiers:
83 0f85ebd9 Iustin Pop
      n.del_channel()
84 0f85ebd9 Iustin Pop
85 17496050 Guido Trotter
  class OnInotifyCallback:
86 49f986e7 Guido Trotter
    def __init__(self, testobj, i):
87 49f986e7 Guido Trotter
      self.testobj = testobj
88 49f986e7 Guido Trotter
      self.notified = testobj.notified
89 17496050 Guido Trotter
      self.i = i
90 17496050 Guido Trotter
91 17496050 Guido Trotter
    def __call__(self, enabled):
92 17496050 Guido Trotter
      self.notified[self.i] = True
93 49f986e7 Guido Trotter
      if self.i == self.testobj.NOTIFIER_TERM:
94 17496050 Guido Trotter
        os.kill(os.getpid(), signal.SIGTERM)
95 7678409f Guido Trotter
      elif self.i == self.testobj.NOTIFIER_ERR:
96 7678409f Guido Trotter
        raise errors.GenericError("an error")
97 17496050 Guido Trotter
98 17496050 Guido Trotter
  def testReplace(self):
99 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
100 17496050 Guido Trotter
    self.mainloop.Run()
101 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
102 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
103 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
104 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
105 17496050 Guido Trotter
106 17496050 Guido Trotter
  def testEnableDisable(self):
107 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
108 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
109 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
110 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
111 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
112 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
113 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
114 17496050 Guido Trotter
    self.mainloop.Run()
115 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
116 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
117 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
118 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
119 17496050 Guido Trotter
120 17496050 Guido Trotter
  def testDoubleEnable(self):
121 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
122 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
123 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
124 17496050 Guido Trotter
    self.mainloop.Run()
125 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
126 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
127 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
128 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
129 17496050 Guido Trotter
130 17496050 Guido Trotter
  def testDefaultDisabled(self):
131 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
132 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
133 17496050 Guido Trotter
    self.mainloop.Run()
134 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
135 49f986e7 Guido Trotter
    # NORM notifier is disabled by default
136 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
137 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
138 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
139 17496050 Guido Trotter
140 17496050 Guido Trotter
  def testBothEnabled(self):
141 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_NORM].enable()
142 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
143 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
144 17496050 Guido Trotter
    self.mainloop.Run()
145 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
146 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_NORM])
147 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
148 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
149 7678409f Guido Trotter
150 7678409f Guido Trotter
  def testError(self):
151 7678409f Guido Trotter
    self.ihandler[self.NOTIFIER_ERR].enable()
152 7678409f Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_ERR], data="dummy")
153 e3cc4c69 Guido Trotter
    self.assertRaises(errors.GenericError, self.mainloop.Run)
154 7678409f Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_ERR])
155 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_ERR].error_count, 1)
156 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
157 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
158 17496050 Guido Trotter
159 17496050 Guido Trotter
160 e543a42f Michael Hanselmann
class TestSingleFileEventHandlerError(unittest.TestCase):
161 e543a42f Michael Hanselmann
  def setUp(self):
162 e543a42f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
163 e543a42f Michael Hanselmann
164 e543a42f Michael Hanselmann
  def tearDown(self):
165 e543a42f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
166 e543a42f Michael Hanselmann
167 e543a42f Michael Hanselmann
  def test(self):
168 e543a42f Michael Hanselmann
    wm = pyinotify.WatchManager()
169 e543a42f Michael Hanselmann
    handler = asyncnotifier.SingleFileEventHandler(wm, None,
170 e543a42f Michael Hanselmann
                                                   utils.PathJoin(self.tmpdir,
171 e543a42f Michael Hanselmann
                                                                  "nonexist"))
172 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
173 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
174 e543a42f Michael Hanselmann
    handler.disable()
175 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
176 e543a42f Michael Hanselmann
177 e543a42f Michael Hanselmann
178 17496050 Guido Trotter
if __name__ == "__main__":
179 17496050 Guido Trotter
  testutils.GanetiTestProgram()