Revision dd7f6776 test/ganeti.hooks_unittest.py

b/test/ganeti.hooks_unittest.py
35 35
from ganeti import constants
36 36
from ganeti import cmdlib
37 37
from ganeti import rpc
38
from ganeti import compat
38 39
from ganeti.constants import HKR_SUCCESS, HKR_FAIL, HKR_SKIP
39 40

  
40 41
from mocks import FakeConfig, FakeProc, FakeContext
......
191 192
                           [(self._rname(fname), HKR_SUCCESS, env_exp)])
192 193

  
193 194

  
195
def FakeHooksRpcSuccess(node_list, hpath, phase, env):
196
  """Fake call_hooks_runner function.
197

  
198
  @rtype: dict of node -> L{rpc.RpcResult} with a successful script result
199
  @return: script execution from all nodes
200

  
201
  """
202
  rr = rpc.RpcResult
203
  return dict([(node, rr(True, [("utest", constants.HKR_SUCCESS, "ok")],
204
                         node=node, call='FakeScriptOk'))
205
               for node in node_list])
206

  
207

  
194 208
class TestHooksMaster(unittest.TestCase):
195 209
  """Testing case for HooksMaster"""
196 210

  
......
222 236
                           node=node, call='FakeScriptFail'))
223 237
                  for node in node_list])
224 238

  
225
  @staticmethod
226
  def _call_script_succeed(node_list, hpath, phase, env):
227
    """Fake call_hooks_runner function.
228

  
229
    @rtype: dict of node -> L{rpc.RpcResult} with a successful script result
230
    @return: script execution from all nodes
231

  
232
    """
233
    rr = rpc.RpcResult
234
    return dict([(node, rr(True, [("utest", constants.HKR_SUCCESS, "ok")],
235
                           node=node, call='FakeScriptOk'))
236
                 for node in node_list])
237

  
238 239
  def setUp(self):
239 240
    self.op = opcodes.OpCode()
240 241
    self.context = FakeContext()
......
266 267

  
267 268
  def testScriptSucceed(self):
268 269
    """Test individual rpc failure"""
269
    hm = mcpu.HooksMaster(self._call_script_succeed, self.lu)
270
    hm = mcpu.HooksMaster(FakeHooksRpcSuccess, self.lu)
270 271
    for phase in (constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST):
271 272
      hm.RunPhase(phase)
272 273

  
273 274

  
275
class FakeEnvLU(cmdlib.LogicalUnit):
276
  HPATH = "env_test_lu"
277
  HTYPE = constants.HTYPE_GROUP
278

  
279
  def __init__(self, *args):
280
    cmdlib.LogicalUnit.__init__(self, *args)
281
    self.hook_env = None
282

  
283
  def BuildHooksEnv(self):
284
    assert self.hook_env is not None
285

  
286
    return self.hook_env, ["localhost"], ["localhost"]
287

  
288

  
289
class TestHooksRunnerEnv(unittest.TestCase):
290
  def setUp(self):
291
    self._rpcs = []
292

  
293
    self.op = opcodes.OpTestDummy(result=False, messages=[], fail=False)
294
    self.lu = FakeEnvLU(FakeProc(), self.op, FakeContext(), None)
295
    self.hm = mcpu.HooksMaster(self._HooksRpc, self.lu)
296

  
297
  def _HooksRpc(self, *args):
298
    self._rpcs.append(args)
299
    return FakeHooksRpcSuccess(*args)
300

  
301
  def _CheckEnv(self, env, phase, hpath):
302
    self.assertTrue(env["PATH"].startswith("/sbin"))
303
    self.assertEqual(env["GANETI_HOOKS_PHASE"], phase)
304
    self.assertEqual(env["GANETI_HOOKS_PATH"], hpath)
305
    self.assertEqual(env["GANETI_OP_CODE"], self.op.OP_ID)
306
    self.assertEqual(env["GANETI_OBJECT_TYPE"], constants.HTYPE_GROUP)
307
    self.assertEqual(env["GANETI_HOOKS_VERSION"], str(constants.HOOKS_VERSION))
308
    self.assertEqual(env["GANETI_DATA_DIR"], constants.DATA_DIR)
309

  
310
  def testEmptyEnv(self):
311
    # Check pre-phase hook
312
    self.lu.hook_env = {}
313
    self.hm.RunPhase(constants.HOOKS_PHASE_PRE)
314

  
315
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
316
    self.assertEqual(node_list, set(["localhost"]))
317
    self.assertEqual(hpath, self.lu.HPATH)
318
    self.assertEqual(phase, constants.HOOKS_PHASE_PRE)
319
    self._CheckEnv(env, constants.HOOKS_PHASE_PRE, self.lu.HPATH)
320

  
321
    # Check post-phase hook
322
    self.lu.hook_env = {}
323
    self.hm.RunPhase(constants.HOOKS_PHASE_POST)
324

  
325
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
326
    self.assertEqual(node_list, set(["localhost"]))
327
    self.assertEqual(hpath, self.lu.HPATH)
328
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
329
    self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
330

  
331
    self.assertRaises(IndexError, self._rpcs.pop)
332

  
333
  def testEnv(self):
334
    # Check pre-phase hook
335
    self.lu.hook_env = {
336
      "FOO": "pre-foo-value",
337
      }
338
    self.hm.RunPhase(constants.HOOKS_PHASE_PRE)
339

  
340
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
341
    self.assertEqual(node_list, set(["localhost"]))
342
    self.assertEqual(hpath, self.lu.HPATH)
343
    self.assertEqual(phase, constants.HOOKS_PHASE_PRE)
344
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
345
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
346
    self._CheckEnv(env, constants.HOOKS_PHASE_PRE, self.lu.HPATH)
347

  
348
    # Check post-phase hook
349
    self.lu.hook_env = {
350
      "FOO": "post-value",
351
      "BAR": 123,
352
      }
353
    self.hm.RunPhase(constants.HOOKS_PHASE_POST)
354

  
355
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
356
    self.assertEqual(node_list, set(["localhost"]))
357
    self.assertEqual(hpath, self.lu.HPATH)
358
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
359
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
360
    self.assertEqual(env["GANETI_POST_FOO"], "post-value")
361
    self.assertEqual(env["GANETI_POST_BAR"], "123")
362
    self.assertFalse("GANETI_BAR" in env)
363
    self._CheckEnv(env, constants.HOOKS_PHASE_POST, self.lu.HPATH)
364

  
365
    self.assertRaises(IndexError, self._rpcs.pop)
366

  
367
    # Check configuration update hook
368
    self.hm.RunConfigUpdate()
369
    (node_list, hpath, phase, env) = self._rpcs.pop(0)
370
    self.assertEqual(set(node_list), set([self.lu.cfg.GetMasterNode()]))
371
    self.assertEqual(hpath, constants.HOOKS_NAME_CFGUPDATE)
372
    self.assertEqual(phase, constants.HOOKS_PHASE_POST)
373
    self._CheckEnv(env, constants.HOOKS_PHASE_POST,
374
                   constants.HOOKS_NAME_CFGUPDATE)
375
    self.assertFalse(compat.any(key.startswith("GANETI_POST") for key in env))
376
    self.assertEqual(env["GANETI_FOO"], "pre-foo-value")
377
    self.assertRaises(IndexError, self._rpcs.pop)
378

  
379
  def testConflict(self):
380
    for name in ["DATA_DIR", "OP_CODE"]:
381
      self.lu.hook_env = { name: "value" }
382
      for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
383
        # Test using a clean HooksMaster instance
384
        self.assertRaises(AssertionError,
385
                          mcpu.HooksMaster(self._HooksRpc, self.lu).RunPhase,
386
                          phase)
387
        self.assertRaises(IndexError, self._rpcs.pop)
388

  
389
  def testNoNodes(self):
390
    self.lu.hook_env = {}
391
    self.hm.RunPhase(constants.HOOKS_PHASE_PRE, nodes=[])
392
    self.assertRaises(IndexError, self._rpcs.pop)
393

  
394
  def testSpecificNodes(self):
395
    self.lu.hook_env = {}
396

  
397
    nodes = [
398
      "node1.example.com",
399
      "node93782.example.net",
400
      ]
401

  
402
    for phase in [constants.HOOKS_PHASE_PRE, constants.HOOKS_PHASE_POST]:
403
      self.hm.RunPhase(phase, nodes=nodes)
404

  
405
      (node_list, hpath, rpc_phase, env) = self._rpcs.pop(0)
406
      self.assertEqual(set(node_list), set(nodes))
407
      self.assertEqual(hpath, self.lu.HPATH)
408
      self.assertEqual(rpc_phase, phase)
409
      self._CheckEnv(env, phase, self.lu.HPATH)
410

  
411
      self.assertRaises(IndexError, self._rpcs.pop)
412

  
413
  def testRunConfigUpdateNoPre(self):
414
    self.lu.hook_env = {}
415
    self.assertRaises(AssertionError, self.hm.RunConfigUpdate)
416
    self.assertRaises(IndexError, self._rpcs.pop)
417

  
418

  
274 419
if __name__ == '__main__':
275 420
  testutils.GanetiTestProgram()

Also available in: Unified diff