github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/jujupy/tests/test_timeout.py (about)

     1  from argparse import Namespace
     2  from contextlib import contextmanager
     3  import datetime
     4  import random
     5  from signal import SIGTERM
     6  from unittest import TestCase
     7  
     8  try:
     9      from mock import (
    10          call,
    11          patch,
    12      )
    13  except ImportError:
    14      from unittest.mock import (
    15          call,
    16          patch,
    17      )
    18  
    19  from jujupy.timeout import (
    20      main,
    21      parse_args,
    22      run_command,
    23      signals,
    24      )
    25  from tests import parse_error
    26  
    27  
    28  class TestParseArgs(TestCase):
    29  
    30      def test_parse_args(self):
    31          args, command = parse_args(['500', 'foo', 'bar'])
    32          self.assertEqual(args, Namespace(duration=500.0, signal='TERM'))
    33          self.assertEqual(command, ['foo', 'bar'])
    34  
    35      def test_parse_args_command_options(self):
    36          args, command = parse_args(['500', 'foo', '--bar'])
    37          self.assertEqual(args, Namespace(duration=500.0, signal='TERM'))
    38          self.assertEqual(command, ['foo', '--bar'])
    39  
    40      def test_parse_args_signal(self):
    41          args, command = parse_args(['500', '--', 'foo', '--signal'])
    42          self.assertEqual(args, Namespace(duration=500.0, signal='TERM'))
    43          self.assertEqual(command, ['foo', '--signal'])
    44  
    45      def test_parse_args_signal_novalue(self):
    46          with parse_error(self) as stderr:
    47              args, command = parse_args(['500', 'foo', '--signal'])
    48          self.assertRegexpMatches(
    49              stderr.getvalue(), 'argument --signal: expected one argument')
    50  
    51  
    52  class TestMain(TestCase):
    53  
    54      def test_main(self):
    55          signal_name, signal_value = random.choice(list(signals.items()))
    56          with patch('jujupy.timeout.run_command', autospec=True) as rc_mock:
    57              main(['500', '--signal', signal_name, 'foo', 'bar'])
    58          rc_mock.assert_called_once_with(500, signal_value, ['foo', 'bar'])
    59  
    60  
    61  class TestRunCommand(TestCase):
    62  
    63      @contextmanager
    64      def patch_po(self):
    65          with patch('subprocess.Popen', autospec=True) as po_mock:
    66              with patch('time.sleep') as sleep_mock:
    67                  yield po_mock, po_mock.return_value.poll, sleep_mock
    68  
    69      def test_run_and_poll(self):
    70          with self.patch_po() as (po_mock, poll_mock, sleep_mock):
    71              poll_mock = po_mock.return_value.poll
    72              poll_mock.return_value = 123
    73              self.assertEqual(run_command(57.5, SIGTERM, ['ls', 'foo']),
    74                               123)
    75          po_mock.assert_called_once_with(['ls', 'foo'], creationflags=0)
    76          poll_mock.assert_called_once_with()
    77          self.assertEqual(sleep_mock.call_count, 0)
    78  
    79      def test_multiple_polls(self):
    80          with self.patch_po() as (po_mock, poll_mock, sleep_mock):
    81              poll_mock.side_effect = [None, None, 123, 124]
    82              self.assertEqual(run_command(57.5, SIGTERM, ['ls', 'foo']),
    83                               123)
    84          self.assertEqual(
    85              poll_mock.mock_calls, [call(), call(), call()])
    86          self.assertEqual(
    87              sleep_mock.mock_calls, [call(0.1), call(0.1)])
    88  
    89      def test_duration_elapsed(self):
    90          start = datetime.datetime(2015, 1, 1)
    91          middle = start + datetime.timedelta(seconds=57.4)
    92          end = start + datetime.timedelta(seconds=57.6)
    93          with self.patch_po() as (po_mock, poll_mock, sleep_mock):
    94              poll_mock.side_effect = [None, None, None, None]
    95              with patch('utility.until_timeout.now') as utn_mock:
    96                  utn_mock.side_effect = [start, middle, end, end]
    97                  self.assertEqual(run_command(57.5, SIGTERM, ['ls', 'foo']),
    98                                   124)
    99          self.assertEqual(
   100              poll_mock.mock_calls, [call(), call()])
   101          self.assertEqual(
   102              sleep_mock.mock_calls, [call(0.1), call(0.1)])
   103          self.assertEqual(utn_mock.mock_calls, [call(), call(), call()])
   104          po_mock.return_value.send_signal.assert_called_once_with(SIGTERM)
   105          po_mock.return_value.wait.assert_called_once_with()