Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.hooks_unittest.py @ 83c046a2

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 a8083063 Iustin Pop
from ganeti.constants import HKR_SUCCESS, HKR_FAIL, HKR_SKIP
40 a8083063 Iustin Pop
41 c259ce64 Michael Hanselmann
from mocks import FakeConfig, FakeProc, FakeContext
42 a8083063 Iustin Pop
43 25231ec5 Michael Hanselmann
import testutils
44 25231ec5 Michael Hanselmann
45 25231ec5 Michael Hanselmann
46 a8083063 Iustin Pop
class FakeLU(cmdlib.LogicalUnit):
47 a8083063 Iustin Pop
  HPATH = "test"
48 07e0896f Michael Hanselmann
49 a8083063 Iustin Pop
  def BuildHooksEnv(self):
50 07e0896f Michael Hanselmann
    return {}
51 07e0896f Michael Hanselmann
52 07e0896f Michael Hanselmann
  def BuildHooksNodes(self):
53 07e0896f Michael Hanselmann
    return ["localhost"], ["localhost"]
54 a8083063 Iustin Pop
55 25231ec5 Michael Hanselmann
56 a8083063 Iustin Pop
class TestHooksRunner(unittest.TestCase):
57 a8083063 Iustin Pop
  """Testing case for HooksRunner"""
58 a8083063 Iustin Pop
  def setUp(self):
59 a8083063 Iustin Pop
    self.torm = []
60 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp()
61 a8083063 Iustin Pop
    self.torm.append((self.tmpdir, True))
62 a8083063 Iustin Pop
    self.logdir = tempfile.mkdtemp()
63 a8083063 Iustin Pop
    self.torm.append((self.logdir, True))
64 a8083063 Iustin Pop
    self.hpath = "fake"
65 a8083063 Iustin Pop
    self.ph_dirs = {}
66 a8083063 Iustin Pop
    for i in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
67 a8083063 Iustin Pop
      dname = "%s/%s-%s.d" % (self.tmpdir, self.hpath, i)
68 a8083063 Iustin Pop
      os.mkdir(dname)
69 a8083063 Iustin Pop
      self.torm.append((dname, True))
70 a8083063 Iustin Pop
      self.ph_dirs[i] = dname
71 a8083063 Iustin Pop
    self.hr = backend.HooksRunner(hooks_base_dir=self.tmpdir)
72 a8083063 Iustin Pop
73 a8083063 Iustin Pop
  def tearDown(self):
74 a8083063 Iustin Pop
    self.torm.reverse()
75 a8083063 Iustin Pop
    for path, kind in self.torm:
76 a8083063 Iustin Pop
      if kind:
77 a8083063 Iustin Pop
        os.rmdir(path)
78 a8083063 Iustin Pop
      else:
79 a8083063 Iustin Pop
        os.unlink(path)
80 a8083063 Iustin Pop
81 a8083063 Iustin Pop
  def _rname(self, fname):
82 a8083063 Iustin Pop
    return "/".join(fname.split("/")[-2:])
83 a8083063 Iustin Pop
84 a8083063 Iustin Pop
  def testEmpty(self):
85 a8083063 Iustin Pop
    """Test no hooks"""
86 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
87 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), [])
88 a8083063 Iustin Pop
89 a8083063 Iustin Pop
  def testSkipNonExec(self):
90 a8083063 Iustin Pop
    """Test skip non-exec file"""
91 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
92 a8083063 Iustin Pop
      fname = "%s/test" % self.ph_dirs[phase]
93 a8083063 Iustin Pop
      f = open(fname, "w")
94 a8083063 Iustin Pop
      f.close()
95 a8083063 Iustin Pop
      self.torm.append((fname, False))
96 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
97 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
98 a8083063 Iustin Pop
99 a8083063 Iustin Pop
  def testSkipInvalidName(self):
100 a8083063 Iustin Pop
    """Test skip script with invalid name"""
101 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
102 a8083063 Iustin Pop
      fname = "%s/a.off" % self.ph_dirs[phase]
103 a8083063 Iustin Pop
      f = open(fname, "w")
104 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 0\n")
105 a8083063 Iustin Pop
      f.close()
106 a8083063 Iustin Pop
      os.chmod(fname, 0700)
107 a8083063 Iustin Pop
      self.torm.append((fname, False))
108 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
109 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
110 a8083063 Iustin Pop
111 a8083063 Iustin Pop
  def testSkipDir(self):
112 a8083063 Iustin Pop
    """Test skip directory"""
113 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
114 a8083063 Iustin Pop
      fname = "%s/testdir" % self.ph_dirs[phase]
115 a8083063 Iustin Pop
      os.mkdir(fname)
116 a8083063 Iustin Pop
      self.torm.append((fname, True))
117 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
118 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SKIP, "")])
119 a8083063 Iustin Pop
120 a8083063 Iustin Pop
  def testSuccess(self):
121 a8083063 Iustin Pop
    """Test success execution"""
122 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
123 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
124 a8083063 Iustin Pop
      f = open(fname, "w")
125 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 0\n")
126 a8083063 Iustin Pop
      f.close()
127 a8083063 Iustin Pop
      self.torm.append((fname, False))
128 a8083063 Iustin Pop
      os.chmod(fname, 0700)
129 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
130 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, "")])
131 a8083063 Iustin Pop
132 a8083063 Iustin Pop
  def testSymlink(self):
133 a8083063 Iustin Pop
    """Test running a symlink"""
134 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
135 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
136 a8083063 Iustin Pop
      os.symlink("/bin/true", fname)
137 a8083063 Iustin Pop
      self.torm.append((fname, False))
138 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
139 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, "")])
140 a8083063 Iustin Pop
141 a8083063 Iustin Pop
  def testFail(self):
142 a8083063 Iustin Pop
    """Test success execution"""
143 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
144 a8083063 Iustin Pop
      fname = "%s/success" % self.ph_dirs[phase]
145 a8083063 Iustin Pop
      f = open(fname, "w")
146 a8083063 Iustin Pop
      f.write("#!/bin/sh\nexit 1\n")
147 a8083063 Iustin Pop
      f.close()
148 a8083063 Iustin Pop
      self.torm.append((fname, False))
149 a8083063 Iustin Pop
      os.chmod(fname, 0700)
150 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}),
151 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_FAIL, "")])
152 a8083063 Iustin Pop
153 a8083063 Iustin Pop
  def testCombined(self):
154 a8083063 Iustin Pop
    """Test success, failure and skip all in one test"""
155 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
156 a8083063 Iustin Pop
      expect = []
157 a8083063 Iustin Pop
      for fbase, ecode, rs in [("00succ", 0, HKR_SUCCESS),
158 a8083063 Iustin Pop
                               ("10fail", 1, HKR_FAIL),
159 a8083063 Iustin Pop
                               ("20inv.", 0, HKR_SKIP),
160 a8083063 Iustin Pop
                               ]:
161 a8083063 Iustin Pop
        fname = "%s/%s" % (self.ph_dirs[phase], fbase)
162 a8083063 Iustin Pop
        f = open(fname, "w")
163 a8083063 Iustin Pop
        f.write("#!/bin/sh\nexit %d\n" % ecode)
164 a8083063 Iustin Pop
        f.close()
165 a8083063 Iustin Pop
        self.torm.append((fname, False))
166 a8083063 Iustin Pop
        os.chmod(fname, 0700)
167 a8083063 Iustin Pop
        expect.append((self._rname(fname), rs, ""))
168 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), expect)
169 a8083063 Iustin Pop
170 a8083063 Iustin Pop
  def testOrdering(self):
171 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
172 a8083063 Iustin Pop
      expect = []
173 a8083063 Iustin Pop
      for fbase in ["10s1",
174 a8083063 Iustin Pop
                    "00s0",
175 a8083063 Iustin Pop
                    "10sa",
176 a8083063 Iustin Pop
                    "80sc",
177 a8083063 Iustin Pop
                    "60sd",
178 a8083063 Iustin Pop
                    ]:
179 a8083063 Iustin Pop
        fname = "%s/%s" % (self.ph_dirs[phase], fbase)
180 a8083063 Iustin Pop
        os.symlink("/bin/true", fname)
181 a8083063 Iustin Pop
        self.torm.append((fname, False))
182 a8083063 Iustin Pop
        expect.append((self._rname(fname), HKR_SUCCESS, ""))
183 a8083063 Iustin Pop
      expect.sort()
184 d019f8bd Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, {}), expect)
185 a8083063 Iustin Pop
186 a8083063 Iustin Pop
  def testEnv(self):
187 a8083063 Iustin Pop
    """Test environment execution"""
188 a8083063 Iustin Pop
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
189 a8083063 Iustin Pop
      fbase = "success"
190 a8083063 Iustin Pop
      fname = "%s/%s" % (self.ph_dirs[phase], fbase)
191 a8083063 Iustin Pop
      os.symlink("/usr/bin/env", fname)
192 a8083063 Iustin Pop
      self.torm.append((fname, False))
193 a8083063 Iustin Pop
      env_snt = {"PHASE": phase}
194 7b80424f Iustin Pop
      env_exp = "PHASE=%s" % phase
195 a8083063 Iustin Pop
      self.failUnlessEqual(self.hr.RunHooks(self.hpath, phase, env_snt),
196 d019f8bd Iustin Pop
                           [(self._rname(fname), HKR_SUCCESS, env_exp)])
197 a8083063 Iustin Pop
198 a8083063 Iustin Pop
199 dd7f6776 Michael Hanselmann
def FakeHooksRpcSuccess(node_list, hpath, phase, env):
200 dd7f6776 Michael Hanselmann
  """Fake call_hooks_runner function.
201 dd7f6776 Michael Hanselmann

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

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

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

226 a8083063 Iustin Pop
    """
227 7ccb3074 Guido Trotter
    return dict([(node, rpc.RpcResult('error', failed=True,
228 7ccb3074 Guido Trotter
                  node=node, call='FakeError')) for node in node_list])
229 a8083063 Iustin Pop
230 a8083063 Iustin Pop
  @staticmethod
231 a8083063 Iustin Pop
  def _call_script_fail(node_list, hpath, phase, env):
232 a8083063 Iustin Pop
    """Fake call_hooks_runner function.
233 a8083063 Iustin Pop

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

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