~jimbaker/pyjuju/robust-hook-exit

« back to all changes in this revision

Viewing changes to ensemble/hooks/tests/test_invoker.py

  • Committer: Jim Baker
  • Date: 2011-07-25 20:36:15 UTC
  • Revision ID: jim.baker@canonical.com-20110725203615-sd215gqijjbg2n0c
Initial mock test for hanging process

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
from ensemble.hooks import invoker
16
16
from ensemble.hooks import commands
17
17
from ensemble.hooks.protocol import UnitSettingsFactory
 
18
from ensemble.lib.mocker import ANY, ARGS, KWARGS  # XXX - use an actual matcher
18
19
from ensemble.lib.testing import TestCase
19
20
from ensemble.lib.twistutils import get_module_directory
20
21
from ensemble.state import hook
219
220
 
220
221
    @defer.inlineCallbacks
221
222
    def test_get_from_different_unit(self):
222
 
        """Verify that relation-get words with a remote unit.
 
223
        """Verify that relation-get works with a remote unit.
223
224
 
224
225
        This test will run the logic of relation-get and will ensure
225
226
        that, even though we're running the hook within the context of
442
443
        self.assertIn("FAIL", self.log.getvalue())
443
444
        self.assertIn("exit code 1", self.log.getvalue())
444
445
 
 
446
    @defer.inlineCallbacks
 
447
    def test_slow_hook_ending(self):
 
448
        """Verify that a hook that's slow to end is terminated.
 
449
 
 
450
        Test this by having the hook fork a process that hangs around
 
451
        for a while, necessitating reaping. (We will change the
 
452
        callLater so it does it more quickly than 5s. There may be
 
453
        better solutions.)
 
454
 
 
455
        http://www.snailbook.com/faq/background-jobs.auto.html
 
456
        provides some insight into what can happen.
 
457
        """
 
458
        from twisted.internet import reactor
 
459
        
 
460
        # verify we get this call
 
461
 
 
462
        mock_reaper = self.mocker.mock()
 
463
        mock_reaper.cancel()
 
464
        def f():
 
465
            print "I have been canceled"
 
466
        self.mocker.call(f)
 
467
 
 
468
        mock_reactor = self.mocker.patch(reactor)
 
469
        mock_reactor.callLater(5, ANY)  # XXX construct a better match
 
470
        self.mocker.result(mock_reaper)
 
471
        self.mocker.replay()
 
472
 
 
473
        # The hook will immediately exit with a status code of 0,
 
474
        # but it has a background process that is running (and will sleep for 10s)
 
475
        exe = self.ua.get_invoker("database", "add", "mysql/0", self.relation)
 
476
        result = yield exe(self.get_test_hook("hanging-hook"))
 
477
        self.assertEqual(result, 0)
 
478
        # self.assertFalse(exe.ended.called)
 
479
 
 
480
        # now force it to end
 
481
        #yield self.sleep(2)
 
482
        yield exe.ended
 
483
        #yield self.sleep(3)
 
484
 
445
485
    def test_path_setup(self):
446
486
        """Validate that the path allows finding the executable."""
447
487
        from twisted.python.procutils import which