Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.asyncnotifier_unittest.py @ 7578ab0a

History | View | Annotate | Download (6.4 kB)

1 17496050 Guido Trotter
#!/usr/bin/python
2 17496050 Guido Trotter
#
3 17496050 Guido Trotter
4 17496050 Guido Trotter
# Copyright (C) 2010 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 17496050 Guido Trotter
  # pylint: disable-msg=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 17496050 Guido Trotter
  class OnInotifyCallback:
77 49f986e7 Guido Trotter
    def __init__(self, testobj, i):
78 49f986e7 Guido Trotter
      self.testobj = testobj
79 49f986e7 Guido Trotter
      self.notified = testobj.notified
80 17496050 Guido Trotter
      self.i = i
81 17496050 Guido Trotter
82 17496050 Guido Trotter
    def __call__(self, enabled):
83 17496050 Guido Trotter
      self.notified[self.i] = True
84 49f986e7 Guido Trotter
      if self.i == self.testobj.NOTIFIER_TERM:
85 17496050 Guido Trotter
        os.kill(os.getpid(), signal.SIGTERM)
86 7678409f Guido Trotter
      elif self.i == self.testobj.NOTIFIER_ERR:
87 7678409f Guido Trotter
        raise errors.GenericError("an error")
88 17496050 Guido Trotter
89 17496050 Guido Trotter
  def testReplace(self):
90 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
91 17496050 Guido Trotter
    self.mainloop.Run()
92 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
93 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
94 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
95 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
96 17496050 Guido Trotter
97 17496050 Guido Trotter
  def testEnableDisable(self):
98 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
99 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
100 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
101 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
102 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
103 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
104 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
105 17496050 Guido Trotter
    self.mainloop.Run()
106 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
107 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
108 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
109 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
110 17496050 Guido Trotter
111 17496050 Guido Trotter
  def testDoubleEnable(self):
112 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
113 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
114 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
115 17496050 Guido Trotter
    self.mainloop.Run()
116 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
117 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
118 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
119 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
120 17496050 Guido Trotter
121 17496050 Guido Trotter
  def testDefaultDisabled(self):
122 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
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 49f986e7 Guido Trotter
    # NORM notifier is disabled by default
127 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
128 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
129 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
130 17496050 Guido Trotter
131 17496050 Guido Trotter
  def testBothEnabled(self):
132 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_NORM].enable()
133 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
134 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
135 17496050 Guido Trotter
    self.mainloop.Run()
136 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
137 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_NORM])
138 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
139 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
140 7678409f Guido Trotter
141 7678409f Guido Trotter
  def testError(self):
142 7678409f Guido Trotter
    self.ihandler[self.NOTIFIER_ERR].enable()
143 7678409f Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_ERR], data="dummy")
144 e3cc4c69 Guido Trotter
    self.assertRaises(errors.GenericError, self.mainloop.Run)
145 7678409f Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_ERR])
146 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_ERR].error_count, 1)
147 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
148 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
149 17496050 Guido Trotter
150 17496050 Guido Trotter
151 e543a42f Michael Hanselmann
class TestSingleFileEventHandlerError(unittest.TestCase):
152 e543a42f Michael Hanselmann
  def setUp(self):
153 e543a42f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
154 e543a42f Michael Hanselmann
155 e543a42f Michael Hanselmann
  def tearDown(self):
156 e543a42f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
157 e543a42f Michael Hanselmann
158 e543a42f Michael Hanselmann
  def test(self):
159 e543a42f Michael Hanselmann
    wm = pyinotify.WatchManager()
160 e543a42f Michael Hanselmann
    handler = asyncnotifier.SingleFileEventHandler(wm, None,
161 e543a42f Michael Hanselmann
                                                   utils.PathJoin(self.tmpdir,
162 e543a42f Michael Hanselmann
                                                                  "nonexist"))
163 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
164 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
165 e543a42f Michael Hanselmann
    handler.disable()
166 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
167 e543a42f Michael Hanselmann
168 e543a42f Michael Hanselmann
169 17496050 Guido Trotter
if __name__ == "__main__":
170 17496050 Guido Trotter
  testutils.GanetiTestProgram()