|
@@ -76,7 +76,7 @@ class SubprocessTests(unittest.TestCase):
|
|
instance.reopenlogs()
|
|
instance.reopenlogs()
|
|
self.assertEqual(instance.dispatchers[0].logs_reopened, True)
|
|
self.assertEqual(instance.dispatchers[0].logs_reopened, True)
|
|
self.assertEqual(instance.dispatchers[1].logs_reopened, False)
|
|
self.assertEqual(instance.dispatchers[1].logs_reopened, False)
|
|
-
|
|
|
|
|
|
+
|
|
def test_removelogs(self):
|
|
def test_removelogs(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
config = DummyPConfig(options, 'test', '/test')
|
|
config = DummyPConfig(options, 'test', '/test')
|
|
@@ -99,12 +99,24 @@ class SubprocessTests(unittest.TestCase):
|
|
self.assertTrue(instance.dispatchers[0].read_event_handled)
|
|
self.assertTrue(instance.dispatchers[0].read_event_handled)
|
|
self.assertTrue(instance.dispatchers[1].write_event_handled)
|
|
self.assertTrue(instance.dispatchers[1].write_event_handled)
|
|
|
|
|
|
- def test_get_execv_args_bad_command(self):
|
|
|
|
|
|
+ def test_get_execv_args_bad_command_extraquote(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
config = DummyPConfig(options, 'extraquote', 'extraquote"')
|
|
config = DummyPConfig(options, 'extraquote', 'extraquote"')
|
|
instance = self._makeOne(config)
|
|
instance = self._makeOne(config)
|
|
self.assertRaises(BadCommand, instance.get_execv_args)
|
|
self.assertRaises(BadCommand, instance.get_execv_args)
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ def test_get_execv_args_bad_command_empty(self):
|
|
|
|
+ options = DummyOptions()
|
|
|
|
+ config = DummyPConfig(options, 'empty', '')
|
|
|
|
+ instance = self._makeOne(config)
|
|
|
|
+ self.assertRaises(BadCommand, instance.get_execv_args)
|
|
|
|
+
|
|
|
|
+ def test_get_execv_args_bad_command_whitespaceonly(self):
|
|
|
|
+ options = DummyOptions()
|
|
|
|
+ config = DummyPConfig(options, 'whitespaceonly', ' \t ')
|
|
|
|
+ instance = self._makeOne(config)
|
|
|
|
+ self.assertRaises(BadCommand, instance.get_execv_args)
|
|
|
|
+
|
|
def test_get_execv_args_abs_missing(self):
|
|
def test_get_execv_args_abs_missing(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
config = DummyPConfig(options, 'notthere', '/notthere')
|
|
config = DummyPConfig(options, 'notthere', '/notthere')
|
|
@@ -1228,14 +1240,14 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
instance = self._makeOne(config)
|
|
instance = self._makeOne(config)
|
|
instance.group = DummyProcessGroup(DummyPGroupConfig(options))
|
|
instance.group = DummyProcessGroup(DummyPGroupConfig(options))
|
|
self.assertRaises(NotImplementedError, instance.spawn)
|
|
self.assertRaises(NotImplementedError, instance.spawn)
|
|
-
|
|
|
|
|
|
+
|
|
def test_prepare_child_fds(self):
|
|
def test_prepare_child_fds(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
options.forkpid = 0
|
|
options.forkpid = 0
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
instance = self._makeOne(config)
|
|
instance = self._makeOne(config)
|
|
sock_config = DummySocketConfig(7)
|
|
sock_config = DummySocketConfig(7)
|
|
- gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
|
|
|
|
+ gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
sock_config)
|
|
sock_config)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
result = instance.spawn()
|
|
result = instance.spawn()
|
|
@@ -1253,7 +1265,7 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
config.redirect_stderr = True
|
|
config.redirect_stderr = True
|
|
instance = self._makeOne(config)
|
|
instance = self._makeOne(config)
|
|
sock_config = DummySocketConfig(13)
|
|
sock_config = DummySocketConfig(13)
|
|
- gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
|
|
|
|
+ gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
sock_config)
|
|
sock_config)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
result = instance.spawn()
|
|
result = instance.spawn()
|
|
@@ -1261,19 +1273,19 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
self.assertEqual(len(options.duped), 2)
|
|
self.assertEqual(len(options.duped), 2)
|
|
self.assertEqual(options.duped[13], 0)
|
|
self.assertEqual(options.duped[13], 0)
|
|
self.assertEqual(len(options.fds_closed), options.minfds - 3)
|
|
self.assertEqual(len(options.fds_closed), options.minfds - 3)
|
|
-
|
|
|
|
|
|
+
|
|
def test_before_spawn_gets_socket_ref(self):
|
|
def test_before_spawn_gets_socket_ref(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
instance = self._makeOne(config)
|
|
instance = self._makeOne(config)
|
|
sock_config = DummySocketConfig(7)
|
|
sock_config = DummySocketConfig(7)
|
|
- gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
|
|
|
|
+ gconfig = DummyFCGIGroupConfig(options, 'whatever', 999, None,
|
|
sock_config)
|
|
sock_config)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
instance.group = DummyFCGIProcessGroup(gconfig)
|
|
self.assertTrue(instance.fcgi_sock is None)
|
|
self.assertTrue(instance.fcgi_sock is None)
|
|
instance.before_spawn()
|
|
instance.before_spawn()
|
|
self.assertFalse(instance.fcgi_sock is None)
|
|
self.assertFalse(instance.fcgi_sock is None)
|
|
-
|
|
|
|
|
|
+
|
|
def test_after_finish_removes_socket_ref(self):
|
|
def test_after_finish_removes_socket_ref(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
config = DummyPConfig(options, 'good', '/good/filename', uid=1)
|
|
@@ -1281,7 +1293,7 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
instance.fcgi_sock = 'hello'
|
|
instance.fcgi_sock = 'hello'
|
|
instance.after_finish()
|
|
instance.after_finish()
|
|
self.assertTrue(instance.fcgi_sock is None)
|
|
self.assertTrue(instance.fcgi_sock is None)
|
|
-
|
|
|
|
|
|
+
|
|
#Patch Subprocess.finish() method for this test to verify override
|
|
#Patch Subprocess.finish() method for this test to verify override
|
|
@patch.object(Subprocess, 'finish', Mock(return_value=sentinel.finish_result))
|
|
@patch.object(Subprocess, 'finish', Mock(return_value=sentinel.finish_result))
|
|
def test_finish_override(self):
|
|
def test_finish_override(self):
|
|
@@ -1303,7 +1315,7 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
'Subprocess.finish() pid arg was not passed')
|
|
'Subprocess.finish() pid arg was not passed')
|
|
self.assertEqual(sentinel.sts, sts_arg,
|
|
self.assertEqual(sentinel.sts, sts_arg,
|
|
'Subprocess.finish() sts arg was not passed')
|
|
'Subprocess.finish() sts arg was not passed')
|
|
-
|
|
|
|
|
|
+
|
|
#Patch Subprocess.spawn() method for this test to verify override
|
|
#Patch Subprocess.spawn() method for this test to verify override
|
|
@patch.object(Subprocess, 'spawn', Mock(return_value=sentinel.ppid))
|
|
@patch.object(Subprocess, 'spawn', Mock(return_value=sentinel.ppid))
|
|
def test_spawn_override_success(self):
|
|
def test_spawn_override_success(self):
|
|
@@ -1334,7 +1346,7 @@ class FastCGISubprocessTests(unittest.TestCase):
|
|
self.assertEqual(1, instance.before_spawn.call_count,
|
|
self.assertEqual(1, instance.before_spawn.call_count,
|
|
'FastCGISubprocess.before_spawn() not called once')
|
|
'FastCGISubprocess.before_spawn() not called once')
|
|
self.assertEqual(None, instance.fcgi_sock,
|
|
self.assertEqual(None, instance.fcgi_sock,
|
|
- 'FastCGISubprocess.spawn() did not remove sock ref on error')
|
|
|
|
|
|
+ 'FastCGISubprocess.spawn() did not remove sock ref on error')
|
|
|
|
|
|
class ProcessGroupBaseTests(unittest.TestCase):
|
|
class ProcessGroupBaseTests(unittest.TestCase):
|
|
def _getTargetClass(self):
|
|
def _getTargetClass(self):
|
|
@@ -1399,7 +1411,7 @@ class ProcessGroupBaseTests(unittest.TestCase):
|
|
group.processes = { 'process1': process1, 'process2': process2 }
|
|
group.processes = { 'process1': process1, 'process2': process2 }
|
|
result= group.get_dispatchers()
|
|
result= group.get_dispatchers()
|
|
self.assertEqual(result, {4:None, 5:None})
|
|
self.assertEqual(result, {4:None, 5:None})
|
|
-
|
|
|
|
|
|
+
|
|
def test_reopenlogs(self):
|
|
def test_reopenlogs(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
from supervisor.states import ProcessStates
|
|
from supervisor.states import ProcessStates
|
|
@@ -1426,7 +1438,7 @@ class ProcessGroupBaseTests(unittest.TestCase):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
gconfig1 = DummyPGroupConfig(options)
|
|
gconfig1 = DummyPGroupConfig(options)
|
|
group1 = self._makeOne(gconfig1)
|
|
group1 = self._makeOne(gconfig1)
|
|
-
|
|
|
|
|
|
+
|
|
gconfig2 = DummyPGroupConfig(options)
|
|
gconfig2 = DummyPGroupConfig(options)
|
|
group2 = self._makeOne(gconfig2)
|
|
group2 = self._makeOne(gconfig2)
|
|
|
|
|
|
@@ -1462,7 +1474,7 @@ class ProcessGroupTests(ProcessGroupBaseTests):
|
|
group.processes = {'process1': process1}
|
|
group.processes = {'process1': process1}
|
|
group.transition()
|
|
group.transition()
|
|
self.assertEqual(process1.transitioned, True)
|
|
self.assertEqual(process1.transitioned, True)
|
|
-
|
|
|
|
|
|
+
|
|
class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
def setUp(self):
|
|
def setUp(self):
|
|
from supervisor.events import clear
|
|
from supervisor.events import clear
|
|
@@ -1471,7 +1483,7 @@ class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
def tearDown(self):
|
|
def tearDown(self):
|
|
from supervisor.events import clear
|
|
from supervisor.events import clear
|
|
clear()
|
|
clear()
|
|
-
|
|
|
|
|
|
+
|
|
def _getTargetClass(self):
|
|
def _getTargetClass(self):
|
|
from supervisor.process import EventListenerPool
|
|
from supervisor.process import EventListenerPool
|
|
return EventListenerPool
|
|
return EventListenerPool
|
|
@@ -1485,9 +1497,9 @@ class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
pool = self._makeOne(gconfig)
|
|
pool = self._makeOne(gconfig)
|
|
from supervisor import events
|
|
from supervisor import events
|
|
self.assertEqual(len(events.callbacks), 2)
|
|
self.assertEqual(len(events.callbacks), 2)
|
|
- self.assertEqual(events.callbacks[0],
|
|
|
|
|
|
+ self.assertEqual(events.callbacks[0],
|
|
(EventType, pool._acceptEvent))
|
|
(EventType, pool._acceptEvent))
|
|
- self.assertEqual(events.callbacks[1],
|
|
|
|
|
|
+ self.assertEqual(events.callbacks[1],
|
|
(events.EventRejectedEvent, pool.handle_rejected))
|
|
(events.EventRejectedEvent, pool.handle_rejected))
|
|
self.assertEqual(pool.serial, -1)
|
|
self.assertEqual(pool.serial, -1)
|
|
|
|
|
|
@@ -1529,7 +1541,7 @@ class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
dummyevent.serial = 1
|
|
dummyevent.serial = 1
|
|
pool.handle_rejected(dummyevent)
|
|
pool.handle_rejected(dummyevent)
|
|
self.assertEqual(pool.event_buffer, [dummyevent.event, None, None])
|
|
self.assertEqual(pool.event_buffer, [dummyevent.event, None, None])
|
|
-
|
|
|
|
|
|
+
|
|
def test_handle_rejected_event_buffer_overflowed(self):
|
|
def test_handle_rejected_event_buffer_overflowed(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
gconfig = DummyPGroupConfig(options)
|
|
gconfig = DummyPGroupConfig(options)
|
|
@@ -1618,7 +1630,7 @@ class EventListenerPoolTests(ProcessGroupBaseTests):
|
|
self.assertEqual(process1.transitioned, True)
|
|
self.assertEqual(process1.transitioned, True)
|
|
self.assertEqual(pool.event_buffer, [event])
|
|
self.assertEqual(pool.event_buffer, [event])
|
|
data = pool.config.options.logger.data
|
|
data = pool.config.options.logger.data
|
|
-
|
|
|
|
|
|
+
|
|
def test_transition_event_proc_not_running(self):
|
|
def test_transition_event_proc_not_running(self):
|
|
options = DummyOptions()
|
|
options = DummyOptions()
|
|
from supervisor.states import ProcessStates
|
|
from supervisor.states import ProcessStates
|