Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.asyncnotifier_unittest.py @ e543a42f

History | View | Annotate | Download (6.6 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 49f986e7 Guido Trotter
    self.cbk = [self.OnInotifyCallback(self, i)
68 49f986e7 Guido Trotter
                 for i in range(len(self.NOTIFIERS))]
69 17496050 Guido Trotter
    self.ihandler = [asyncnotifier.SingleFileEventHandler(self.wms[i],
70 17496050 Guido Trotter
                                                          self.cbk[i],
71 17496050 Guido Trotter
                                                          self.chk_files[i])
72 49f986e7 Guido Trotter
                      for i in range(len(self.NOTIFIERS))]
73 7678409f Guido Trotter
    self.notifiers = [_MyErrorLoggingAsyncNotifier(self.wms[i],
74 7678409f Guido Trotter
                                                   self.ihandler[i])
75 49f986e7 Guido Trotter
                       for i in range(len(self.NOTIFIERS))]
76 49f986e7 Guido Trotter
    # TERM notifier is enabled by default, as we use it to get out of the loop
77 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
78 17496050 Guido Trotter
79 17496050 Guido Trotter
  class OnInotifyCallback:
80 49f986e7 Guido Trotter
    def __init__(self, testobj, i):
81 49f986e7 Guido Trotter
      self.testobj = testobj
82 49f986e7 Guido Trotter
      self.notified = testobj.notified
83 17496050 Guido Trotter
      self.i = i
84 17496050 Guido Trotter
85 17496050 Guido Trotter
    def __call__(self, enabled):
86 17496050 Guido Trotter
      self.notified[self.i] = True
87 49f986e7 Guido Trotter
      if self.i == self.testobj.NOTIFIER_TERM:
88 17496050 Guido Trotter
        os.kill(os.getpid(), signal.SIGTERM)
89 7678409f Guido Trotter
      elif self.i == self.testobj.NOTIFIER_ERR:
90 7678409f Guido Trotter
        raise errors.GenericError("an error")
91 17496050 Guido Trotter
92 17496050 Guido Trotter
  def testReplace(self):
93 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
94 17496050 Guido Trotter
    self.mainloop.Run()
95 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
96 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
97 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
98 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
99 17496050 Guido Trotter
100 17496050 Guido Trotter
  def testEnableDisable(self):
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].disable()
104 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
105 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
106 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
107 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
108 17496050 Guido Trotter
    self.mainloop.Run()
109 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
110 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
111 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
112 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
113 17496050 Guido Trotter
114 17496050 Guido Trotter
  def testDoubleEnable(self):
115 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
116 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
117 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
118 17496050 Guido Trotter
    self.mainloop.Run()
119 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
120 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
121 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
122 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
123 17496050 Guido Trotter
124 17496050 Guido Trotter
  def testDefaultDisabled(self):
125 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
126 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
127 17496050 Guido Trotter
    self.mainloop.Run()
128 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
129 49f986e7 Guido Trotter
    # NORM notifier is disabled by default
130 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
131 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
132 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
133 17496050 Guido Trotter
134 17496050 Guido Trotter
  def testBothEnabled(self):
135 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_NORM].enable()
136 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
137 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
138 17496050 Guido Trotter
    self.mainloop.Run()
139 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
140 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_NORM])
141 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
142 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
143 7678409f Guido Trotter
144 7678409f Guido Trotter
  def testError(self):
145 7678409f Guido Trotter
    self.ihandler[self.NOTIFIER_ERR].enable()
146 7678409f Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_ERR], data="dummy")
147 e3cc4c69 Guido Trotter
    self.assertRaises(errors.GenericError, self.mainloop.Run)
148 7678409f Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_ERR])
149 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_ERR].error_count, 1)
150 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
151 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
152 17496050 Guido Trotter
153 17496050 Guido Trotter
154 e543a42f Michael Hanselmann
class TestSingleFileEventHandlerError(unittest.TestCase):
155 e543a42f Michael Hanselmann
  def setUp(self):
156 e543a42f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
157 e543a42f Michael Hanselmann
158 e543a42f Michael Hanselmann
  def tearDown(self):
159 e543a42f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
160 e543a42f Michael Hanselmann
161 e543a42f Michael Hanselmann
  def test(self):
162 e543a42f Michael Hanselmann
    wm = pyinotify.WatchManager()
163 e543a42f Michael Hanselmann
    handler = asyncnotifier.SingleFileEventHandler(wm, None,
164 e543a42f Michael Hanselmann
                                                   utils.PathJoin(self.tmpdir,
165 e543a42f Michael Hanselmann
                                                                  "nonexist"))
166 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
167 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
168 e543a42f Michael Hanselmann
    handler.disable()
169 e543a42f Michael Hanselmann
    self.assertRaises(errors.InotifyError, handler.enable)
170 e543a42f Michael Hanselmann
171 e543a42f Michael Hanselmann
172 17496050 Guido Trotter
if __name__ == "__main__":
173 17496050 Guido Trotter
  testutils.GanetiTestProgram()