123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641 |
- """Test suite for supervisor.options"""
- import os
- import sys
- import tempfile
- import socket
- import unittest
- import signal
- import shutil
- import errno
- from mock import Mock, patch, sentinel
- from supervisor.tests.base import DummySupervisor
- from supervisor.tests.base import DummyLogger
- from supervisor.tests.base import DummyOptions
- from supervisor.tests.base import DummyPConfig
- from supervisor.tests.base import DummyProcess
- from supervisor.tests.base import DummySocketConfig
- from supervisor.tests.base import lstrip
- class OptionTests(unittest.TestCase):
- def _makeOptions(self, read_error=False):
- from cStringIO import StringIO
- from supervisor.options import Options
- from supervisor.datatypes import integer
- class MyOptions(Options):
- master = {
- 'other': 41 }
- def __init__(self, read_error=read_error):
- self.read_error = read_error
- Options.__init__(self)
- class Foo(object): pass
- self.configroot = Foo()
- def read_config(self, fp):
- if self.read_error:
- raise ValueError(self.read_error)
- # Pretend we read it from file:
- self.configroot.__dict__.update(self.default_map)
- self.configroot.__dict__.update(self.master)
- options = MyOptions()
- options.configfile = StringIO()
- options.add(name='anoption', confname='anoption',
- short='o', long='option', default='default')
- options.add(name='other', confname='other', env='OTHER',
- short='p:', long='other=', handler=integer)
- return options
- def test_options_and_args_order(self):
- # Only config file exists
- options = self._makeOptions()
- options.realize([])
- self.assertEquals(options.anoption, 'default')
- self.assertEquals(options.other, 41)
- # Env should trump config
- options = self._makeOptions()
- os.environ['OTHER'] = '42'
- options.realize([])
- self.assertEquals(options.other, 42)
- # Opt should trump both env (still set) and config
- options = self._makeOptions()
- options.realize(['-p', '43'])
- self.assertEquals(options.other, 43)
- del os.environ['OTHER']
- def test_config_reload(self):
- options = self._makeOptions()
- options.realize([])
- self.assertEquals(options.other, 41)
- options.master['other'] = 42
- options.process_config_file()
- self.assertEquals(options.other, 42)
- def test_config_reload_do_usage_false(self):
- options = self._makeOptions(read_error='error')
- self.assertRaises(ValueError, options.process_config_file,
- False)
- def test_config_reload_do_usage_true(self):
- options = self._makeOptions(read_error='error')
- from StringIO import StringIO
- L = []
- def exit(num):
- L.append(num)
- options.stderr = options.stdout = StringIO()
- options.exit = exit
- options.configroot.anoption = 1
- options.configroot.other = 1
- options.process_config_file(True)
- self.assertEqual(L, [2])
- def test__set(self):
- from supervisor.options import Options
- options = Options()
- options._set('foo', 'bar', 0)
- self.assertEquals(options.foo, 'bar')
- self.assertEquals(options.attr_priorities['foo'], 0)
- options._set('foo', 'baz', 1)
- self.assertEquals(options.foo, 'baz')
- self.assertEquals(options.attr_priorities['foo'], 1)
- options._set('foo', 'gazonk', 0)
- self.assertEquals(options.foo, 'baz')
- self.assertEquals(options.attr_priorities['foo'], 1)
- options._set('foo', 'gazonk', 1)
- self.assertEquals(options.foo, 'gazonk')
- class ClientOptionsTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import ClientOptions
- return ClientOptions
- def _makeOne(self):
- return self._getTargetClass()()
- def test_options(self):
- tempdir = tempfile.gettempdir()
- s = lstrip("""[supervisorctl]
- serverurl=http://localhost:9001
- username=chris
- password=123
- prompt=mysupervisor
- history_file=%s/sc_history
- """ % tempdir)
- from StringIO import StringIO
- fp = StringIO(s)
- instance = self._makeOne()
- instance.configfile = fp
- instance.realize(args=[])
- self.assertEqual(instance.interactive, True)
- history_file = os.path.join(tempdir, 'sc_history')
- self.assertEqual(instance.history_file, history_file)
- options = instance.configroot.supervisorctl
- self.assertEqual(options.prompt, 'mysupervisor')
- self.assertEqual(options.serverurl, 'http://localhost:9001')
- self.assertEqual(options.username, 'chris')
- self.assertEqual(options.password, '123')
- self.assertEqual(options.history_file, history_file)
- def test_options_unixsocket_cli(self):
- from StringIO import StringIO
- fp = StringIO('[supervisorctl]')
- instance = self._makeOne()
- instance.configfile = fp
- instance.realize(args=['--serverurl', 'unix:///dev/null'])
- self.assertEqual(instance.serverurl, 'unix:///dev/null')
- class ServerOptionsTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import ServerOptions
- return ServerOptions
- def _makeOne(self):
- return self._getTargetClass()()
- def test_version(self):
- from supervisor.options import VERSION
- options = self._makeOne()
- from StringIO import StringIO
- options.stdout = StringIO()
- self.assertRaises(SystemExit, options.version, None)
- self.assertEqual(options.stdout.getvalue(), VERSION + '\n')
- def test_options(self):
- s = lstrip("""[inet_http_server]
- port=127.0.0.1:8999
- username=chrism
- password=foo
- [supervisord]
- directory=%(tempdir)s
- backofflimit=10
- user=root
- umask=022
- logfile=supervisord.log
- logfile_maxbytes=1000MB
- logfile_backups=5
- loglevel=error
- pidfile=supervisord.pid
- nodaemon=true
- identifier=fleeb
- childlogdir=%(tempdir)s
- nocleanup=true
- minfds=2048
- minprocs=300
- environment=FAKE_ENV_VAR=/some/path
- [program:cat1]
- command=/bin/cat
- priority=1
- autostart=true
- user=root
- stdout_logfile=/tmp/cat.log
- stopsignal=KILL
- stopwaitsecs=5
- startsecs=5
- startretries=10
- directory=/tmp
- umask=002
- [program:cat2]
- priority=2
- command=/bin/cat
- autostart=true
- autorestart=false
- stdout_logfile_maxbytes = 1024
- stdout_logfile_backups = 2
- stdout_logfile = /tmp/cat2.log
- [program:cat3]
- priority=3
- process_name = replaced
- command=/bin/cat
- autorestart=true
- exitcodes=0,1,127
- stopasgroup=true
- killasgroup=true
- [program:cat4]
- priority=4
- process_name = fleeb_%%(process_num)s
- numprocs = 2
- command = /bin/cat
- autorestart=unexpected
- [program:cat5]
- priority=5
- process_name = foo_%%(process_num)02d
- numprocs = 2
- numprocs_start = 1
- command = /bin/cat
- directory = /some/path/foo_%%(process_num)02d
- """ % {'tempdir':tempfile.gettempdir()})
- from supervisor import datatypes
- from StringIO import StringIO
- fp = StringIO(s)
- instance = self._makeOne()
- instance.configfile = fp
- instance.realize(args=[])
- options = instance.configroot.supervisord
- self.assertEqual(options.directory, tempfile.gettempdir())
- self.assertEqual(options.umask, 022)
- self.assertEqual(options.logfile, 'supervisord.log')
- self.assertEqual(options.logfile_maxbytes, 1000 * 1024 * 1024)
- self.assertEqual(options.logfile_backups, 5)
- self.assertEqual(options.loglevel, 40)
- self.assertEqual(options.pidfile, 'supervisord.pid')
- self.assertEqual(options.nodaemon, True)
- self.assertEqual(options.identifier, 'fleeb')
- self.assertEqual(options.childlogdir, tempfile.gettempdir())
- self.assertEqual(len(options.server_configs), 1)
- self.assertEqual(options.server_configs[0]['family'], socket.AF_INET)
- self.assertEqual(options.server_configs[0]['host'], '127.0.0.1')
- self.assertEqual(options.server_configs[0]['port'], 8999)
- self.assertEqual(options.server_configs[0]['username'], 'chrism')
- self.assertEqual(options.server_configs[0]['password'], 'foo')
- self.assertEqual(options.nocleanup, True)
- self.assertEqual(options.minfds, 2048)
- self.assertEqual(options.minprocs, 300)
- self.assertEqual(options.nocleanup, True)
- self.assertEqual(len(options.process_group_configs), 5)
- self.assertEqual(options.environment, dict(FAKE_ENV_VAR='/some/path'))
- cat1 = options.process_group_configs[0]
- self.assertEqual(cat1.name, 'cat1')
- self.assertEqual(cat1.priority, 1)
- self.assertEqual(len(cat1.process_configs), 1)
- proc1 = cat1.process_configs[0]
- self.assertEqual(proc1.name, 'cat1')
- self.assertEqual(proc1.command, '/bin/cat')
- self.assertEqual(proc1.priority, 1)
- self.assertEqual(proc1.autostart, True)
- self.assertEqual(proc1.autorestart, datatypes.RestartWhenExitUnexpected)
- self.assertEqual(proc1.startsecs, 5)
- self.assertEqual(proc1.startretries, 10)
- self.assertEqual(proc1.uid, 0)
- self.assertEqual(proc1.stdout_logfile, '/tmp/cat.log')
- self.assertEqual(proc1.stopsignal, signal.SIGKILL)
- self.assertEqual(proc1.stopwaitsecs, 5)
- self.assertEqual(proc1.stopasgroup, False)
- self.assertEqual(proc1.killasgroup, False)
- self.assertEqual(proc1.stdout_logfile_maxbytes,
- datatypes.byte_size('50MB'))
- self.assertEqual(proc1.stdout_logfile_backups, 10)
- self.assertEqual(proc1.exitcodes, [0,2])
- self.assertEqual(proc1.directory, '/tmp')
- self.assertEqual(proc1.umask, 002)
- self.assertEqual(proc1.environment, dict(FAKE_ENV_VAR='/some/path'))
- cat2 = options.process_group_configs[1]
- self.assertEqual(cat2.name, 'cat2')
- self.assertEqual(cat2.priority, 2)
- self.assertEqual(len(cat2.process_configs), 1)
- proc2 = cat2.process_configs[0]
- self.assertEqual(proc2.name, 'cat2')
- self.assertEqual(proc2.command, '/bin/cat')
- self.assertEqual(proc2.priority, 2)
- self.assertEqual(proc2.autostart, True)
- self.assertEqual(proc2.autorestart, False)
- self.assertEqual(proc2.uid, None)
- self.assertEqual(proc2.stdout_logfile, '/tmp/cat2.log')
- self.assertEqual(proc2.stopsignal, signal.SIGTERM)
- self.assertEqual(proc2.stopasgroup, False)
- self.assertEqual(proc2.killasgroup, False)
- self.assertEqual(proc2.stdout_logfile_maxbytes, 1024)
- self.assertEqual(proc2.stdout_logfile_backups, 2)
- self.assertEqual(proc2.exitcodes, [0,2])
- self.assertEqual(proc2.directory, None)
- cat3 = options.process_group_configs[2]
- self.assertEqual(cat3.name, 'cat3')
- self.assertEqual(cat3.priority, 3)
- self.assertEqual(len(cat3.process_configs), 1)
- proc3 = cat3.process_configs[0]
- self.assertEqual(proc3.name, 'replaced')
- self.assertEqual(proc3.command, '/bin/cat')
- self.assertEqual(proc3.priority, 3)
- self.assertEqual(proc3.autostart, True)
- self.assertEqual(proc3.autorestart, datatypes.RestartUnconditionally)
- self.assertEqual(proc3.uid, None)
- self.assertEqual(proc3.stdout_logfile, datatypes.Automatic)
- self.assertEqual(proc3.stdout_logfile_maxbytes,
- datatypes.byte_size('50MB'))
- self.assertEqual(proc3.stdout_logfile_backups, 10)
- self.assertEqual(proc3.exitcodes, [0,1,127])
- self.assertEqual(proc3.stopsignal, signal.SIGTERM)
- self.assertEqual(proc3.stopasgroup, True)
- self.assertEqual(proc3.killasgroup, True)
- cat4 = options.process_group_configs[3]
- self.assertEqual(cat4.name, 'cat4')
- self.assertEqual(cat4.priority, 4)
- self.assertEqual(len(cat4.process_configs), 2)
- proc4_a = cat4.process_configs[0]
- self.assertEqual(proc4_a.name, 'fleeb_0')
- self.assertEqual(proc4_a.command, '/bin/cat')
- self.assertEqual(proc4_a.priority, 4)
- self.assertEqual(proc4_a.autostart, True)
- self.assertEqual(proc4_a.autorestart,
- datatypes.RestartWhenExitUnexpected)
- self.assertEqual(proc4_a.uid, None)
- self.assertEqual(proc4_a.stdout_logfile, datatypes.Automatic)
- self.assertEqual(proc4_a.stdout_logfile_maxbytes,
- datatypes.byte_size('50MB'))
- self.assertEqual(proc4_a.stdout_logfile_backups, 10)
- self.assertEqual(proc4_a.exitcodes, [0,2])
- self.assertEqual(proc4_a.stopsignal, signal.SIGTERM)
- self.assertEqual(proc4_a.stopasgroup, False)
- self.assertEqual(proc4_a.killasgroup, False)
- self.assertEqual(proc4_a.directory, None)
- proc4_b = cat4.process_configs[1]
- self.assertEqual(proc4_b.name, 'fleeb_1')
- self.assertEqual(proc4_b.command, '/bin/cat')
- self.assertEqual(proc4_b.priority, 4)
- self.assertEqual(proc4_b.autostart, True)
- self.assertEqual(proc4_b.autorestart,
- datatypes.RestartWhenExitUnexpected)
- self.assertEqual(proc4_b.uid, None)
- self.assertEqual(proc4_b.stdout_logfile, datatypes.Automatic)
- self.assertEqual(proc4_b.stdout_logfile_maxbytes,
- datatypes.byte_size('50MB'))
- self.assertEqual(proc4_b.stdout_logfile_backups, 10)
- self.assertEqual(proc4_b.exitcodes, [0,2])
- self.assertEqual(proc4_b.stopsignal, signal.SIGTERM)
- self.assertEqual(proc4_b.stopasgroup, False)
- self.assertEqual(proc4_b.killasgroup, False)
- self.assertEqual(proc4_b.directory, None)
- cat5 = options.process_group_configs[4]
- self.assertEqual(cat5.name, 'cat5')
- self.assertEqual(cat5.priority, 5)
- self.assertEqual(len(cat5.process_configs), 2)
- proc5_a = cat5.process_configs[0]
- self.assertEqual(proc5_a.name, 'foo_01')
- self.assertEqual(proc5_a.directory, '/some/path/foo_01')
- proc5_b = cat5.process_configs[1]
- self.assertEqual(proc5_b.name, 'foo_02')
- self.assertEqual(proc5_b.directory, '/some/path/foo_02')
- here = os.path.abspath(os.getcwd())
- self.assertEqual(instance.uid, 0)
- self.assertEqual(instance.gid, 0)
- self.assertEqual(instance.directory, tempfile.gettempdir())
- self.assertEqual(instance.umask, 022)
- self.assertEqual(instance.logfile, os.path.join(here,'supervisord.log'))
- self.assertEqual(instance.logfile_maxbytes, 1000 * 1024 * 1024)
- self.assertEqual(instance.logfile_backups, 5)
- self.assertEqual(instance.loglevel, 40)
- self.assertEqual(instance.pidfile, os.path.join(here,'supervisord.pid'))
- self.assertEqual(instance.nodaemon, True)
- self.assertEqual(instance.passwdfile, None)
- self.assertEqual(instance.identifier, 'fleeb')
- self.assertEqual(instance.childlogdir, tempfile.gettempdir())
- self.assertEqual(len(instance.server_configs), 1)
- self.assertEqual(instance.server_configs[0]['family'], socket.AF_INET)
- self.assertEqual(instance.server_configs[0]['host'], '127.0.0.1')
- self.assertEqual(instance.server_configs[0]['port'], 8999)
- self.assertEqual(instance.server_configs[0]['username'], 'chrism')
- self.assertEqual(instance.server_configs[0]['password'], 'foo')
- self.assertEqual(instance.nocleanup, True)
- self.assertEqual(instance.minfds, 2048)
- self.assertEqual(instance.minprocs, 300)
- def test_reload(self):
- from cStringIO import StringIO
- text = lstrip("""\
- [supervisord]
- user=root
- [program:one]
- command = /bin/cat
- [program:two]
- command = /bin/dog
- [program:four]
- command = /bin/sheep
- [group:thegroup]
- programs = one,two
- """)
- instance = self._makeOne()
- instance.configfile = StringIO(text)
- instance.realize(args=[])
- section = instance.configroot.supervisord
- self.assertEqual(len(section.process_group_configs), 2)
- cat = section.process_group_configs[0]
- self.assertEqual(len(cat.process_configs), 1)
- cat = section.process_group_configs[1]
- self.assertEqual(len(cat.process_configs), 2)
- self.assertTrue(section.process_group_configs is
- instance.process_group_configs)
- text = lstrip("""\
- [supervisord]
- user=root
- [program:one]
- command = /bin/cat
- [program:three]
- command = /bin/pig
- [group:thegroup]
- programs = three
- """)
- instance.configfile = StringIO(text)
- instance.process_config_file()
- section = instance.configroot.supervisord
- self.assertEqual(len(section.process_group_configs), 2)
- cat = section.process_group_configs[0]
- self.assertEqual(len(cat.process_configs), 1)
- proc = cat.process_configs[0]
- self.assertEqual(proc.name, 'one')
- self.assertEqual(proc.command, '/bin/cat')
- self.assertTrue(section.process_group_configs is
- instance.process_group_configs)
- cat = section.process_group_configs[1]
- self.assertEqual(len(cat.process_configs), 1)
- proc = cat.process_configs[0]
- self.assertEqual(proc.name, 'three')
- self.assertEqual(proc.command, '/bin/pig')
- def test_reload_clears_parse_warnings(self):
- instance = self._makeOne()
- old_warning = "Warning from a prior config read"
- instance.parse_warnings = [old_warning]
- from cStringIO import StringIO
- text = lstrip("""\
- [supervisord]
- user=root
- [program:cat]
- command = /bin/cat
- """)
- instance.configfile = StringIO(text)
- instance.realize(args=[])
- self.assertFalse(old_warning in instance.parse_warnings)
- def test_readFile_failed(self):
- from supervisor.options import readFile
- try:
- readFile('/notthere', 0, 10)
- except ValueError, inst:
- self.assertEqual(inst.args[0], 'FAILED')
- else:
- raise AssertionError("Didn't raise")
- def test_get_pid(self):
- instance = self._makeOne()
- self.assertEqual(os.getpid(), instance.get_pid())
- def test_get_signal_delegates_to_signal_receiver(self):
- instance = self._makeOne()
- instance.signal_receiver.receive(signal.SIGTERM, None)
- instance.signal_receiver.receive(signal.SIGCHLD, None)
- self.assertEqual(instance.get_signal(), signal.SIGTERM)
- self.assertEqual(instance.get_signal(), signal.SIGCHLD)
- self.assertEqual(instance.get_signal(), None)
- def test_check_execv_args_cant_find_command(self):
- instance = self._makeOne()
- from supervisor.options import NotFound
- self.assertRaises(NotFound, instance.check_execv_args,
- '/not/there', None, None)
- def test_check_execv_args_notexecutable(self):
- instance = self._makeOne()
- from supervisor.options import NotExecutable
- self.assertRaises(NotExecutable,
- instance.check_execv_args, '/etc/passwd',
- ['etc/passwd'], os.stat('/etc/passwd'))
- def test_check_execv_args_isdir(self):
- instance = self._makeOne()
- from supervisor.options import NotExecutable
- self.assertRaises(NotExecutable,
- instance.check_execv_args, '/',
- ['/'], os.stat('/'))
- def test_cleanup_afunix_unlink(self):
- fn = tempfile.mktemp()
- f = open(fn, 'w')
- f.write('foo')
- f.close()
- instance = self._makeOne()
- class Port:
- family = socket.AF_UNIX
- address = fn
- class Server:
- pass
- instance.httpservers = [({'family':socket.AF_UNIX, 'file':fn},
- Server())]
- instance.pidfile = ''
- instance.cleanup()
- self.failIf(os.path.exists(fn))
- def test_cleanup_afunix_nounlink(self):
- fn = tempfile.mktemp()
- try:
- f = open(fn, 'w')
- f.write('foo')
- f.close()
- instance = self._makeOne()
- class Port:
- family = socket.AF_UNIX
- address = fn
- class Server:
- pass
- instance.httpservers = [({'family':socket.AF_UNIX, 'file':fn},
- Server())]
- instance.pidfile = ''
- instance.unlink_socketfiles = False
- instance.cleanup()
- self.failUnless(os.path.exists(fn))
- finally:
- try:
- os.unlink(fn)
- except OSError:
- pass
- def test_close_httpservers(self):
- instance = self._makeOne()
- class Server:
- closed = False
- def close(self):
- self.closed = True
- server = Server()
- instance.httpservers = [({}, server)]
- instance.close_httpservers()
- self.assertEqual(server.closed, True)
- def test_close_logger(self):
- instance = self._makeOne()
- logger = DummyLogger()
- instance.logger = logger
- instance.close_logger()
- self.assertEqual(logger.closed, True)
- def test_write_pidfile_ok(self):
- fn = tempfile.mktemp()
- try:
- instance = self._makeOne()
- instance.logger = DummyLogger()
- instance.pidfile = fn
- instance.write_pidfile()
- self.failUnless(os.path.exists(fn))
- pid = int(open(fn, 'r').read()[:-1])
- self.assertEqual(pid, os.getpid())
- msg = instance.logger.data[0]
- self.failUnless(msg.startswith('supervisord started with pid'))
- finally:
- try:
- os.unlink(fn)
- except OSError:
- pass
- def test_write_pidfile_fail(self):
- fn = '/cannot/possibly/exist'
- instance = self._makeOne()
- instance.logger = DummyLogger()
- instance.pidfile = fn
- instance.write_pidfile()
- msg = instance.logger.data[0]
- self.failUnless(msg.startswith('could not write pidfile'))
- def test_close_fd(self):
- instance = self._makeOne()
- innie, outie = os.pipe()
- os.read(innie, 0) # we can read it while its open
- os.write(outie, 'foo') # we can write to it while its open
- instance.close_fd(innie)
- self.assertRaises(OSError, os.read, innie, 0)
- instance.close_fd(outie)
- self.assertRaises(OSError, os.write, outie, 'foo')
- def test_processes_from_section(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- priority = 1
- autostart = false
- autorestart = false
- startsecs = 100
- startretries = 100
- user = root
- stdout_logfile = NONE
- stdout_logfile_backups = 1
- stdout_logfile_maxbytes = 100MB
- stdout_events_enabled = true
- stopsignal = KILL
- stopwaitsecs = 100
- killasgroup = true
- exitcodes = 1,4
- redirect_stderr = false
- environment = KEY1=val1,KEY2=val2,KEY3=%(process_num)s
- numprocs = 2
- process_name = %(group_name)s_%(program_name)s_%(process_num)02d
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- pconfigs = instance.processes_from_section(config, 'program:foo', 'bar')
- self.assertEqual(len(pconfigs), 2)
- pconfig = pconfigs[0]
- self.assertEqual(pconfig.name, 'bar_foo_00')
- self.assertEqual(pconfig.command, '/bin/cat')
- self.assertEqual(pconfig.autostart, False)
- self.assertEqual(pconfig.autorestart, False)
- self.assertEqual(pconfig.startsecs, 100)
- self.assertEqual(pconfig.startretries, 100)
- self.assertEqual(pconfig.uid, 0)
- self.assertEqual(pconfig.stdout_logfile, None)
- self.assertEqual(pconfig.stdout_capture_maxbytes, 0)
- self.assertEqual(pconfig.stdout_logfile_maxbytes, 104857600)
- self.assertEqual(pconfig.stdout_events_enabled, True)
- self.assertEqual(pconfig.stopsignal, signal.SIGKILL)
- self.assertEqual(pconfig.stopasgroup, False)
- self.assertEqual(pconfig.killasgroup, True)
- self.assertEqual(pconfig.stopwaitsecs, 100)
- self.assertEqual(pconfig.exitcodes, [1,4])
- self.assertEqual(pconfig.redirect_stderr, False)
- self.assertEqual(pconfig.environment,
- {'KEY1':'val1', 'KEY2':'val2', 'KEY3':'0'})
- def test_processes_from_section_host_node_name_expansion(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/foo --host=%(host_node_name)s
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- pconfigs = instance.processes_from_section(config, 'program:foo', 'bar')
- import platform
- expected = "/bin/foo --host=" + platform.node()
- self.assertEqual(pconfigs[0].command, expected)
- def test_processes_from_section_environment_variables_expansion(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/foo --path='%(ENV_PATH)s'
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- pconfigs = instance.processes_from_section(config, 'program:foo', 'bar')
- expected = "/bin/foo --path='%s'" % os.environ['PATH']
- self.assertEqual(pconfigs[0].command, expected)
- def test_processes_from_section_no_procnum_in_processname(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- numprocs = 2
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- self.assertRaises(ValueError, instance.processes_from_section,
- config, 'program:foo', None)
- def test_processes_from_section_no_command(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- numprocs = 2
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- self.assertRaises(ValueError, instance.processes_from_section,
- config, 'program:foo', None)
- def test_processes_from_section_missing_replacement_in_process_name(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- process_name = %(not_there)s
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- self.assertRaises(ValueError, instance.processes_from_section,
- config, 'program:foo', None)
- def test_processes_from_section_bad_expression_in_process_name(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- process_name = %(program_name)
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- self.assertRaises(ValueError, instance.processes_from_section,
- config, 'program:foo', None)
- def test_processes_from_section_stopasgroup_implies_killasgroup(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- process_name = %(program_name)s
- stopasgroup = true
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- pconfigs = instance.processes_from_section(config, 'program:foo', 'bar')
- self.assertEqual(len(pconfigs), 1)
- pconfig = pconfigs[0]
- self.assertEqual(pconfig.stopasgroup, True)
- self.assertEqual(pconfig.killasgroup, True)
-
- def test_processes_from_section_killasgroup_mismatch_w_stopasgroup(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/cat
- process_name = %(program_name)s
- stopasgroup = true
- killasgroup = false
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- self.assertRaises(ValueError, instance.processes_from_section,
- config, 'program:foo', None)
- def test_processes_from_autolog_without_rollover(self):
- instance = self._makeOne()
- text = lstrip("""\
- [program:foo]
- command = /bin/foo
- stdout_logfile = AUTO
- stdout_logfile_maxbytes = 0
- stderr_logfile = AUTO
- stderr_logfile_maxbytes = 0
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- instance.logger = DummyLogger()
- config.read_string(text)
- instance.processes_from_section(config, 'program:foo', None)
- self.assertEqual(instance.parse_warnings[0],
- 'For [program:foo], AUTO logging used for stdout_logfile '
- 'without rollover, set maxbytes > 0 to avoid filling up '
- 'filesystem unintentionally')
- self.assertEqual(instance.parse_warnings[1],
- 'For [program:foo], AUTO logging used for stderr_logfile '
- 'without rollover, set maxbytes > 0 to avoid filling up '
- 'filesystem unintentionally')
- def test_homogeneous_process_groups_from_parser(self):
- text = lstrip("""\
- [program:many]
- process_name = %(program_name)s_%(process_num)s
- command = /bin/cat
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 1)
- gconfig = gconfigs[0]
- self.assertEqual(gconfig.name, 'many')
- self.assertEqual(gconfig.priority, 1)
- self.assertEqual(len(gconfig.process_configs), 2)
- def test_event_listener_pools_from_parser(self):
- text = lstrip("""\
- [eventlistener:dog]
- events=PROCESS_COMMUNICATION
- process_name = %(program_name)s_%(process_num)s
- command = /bin/dog
- numprocs = 2
- priority = 1
- [eventlistener:cat]
- events=PROCESS_COMMUNICATION
- process_name = %(program_name)s_%(process_num)s
- command = /bin/cat
- numprocs = 3
- [eventlistener:biz]
- events=PROCESS_COMMUNICATION
- process_name = %(program_name)s_%(process_num)s
- command = /bin/biz
- numprocs = 2
- """)
- from supervisor.options import UnhosedConfigParser
- from supervisor.dispatchers import default_handler
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 3)
- gconfig1 = gconfigs[0]
- self.assertEqual(gconfig1.name, 'biz')
- self.assertEqual(gconfig1.result_handler, default_handler)
- self.assertEqual(len(gconfig1.process_configs), 2)
- gconfig1 = gconfigs[1]
- self.assertEqual(gconfig1.name, 'cat')
- self.assertEqual(gconfig1.priority, -1)
- self.assertEqual(gconfig1.result_handler, default_handler)
- self.assertEqual(len(gconfig1.process_configs), 3)
- gconfig1 = gconfigs[2]
- self.assertEqual(gconfig1.name, 'dog')
- self.assertEqual(gconfig1.priority, 1)
- self.assertEqual(gconfig1.result_handler, default_handler)
- self.assertEqual(len(gconfig1.process_configs), 2)
- def test_event_listener_pool_with_event_results_handler(self):
- text = lstrip("""\
- [eventlistener:dog]
- events=PROCESS_COMMUNICATION
- command = /bin/dog
- result_handler = supervisor.tests.base:dummy_handler
- """)
- from supervisor.options import UnhosedConfigParser
- from supervisor.tests.base import dummy_handler
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 1)
- gconfig1 = gconfigs[0]
- self.assertEqual(gconfig1.result_handler, dummy_handler)
- def test_event_listener_pool_noeventsline(self):
- text = lstrip("""\
- [eventlistener:dog]
- process_name = %(program_name)s_%(process_num)s
- command = /bin/dog
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_event_listener_pool_unknown_eventtype(self):
- text = lstrip("""\
- [eventlistener:dog]
- events=PROCESS_COMMUNICATION,THIS_EVENT_TYPE_DOESNT_EXIST
- process_name = %(program_name)s_%(process_num)s
- command = /bin/dog
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_programs_from_parser(self):
- from supervisor.options import FastCGIGroupConfig
- from supervisor.options import FastCGIProcessConfig
- text = lstrip("""\
- [fcgi-program:foo]
- socket = unix:///tmp/%(program_name)s.sock
- socket_owner = testuser:testgroup
- socket_mode = 0666
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- [fcgi-program:bar]
- socket = unix:///tmp/%(program_name)s.sock
- process_name = %(program_name)s_%(process_num)s
- command = /bin/bar
- user = testuser
- numprocs = 3
- [fcgi-program:flub]
- socket = unix:///tmp/%(program_name)s.sock
- command = /bin/flub
- [fcgi-program:cub]
- socket = tcp://localhost:6000
- command = /bin/cub
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- #Patch pwd and grp module functions to give us sentinel
- #uid/gid values so that the test does not depend on
- #any specific system users
- pwd_mock = Mock()
- pwd_mock.return_value = (None, None, sentinel.uid, sentinel.gid)
- grp_mock = Mock()
- grp_mock.return_value = (None, None, sentinel.gid)
- @patch('pwd.getpwuid', pwd_mock)
- @patch('pwd.getpwnam', pwd_mock)
- @patch('grp.getgrnam', grp_mock)
- def get_process_groups(instance, config):
- return instance.process_groups_from_parser(config)
- gconfigs = get_process_groups(instance, config)
- exp_owner = (sentinel.uid, sentinel.gid)
- self.assertEqual(len(gconfigs), 4)
- gconf_foo = gconfigs[0]
- self.assertEqual(gconf_foo.__class__, FastCGIGroupConfig)
- self.assertEqual(gconf_foo.name, 'foo')
- self.assertEqual(gconf_foo.priority, 1)
- self.assertEqual(gconf_foo.socket_config.url,
- 'unix:///tmp/foo.sock')
- self.assertEqual(exp_owner, gconf_foo.socket_config.get_owner())
- self.assertEqual(0666, gconf_foo.socket_config.get_mode())
- self.assertEqual(len(gconf_foo.process_configs), 2)
- pconfig_foo = gconf_foo.process_configs[0]
- self.assertEqual(pconfig_foo.__class__, FastCGIProcessConfig)
- gconf_bar = gconfigs[1]
- self.assertEqual(gconf_bar.name, 'bar')
- self.assertEqual(gconf_bar.priority, 999)
- self.assertEqual(gconf_bar.socket_config.url,
- 'unix:///tmp/bar.sock')
- self.assertEqual(exp_owner, gconf_bar.socket_config.get_owner())
- self.assertEqual(0700, gconf_bar.socket_config.get_mode())
- self.assertEqual(len(gconf_bar.process_configs), 3)
- gconf_cub = gconfigs[2]
- self.assertEqual(gconf_cub.name, 'cub')
- self.assertEqual(gconf_cub.socket_config.url,
- 'tcp://localhost:6000')
- self.assertEqual(len(gconf_cub.process_configs), 1)
- gconf_flub = gconfigs[3]
- self.assertEqual(gconf_flub.name, 'flub')
- self.assertEqual(gconf_flub.socket_config.url,
- 'unix:///tmp/flub.sock')
- self.assertEqual(None, gconf_flub.socket_config.get_owner())
- self.assertEqual(0700, gconf_flub.socket_config.get_mode())
- self.assertEqual(len(gconf_flub.process_configs), 1)
- def test_fcgi_program_no_socket(self):
- text = lstrip("""\
- [fcgi-program:foo]
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_unknown_socket_protocol(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket=junk://blah
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_rel_unix_sock_path(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket=unix://relative/path
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_bad_tcp_sock_format(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket=tcp://missingport
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_bad_expansion_proc_num(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket=unix:///tmp/%(process_num)s.sock
- process_name = %(program_name)s_%(process_num)s
- command = /bin/foo
- numprocs = 2
- priority = 1
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_socket_owner_set_for_tcp(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket=tcp://localhost:8000
- socket_owner=nobody:nobody
- command = /bin/foo
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_socket_mode_set_for_tcp(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket = tcp://localhost:8000
- socket_mode = 0777
- command = /bin/foo
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_bad_socket_owner(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket = unix:///tmp/foo.sock
- socket_owner = sometotaljunkuserthatshouldnobethere
- command = /bin/foo
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_fcgi_program_bad_socket_mode(self):
- text = lstrip("""\
- [fcgi-program:foo]
- socket = unix:///tmp/foo.sock
- socket_mode = junk
- command = /bin/foo
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError,instance.process_groups_from_parser,config)
- def test_heterogeneous_process_groups_from_parser(self):
- text = lstrip("""\
- [program:one]
- command = /bin/cat
- [program:two]
- command = /bin/cat
- [group:thegroup]
- programs = one,two
- priority = 5
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 1)
- gconfig = gconfigs[0]
- self.assertEqual(gconfig.name, 'thegroup')
- self.assertEqual(gconfig.priority, 5)
- self.assertEqual(len(gconfig.process_configs), 2)
- def test_mixed_process_groups_from_parser1(self):
- text = lstrip("""\
- [program:one]
- command = /bin/cat
- [program:two]
- command = /bin/cat
- [program:many]
- process_name = %(program_name)s_%(process_num)s
- command = /bin/cat
- numprocs = 2
- priority = 1
- [group:thegroup]
- programs = one,two
- priority = 5
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 2)
- manyconfig = gconfigs[0]
- self.assertEqual(manyconfig.name, 'many')
- self.assertEqual(manyconfig.priority, 1)
- self.assertEqual(len(manyconfig.process_configs), 2)
- gconfig = gconfigs[1]
- self.assertEqual(gconfig.name, 'thegroup')
- self.assertEqual(gconfig.priority, 5)
- self.assertEqual(len(gconfig.process_configs), 2)
- def test_mixed_process_groups_from_parser2(self):
- text = lstrip("""\
- [program:one]
- command = /bin/cat
- [program:two]
- command = /bin/cat
- [program:many]
- process_name = %(program_name)s_%(process_num)s
- command = /bin/cat
- numprocs = 2
- priority = 1
- [group:thegroup]
- programs = one,two, many
- priority = 5
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- gconfigs = instance.process_groups_from_parser(config)
- self.assertEqual(len(gconfigs), 1)
- gconfig = gconfigs[0]
- self.assertEqual(gconfig.name, 'thegroup')
- self.assertEqual(gconfig.priority, 5)
- self.assertEqual(len(gconfig.process_configs), 4)
- def test_unknown_program_in_heterogeneous_group(self):
- text = lstrip("""\
- [program:one]
- command = /bin/cat
- [group:foo]
- programs = notthere
- """)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- self.assertRaises(ValueError, instance.process_groups_from_parser,
- config)
- def test_rpcinterfaces_from_parser(self):
- text = lstrip("""\
- [rpcinterface:dummy]
- supervisor.rpcinterface_factory = %s
- foo = bar
- """ % __name__)
- from supervisor.options import UnhosedConfigParser
- config = UnhosedConfigParser()
- config.read_string(text)
- instance = self._makeOne()
- factories = instance.get_plugins(config,
- 'supervisor.rpcinterface_factory',
- 'rpcinterface:')
- self.assertEqual(len(factories), 1)
- factory = factories[0]
- self.assertEqual(factory[0], 'dummy')
- self.assertEqual(factory[1], sys.modules[__name__])
- self.assertEqual(factory[2], {'foo':'bar'})
- def test_clear_autochildlogdir(self):
- dn = tempfile.mkdtemp()
- try:
- instance = self._makeOne()
- instance.childlogdir = dn
- sid = 'supervisor'
- instance.identifier = sid
- logfn = instance.get_autochildlog_name('foo', sid,'stdout')
- first = logfn + '.1'
- second = logfn + '.2'
- open(first, 'w')
- open(second, 'w')
- instance.clear_autochildlogdir()
- self.failIf(os.path.exists(logfn))
- self.failIf(os.path.exists(first))
- self.failIf(os.path.exists(second))
- finally:
- shutil.rmtree(dn)
- def test_clear_autochildlog_oserror(self):
- instance = self._makeOne()
- instance.childlogdir = '/tmp/this/cant/possibly/existjjjj'
- instance.logger = DummyLogger()
- instance.clear_autochildlogdir()
- self.assertEqual(instance.logger.data, ['Could not clear childlog dir'])
- def test_openhttpservers_reports_friendly_usage_when_eaddrinuse(self):
- supervisord = DummySupervisor()
- instance = self._makeOne()
- def raise_eaddrinuse(supervisord):
- raise socket.error(errno.EADDRINUSE)
- instance.make_http_servers = raise_eaddrinuse
- recorder = []
- def record_usage(message):
- recorder.append(message)
- instance.usage = record_usage
- instance.openhttpservers(supervisord)
- self.assertEqual(len(recorder), 1)
- expected = 'Another program is already listening'
- self.assertTrue(recorder[0].startswith(expected))
- def test_openhttpservers_reports_socket_error_with_errno(self):
- supervisord = DummySupervisor()
- instance = self._makeOne()
- def make_http_servers(supervisord):
- raise socket.error(errno.EPERM)
- instance.make_http_servers = make_http_servers
- recorder = []
- def record_usage(message):
- recorder.append(message)
- instance.usage = record_usage
- instance.openhttpservers(supervisord)
- self.assertEqual(len(recorder), 1)
- expected = ('Cannot open an HTTP server: socket.error '
- 'reported errno.EPERM (%d)' % errno.EPERM)
- self.assertEqual(recorder[0], expected)
- def test_openhttpservers_reports_other_socket_errors(self):
- supervisord = DummySupervisor()
- instance = self._makeOne()
- def make_http_servers(supervisord):
- raise socket.error('uh oh')
- instance.make_http_servers = make_http_servers
- recorder = []
- def record_usage(message):
- recorder.append(message)
- instance.usage = record_usage
- instance.openhttpservers(supervisord)
- self.assertEqual(len(recorder), 1)
- expected = ('Cannot open an HTTP server: socket.error '
- 'reported uh oh')
- self.assertEqual(recorder[0], expected)
- def test_openhttpservers_reports_value_errors(self):
- supervisord = DummySupervisor()
- instance = self._makeOne()
- def make_http_servers(supervisord):
- raise ValueError('not prefixed with help')
- instance.make_http_servers = make_http_servers
- recorder = []
- def record_usage(message):
- recorder.append(message)
- instance.usage = record_usage
- instance.openhttpservers(supervisord)
- self.assertEqual(len(recorder), 1)
- expected = 'not prefixed with help'
- self.assertEqual(recorder[0], expected)
- def test_openhttpservers_does_not_catch_other_exception_types(self):
- supervisord = DummySupervisor()
- instance = self._makeOne()
- def make_http_servers(supervisord):
- raise OverflowError
- instance.make_http_servers = make_http_servers
- # this scenario probably means a bug in supervisor. we dump
- # all the gory details on the poor user for troubleshooting
- self.assertRaises(OverflowError,
- instance.openhttpservers, supervisord)
- class TestProcessConfig(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import ProcessConfig
- return ProcessConfig
- def _makeOne(self, *arg, **kw):
- defaults = {}
- for name in ('name', 'command', 'directory', 'umask',
- 'priority', 'autostart', 'autorestart',
- 'startsecs', 'startretries', 'uid',
- 'stdout_logfile', 'stdout_capture_maxbytes',
- 'stdout_events_enabled',
- 'stdout_logfile_backups', 'stdout_logfile_maxbytes',
- 'stderr_logfile', 'stderr_capture_maxbytes',
- 'stderr_events_enabled',
- 'stderr_logfile_backups', 'stderr_logfile_maxbytes',
- 'stopsignal', 'stopwaitsecs', 'stopasgroup', 'killasgroup', 'exitcodes',
- 'redirect_stderr', 'environment'):
- defaults[name] = name
- defaults.update(kw)
- return self._getTargetClass()(*arg, **defaults)
- def test_create_autochildlogs(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- from supervisor.datatypes import Automatic
- instance.stdout_logfile = Automatic
- instance.stderr_logfile = Automatic
- instance.create_autochildlogs()
- self.assertEqual(instance.stdout_logfile, options.tempfile_name)
- self.assertEqual(instance.stderr_logfile, options.tempfile_name)
- def test_make_process(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- process = instance.make_process()
- from supervisor.process import Subprocess
- self.assertEqual(process.__class__, Subprocess)
- self.assertEqual(process.group, None)
- def test_make_process_with_group(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- process = instance.make_process('abc')
- from supervisor.process import Subprocess
- self.assertEqual(process.__class__, Subprocess)
- self.assertEqual(process.group, 'abc')
- def test_make_dispatchers_stderr_not_redirected(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- instance.redirect_stderr = False
- process1 = DummyProcess(instance)
- dispatchers, pipes = instance.make_dispatchers(process1)
- self.assertEqual(dispatchers[5].channel, 'stdout')
- from supervisor.events import ProcessCommunicationStdoutEvent
- self.assertEqual(dispatchers[5].event_type,
- ProcessCommunicationStdoutEvent)
- self.assertEqual(pipes['stdout'], 5)
- self.assertEqual(dispatchers[7].channel, 'stderr')
- from supervisor.events import ProcessCommunicationStderrEvent
- self.assertEqual(dispatchers[7].event_type,
- ProcessCommunicationStderrEvent)
- self.assertEqual(pipes['stderr'], 7)
- def test_make_dispatchers_stderr_redirected(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- process1 = DummyProcess(instance)
- dispatchers, pipes = instance.make_dispatchers(process1)
- self.assertEqual(dispatchers[5].channel, 'stdout')
- self.assertEqual(pipes['stdout'], 5)
- self.assertEqual(pipes['stderr'], None)
- class FastCGIProcessConfigTest(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import FastCGIProcessConfig
- return FastCGIProcessConfig
- def _makeOne(self, *arg, **kw):
- defaults = {}
- for name in ('name', 'command', 'directory', 'umask',
- 'priority', 'autostart', 'autorestart',
- 'startsecs', 'startretries', 'uid',
- 'stdout_logfile', 'stdout_capture_maxbytes',
- 'stdout_events_enabled',
- 'stdout_logfile_backups', 'stdout_logfile_maxbytes',
- 'stderr_logfile', 'stderr_capture_maxbytes',
- 'stderr_events_enabled',
- 'stderr_logfile_backups', 'stderr_logfile_maxbytes',
- 'stopsignal', 'stopwaitsecs', 'stopasgroup', 'killasgroup', 'exitcodes',
- 'redirect_stderr', 'environment'):
- defaults[name] = name
- defaults.update(kw)
- return self._getTargetClass()(*arg, **defaults)
- def test_make_process(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- self.assertRaises(NotImplementedError, instance.make_process)
- def test_make_process_with_group(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- process = instance.make_process('abc')
- from supervisor.process import FastCGISubprocess
- self.assertEqual(process.__class__, FastCGISubprocess)
- self.assertEqual(process.group, 'abc')
- def test_make_dispatchers(self):
- options = DummyOptions()
- instance = self._makeOne(options)
- instance.redirect_stderr = False
- process1 = DummyProcess(instance)
- dispatchers, pipes = instance.make_dispatchers(process1)
- self.assertEqual(dispatchers[4].channel, 'stdin')
- self.assertEqual(dispatchers[4].closed, True)
- self.assertEqual(dispatchers[5].channel, 'stdout')
- from supervisor.events import ProcessCommunicationStdoutEvent
- self.assertEqual(dispatchers[5].event_type,
- ProcessCommunicationStdoutEvent)
- self.assertEqual(pipes['stdout'], 5)
- self.assertEqual(dispatchers[7].channel, 'stderr')
- from supervisor.events import ProcessCommunicationStderrEvent
- self.assertEqual(dispatchers[7].event_type,
- ProcessCommunicationStderrEvent)
- self.assertEqual(pipes['stderr'], 7)
- class ProcessGroupConfigTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import ProcessGroupConfig
- return ProcessGroupConfig
- def _makeOne(self, options, name, priority, pconfigs):
- return self._getTargetClass()(options, name, priority, pconfigs)
- def test_ctor(self):
- options = DummyOptions()
- instance = self._makeOne(options, 'whatever', 999, [])
- self.assertEqual(instance.options, options)
- self.assertEqual(instance.name, 'whatever')
- self.assertEqual(instance.priority, 999)
- self.assertEqual(instance.process_configs, [])
- def test_after_setuid(self):
- options = DummyOptions()
- pconfigs = [DummyPConfig(options, 'process1', '/bin/process1')]
- instance = self._makeOne(options, 'whatever', 999, pconfigs)
- instance.after_setuid()
- self.assertEqual(pconfigs[0].autochildlogs_created, True)
- def test_make_group(self):
- options = DummyOptions()
- pconfigs = [DummyPConfig(options, 'process1', '/bin/process1')]
- instance = self._makeOne(options, 'whatever', 999, pconfigs)
- group = instance.make_group()
- from supervisor.process import ProcessGroup
- self.assertEqual(group.__class__, ProcessGroup)
- class FastCGIGroupConfigTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.options import FastCGIGroupConfig
- return FastCGIGroupConfig
- def _makeOne(self, *args, **kw):
- return self._getTargetClass()(*args, **kw)
- def test_ctor(self):
- options = DummyOptions()
- sock_config = DummySocketConfig(6)
- instance = self._makeOne(options, 'whatever', 999, [], sock_config)
- self.assertEqual(instance.options, options)
- self.assertEqual(instance.name, 'whatever')
- self.assertEqual(instance.priority, 999)
- self.assertEqual(instance.process_configs, [])
- self.assertEqual(instance.socket_config, sock_config)
- def test_same_sockets_are_equal(self):
- options = DummyOptions()
- sock_config1 = DummySocketConfig(6)
- instance1 = self._makeOne(options, 'whatever', 999, [], sock_config1)
- sock_config2 = DummySocketConfig(6)
- instance2 = self._makeOne(options, 'whatever', 999, [], sock_config2)
- self.assertTrue(instance1 == instance2)
- self.assertFalse(instance1 != instance2)
- def test_diff_sockets_are_not_equal(self):
- options = DummyOptions()
- sock_config1 = DummySocketConfig(6)
- instance1 = self._makeOne(options, 'whatever', 999, [], sock_config1)
- sock_config2 = DummySocketConfig(7)
- instance2 = self._makeOne(options, 'whatever', 999, [], sock_config2)
- self.assertTrue(instance1 != instance2)
- self.assertFalse(instance1 == instance2)
- class SignalReceiverTests(unittest.TestCase):
- def test_returns_None_initially(self):
- from supervisor.options import SignalReceiver
- sr = SignalReceiver()
- self.assertEquals(sr.get_signal(), None)
- def test_returns_signals_in_order_received(self):
- from supervisor.options import SignalReceiver
- sr = SignalReceiver()
- sr.receive(signal.SIGTERM, 'frame')
- sr.receive(signal.SIGCHLD, 'frame')
- self.assertEquals(sr.get_signal(), signal.SIGTERM)
- self.assertEquals(sr.get_signal(), signal.SIGCHLD)
- self.assertEquals(sr.get_signal(), None)
- def test_does_not_queue_duplicate_signals(self):
- from supervisor.options import SignalReceiver
- sr = SignalReceiver()
- sr.receive(signal.SIGTERM, 'frame')
- sr.receive(signal.SIGTERM, 'frame')
- self.assertEquals(sr.get_signal(), signal.SIGTERM)
- self.assertEquals(sr.get_signal(), None)
- def test_queues_again_after_being_emptied(self):
- from supervisor.options import SignalReceiver
- sr = SignalReceiver()
- sr.receive(signal.SIGTERM, 'frame')
- self.assertEquals(sr.get_signal(), signal.SIGTERM)
- self.assertEquals(sr.get_signal(), None)
- sr.receive(signal.SIGCHLD, 'frame')
- self.assertEquals(sr.get_signal(), signal.SIGCHLD)
- self.assertEquals(sr.get_signal(), None)
- class UtilFunctionsTests(unittest.TestCase):
- def test_make_namespec(self):
- from supervisor.options import make_namespec
- self.assertEquals(make_namespec('group', 'process'), 'group:process')
- self.assertEquals(make_namespec('process', 'process'), 'process')
- def test_split_namespec(self):
- from supervisor.options import split_namespec
- s = split_namespec
- self.assertEquals(s('process:group'), ('process', 'group'))
- self.assertEquals(s('process'), ('process', 'process'))
- self.assertEquals(s('group:'), ('group', None))
- self.assertEquals(s('group:*'), ('group', None))
- def test_suite():
- return unittest.findTestCases(sys.modules[__name__])
- if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
|