Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.hooks_unittest.py @ d01e51a5

History | View | Annotate | Download (17.1 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Script for unittesting the hooks module"""
23 a8083063 Iustin Pop
24 a8083063 Iustin Pop
25 a8083063 Iustin Pop
import unittest
26 a8083063 Iustin Pop
import os
27 a8083063 Iustin Pop
import time
28 a8083063 Iustin Pop
import tempfile
29 a8083063 Iustin Pop
import os.path
30 a8083063 Iustin Pop
31 a8083063 Iustin Pop
from ganeti import errors
32 a8083063 Iustin Pop
from ganeti import opcodes
33 a8083063 Iustin Pop
from ganeti import mcpu
34 a8083063 Iustin Pop
from ganeti import backend
35 a8083063 Iustin Pop
from ganeti import constants
36 a8083063 Iustin Pop
from ganeti import cmdlib
37 7ccb3074 Guido Trotter
from ganeti import rpc
38 dd7f6776 Michael Hanselmann
from ganeti import compat
39 a56625a2 Michael Hanselmann
from ganeti import pathutils
40 a8083063 Iustin Pop
from ganeti.constants import HKR_SUCCESS, HKR_FAIL, HKR_SKIP
41 a8083063 Iustin Pop
42 c259ce64 Michael Hanselmann
from mocks import FakeConfig, FakeProc, FakeContext
43 a8083063 Iustin Pop
44 25231ec5 Michael Hanselmann
import testutils
45 25231ec5 Michael Hanselmann
46 25231ec5 Michael Hanselmann
47 a8083063 Iustin Pop
class FakeLU(cmdlib.LogicalUnit):
48 a8083063 Iustin Pop
  HPATH = "test"
49 07e0896f Michael Hanselmann
50 a8083063 Iustin Pop
  def BuildHooksEnv(self):
51 07e0896f Michael Hanselmann
    return {}
52 07e0896f Michael Hanselmann
53 07e0896f Michael Hanselmann
  def BuildHooksNodes(self):
54 07e0896f Michael Hanselmann
    return ["localhost"], ["localhost"]
55 a8083063 Iustin Pop
56 25231ec5 Michael Hanselmann
57 a8083063 Iustin Pop
class TestHooksRunner(unittest.TestCase):
58 a8083063 Iustin Pop
  """Testing case for HooksRunner"""
59 a8083063 Iustin Pop
  def setUp(self):
60 a8083063 Iustin Pop
    self.torm = []
61 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp()
62 a8083063 Iustin Pop
    self.torm.append((self.tmpdir, True))
63 a8083063 Iustin Pop
    self.logdir = tempfile.mkdtemp()
64 a8083063 Iustin Pop
    self.torm.append((self.logdir, True))
65 a8083063 Iustin Pop
    self.hpath = "fake"
66 a8083063 Iustin Pop
    self.ph_dirs = {}
67 a8083063 Iustin Pop
    for i in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
68 a8083063 Iustin Pop
      dname = "%s/%s-%s.d" % (self.tmpdir, self.hpath, i)
69 a8083063 Iustin Pop
      os.mkdir(dname)
70 a8083063 Iustin Pop
      self.torm.append((dname, True))
71 a8083063 Iustin Pop
      self.ph_dirs[i] = dname
72 a8083063 Iustin Pop
    self.hr = backend.HooksRunner(hooks_base_dir=self.tmpdir)
73 a8083063 Iustin Pop
74 a8083063 Iustin Pop
  def tearDown(self):
75 a8083063 Iustin Pop
    self.torm.reverse()
76 a8083063 Iustin Pop
    for path, kind in self.torm:
77 a8083063 Iustin Pop
      if kind:
78 a8083063 Iustin Pop
        os.rmdir(path)
79 a8083063 Iustin Pop
      else:
80 a8083063 Iustin Pop
        os.unlink(path)
81 a8083063 Iustin Pop
82 a8083063 Iustin Pop
  def _rname(self, fname):
83 a8083063 Iustin Pop
    return "/".join(fname.split("/")[-2:])
84 a8083063 Iustin Pop
85 a8083063 Iustin Pop
  def testEmpty(self):
86 a8083063 Iustin Pop
    """Test no hooks"""
87 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
88 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), [])
89 a8083063 Iustin Pop
90 a8083063 Iustin Pop
  def testSkipNonExec(self):
91 a8083063 Iustin Pop
    """Test skip non-exec file"""
92 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
93 a8083063 Iustin Pop
      fname = "%s/test" % self.ph_dirs[phase]
94 a8083063 Iustin Pop
      f = open(fname, "w")
95 a8083063 Iustin Pop
      f.close()
96 a8083063 Iustin Pop
      self.torm.append((fname, False))
97 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
98 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
99 a8083063 Iustin Pop
100 a8083063 Iustin Pop
  def testSkipInvalidName(self):
101 a8083063 Iustin Pop
    """Test skip script with invalid name"""
102 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
103 a8083063 Iustin Pop
      fname = "%s/a.off" % self.ph_dirs[phase]
104 a8083063 Iustin Pop
      f = open(fname, "w")
105 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 0\n")
106 a8083063 Iustin Pop
      f.close()
107 a8083063 Iustin Pop
      os.chmod(fname, 0700)
108 a8083063 Iustin Pop
      self.torm.append((fname, False))
109 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
110 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
111 a8083063 Iustin Pop
112 a8083063 Iustin Pop
  def testSkipDir(self):
113 a8083063 Iustin Pop
    """Test skip directory"""
114 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
115 a8083063 Iustin Pop
      fname = "%s/testdir" % self.ph_dirs[phase]
116 a8083063 Iustin Pop
      os.mkdir(fname)
117 a8083063 Iustin Pop
      self.torm.append((fname, True))
118 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
119 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
120 a8083063 Iustin Pop
121 a8083063 Iustin Pop
  def testSuccess(self):
122 a8083063 Iustin Pop
    """Test success execution"""
123 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
124 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
125 a8083063 Iustin Pop
      f = open(fname, "w")
126 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 0\n")
127 a8083063 Iustin Pop
      f.close()
128 a8083063 Iustin Pop
      self.torm.append((fname, False))
129 a8083063 Iustin Pop
      os.chmod(fname, 0700)
130 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
131 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, "")])
132 a8083063 Iustin Pop
133 a8083063 Iustin Pop
  def testSymlink(self):
134 a8083063 Iustin Pop
    """Test running a symlink"""
135 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
136 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
137 a8083063 Iustin Pop
      os.symlink("/bin/true", fname)
138 a8083063 Iustin Pop
      self.torm.append((fname, False))
139 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
140 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, "")])
141 a8083063 Iustin Pop
142 a8083063 Iustin Pop
  def testFail(self):
143 a8083063 Iustin Pop
    """Test success execution"""
144 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
145 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
146 a8083063 Iustin Pop
      f = open(fname, "w")
147 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 1\n")
148 a8083063 Iustin Pop
      f.close()
149 a8083063 Iustin Pop
      self.torm.append((fname, False))
150 a8083063 Iustin Pop
      os.chmod(fname, 0700)
151 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
152 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_FAIL, "")])
153 a8083063 Iustin Pop
154 a8083063 Iustin Pop
  def testCombined(self):
155 a8083063 Iustin Pop
    """Test success, failure and skip all in one test"""
156 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
157 a8083063 Iustin Pop
      expect = []
158 a8083063 Iustin Pop
      for fbase, ecode, rs in [("00succ", 0, HKR_SUCCESS),
159 a8083063 Iustin Pop
                               ("10fail", 1, HKR_FAIL),
160 a8083063 Iustin Pop
                               ("20inv.", 0, HKR_SKIP),
161 a8083063 Iustin Pop
                               ]:
162 a8083063 Iustin Pop
        fname = "%s/%s" % (self.ph_dirs[phase], fbase)
163 a8083063 Iustin Pop
        f = open(fname, "w")
164 a8083063 Iustin Pop
        f.write("#!/bin/sh\nexit %d\n" % ecode)
165 a8083063 Iustin Pop
        f.close()
166 a8083063 Iustin Pop
        self.torm.append((fname, False))
167 a8083063 Iustin Pop
        os.chmod(fname, 0700)
168 a8083063 Iustin Pop
        expect.append((self._rname(fname), rs, ""))
169 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), expect)
170 a8083063 Iustin Pop
171 a8083063 Iustin Pop
  def testOrdering(self):
172 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
173 a8083063 Iustin Pop
      expect = []
174 a8083063 Iustin Pop
      for fbase in ["10s1",
175 a8083063 Iustin Pop
                    "00s0",
176 a8083063 Iustin Pop
                    "10sa",
177 a8083063 Iustin Pop
                    "80sc",
178 a8083063 Iustin Pop
                    "60sd",
179 a8083063 Iustin Pop
                    ]:
180 a8083063 Iustin Pop
        fname = "%s/%s" % (self.ph_dirs[phase], fbase)
181 a8083063 Iustin Pop
        os.symlink("/bin/true", fname)
182 a8083063 Iustin Pop
        self.torm.append((fname, False))
183 a8083063 Iustin Pop
        expect.append((self._rname(fname), HKR_SUCCESS, ""))
184 a8083063 Iustin Pop
      expect.sort()
185 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), expect)
186 a8083063 Iustin Pop
187 a8083063 Iustin Pop
  def testEnv(self):
188 a8083063 Iustin Pop
    """Test environment execution"""
189 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
190 a8083063 Iustin Pop
      fbase = "success"
191 a8083063 Iustin Pop
      fname = "%s/%s" % (self.ph_dirs[phase], fbase)
192 a8083063 Iustin Pop
      os.symlink("/usr/bin/env", fname)
193 a8083063 Iustin Pop
      self.torm.append((fname, False))
194 a8083063 Iustin Pop
      env_snt = {"PHASE": phase}
195 7b80424f Iustin Pop
      env_exp = "PHASE=%s" % phase
196 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, env_snt),
197 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, env_exp)])
198 a8083063 Iustin Pop
199 a8083063 Iustin Pop
200 dd7f6776 Michael Hanselmann
def FakeHooksRpcSuccess(node_list, hpath, phase, env):
201 dd7f6776 Michael Hanselmann
  """Fake call_hooks_runner function.
202 dd7f6776 Michael Hanselmann

203 dd7f6776 Michael Hanselmann
  @rtype: dict of node -> L{rpc.RpcResult} with a successful script result
204 dd7f6776 Michael Hanselmann
  @return: script execution from all nodes
205 dd7f6776 Michael Hanselmann

206 dd7f6776 Michael Hanselmann
  """
207 dd7f6776 Michael Hanselmann
  rr = rpc.RpcResult
208 3fc210de Andrea Spadaccini
  return dict([(node, rr((True, [("utest", constants.HKR_SUCCESS, "ok")]),
209 8c114acd Michael Hanselmann
                         node=node, call="FakeScriptOk"))
210 dd7f6776 Michael Hanselmann
               for node in node_list])
211 dd7f6776 Michael Hanselmann
212 dd7f6776 Michael Hanselmann
213 a8083063 Iustin Pop
class TestHooksMaster(unittest.TestCase):
214 a8083063 Iustin Pop
  """Testing case for HooksMaster"""
215 a8083063 Iustin Pop
216 a8083063 Iustin Pop
  def _call_false(*args):
217 a8083063 Iustin Pop
    """Fake call_hooks_runner function which returns False."""
218 a8083063 Iustin Pop
    return False
219 a8083063 Iustin Pop
220 a8083063 Iustin Pop
  @staticmethod
221 a8083063 Iustin Pop
  def _call_nodes_false(node_list, hpath, phase, env):
222 a8083063 Iustin Pop
    """Fake call_hooks_runner function.
223 a8083063 Iustin Pop

224 7ccb3074 Guido Trotter
    @rtype: dict of node -> L{rpc.RpcResult} with an rpc error
225 7ccb3074 Guido Trotter
    @return: rpc failure from all nodes
226 a8083063 Iustin Pop

227 a8083063 Iustin Pop
    """
228 8c114acd Michael Hanselmann
    return dict([(node, rpc.RpcResult("error", failed=True,
229 8c114acd Michael Hanselmann
                  node=node, call="FakeError")) for node in node_list])
230 a8083063 Iustin Pop
231 a8083063 Iustin Pop
  @staticmethod
232 a8083063 Iustin Pop
  def _call_script_fail(node_list, hpath, phase, env):
233 a8083063 Iustin Pop
    """Fake call_hooks_runner function.
234 a8083063 Iustin Pop

235 7ccb3074 Guido Trotter
    @rtype: dict of node -> L{rpc.RpcResult} with a failed script result
236 7ccb3074 Guido Trotter
    @return: script execution failure from all nodes
237 a8083063 Iustin Pop

238 a8083063 Iustin Pop
    """
239 3fb4f740 Iustin Pop
    rr = rpc.RpcResult
240 3fb4f740 Iustin Pop
    return dict([(node, rr((True, [("utest", constants.HKR_FAIL, "err")]),
241 8c114acd Michael Hanselmann
                           node=node, call="FakeScriptFail"))
242 3fb4f740 Iustin Pop
                  for node in node_list])
243 a8083063 Iustin Pop
244 d2525573 Guido Trotter
  def setUp(self):
245 d2525573 Guido Trotter
    self.op = opcodes.OpCode()
246 77b657a3 Guido Trotter
    self.context = FakeContext()
247 72737a7f Iustin Pop
    # WARNING: here we pass None as RpcRunner instance since we know
248 72737a7f Iustin Pop
    # our usage via HooksMaster will not use lu.rpc
249 86d9d3bb Iustin Pop
    self.lu = FakeLU(FakeProc(), self.op, self.context, None)
250 d2525573 Guido Trotter
251 a8083063 Iustin Pop
  def testTotalFalse(self):
252 a8083063 Iustin Pop
    """Test complete rpc failure"""
253 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._call_false, self.lu)
254 a8083063 Iustin Pop
    self.failUnlessRaises(errors.HooksFailure,
255 a8083063 Iustin Pop
                          hm.RunPhase, constants.HOOKS_PHASE_PRE)
256 a8083063 Iustin Pop
    hm.RunPhase(constants.HOOKS_PHASE_POST)
257 a8083063 Iustin Pop
258 a8083063 Iustin Pop
  def testIndividualFalse(self):
259 2395c322 Iustin Pop
    """Test individual node failure"""
260 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._call_nodes_false, self.lu)
261 2395c322 Iustin Pop
    hm.RunPhase(constants.HOOKS_PHASE_PRE)
262 2395c322 Iustin Pop
    #self.failUnlessRaises(errors.HooksFailure,
263 2395c322 Iustin Pop
    #                      hm.RunPhase, constants.HOOKS_PHASE_PRE)
264 a8083063 Iustin Pop
    hm.RunPhase(constants.HOOKS_PHASE_POST)
265 a8083063 Iustin Pop
266 a8083063 Iustin Pop
  def testScriptFalse(self):
267 a8083063 Iustin Pop
    """Test individual rpc failure"""
268 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._call_script_fail, self.lu)
269 a8083063 Iustin Pop
    self.failUnlessRaises(errors.HooksAbort,
270 a8083063 Iustin Pop
                          hm.RunPhase, constants.HOOKS_PHASE_PRE)
271 a8083063 Iustin Pop
    hm.RunPhase(constants.HOOKS_PHASE_POST)
272 a8083063 Iustin Pop
273 a8083063 Iustin Pop
  def testScriptSucceed(self):
274 a8083063 Iustin Pop
    """Test individual rpc failure"""
275 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(FakeHooksRpcSuccess, self.lu)
276 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
277 a8083063 Iustin Pop
      hm.RunPhase(phase)
278 a8083063 Iustin Pop
279 25231ec5 Michael Hanselmann
280 dd7f6776 Michael Hanselmann
class FakeEnvLU(cmdlib.LogicalUnit):
281 dd7f6776 Michael Hanselmann
  HPATH = "env_test_lu"
282 dd7f6776 Michael Hanselmann
  HTYPE = constants.HTYPE_GROUP
283 dd7f6776 Michael Hanselmann
284 dd7f6776 Michael Hanselmann
  def __init__(self, *args):
285 dd7f6776 Michael Hanselmann
    cmdlib.LogicalUnit.__init__(self, *args)
286 dd7f6776 Michael Hanselmann
    self.hook_env = None
287 dd7f6776 Michael Hanselmann
288 dd7f6776 Michael Hanselmann
  def BuildHooksEnv(self):
289 dd7f6776 Michael Hanselmann
    assert self.hook_env is not None
290 07e0896f Michael Hanselmann
    return self.hook_env
291 07e0896f Michael Hanselmann
292 07e0896f Michael Hanselmann
  def BuildHooksNodes(self):
293 07e0896f Michael Hanselmann
    return (["localhost"], ["localhost"])
294 07e0896f Michael Hanselmann
295 dd7f6776 Michael Hanselmann
296 07e0896f Michael Hanselmann
class FakeNoHooksLU(cmdlib.NoHooksLU):
297 07e0896f Michael Hanselmann
  pass
298 dd7f6776 Michael Hanselmann
299 dd7f6776 Michael Hanselmann
300 dd7f6776 Michael Hanselmann
class TestHooksRunnerEnv(unittest.TestCase):
301 dd7f6776 Michael Hanselmann
  def setUp(self):
302 dd7f6776 Michael Hanselmann
    self._rpcs = []
303 dd7f6776 Michael Hanselmann
304 dd7f6776 Michael Hanselmann
    self.op = opcodes.OpTestDummy(result=False, messages=[], fail=False)
305 dd7f6776 Michael Hanselmann
    self.lu = FakeEnvLU(FakeProc(), self.op, FakeContext(), None)
306 dd7f6776 Michael Hanselmann
307 dd7f6776 Michael Hanselmann
  def _HooksRpc(self, *args):
308 dd7f6776 Michael Hanselmann
    self._rpcs.append(args)
309 dd7f6776 Michael Hanselmann
    return FakeHooksRpcSuccess(*args)
310 dd7f6776 Michael Hanselmann
311 dd7f6776 Michael Hanselmann
  def _CheckEnv(self, env, phase, hpath):
312 dd7f6776 Michael Hanselmann
    self.assertTrue(env["PATH"].startswith("/sbin"))
313 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_HOOKS_PHASE"], phase)
314 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_HOOKS_PATH"], hpath)
315 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_OP_CODE"], self.op.OP_ID)
316 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_HOOKS_VERSION"], str(constants.HOOKS_VERSION))
317 a56625a2 Michael Hanselmann
    self.assertEqual(env["GANETI_DATA_DIR"], pathutils.DATA_DIR)
318 07e0896f Michael Hanselmann
    if "GANETI_OBJECT_TYPE" in env:
319 07e0896f Michael Hanselmann
      self.assertEqual(env["GANETI_OBJECT_TYPE"], constants.HTYPE_GROUP)
320 07e0896f Michael Hanselmann
    else:
321 07e0896f Michael Hanselmann
      self.assertTrue(self.lu.HTYPE is None)
322 dd7f6776 Michael Hanselmann
323 dd7f6776 Michael Hanselmann
  def testEmptyEnv(self):
324 dd7f6776 Michael Hanselmann
    # Check pre-phase hook
325 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {}
326 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
327 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_PRE)
328 dd7f6776 Michael Hanselmann
329 dd7f6776 Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
330 dd7f6776 Michael Hanselmann
    self.assertEqual(node_list, set(["localhost"]))
331 dd7f6776 Michael Hanselmann
    self.assertEqual(hpath, self.lu.HPATH)
332 dd7f6776 Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_PRE)
333 dd7f6776 Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_PRE, self.lu.HPATH)
334 dd7f6776 Michael Hanselmann
335 dd7f6776 Michael Hanselmann
    # Check post-phase hook
336 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {}
337 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_POST)
338 dd7f6776 Michael Hanselmann
339 dd7f6776 Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
340 dd7f6776 Michael Hanselmann
    self.assertEqual(node_list, set(["localhost"]))
341 dd7f6776 Michael Hanselmann
    self.assertEqual(hpath, self.lu.HPATH)
342 dd7f6776 Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
343 dd7f6776 Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
344 dd7f6776 Michael Hanselmann
345 dd7f6776 Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
346 dd7f6776 Michael Hanselmann
347 dd7f6776 Michael Hanselmann
  def testEnv(self):
348 dd7f6776 Michael Hanselmann
    # Check pre-phase hook
349 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {
350 dd7f6776 Michael Hanselmann
      "FOO": "pre-foo-value",
351 dd7f6776 Michael Hanselmann
      }
352 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
353 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_PRE)
354 dd7f6776 Michael Hanselmann
355 dd7f6776 Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
356 dd7f6776 Michael Hanselmann
    self.assertEqual(node_list, set(["localhost"]))
357 dd7f6776 Michael Hanselmann
    self.assertEqual(hpath, self.lu.HPATH)
358 dd7f6776 Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_PRE)
359 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
360 dd7f6776 Michael Hanselmann
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
361 dd7f6776 Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_PRE, self.lu.HPATH)
362 dd7f6776 Michael Hanselmann
363 dd7f6776 Michael Hanselmann
    # Check post-phase hook
364 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {
365 dd7f6776 Michael Hanselmann
      "FOO": "post-value",
366 dd7f6776 Michael Hanselmann
      "BAR": 123,
367 dd7f6776 Michael Hanselmann
      }
368 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_POST)
369 dd7f6776 Michael Hanselmann
370 dd7f6776 Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
371 dd7f6776 Michael Hanselmann
    self.assertEqual(node_list, set(["localhost"]))
372 dd7f6776 Michael Hanselmann
    self.assertEqual(hpath, self.lu.HPATH)
373 dd7f6776 Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
374 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
375 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_POST_FOO"], "post-value")
376 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_POST_BAR"], "123")
377 dd7f6776 Michael Hanselmann
    self.assertFalse("GANETI_BAR" in env)
378 dd7f6776 Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
379 dd7f6776 Michael Hanselmann
380 dd7f6776 Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
381 dd7f6776 Michael Hanselmann
382 dd7f6776 Michael Hanselmann
    # Check configuration update hook
383 07e0896f Michael Hanselmann
    hm.RunConfigUpdate()
384 dd7f6776 Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
385 dd7f6776 Michael Hanselmann
    self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
386 dd7f6776 Michael Hanselmann
    self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
387 dd7f6776 Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
388 dd7f6776 Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST,
389 dd7f6776 Michael Hanselmann
                   constants.HOOKS_NAME_CFGUPDATE)
390 dd7f6776 Michael Hanselmann
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
391 dd7f6776 Michael Hanselmann
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
392 dd7f6776 Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
393 dd7f6776 Michael Hanselmann
394 dd7f6776 Michael Hanselmann
  def testConflict(self):
395 dd7f6776 Michael Hanselmann
    for name in ["DATA_DIR", "OP_CODE"]:
396 dd7f6776 Michael Hanselmann
      self.lu.hook_env = { name: "value" }
397 b423c513 Michael Hanselmann
398 b423c513 Michael Hanselmann
      # Test using a clean HooksMaster instance
399 949dcb1d Andrea Spadaccini
      hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
400 b423c513 Michael Hanselmann
401 dd7f6776 Michael Hanselmann
      for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
402 b423c513 Michael Hanselmann
        self.assertRaises(AssertionError, hm.RunPhase, phase)
403 dd7f6776 Michael Hanselmann
        self.assertRaises(IndexError, self._rpcs.pop)
404 dd7f6776 Michael Hanselmann
405 dd7f6776 Michael Hanselmann
  def testNoNodes(self):
406 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {}
407 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
408 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_PRE, nodes=[])
409 dd7f6776 Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
410 dd7f6776 Michael Hanselmann
411 dd7f6776 Michael Hanselmann
  def testSpecificNodes(self):
412 dd7f6776 Michael Hanselmann
    self.lu.hook_env = {}
413 dd7f6776 Michael Hanselmann
414 dd7f6776 Michael Hanselmann
    nodes = [
415 dd7f6776 Michael Hanselmann
      "node1.example.com",
416 dd7f6776 Michael Hanselmann
      "node93782.example.net",
417 dd7f6776 Michael Hanselmann
      ]
418 dd7f6776 Michael Hanselmann
419 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
420 07e0896f Michael Hanselmann
421 dd7f6776 Michael Hanselmann
    for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
422 07e0896f Michael Hanselmann
      hm.RunPhase(phase, nodes=nodes)
423 dd7f6776 Michael Hanselmann
424 dd7f6776 Michael Hanselmann
      (node_list, hpath, rpc_phase, env) = self._rpcs.pop(0)
425 dd7f6776 Michael Hanselmann
      self.assertEqual(set(node_list), set(nodes))
426 dd7f6776 Michael Hanselmann
      self.assertEqual(hpath, self.lu.HPATH)
427 dd7f6776 Michael Hanselmann
      self.assertEqual(rpc_phase, phase)
428 dd7f6776 Michael Hanselmann
      self._CheckEnv(env, phase, self.lu.HPATH)
429 dd7f6776 Michael Hanselmann
430 dd7f6776 Michael Hanselmann
      self.assertRaises(IndexError, self._rpcs.pop)
431 dd7f6776 Michael Hanselmann
432 dd7f6776 Michael Hanselmann
  def testRunConfigUpdateNoPre(self):
433 07e0896f Michael Hanselmann
    self.lu.hook_env = {
434 07e0896f Michael Hanselmann
      "FOO": "value",
435 07e0896f Michael Hanselmann
      }
436 07e0896f Michael Hanselmann
437 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
438 07e0896f Michael Hanselmann
    hm.RunConfigUpdate()
439 07e0896f Michael Hanselmann
440 07e0896f Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
441 07e0896f Michael Hanselmann
    self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
442 07e0896f Michael Hanselmann
    self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
443 07e0896f Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
444 07e0896f Michael Hanselmann
    self.assertEqual(env["GANETI_FOO"], "value")
445 07e0896f Michael Hanselmann
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
446 07e0896f Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST,
447 07e0896f Michael Hanselmann
                   constants.HOOKS_NAME_CFGUPDATE)
448 07e0896f Michael Hanselmann
449 dd7f6776 Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
450 dd7f6776 Michael Hanselmann
451 b423c513 Michael Hanselmann
  def testNoPreBeforePost(self):
452 07e0896f Michael Hanselmann
    self.lu.hook_env = {
453 07e0896f Michael Hanselmann
      "FOO": "value",
454 07e0896f Michael Hanselmann
      }
455 07e0896f Michael Hanselmann
456 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
457 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_POST)
458 07e0896f Michael Hanselmann
459 07e0896f Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
460 07e0896f Michael Hanselmann
    self.assertEqual(node_list, set(["localhost"]))
461 07e0896f Michael Hanselmann
    self.assertEqual(hpath, self.lu.HPATH)
462 07e0896f Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
463 07e0896f Michael Hanselmann
    self.assertEqual(env["GANETI_FOO"], "value")
464 07e0896f Michael Hanselmann
    self.assertEqual(env["GANETI_POST_FOO"], "value")
465 07e0896f Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
466 07e0896f Michael Hanselmann
467 07e0896f Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
468 07e0896f Michael Hanselmann
469 07e0896f Michael Hanselmann
  def testNoHooksLU(self):
470 07e0896f Michael Hanselmann
    self.lu = FakeNoHooksLU(FakeProc(), self.op, FakeContext(), None)
471 07e0896f Michael Hanselmann
    self.assertRaises(AssertionError, self.lu.BuildHooksEnv)
472 07e0896f Michael Hanselmann
    self.assertRaises(AssertionError, self.lu.BuildHooksNodes)
473 07e0896f Michael Hanselmann
474 949dcb1d Andrea Spadaccini
    hm = mcpu.HooksMaster.BuildFromLu(self._HooksRpc, self.lu)
475 07e0896f Michael Hanselmann
    self.assertEqual(hm.pre_env, {})
476 07e0896f Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
477 07e0896f Michael Hanselmann
478 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_PRE)
479 07e0896f Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
480 07e0896f Michael Hanselmann
481 07e0896f Michael Hanselmann
    hm.RunPhase(constants.HOOKS_PHASE_POST)
482 07e0896f Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
483 07e0896f Michael Hanselmann
484 07e0896f Michael Hanselmann
    hm.RunConfigUpdate()
485 07e0896f Michael Hanselmann
486 07e0896f Michael Hanselmann
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
487 07e0896f Michael Hanselmann
    self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
488 07e0896f Michael Hanselmann
    self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
489 07e0896f Michael Hanselmann
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
490 07e0896f Michael Hanselmann
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
491 07e0896f Michael Hanselmann
    self._CheckEnv(env, constants.HOOKS_PHASE_POST,
492 07e0896f Michael Hanselmann
                   constants.HOOKS_NAME_CFGUPDATE)
493 07e0896f Michael Hanselmann
    self.assertRaises(IndexError, self._rpcs.pop)
494 07e0896f Michael Hanselmann
495 07e0896f Michael Hanselmann
    assert isinstance(self.lu, FakeNoHooksLU), "LU was replaced"
496 b423c513 Michael Hanselmann
497 dd7f6776 Michael Hanselmann
498 2f96c43c Michael Hanselmann
if __name__ == "__main__":
499 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()