123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845 |
- import sys
- import unittest
- from supervisor.tests.base import DummySupervisor
- from supervisor.tests.base import DummyRequest
- from supervisor.tests.base import DummySupervisorRPCNamespace
- class GetFaultDescriptionTests(unittest.TestCase):
- def test_returns_description_for_known_fault(self):
- from supervisor import xmlrpc
- desc = xmlrpc.getFaultDescription(xmlrpc.Faults.SHUTDOWN_STATE)
- self.assertEqual(desc, 'SHUTDOWN_STATE')
- def test_returns_unknown_for_unknown_fault(self):
- from supervisor import xmlrpc
- desc = xmlrpc.getFaultDescription(999999)
- self.assertEqual(desc, 'UNKNOWN')
- class RPCErrorTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.xmlrpc import RPCError
- return RPCError
- def _makeOne(self, code, extra=None):
- return self._getTargetClass()(code, extra)
- def test_sets_text_with_fault_name_only(self):
- from supervisor import xmlrpc
- e = self._makeOne(xmlrpc.Faults.FAILED)
- self.assertEqual(e.text, 'FAILED')
- def test_sets_text_with_fault_name_and_extra(self):
- from supervisor import xmlrpc
- e = self._makeOne(xmlrpc.Faults.FAILED, 'oops')
- self.assertEqual(e.text, 'FAILED: oops')
- def test___str___shows_code_and_text(self):
- from supervisor import xmlrpc
- e = self._makeOne(xmlrpc.Faults.NO_FILE, '/nonexistent')
- self.assertEqual(str(e),
- "code=%r, text='NO_FILE: /nonexistent'" % xmlrpc.Faults.NO_FILE
- )
- class XMLRPCMarshallingTests(unittest.TestCase):
- def test_xmlrpc_marshal(self):
- import xmlrpclib
- from supervisor import xmlrpc
- data = xmlrpc.xmlrpc_marshal(1)
- self.assertEqual(data, xmlrpclib.dumps((1,), methodresponse=True))
- fault = xmlrpclib.Fault(1, 'foo')
- data = xmlrpc.xmlrpc_marshal(fault)
- self.assertEqual(data, xmlrpclib.dumps(fault))
- class XMLRPCHandlerTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.xmlrpc import supervisor_xmlrpc_handler
- return supervisor_xmlrpc_handler
- def _makeOne(self, supervisord, subinterfaces):
- return self._getTargetClass()(supervisord, subinterfaces)
- def test_ctor(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- self.assertEqual(handler.supervisord, supervisor)
- from supervisor.xmlrpc import RootRPCInterface
- self.assertEqual(handler.rpcinterface.__class__, RootRPCInterface)
- def test_match(self):
- class DummyRequest2:
- def __init__(self, uri):
- self.uri = uri
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- self.assertEqual(handler.match(DummyRequest2('/RPC2')), True)
- self.assertEqual(handler.match(DummyRequest2('/nope')), False)
- def test_continue_request_nosuchmethod(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- import xmlrpclib
- data = xmlrpclib.dumps(('a', 'b'), 'supervisor.noSuchMethod')
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 2
- else:
- expected = 3
- self.assertEqual(len(logdata), expected)
- self.assertEqual(logdata[-2],
- u'XML-RPC method called: supervisor.noSuchMethod()')
- self.assertEqual(logdata[-1],
- (u'XML-RPC method supervisor.noSuchMethod() returned fault: '
- '[1] UNKNOWN_METHOD'))
- self.assertEqual(len(request.producers), 1)
- xml_response = request.producers[0]
- self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, xml_response)
- def test_continue_request_methodsuccess(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- import xmlrpclib
- data = xmlrpclib.dumps((), 'supervisor.getAPIVersion')
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 2
- else:
- expected = 3
- self.assertEqual(len(logdata), expected)
- self.assertEqual(logdata[-2],
- u'XML-RPC method called: supervisor.getAPIVersion()')
- self.assertEqual(logdata[-1],
- u'XML-RPC method supervisor.getAPIVersion() returned successfully')
- self.assertEqual(len(request.producers), 1)
- xml_response = request.producers[0]
- response = xmlrpclib.loads(xml_response)
- from supervisor.rpcinterface import API_VERSION
- self.assertEqual(response[0][0], API_VERSION)
- self.assertEqual(request._done, True)
- self.assertEqual(request.headers['Content-Type'], 'text/xml')
- self.assertEqual(request.headers['Content-Length'], len(xml_response))
- def test_continue_request_no_params_in_request(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- data = '<?xml version="1.0" encoding="UTF-8"?>' \
- '<methodCall>' \
- '<methodName>supervisor.getAPIVersion</methodName>' \
- '</methodCall>'
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 2
- else:
- expected = 3
- self.assertEqual(len(logdata), expected)
- self.assertEqual(logdata[-2],
- u'XML-RPC method called: supervisor.getAPIVersion()')
- self.assertEqual(logdata[-1],
- u'XML-RPC method supervisor.getAPIVersion() returned successfully')
- self.assertEqual(len(request.producers), 1)
- xml_response = request.producers[0]
- import xmlrpclib
- response = xmlrpclib.loads(xml_response)
- from supervisor.rpcinterface import API_VERSION
- self.assertEqual(response[0][0], API_VERSION)
- self.assertEqual(request._done, True)
- self.assertEqual(request.headers['Content-Type'], 'text/xml')
- self.assertEqual(request.headers['Content-Length'], len(xml_response))
- def test_continue_request_400_if_method_name_is_empty(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- data = '<?xml version="1.0" encoding="UTF-8"?>' \
- '<methodCall><methodName></methodName></methodCall>'
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 1
- else:
- expected = 2
- self.assertEqual(len(logdata), expected)
- self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
- self.assertTrue(repr(data) in logdata[-1])
- self.assertTrue(logdata[-1].endswith('is invalid: no method name'))
- self.assertEqual(request._error, 400)
- def test_continue_request_400_if_loads_raises_not_xml(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- data = 'this is not an xml-rpc request body'
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 1
- else:
- expected = 2
- self.assertEqual(len(logdata), expected)
- self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
- self.assertTrue(repr(data) in logdata[-1])
- self.assertTrue(logdata[-1].endswith('is invalid: unmarshallable'))
- self.assertEqual(request._error, 400)
- def test_continue_request_400_if_loads_raises_weird_xml(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- data = '<methodName></methodName><junk></junk>'
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 1
- else:
- expected = 2
- self.assertEqual(len(logdata), expected)
- self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
- self.assertTrue(repr(data) in logdata[-1])
- self.assertTrue(logdata[-1].endswith('is invalid: unmarshallable'))
- self.assertEqual(request._error, 400)
- def test_continue_request_500_if_rpcinterface_method_call_raises(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- import xmlrpclib
- data = xmlrpclib.dumps((), 'supervisor.raiseError')
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 2
- else:
- expected = 3
- self.assertEqual(len(logdata), expected)
- self.assertEqual(logdata[-2],
- u'XML-RPC method called: supervisor.raiseError()')
- self.assertTrue("unexpected exception" in logdata[-1])
- self.assertTrue(repr(data) in logdata[-1])
- self.assertTrue("Traceback" in logdata[-1])
- self.assertTrue("ValueError: error" in logdata[-1])
- self.assertEqual(len(request.producers), 0)
- self.assertEqual(request._error, 500)
- def test_continue_request_500_if_xmlrpc_dumps_raises(self):
- supervisor = DummySupervisor()
- subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
- handler = self._makeOne(supervisor, subinterfaces)
- import xmlrpclib
- data = xmlrpclib.dumps((), 'supervisor.getXmlRpcUnmarshallable')
- request = DummyRequest('/what/ever', None, None, None)
- handler.continue_request(data, request)
- logdata = supervisor.options.logger.data
- from supervisor.xmlrpc import loads
- if loads:
- expected = 3
- else:
- expected = 4
- self.assertEqual(len(logdata), expected)
- self.assertEqual(logdata[-3],
- 'XML-RPC method called: supervisor.getXmlRpcUnmarshallable()')
- self.assertEqual(logdata[-2],
- 'XML-RPC method supervisor.getXmlRpcUnmarshallable() '
- 'returned successfully')
- self.assertTrue("unexpected exception" in logdata[-1])
- self.assertTrue(repr(data) in logdata[-1])
- self.assertTrue("Traceback" in logdata[-1])
- self.assertTrue("TypeError: cannot marshal" in logdata[-1])
- self.assertEqual(request._error, 500)
- class TraverseTests(unittest.TestCase):
- def test_underscore(self):
- from supervisor import xmlrpc
- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, None, '_', None)
- def test_notfound(self):
- from supervisor import xmlrpc
- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, None, 'foo', None)
- def test_badparams(self):
- from supervisor import xmlrpc
- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, self,
- 'test_badparams', (1, 2, 3))
- def test_success(self):
- from supervisor import xmlrpc
- L = []
- class Dummy:
- def foo(self, a):
- L.append(a)
- dummy = Dummy()
- xmlrpc.traverse(dummy, 'foo', [1])
- self.assertEqual(L, [1])
- class SupervisorTransportTests(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.xmlrpc import SupervisorTransport
- return SupervisorTransport
- def _makeOne(self, *arg, **kw):
- return self._getTargetClass()(*arg, **kw)
- def test_ctor_unix(self):
- from supervisor import xmlrpc
- transport = self._makeOne('user', 'pass', 'unix:///foo/bar')
- conn = transport._get_connection()
- self.assertTrue(isinstance(conn, xmlrpc.UnixStreamHTTPConnection))
- self.assertEqual(conn.host, 'localhost')
- self.assertEqual(conn.socketfile, '/foo/bar')
- def test__get_connection_http_9001(self):
- import httplib
- transport = self._makeOne('user', 'pass', 'http://127.0.0.1:9001/')
- conn = transport._get_connection()
- self.assertTrue(isinstance(conn, httplib.HTTPConnection))
- self.assertEqual(conn.host, '127.0.0.1')
- self.assertEqual(conn.port, 9001)
- def test__get_connection_http_80(self):
- import httplib
- transport = self._makeOne('user', 'pass', 'http://127.0.0.1/')
- conn = transport._get_connection()
- self.assertTrue(isinstance(conn, httplib.HTTPConnection))
- self.assertEqual(conn.host, '127.0.0.1')
- self.assertEqual(conn.port, 80)
- def test_request_non_200_response(self):
- import xmlrpclib
- transport = self._makeOne('user', 'pass', 'http://127.0.0.1/')
- dummy_conn = DummyConnection(400, '')
- def getconn():
- return dummy_conn
- transport._get_connection = getconn
- self.assertRaises(xmlrpclib.ProtocolError,
- transport.request, 'localhost', '/', '')
- self.assertEqual(transport.connection, None)
- self.assertEqual(dummy_conn.closed, True)
- def test_request_400_response(self):
- import xmlrpclib
- transport = self._makeOne('user', 'pass', 'http://127.0.0.1/')
- dummy_conn = DummyConnection(400, '')
- def getconn():
- return dummy_conn
- transport._get_connection = getconn
- self.assertRaises(xmlrpclib.ProtocolError,
- transport.request, 'localhost', '/', '')
- self.assertEqual(transport.connection, None)
- self.assertEqual(dummy_conn.closed, True)
- self.assertEqual(dummy_conn.requestargs[0], 'POST')
- self.assertEqual(dummy_conn.requestargs[1], '/')
- self.assertEqual(dummy_conn.requestargs[2], '')
- self.assertEqual(dummy_conn.requestargs[3]['Content-Length'], '0')
- self.assertEqual(dummy_conn.requestargs[3]['Content-Type'], 'text/xml')
- self.assertEqual(dummy_conn.requestargs[3]['Authorization'],
- 'Basic dXNlcjpwYXNz')
- self.assertEqual(dummy_conn.requestargs[3]['Accept'], 'text/xml')
- def test_request_200_response(self):
- transport = self._makeOne('user', 'pass', 'http://127.0.0.1/')
- response = """<?xml version="1.0"?>
- <methodResponse>
- <params>
- <param>
- <value><string>South Dakota</string></value>
- </param>
- </params>
- </methodResponse>"""
- dummy_conn = DummyConnection(200, response)
- def getconn():
- return dummy_conn
- transport._get_connection = getconn
- result = transport.request('localhost', '/', '')
- self.assertEqual(transport.connection, dummy_conn)
- self.assertEqual(dummy_conn.closed, False)
- self.assertEqual(dummy_conn.requestargs[0], 'POST')
- self.assertEqual(dummy_conn.requestargs[1], '/')
- self.assertEqual(dummy_conn.requestargs[2], '')
- self.assertEqual(dummy_conn.requestargs[3]['Content-Length'], '0')
- self.assertEqual(dummy_conn.requestargs[3]['Content-Type'], 'text/xml')
- self.assertEqual(dummy_conn.requestargs[3]['Authorization'],
- 'Basic dXNlcjpwYXNz')
- self.assertEqual(dummy_conn.requestargs[3]['Accept'], 'text/xml')
- self.assertEqual(result, ('South Dakota',))
- def test_works_with_py25(self):
- instance = self._makeOne('username', 'password', 'http://127.0.0.1')
- # the test is just to insure that this method can be called; failure
- # would be an AttributeError for _use_datetime under Python 2.5
- parser, unmarshaller = instance.getparser() # this uses _use_datetime
- class IterparseLoadsTests(unittest.TestCase):
- def test_iterparse_loads_methodcall(self):
- s = """<?xml version="1.0"?>
- <methodCall>
- <methodName>examples.getStateName</methodName>
- <params>
- <param>
- <value><i4>41</i4></value>
- </param>
- <param>
- <value><string>foo</string></value>
- </param>
- <param>
- <value><string></string></value>
- </param>
- <param>
- <!-- xml-rpc spec allows strings without <string> tag -->
- <value>bar</value>
- </param>
- <param>
- <value></value>
- </param>
- <param>
- <value><boolean>1</boolean></value>
- </param>
- <param>
- <value><double>-12.214</double></value>
- </param>
- <param>
- <value>
- <dateTime.iso8601>19980717T14:08:55</dateTime.iso8601>
- </value>
- </param>
- <param>
- <value><base64>eW91IGNhbid0IHJlYWQgdGhpcyE=</base64></value>
- </param>
- <param>
- <struct>
- <member><name>j</name><value><i4>5</i4></value></member>
- <member><name>k</name><value>abc</value></member>
- </struct>
- </param>
- <param>
- <array>
- <data>
- <value><i4>12</i4></value>
- <value><string>abc</string></value>
- <value>def</value>
- <value><i4>34</i4></value>
- </data>
- </array>
- </param>
- <param>
- <struct>
- <member>
- <name>k</name>
- <value><array><data>
- <value><i4>1</i4></value>
- <struct></struct>
- </data></array></value>
- </member>
- </struct>
- </param>
- </params>
- </methodCall>
- """
- from supervisor.xmlrpc import loads
- if loads is None:
- return # no cElementTree
- result = loads(s)
- params, method = result
- import datetime
- self.assertEqual(method, 'examples.getStateName')
- self.assertEqual(params[0], 41)
- self.assertEqual(params[1], 'foo')
- self.assertEqual(params[2], '')
- self.assertEqual(params[3], 'bar')
- self.assertEqual(params[4], '')
- self.assertEqual(params[5], True)
- self.assertEqual(params[6], -12.214)
- self.assertEqual(params[7], datetime.datetime(1998, 7, 17, 14, 8, 55))
- self.assertEqual(params[8], "you can't read this!")
- self.assertEqual(params[9], {'j': 5, 'k': 'abc'})
- self.assertEqual(params[10], [12, 'abc', 'def', 34])
- self.assertEqual(params[11], {'k': [1, {}]})
- class TestDeferredXMLRPCResponse(unittest.TestCase):
- def _getTargetClass(self):
- from supervisor.xmlrpc import DeferredXMLRPCResponse
- return DeferredXMLRPCResponse
- def _makeOne(self, request=None, callback=None):
- if request is None:
- request = DummyRequest(None, None, None, None, None)
- if callback is None:
- callback = Dummy()
- callback.delay = 1
- return self._getTargetClass()(request, callback)
- def test_ctor(self):
- callback = Dummy()
- callback.delay = 1
- inst = self._makeOne(request='request', callback=callback)
- self.assertEqual(inst.callback, callback)
- self.assertEqual(inst.delay, 1.0)
- self.assertEqual(inst.request, 'request')
- self.assertEqual(inst.finished, False)
- def test_more_finished(self):
- inst = self._makeOne()
- inst.finished = True
- result = inst.more()
- self.assertEqual(result, '')
- def test_more_callback_returns_not_done_yet(self):
- from supervisor.http import NOT_DONE_YET
- def callback():
- return NOT_DONE_YET
- callback.delay = 1
- inst = self._makeOne(callback=callback)
- self.assertEqual(inst.more(), NOT_DONE_YET)
- def test_more_callback_raises_RPCError(self):
- from supervisor.xmlrpc import RPCError, Faults
- def callback():
- raise RPCError(Faults.UNKNOWN_METHOD)
- callback.delay = 1
- inst = self._makeOne(callback=callback)
- self.assertEqual(inst.more(), None)
- self.assertEqual(len(inst.request.producers), 1)
- self.assertTrue('UNKNOWN_METHOD' in inst.request.producers[0])
- self.assertTrue(inst.finished)
- def test_more_callback_returns_value(self):
- def callback():
- return 'abc'
- callback.delay = 1
- inst = self._makeOne(callback=callback)
- self.assertEqual(inst.more(), None)
- self.assertEqual(len(inst.request.producers), 1)
- self.assertTrue('abc' in inst.request.producers[0])
- self.assertTrue(inst.finished)
- def test_more_callback_raises_unexpected_exception(self):
- def callback():
- raise ValueError('foo')
- callback.delay = 1
- inst = self._makeOne(callback=callback)
- self.assertEqual(inst.more(), None)
- self.assertEqual(inst.request._error, 500)
- self.assertTrue(inst.finished)
- logged = inst.request.channel.server.logger.logged
- self.assertEqual(len(logged), 1)
- src, msg = logged[0]
- self.assertEqual(src, 'XML-RPC response callback error')
- self.assertTrue("Traceback" in msg)
- class TestSystemNamespaceRPCInterface(unittest.TestCase):
- def _makeOne(self, namespaces=()):
- from supervisor.xmlrpc import SystemNamespaceRPCInterface
- return SystemNamespaceRPCInterface(namespaces)
- def test_listMethods_gardenpath(self):
- inst = self._makeOne()
- result = inst.listMethods()
- self.assertEqual(
- result,
- ['system.listMethods',
- 'system.methodHelp',
- 'system.methodSignature',
- 'system.multicall',
- ]
- )
- def test_listMethods_omits_underscore_attrs(self):
- class DummyNamespace(object):
- def foo(self): pass
- def _bar(self): pass
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- result = inst.listMethods()
- self.assertEqual(
- result,
- ['ns1.foo',
- 'system.listMethods',
- 'system.methodHelp',
- 'system.methodSignature',
- 'system.multicall'
- ]
- )
- def test_methodHelp_known_method(self):
- inst = self._makeOne()
- result = inst.methodHelp('system.listMethods')
- self.assertTrue('array' in result)
- def test_methodHelp_unknown_method(self):
- from supervisor.xmlrpc import RPCError
- inst = self._makeOne()
- self.assertRaises(RPCError, inst.methodHelp, 'wont.be.found')
- def test_methodSignature_known_method(self):
- inst = self._makeOne()
- result = inst.methodSignature('system.methodSignature')
- self.assertEqual(result, ['array', 'string'])
- def test_methodSignature_unknown_method(self):
- from supervisor.xmlrpc import RPCError
- inst = self._makeOne()
- self.assertRaises(RPCError, inst.methodSignature, 'wont.be.found')
- def test_methodSignature_with_bad_sig(self):
- from supervisor.xmlrpc import RPCError
- class DummyNamespace(object):
- def foo(self):
- """ @param string name The thing"""
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- self.assertRaises(RPCError, inst.methodSignature, 'ns1.foo')
- def test_multicall_faults_for_recursion(self):
- from supervisor.xmlrpc import Faults
- inst = self._makeOne()
- calls = [{'methodName':'system.multicall'}]
- results = inst.multicall(calls)
- self.assertEqual(
- results,
- [{'faultCode': Faults.INCORRECT_PARAMETERS,
- 'faultString': ('INCORRECT_PARAMETERS: Recursive '
- 'system.multicall forbidden')}]
- )
- def test_multicall_faults_for_missing_methodName(self):
- from supervisor.xmlrpc import Faults
- inst = self._makeOne()
- calls = [{}]
- results = inst.multicall(calls)
- self.assertEqual(
- results,
- [{'faultCode': Faults.INCORRECT_PARAMETERS,
- 'faultString': 'INCORRECT_PARAMETERS: No methodName'}]
- )
- def test_multicall_faults_for_methodName_bad_namespace(self):
- from supervisor.xmlrpc import Faults
- inst = self._makeOne()
- calls = [{'methodName': 'bad.stopProcess'}]
- results = inst.multicall(calls)
- self.assertEqual(
- results,
- [{'faultCode': Faults.UNKNOWN_METHOD,
- 'faultString': 'UNKNOWN_METHOD'}]
- )
- def test_multicall_faults_for_methodName_good_ns_bad_method(self):
- from supervisor.xmlrpc import Faults
- class DummyNamespace(object):
- pass
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- calls = [{'methodName': 'ns1.bad'}]
- results = inst.multicall(calls)
- self.assertEqual(
- results,
- [{'faultCode': Faults.UNKNOWN_METHOD,
- 'faultString': 'UNKNOWN_METHOD'}]
- )
- def test_multicall_returns_empty_results_for_empty_calls(self):
- inst = self._makeOne()
- calls = []
- results = inst.multicall(calls)
- self.assertEqual(results, [])
- def test_multicall_performs_noncallback_functions_serially(self):
- class DummyNamespace(object):
- def say(self, name):
- """ @param string name Process name"""
- return name
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- calls = [
- {'methodName': 'ns1.say', 'params': ['Alvin']},
- {'methodName': 'ns1.say', 'params': ['Simon']},
- {'methodName': 'ns1.say', 'params': ['Theodore']}
- ]
- results = inst.multicall(calls)
- self.assertEqual(results, ['Alvin', 'Simon', 'Theodore'])
- def test_multicall_catches_noncallback_exceptions(self):
- import errno
- from supervisor.xmlrpc import RPCError, Faults
- class DummyNamespace(object):
- def bad_name(self):
- raise RPCError(Faults.BAD_NAME, 'foo')
- def os_error(self):
- raise OSError(errno.ENOENT)
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- calls = [{'methodName': 'ns1.bad_name'}, {'methodName': 'ns1.os_error'}]
- results = inst.multicall(calls)
- bad_name = {'faultCode': Faults.BAD_NAME,
- 'faultString': 'BAD_NAME: foo'}
- os_error = {'faultCode': Faults.FAILED,
- 'faultString': "FAILED: %s:2" % OSError}
- self.assertEqual(results, [bad_name, os_error])
- def test_multicall_catches_callback_exceptions(self):
- import errno
- from supervisor.xmlrpc import RPCError, Faults
- from supervisor.http import NOT_DONE_YET
- class DummyNamespace(object):
- def bad_name(self):
- def inner():
- raise RPCError(Faults.BAD_NAME, 'foo')
- return inner
- def os_error(self):
- def inner():
- raise OSError(errno.ENOENT)
- return inner
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- calls = [{'methodName': 'ns1.bad_name'}, {'methodName': 'ns1.os_error'}]
- callback = inst.multicall(calls)
- results = NOT_DONE_YET
- while results is NOT_DONE_YET:
- results = callback()
- bad_name = {'faultCode': Faults.BAD_NAME,
- 'faultString': 'BAD_NAME: foo'}
- os_error = {'faultCode': Faults.FAILED,
- 'faultString': "FAILED: %s:2" % OSError}
- self.assertEqual(results, [bad_name, os_error])
- def test_multicall_performs_callback_functions_serially(self):
- from supervisor.http import NOT_DONE_YET
- class DummyNamespace(object):
- def __init__(self):
- self.stop_results = [NOT_DONE_YET, NOT_DONE_YET,
- NOT_DONE_YET, 'stop result']
- self.start_results = ['start result']
- def stopProcess(self, name):
- def inner():
- result = self.stop_results.pop(0)
- if result is not NOT_DONE_YET:
- self.stopped = True
- return result
- return inner
- def startProcess(self, name):
- def inner():
- if not self.stopped:
- raise Exception("This should not raise")
- return self.start_results.pop(0)
- return inner
- ns1 = DummyNamespace()
- inst = self._makeOne([('ns1', ns1)])
- calls = [{'methodName': 'ns1.stopProcess',
- 'params': {'name': 'foo'}},
- {'methodName': 'ns1.startProcess',
- 'params': {'name': 'foo'}}]
- callback = inst.multicall(calls)
- results = NOT_DONE_YET
- while results is NOT_DONE_YET:
- results = callback()
- self.assertEqual(results, ['stop result', 'start result'])
- class Test_gettags(unittest.TestCase):
- def _callFUT(self, comment):
- from supervisor.xmlrpc import gettags
- return gettags(comment)
- def test_one_atpart(self):
- lines = '@foo'
- result = self._callFUT(lines)
- self.assertEqual(
- result,
- [(0, None, None, None, ''), (0, 'foo', '', '', '')]
- )
- def test_two_atparts(self):
- lines = '@foo array'
- result = self._callFUT(lines)
- self.assertEqual(
- result,
- [(0, None, None, None, ''), (0, 'foo', 'array', '', '')]
- )
- def test_three_atparts(self):
- lines = '@foo array name'
- result = self._callFUT(lines)
- self.assertEqual(
- result,
- [(0, None, None, None, ''), (0, 'foo', 'array', 'name', '')]
- )
- def test_four_atparts(self):
- lines = '@foo array name text'
- result = self._callFUT(lines)
- self.assertEqual(
- result,
- [(0, None, None, None, ''), (0, 'foo', 'array', 'name', 'text')]
- )
- class Test_capped_int(unittest.TestCase):
- def _callFUT(self, value):
- from supervisor.xmlrpc import capped_int
- return capped_int(value)
- def test_converts_value_to_integer(self):
- self.assertEqual(self._callFUT('42'), 42)
- def test_caps_value_below_minint(self):
- import xmlrpclib
- self.assertEqual(self._callFUT(xmlrpclib.MININT - 1), xmlrpclib.MININT)
- def test_caps_value_above_maxint(self):
- import xmlrpclib
- self.assertEqual(self._callFUT(xmlrpclib.MAXINT + 1), xmlrpclib.MAXINT)
- class DummyResponse:
- def __init__(self, status=200, body='', reason='reason'):
- self.status = status
- self.body = body
- self.reason = reason
- def read(self):
- return self.body
- class Dummy(object):
- pass
- class DummyConnection:
- closed = False
- def __init__(self, status=200, body='', reason='reason'):
- self.response = DummyResponse(status, body, reason)
- def getresponse(self):
- return self.response
- def request(self, *arg, **kw):
- self.requestargs = arg
- self.requestkw = kw
- def close(self):
- self.closed = True
- def test_suite():
- return unittest.findTestCases(sys.modules[__name__])
- if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
|