def test_sync(self): '''Test the threading/transcription works when async=false''' reactor = self.buildReactor() expected = {'some': 'result'} stub_transcriber = StubTranscriber(transcribe_stub=expected) controller = TranscriptionsController(stub_transcriber, reactor=reactor) req = DummyRequest([]) req.method = 'POST' req.args = {'transcript': [''], 'audio': [''], 'async': ['false']} finish = req.notifyFinish() finish.addCallback(lambda _: reactor.callWhenRunning(reactor.stop)) body = controller.render(req) assert_equals(body, NOT_DONE_YET) self.runReactor(reactor, timeout=1) assert_equals(len(req.written), 1) got = json.loads(req.written[0]) assert_equals(got, expected)
def test_render_exceptions(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. """ def process(*a, **kw): raise ValueError('What is this') service = SmsNotificationService(None, None) service.process = process request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ValueError) self.assertEqual(1, len(failures)) self.assertEqual( { str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Server', 'faultstring': 'What is this' } } } }, element_to_dict(fromstring(''.join(request.written))))
def test_render_exceptions(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. """ def process(*a, **kw): raise ValueError('What is this') service = SmsNotificationService(None, None) service.process = process request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ValueError) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Server', 'faultstring': 'What is this'}}}}, element_to_dict(fromstring(''.join(request.written))))
def test_render_soap_fault(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. If the logged exception is a `SoapFault` its ``to_element`` method is invoked to serialize the fault. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(L.hello())) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(SoapFault) self.assertEqual(1, len(failures)) self.assertEqual( { str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Client', 'faultstring': 'Malformed SOAP request' } } } }, element_to_dict(fromstring(''.join(request.written))))
def test_render_soap_fault(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. If the logged exception is a `SoapFault` its ``to_element`` method is invoked to serialize the fault. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(L.hello())) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(SoapFault) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Client', 'faultstring': 'Malformed SOAP request'}}}}, element_to_dict(fromstring(''.join(request.written))))
def request_same_or_different_thread_thread(self): hr = HendrixWSGIResource(reactor, self.tp, self.wsgi_thing) request1 = DummyRequest([b'r1']) request1.isSecure = lambda: False request1.content = b"llamas" request1.client = IPv4Address("TCP", b"50.0.50.0", 5000) d = deferToThreadPool(reactor, self.tp, hr.render, request1) d.addCallback(lambda _: request1.notifyFinish()) return d
def test_bad_status_codes_cause_no_go_in_wsgi_response(self): self.no_go_status_codes = [404, '6xx'] request = DummyRequest('r1') request.isSecure = lambda: False request.content = "llamas" finished = request.notifyFinish() self.resource.render(request) # This must wait until the WSGI response is closed. finished.addCallback( lambda _: self.assertFalse(self.nameSpace.async_task_was_run))
def test_render_invalid_xml(self): """ `SmsNotificationService.render_POST` does not accept invalid XML body content. """ service = SmsNotificationService(None, None) request = DummyRequest([]) request.content = StringIO('sup') d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ParseError) self.assertEqual(1, len(failures))
def test_render_invalid_xml(self): """ `SmsNotificationService.render_POST` does not accept invalid XML body content. """ service = SmsNotificationService(None, None) request = DummyRequest([]) request.content = StringIO('sup') d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ParseError) self.assertEqual(1, len(failures))
def test_renderNoFailure(self): """ If the L{Deferred} fails, L{DeferredResource} reports the failure via C{processingFailed}, and does not cause an unhandled error to be logged. """ request = DummyRequest([]) d = request.notifyFinish() failure = Failure(RuntimeError()) deferredResource = DeferredResource(defer.fail(failure)) deferredResource.render(request) self.assertEqual(self.failureResultOf(d), failure) del deferredResource gc.collect() errors = self.flushLoggedErrors(RuntimeError) self.assertEqual(errors, [])
def test_renderNoFailure(self): """ If the L{Deferred} fails, L{DeferredResource} reports the failure via C{processingFailed}, and does not cause an unhandled error to be logged. """ request = DummyRequest([]) d = request.notifyFinish() failure = Failure(RuntimeError()) deferredResource = DeferredResource(defer.fail(failure)) deferredResource.render(request) self.assertEqual(self.failureResultOf(d), failure) del deferredResource gc.collect() errors = self.flushLoggedErrors(RuntimeError) self.assertEqual(errors, [])
def test_bad_status_codes_cause_no_go_in_wsgi_response(self): self.no_go_status_codes = [404, '6xx'] request = DummyRequest('r1') request.isSecure = lambda: False request.content = "llamas" finished = request.notifyFinish() self.resource.render(request) # This must wait until the WSGI response is closed. finished.addCallback( lambda _: self.assertFalse( self.nameSpace.async_task_was_run ) )
def test_render(self): """ `SmsNotificationService.render_POST` parses a SOAP request and dispatches it to `SmsNotificationService.process` for processing. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.OK, request.responseCode) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { 'done': None}}}, element_to_dict(fromstring(''.join(request.written))))
def forge_request(uri='https://www.globaleaks.org/', headers={}, method=b'GET', client_addr=None): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ _, host, path, query, frag = urlparse.urlsplit(uri) x = host.split(':') if len(x) > 1: port = int(x[1]) else: port = 80 ret = DummyRequest(['']) ret.method = method ret.uri = uri ret.path = path ret._serverName = bytes(host) if client_addr is None: ret.client = IPv4Address('TCP', '1.2.3.4', 12345) else: ret.client = client_addr def getHost(): return IPv4Address('TCP', '127.0.0.1', port) ret.getHost = getHost def notifyFinish(): return Deferred() ret.notifyFinish = notifyFinish for k, v in headers.iteritems(): ret.requestHeaders.setRawHeaders(bytes(k), [bytes(v)]) ret.headers = ret.getAllHeaders() return ret
def test_render(self): """ `SmsNotificationService.render_POST` parses a SOAP request and dispatches it to `SmsNotificationService.process` for processing. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.OK, request.responseCode) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { 'done': None } }}, element_to_dict(fromstring(''.join(request.written))))
def test_sync(self): '''Test the threading/transcription works when async=false''' reactor = self.buildReactor() expected = {'some': 'result'} stub_transcriber = StubTranscriber(transcribe_stub=expected) controller = TranscriptionsController(stub_transcriber, reactor=reactor) req = DummyRequest([]) req.method = 'POST' req.args = {'transcript': [''], 'audio': [''], 'async': ['false']} finish = req.notifyFinish() finish.addCallback(lambda _: reactor.callWhenRunning(reactor.stop)) body = controller.render(req) assert_equals(body, NOT_DONE_YET) self.runReactor(reactor, timeout=1) assert_equals(len(req.written), 1) got = json.loads(req.written[0]) assert_equals(got, expected)
def forge_request(uri=b'https://www.globaleaks.org/', headers=None, body='', client_addr=None, method=b'GET'): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlsplit(uri) x = host.split(b':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest([b'']) request.tid = 1 request.method = method request.uri = uri request.path = path request._serverName = host request.code = 200 request.client_ip = b'127.0.0.1' request.client_proto = b'https' request.client_using_tor = False def getResponseBody(): # Ugh, hack. Twisted returns this all as bytes, and we want it as str if isinstance(request.written[0], binary_type): return b''.join(request.written) else: return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', b'1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', b'127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish request.requestHeaders.setRawHeaders('host', [b'127.0.0.1']) request.requestHeaders.setRawHeaders('user-agent', [b'NSA Agent']) for k, v in headers.items(): request.requestHeaders.setRawHeaders(k, [v]) request.headers = request.getAllHeaders() class fakeBody(object): def read(self): if isinstance(body, dict): ret = json.dumps(body) else: ret = body if isinstance(ret, text_type): ret = ret.encode('utf-8') return ret def close(self): pass request.content = fakeBody() return request
def forge_request(uri=b'https://www.globaleaks.org/', headers=None, body='', client_addr=None, method=b'GET'): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlsplit(uri) x = host.split(b':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest([b'']) request.tid = 1 request.method = method request.uri = uri request.path = path request._serverName = host request.code = 200 request.client_ip = b'127.0.0.1' request.client_proto = b'https' request.client_using_tor = False def getResponseBody(): # Ugh, hack. Twisted returns this all as bytes, and we want it as str if isinstance(request.written[0], binary_type): return b''.join(request.written) else: return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', b'1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', b'127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish request.requestHeaders.setRawHeaders('host', [b'127.0.0.1']) request.requestHeaders.setRawHeaders('user-agent', [b'NSA Agent']) for k, v in headers.items(): request.requestHeaders.setRawHeaders(k, [v]) request.headers = request.getAllHeaders() class fakeBody(object): def read(self): if isinstance(body, dict): ret = json.dumps(body) else: ret = body if isinstance(ret, text_type): ret = ret.encode('utf-8') return ret def close(self): pass request.content = fakeBody() return request
def test_root_json(self): """ The 'welcome' / root page renders properly with ?t=json when some servers show None for available_space while others show a valid int See also https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3852 """ ann = { "anonymous-storage-FURL": "pb://w2hqnbaa25yw4qgcvghl5psa3srpfgw3@tcp:127.0.0.1:51309/vucto2z4fxment3vfxbqecblbf6zyp6x", "permutation-seed-base32": "w2hqnbaa25yw4qgcvghl5psa3srpfgw3", } srv0 = NativeStorageServer(b"server_id0", ann, None, {}, EMPTY_CLIENT_CONFIG) srv0.get_connection_status = lambda: ConnectionStatus( False, "summary0", {}, 0, 0) srv1 = NativeStorageServer(b"server_id1", ann, None, {}, EMPTY_CLIENT_CONFIG) srv1.get_connection_status = lambda: ConnectionStatus( False, "summary1", {}, 0, 0) # arrange for this server to have some valid available space srv1.get_available_space = lambda: 12345 class FakeClient(_Client): history = [] stats_provider = object() nickname = "" nodeid = b"asdf" _node_public_key = create_signing_keypair()[1] introducer_clients = [] helper = None def __init__(self): service.MultiService.__init__(self) self.storage_broker = StorageFarmBroker( permute_peers=True, tub_maker=None, node_config=EMPTY_CLIENT_CONFIG, ) self.storage_broker.test_add_server(b"test-srv0", srv0) self.storage_broker.test_add_server(b"test-srv1", srv1) root = Root(FakeClient(), now_fn=time.time) lines = [] req = DummyRequest(b"") req.fields = {} req.args = { b"t": [b"json"], } # for some reason, DummyRequest is already finished when we # try to add a notifyFinish handler, so override that # behavior. def nop(): return succeed(None) req.notifyFinish = nop req.write = lines.append yield root.render(req) raw_js = b"".join(lines).decode("utf8") js = json.loads(raw_js) servers = js["servers"] self.assertEquals(len(servers), 2) self.assertIn( { "connection_status": "summary0", "nodeid": "server_id0", "last_received_data": 0, "version": None, "available_space": None, "nickname": "" }, servers) self.assertIn( { "connection_status": "summary1", "nodeid": "server_id1", "last_received_data": 0, "version": None, "available_space": 12345, "nickname": "" }, servers)
def notifyFinish(self): # Working around a possible bug in DummyRequest, where self._finishedDeferreds somehow gets set to None if self._finishedDeferreds is None: self._finishedDeferreds = [] return DummyRequest.notifyFinish(self)
def forge_request(uri='https://www.globaleaks.org/', headers=None, body='', client_addr=None, method='GET', handler_cls=None, attached_file={}): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlparse.urlsplit(uri) x = host.split (':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest(['']) request.method = method request.uri = uri request.path = path request._serverName = bytes(host) request.code = 200 request.client_ip = '127.0.0.1' request.client_proto = 'https' request.client_using_tor = False def getResponseBody(): return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', '1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', '127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish for k, v in headers.items(): request.requestHeaders.setRawHeaders(bytes(k), [bytes(v)]) request.headers = request.getAllHeaders() request.args = {} if attached_file is not None: request.args = {'file': [attached_file]} class fakeBody(object): def read(self): if isinstance(body, dict): return json.dumps(body) else: return body def close(self): pass request.content = fakeBody() return request