def test_handle_request_does_not_authorize_bad_credentials(self): request = DummyRequest('/logtail/process1', None, None, None) encoded = base64.b64encode(as_bytes("wrong:wrong")) request.header = ["Authorization: Basic %s" % as_string(encoded)] handler = DummyHandler() auth_handler = self._makeOne({'user':'******'}, handler) auth_handler.handle_request(request) self.assertFalse(handler.handled_request)
def test_handle_request_authorizes_good_password_with_colon(self): request = DummyRequest('/logtail/process1', None, None, None) encoded = base64.b64encode("user:pass:word") # password contains colon request.header = ["Authorization: Basic %s" % encoded] handler = DummyHandler() auth_handler = self._makeOne({'user':'******'}, handler) auth_handler.handle_request(request) self.assertTrue(handler.handled_request)
def test_handle_request_authorizes_good_password_with_colon(self): request = DummyRequest('/logtail/process1', None, None, None) encoded = base64.b64encode("user:pass:word") # password contains colon request.header = ["Authorization: Basic %s" % encoded] handler = DummyHandler() auth_handler = self._makeOne({'user': '******'}, handler) auth_handler.handle_request(request) self.assertTrue(handler.handled_request)
def test_match(self): class DummyRequest: def __init__(self, uri): self.uri = uri supervisor = DummySupervisor() subinterfaces = [('supervisor', DummySupervisorRPCNamespace())] handler = self._makeOne(supervisor, subinterfaces) self.assertEqual(handler.match(DummyRequest('/RPC2')), True) self.assertEqual(handler.match(DummyRequest('/nope')), False)
def test_handle_more_follow_file_recreated(self): request = DummyRequest('/logtail/foo', None, None, None) tmpfile = TempFileOpen() try: tmpfile.write(as_bytes('a' * 80)) tmpfile.flush() producer = self._makeOne(request, tmpfile.name, 80) result = producer.more() self.assertEqual(result, as_bytes('a' * 80)) # in windows open files need to be closed tmpfile.close() tmpfile = open(tmpfile.name, 'wb') try: tmpfile.write(as_bytes('b' * 80)) tmpfile.flush() result = producer.more() finally: tmpfile.close() os.remove(tmpfile.name) finally: tmpfile.close() self.assertEqual(result, as_bytes('b' * 80))
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) self.assertEqual(response[0][0], '3.0') self.assertEqual(request._done, True) self.assertEqual(request.headers['Content-Type'], 'text/xml') self.assertEqual(request.headers['Content-Length'], len(xml_response))
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_continue_request_nosuchmethod(self): supervisor = DummySupervisor() subinterfaces = [('supervisor', DummySupervisorRPCNamespace())] handler = self._makeOne(supervisor, subinterfaces) import xmlrpc.client data = xmlrpc.client.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_lib import loads if loads: expected = 2 else: expected = 3 self.assertEqual(len(logdata), expected) self.assertEqual(logdata[-2], 'XML-RPC method called: supervisor.noSuchMethod()') self.assertEqual( logdata[-1], ('XML-RPC method supervisor.noSuchMethod() returned fault: ' '[1] UNKNOWN_METHOD')) self.assertEqual(len(request.producers), 1) xml_response = request.producers[0] self.assertRaises(xmlrpc.client.Fault, xmlrpc.client.loads, 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_match(self): class DummyRequest: def __init__(self, uri): self.uri = uri supervisor = DummySupervisor() handler = self._makeOne(supervisor) self.assertEqual(handler.match(DummyRequest(handler.path)), True)
def test_handle_request_stdout_logfile_missing(self): supervisor = DummySupervisor() supervisor.options.logfile = '/not/there' request = DummyRequest('/mainlogtail', None, None, None) handler = self._makeOne(supervisor) handler.handle_request(request) self.assertEqual(request._error, 410)
def test_more_not_done_yet(self): request = DummyRequest('/index.html', [], '', '') from supervisor.http import NOT_DONE_YET callback = lambda *x: NOT_DONE_YET callback.delay = 1 producer = self._makeOne(request, callback) self.assertEqual(producer.more(), NOT_DONE_YET)
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)
def test_handle_request_stdout_logfile_missing(self): options = DummyOptions() pconfig = DummyPConfig(options, 'foo', 'foo', 'it/is/missing') supervisord = PopulatedDummySupervisor(options, 'foo', pconfig) handler = self._makeOne(supervisord) request = DummyRequest('/logtail/foo', None, None, None) handler.handle_request(request) self.assertEqual(request._error, 410)
def test_more_finished(self): request = DummyRequest('/index.html', [], '', '') callback = lambda *x: 'done' callback.delay = 1 producer = self._makeOne(request, callback) self.assertEqual(producer.more(), None) self.assertTrue(producer.finished) self.assertEqual(producer.more(), '')
def test_handle_request_default(self): request = DummyRequest('/index.html', [], '', '', {'PATH_INFO':'/index.html'}) handler = self._makeOne() data = handler.handle_request(request) self.assertEqual(data, None) self.assertEqual(request.channel.producer.request, request) from supervisor.web import StatusView self.assertEqual(request.channel.producer.callback.__class__,StatusView)
def test_ctor(self): request = DummyRequest('/index.html', [], '', '') callback = lambda *x: None callback.delay = 1 producer = self._makeOne(request, callback) self.assertEqual(producer.callback, callback) self.assertEqual(producer.request, request) self.assertEqual(producer.finished, False) self.assertEqual(producer.delay, 1)
def test_handle_request_ok_html(self): request = DummyRequest('/tail.html', [], '', '', {'PATH_INFO': '/ok.html'}) handler = self._makeOne() handler.handle_request(request) from supervisor.web import OKView view = request.channel.producer.callback self.assertEqual(view.__class__, OKView) self.assertEqual(view.context.template, None)
def test_handle_request_index_html(self): request = DummyRequest('/index.html', [], '', '', {'PATH_INFO': '/index.html'}) handler = self._makeOne() handler.handle_request(request) from supervisor.web import StatusView view = request.channel.producer.callback self.assertEqual(view.__class__, StatusView) self.assertEqual(view.context.template, 'ui/status.html')
def test_handle_request_stdout_logfile_none(self): options = DummyOptions() pconfig = DummyPConfig(options, 'process1', '/bin/process1', priority=1, stdout_logfile='/tmp/process1.log') supervisord = PopulatedDummySupervisor(options, 'process1', pconfig) handler = self._makeOne(supervisord) request = DummyRequest('/logtail/process1', None, None, None) handler.handle_request(request) self.assertEqual(request._error, 410)
def test_handle_more_fd_closed(self): request = DummyRequest('/logtail/foo', None, None, None) f = tempfile.NamedTemporaryFile() f.write('a' * 80) f.flush() producer = self._makeOne(request, f.name, 80) producer.file.close() result = producer.more() self.assertEqual(result, producer.more())
def test_render_noaction(self): context = DummyContext() context.supervisord = DummySupervisor() context.template = 'ui/status.html' context.request = DummyRequest('/foo', [], '', '') context.form = {} context.response = {} view = self._makeOne(context) data = view.render() self.assertTrue(data.startswith('<!DOCTYPE html PUBLIC'), data)
def test_sendresponse_redirect(self): request = DummyRequest('/index.html', [], '', '') callback = lambda *arg: None callback.delay = 1 producer = self._makeOne(request, callback) response = {'headers': {'Location': 'abc'}} result = producer.sendresponse(response) self.assertEqual(result, None) self.assertEqual(request._error, 301) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(request.headers['Content-Length'], 0)
def test_sendresponse_withbody_and_content_type(self): request = DummyRequest('/index.html', [], '', '') callback = lambda *arg: None callback.delay = 1 producer = self._makeOne(request, callback) response = {'body': 'abc', 'headers': {'Content-Type': 'text/html'}} result = producer.sendresponse(response) self.assertEqual(result, None) self.assertEqual(request.headers['Content-Type'], 'text/html') self.assertEqual(request.headers['Content-Length'], 3) self.assertEqual(request.producers[0], 'abc')
def test_handle_more_fd_closed(self): request = DummyRequest('/logtail/foo', None, None, None) with TempFileOpen() as tmpfile: tmpfile.write(as_bytes('a' * 80)) tmpfile.flush() producer = self._makeOne(request, tmpfile.name, 80) producer.close() producer.more() result = producer.more() self.assertEqual(result, NOT_DONE_YET)
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 self.assertEqual(len(logdata), 1) self.assertTrue(logdata[0].startswith('XML-RPC request data')) self.assertTrue(repr(data) in logdata[0]) self.assertTrue(logdata[0].endswith('is invalid: unmarshallable')) self.assertEqual(request._error, 400)
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 self.assertEqual(len(logdata), 1) self.assertTrue(logdata[0].startswith('XML-RPC request data')) self.assertTrue(repr(data) in logdata[0]) self.assertTrue(logdata[0].endswith('is invalid: no method name')) self.assertEqual(request._error, 400)
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 self.assertEqual(len(logdata), 1) self.assertEqual(logdata[-1], 'XML-RPC request received with no method name') self.assertEqual(len(request.producers), 0) self.assertEqual(request._error, 400)
def test_more_exception_caught(self): request = DummyRequest('/index.html', [], '', '') def callback(*arg): raise ValueError('foo') callback.delay = 1 producer = self._makeOne(request, callback) self.assertEqual(producer.more(), None) logdata = request.channel.server.logger.logged self.assertEqual(len(logdata), 1) logged = logdata[0] self.assertEqual(logged[0], 'Web interface error') self.assertTrue(logged[1].startswith('Traceback'), logged[1]) self.assertEqual(producer.finished, True) self.assertEqual(request._error, 500)
def test_continue_request_500(self): supervisor = DummySupervisor() subinterfaces = [('supervisor', DummySupervisorRPCNamespace())] handler = self._makeOne(supervisor, subinterfaces) data = xmlrpclib.dumps((), 'supervisor.raiseError') request = DummyRequest('/what/ever', None, None, None) handler.continue_request(data, request) logdata = supervisor.options.logger.data self.assertEqual(len(logdata), 2) self.assertEqual(logdata[-2], 'XML-RPC method called: supervisor.raiseError()') self.assertTrue(logdata[-1].startswith('Traceback')) self.assertTrue(logdata[-1].endswith('ValueError: error\n')) self.assertEqual(len(request.producers), 0) self.assertEqual(request._error, 500)
def test_handle_request(self): supervisor = DummySupervisor() f = tempfile.NamedTemporaryFile() t = f.name supervisor.options.logfile = t handler = self._makeOne(supervisor) request = DummyRequest('/mainlogtail', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(t)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True)