Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.asyncnotifier_unittest.py @ 6760e4ed

History | View | Annotate | Download (5.9 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 17496050 Guido Trotter
28 17496050 Guido Trotter
try:
29 17496050 Guido Trotter
  # pylint: disable-msg=E0611
30 17496050 Guido Trotter
  from pyinotify import pyinotify
31 17496050 Guido Trotter
except ImportError:
32 17496050 Guido Trotter
  import pyinotify
33 17496050 Guido Trotter
34 17496050 Guido Trotter
from ganeti import asyncnotifier
35 17496050 Guido Trotter
from ganeti import daemon
36 17496050 Guido Trotter
from ganeti import utils
37 7678409f Guido Trotter
from ganeti import errors
38 17496050 Guido Trotter
39 17496050 Guido Trotter
import testutils
40 17496050 Guido Trotter
41 17496050 Guido Trotter
42 7678409f Guido Trotter
class _MyErrorLoggingAsyncNotifier(asyncnotifier.ErrorLoggingAsyncNotifier):
43 7678409f Guido Trotter
  def __init__(self, *args, **kwargs):
44 7678409f Guido Trotter
    asyncnotifier.ErrorLoggingAsyncNotifier.__init__(self, *args, **kwargs)
45 7678409f Guido Trotter
    self.error_count = 0
46 7678409f Guido Trotter
47 7678409f Guido Trotter
  def handle_error(self):
48 7678409f Guido Trotter
    self.error_count += 1
49 e3cc4c69 Guido Trotter
    raise
50 7678409f Guido Trotter
51 7678409f Guido Trotter
52 17496050 Guido Trotter
class TestSingleFileEventHandler(testutils.GanetiTestCase):
53 17496050 Guido Trotter
  """Test daemon.Mainloop"""
54 17496050 Guido Trotter
55 7678409f Guido Trotter
  NOTIFIERS = [NOTIFIER_TERM, NOTIFIER_NORM, NOTIFIER_ERR] = range(3)
56 49f986e7 Guido Trotter
57 17496050 Guido Trotter
  def setUp(self):
58 17496050 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
59 17496050 Guido Trotter
    self.mainloop = daemon.Mainloop()
60 49f986e7 Guido Trotter
    self.chk_files = [self._CreateTempFile() for i in self.NOTIFIERS]
61 49f986e7 Guido Trotter
    self.notified = [False for i in self.NOTIFIERS]
62 17496050 Guido Trotter
    # We need one watch manager per notifier, as those contain the file
63 17496050 Guido Trotter
    # descriptor which is monitored by asyncore
64 49f986e7 Guido Trotter
    self.wms = [pyinotify.WatchManager() for i in self.NOTIFIERS]
65 49f986e7 Guido Trotter
    self.cbk = [self.OnInotifyCallback(self, i)
66 49f986e7 Guido Trotter
                 for i in range(len(self.NOTIFIERS))]
67 17496050 Guido Trotter
    self.ihandler = [asyncnotifier.SingleFileEventHandler(self.wms[i],
68 17496050 Guido Trotter
                                                          self.cbk[i],
69 17496050 Guido Trotter
                                                          self.chk_files[i])
70 49f986e7 Guido Trotter
                      for i in range(len(self.NOTIFIERS))]
71 7678409f Guido Trotter
    self.notifiers = [_MyErrorLoggingAsyncNotifier(self.wms[i],
72 7678409f Guido Trotter
                                                   self.ihandler[i])
73 49f986e7 Guido Trotter
                       for i in range(len(self.NOTIFIERS))]
74 49f986e7 Guido Trotter
    # TERM notifier is enabled by default, as we use it to get out of the loop
75 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
76 17496050 Guido Trotter
77 17496050 Guido Trotter
  class OnInotifyCallback:
78 49f986e7 Guido Trotter
    def __init__(self, testobj, i):
79 49f986e7 Guido Trotter
      self.testobj = testobj
80 49f986e7 Guido Trotter
      self.notified = testobj.notified
81 17496050 Guido Trotter
      self.i = i
82 17496050 Guido Trotter
83 17496050 Guido Trotter
    def __call__(self, enabled):
84 17496050 Guido Trotter
      self.notified[self.i] = True
85 49f986e7 Guido Trotter
      if self.i == self.testobj.NOTIFIER_TERM:
86 17496050 Guido Trotter
        os.kill(os.getpid(), signal.SIGTERM)
87 7678409f Guido Trotter
      elif self.i == self.testobj.NOTIFIER_ERR:
88 7678409f Guido Trotter
        raise errors.GenericError("an error")
89 17496050 Guido Trotter
90 17496050 Guido Trotter
  def testReplace(self):
91 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
92 17496050 Guido Trotter
    self.mainloop.Run()
93 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
94 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
95 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
96 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
97 17496050 Guido Trotter
98 17496050 Guido Trotter
  def testEnableDisable(self):
99 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
100 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
101 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
102 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
103 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].disable()
104 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
105 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
106 17496050 Guido Trotter
    self.mainloop.Run()
107 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
108 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
109 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
110 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
111 17496050 Guido Trotter
112 17496050 Guido Trotter
  def testDoubleEnable(self):
113 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
114 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_TERM].enable()
115 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
116 17496050 Guido Trotter
    self.mainloop.Run()
117 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
118 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
119 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
120 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
121 17496050 Guido Trotter
122 17496050 Guido Trotter
  def testDefaultDisabled(self):
123 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
124 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
125 17496050 Guido Trotter
    self.mainloop.Run()
126 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
127 49f986e7 Guido Trotter
    # NORM notifier is disabled by default
128 158206e0 Manuel Franceschini
    self.assertFalse(self.notified[self.NOTIFIER_NORM])
129 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
130 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
131 17496050 Guido Trotter
132 17496050 Guido Trotter
  def testBothEnabled(self):
133 49f986e7 Guido Trotter
    self.ihandler[self.NOTIFIER_NORM].enable()
134 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_NORM], data="dummy")
135 49f986e7 Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_TERM], data="dummy")
136 17496050 Guido Trotter
    self.mainloop.Run()
137 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_TERM])
138 49f986e7 Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_NORM])
139 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
140 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
141 7678409f Guido Trotter
142 7678409f Guido Trotter
  def testError(self):
143 7678409f Guido Trotter
    self.ihandler[self.NOTIFIER_ERR].enable()
144 7678409f Guido Trotter
    utils.WriteFile(self.chk_files[self.NOTIFIER_ERR], data="dummy")
145 e3cc4c69 Guido Trotter
    self.assertRaises(errors.GenericError, self.mainloop.Run)
146 7678409f Guido Trotter
    self.assert_(self.notified[self.NOTIFIER_ERR])
147 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_ERR].error_count, 1)
148 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_NORM].error_count, 0)
149 7678409f Guido Trotter
    self.assertEquals(self.notifiers[self.NOTIFIER_TERM].error_count, 0)
150 17496050 Guido Trotter
151 17496050 Guido Trotter
152 17496050 Guido Trotter
if __name__ == "__main__":
153 17496050 Guido Trotter
  testutils.GanetiTestProgram()