Esempio n. 1
0
 def test_worker_disappears_in_cleanup(self):
     d = MyWorkerDaemon({'workers': 2})
     strategy = daemon.DaemonStrategy(d, d.logger)
     strategy.register_worker_start('mock-pid-1', {'mock_options': True})
     strategy.register_worker_start('mock-pid-2', {'mock_options': True})
     self.assertEqual(strategy.unspawned_worker_options, [])
     self.assertEqual(
         strategy.options_by_pid, {
             'mock-pid-1': {
                 'mock_options': True
             },
             'mock-pid-2': {
                 'mock_options': True
             },
         })
     with mock.patch('swift.common.daemon.os.kill') as mock_kill:
         mock_kill.side_effect = [
             None, OSError(errno.ECHILD, os.strerror(errno.ECHILD))
         ]
         strategy.cleanup()
     self.assertEqual(strategy.unspawned_worker_options,
                      [{
                          'mock_options': True
                      }] * 2)
     self.assertEqual(strategy.options_by_pid, {})
     self.assertEqual(
         set([
             ('mock-pid-1', signal.SIGTERM),
             ('mock-pid-2', signal.SIGTERM),
         ]), set(c[0] for c in mock_kill.call_args_list))
     self.assertEqual(
         set(d.logger.get_lines_for_level('debug')[-2:]),
         set([
             'Cleaned up worker mock-pid-1', 'Cleaned up worker mock-pid-2'
         ]))
Esempio n. 2
0
 def test_restart_workers(self):
     d = MyWorkerDaemon({'workers': 3})
     strategy = daemon.DaemonStrategy(d, d.logger)
     d.health_side_effects = [True, False]
     with self.mock_os():
         self.mock_kill.side_effect = lambda *args, **kwargs: setattr(
             strategy, 'running', False)
         strategy.run()
     # six workers forked in total
     self.assertEqual([mock.call()] * 6, self.mock_fork.call_args_list)
     # since the daemon starts healthy, first pass checks children once
     self.assertEqual(self.waitpid_calls, {
         'mock-pid-0': 1,
         'mock-pid-1': 1,
         'mock-pid-2': 1,
     })
     # second pass is not healthy, original pid's killed
     self.assertEqual(
         set([
             ('mock-pid-0', signal.SIGTERM),
             ('mock-pid-1', signal.SIGTERM),
             ('mock-pid-2', signal.SIGTERM),
         ]), set(c[0] for c in self.mock_kill.call_args_list[:3]))
     # our mock_kill side effect breaks out of running, and cleanup kills
     # remaining pids
     self.assertEqual(
         set([
             ('mock-pid-3', signal.SIGTERM),
             ('mock-pid-4', signal.SIGTERM),
             ('mock-pid-5', signal.SIGTERM),
         ]), set(c[0] for c in self.mock_kill.call_args_list[3:]))
Esempio n. 3
0
 def test_worker_disappears(self):
     d = MyWorkerDaemon({'workers': 3})
     strategy = daemon.DaemonStrategy(d, d.logger)
     strategy.register_worker_start('mock-pid', {'mock_options': True})
     self.assertEqual(strategy.unspawned_worker_options, [])
     self.assertEqual(strategy.options_by_pid,
                      {'mock-pid': {
                          'mock_options': True
                      }})
     # still running
     with mock.patch('swift.common.daemon.os.waitpid') as mock_waitpid:
         mock_waitpid.return_value = (0, 0)
         strategy.check_on_all_running_workers()
     self.assertEqual(strategy.unspawned_worker_options, [])
     self.assertEqual(strategy.options_by_pid,
                      {'mock-pid': {
                          'mock_options': True
                      }})
     # finished
     strategy = daemon.DaemonStrategy(d, d.logger)
     strategy.register_worker_start('mock-pid', {'mock_options': True})
     with mock.patch('swift.common.daemon.os.waitpid') as mock_waitpid:
         mock_waitpid.return_value = ('mock-pid', 0)
         strategy.check_on_all_running_workers()
     self.assertEqual(strategy.unspawned_worker_options,
                      [{
                          'mock_options': True
                      }])
     self.assertEqual(strategy.options_by_pid, {})
     self.assertEqual(
         d.logger.get_lines_for_level('debug')[-1],
         'Worker mock-pid exited')
     # disappeared
     strategy = daemon.DaemonStrategy(d, d.logger)
     strategy.register_worker_start('mock-pid', {'mock_options': True})
     with mock.patch('swift.common.daemon.os.waitpid') as mock_waitpid:
         mock_waitpid.side_effect = OSError(errno.ECHILD,
                                            os.strerror(errno.ECHILD))
         mock_waitpid.return_value = ('mock-pid', 0)
         strategy.check_on_all_running_workers()
     self.assertEqual(strategy.unspawned_worker_options,
                      [{
                          'mock_options': True
                      }])
     self.assertEqual(strategy.options_by_pid, {})
     self.assertEqual(
         d.logger.get_lines_for_level('notice')[-1], 'Worker mock-pid died')
Esempio n. 4
0
 def test_forked_worker(self):
     d = MyWorkerDaemon({'workers': 3})
     strategy = daemon.DaemonStrategy(d, d.logger)
     with mock.patch('swift.common.daemon.os.fork') as mock_fork, \
             mock.patch('swift.common.daemon.os._exit') as mock_exit:
         mock_fork.return_value = 0
         mock_exit.side_effect = SystemExit
         self.assertRaises(SystemExit, strategy.run, once=True)
     self.assertTrue(d.once_called)
Esempio n. 5
0
 def test_fork_workers(self):
     d = MyWorkerDaemon({'workers': 3})
     strategy = daemon.DaemonStrategy(d, d.logger)
     with self.mock_os():
         strategy.run(once=True)
     self.assertEqual([mock.call()] * 3, self.mock_fork.call_args_list)
     self.assertEqual(self.waitpid_calls, {
         'mock-pid-0': 3,
         'mock-pid-1': 3,
         'mock-pid-2': 3,
     })
     self.assertEqual([], self.mock_kill.call_args_list)
     self.assertIn('Finished', d.logger.get_lines_for_level('notice')[-1])
Esempio n. 6
0
 def test_signal(self):
     d = MyDaemon({})
     with mock.patch('swift.common.daemon.signal') as mock_signal:
         mock_signal.SIGTERM = signal.SIGTERM
         daemon.DaemonStrategy(d, d.logger).run()
     signal_args, kwargs = mock_signal.signal.call_args
     sig, func = signal_args
     self.assertEqual(sig, signal.SIGTERM)
     with mock.patch('swift.common.daemon.os') as mock_os:
         func()
     self.assertEqual(mock_os.method_calls, [
         mock.call.killpg(0, signal.SIGTERM),
         # hard exit because bare except handlers can trap SystemExit
         mock.call._exit(0)
     ])