def test_oneConnectionAccepted(self): """ When a connection comes in to a listening L{flowFountFromEndpoint}, the L{Listener} that it's flowing to's callback is called. """ endpoint, ports = fakeEndpointWithPorts() deferred = flowFountFromEndpoint(endpoint) self.assertNoResult(deferred) deferred.callback(None) result = self.successResultOf(deferred) connected = [] result.flowTo(Listener(connected.append)) protocol = ports[0].factory.buildProtocol(None) self.assertEqual(len(connected), 0) protocol.makeConnection(StringTransport()) self.assertEqual(len(connected), 1)
def test_too_long_configuration(self): """ AMP protocol can transmit configurations with 800 applications. """ self.client.makeConnection(StringTransport()) actual = DeploymentState(nodes=[]) configuration = huge_deployment() d = self.server.callRemote( ClusterStatusCommand, configuration=configuration, state=actual, eliot_context=TEST_ACTION ) self.successResultOf(d) self.assertEqual(configuration, self.agent.desired)
def test_stop_service_connections(self): """ Stopping the service closes all connections. """ service = build_control_amp_service(self) service.startService() connections = [ControlAMP(Clock(), service) for i in range(3)] initial_disconnecting = [] for c in connections: c.makeConnection(StringTransport()) initial_disconnecting.append(c.transport.disconnecting) service.stopService() self.assertEqual( (initial_disconnecting, [c.transport.disconnecting for c in connections]), ([False] * 3, [True] * 3))
def test_connection_made_send_cluster_status(self, logger): """ When a connection is made the cluster status is sent to the new client. """ sent = [] self.patch_call_remote(sent, self.protocol) self.control_amp_service.configuration_service.save(TEST_DEPLOYMENT) self.control_amp_service.cluster_state.apply_changes([NODE_STATE]) self.protocol.makeConnection(StringTransport()) cluster_state = self.control_amp_service.cluster_state.as_deployment() self.assertEqual( sent[0], (((ClusterStatusCommand,), dict(configuration=TEST_DEPLOYMENT, state=cluster_state))))
def test_signDataWithAgent(self): """ When connected to an agent, L{SSHUserAuthClient} can use it to request signatures of particular data with a particular L{Key}. """ client = SSHUserAuthClient("user", ConchOptions(), None) agent = SSHAgentClient() transport = StringTransport() agent.makeConnection(transport) client.keyAgent = agent cleartext = "Sign here" client.signData(self.rsaPublic, cleartext) self.assertEqual( transport.value(), "\x00\x00\x00\x8b\r\x00\x00\x00u" + self.rsaPublic.blob() + "\x00\x00\x00\t" + cleartext + "\x00\x00\x00\x00")
def test_cluster_updated(self): """ ``ClusterStatusCommand`` sent to the ``AgentClient`` result in agent having cluster state updated. """ self.client.makeConnection(StringTransport()) actual = Deployment(nodes=frozenset()) d = self.server.callRemote(ClusterStatusCommand, configuration=TEST_DEPLOYMENT, state=actual) self.successResultOf(d) self.assertEqual( self.agent, FakeAgent(is_connected=True, desired=TEST_DEPLOYMENT, actual=actual))
def test_disconnect_cancels_timeout(self): """ If the connection is closed, the hang check is cancelled. """ clock = Clock() protocol = HangCheckProtocol( Protocol(), reactor=clock, ) transport = StringTransport() transport.protocol = protocol protocol.makeConnection(transport) protocol.connectionLost(Failure(ConnectionDone("Bye."))) assert_clock_idle(self, clock)
def test_invalid_status_line(self): """ Not speaking RawSocket or MQTT but also not speaking a type of HTTP will cause the connection to be dropped. """ t = StringTransport() f = UniSocketServerFactory() p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'this is not HTTP\r\n\r\n') self.assertFalse(t.connected)
def _versionTest(self, serverVersionResponse): """ Test L{DispatchClient} version negotiation. """ client = msn.DispatchClient() client.userHandle = "foo" transport = StringTransport() client.makeConnection(transport) self.assertEquals(transport.value(), "VER 1 MSNP8 CVR0\r\n") transport.clear() client.dataReceived(serverVersionResponse) self.assertEquals( transport.value(), "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS foo\r\n")
def test_keepalive_requires_full_packet(self): """ If a client connects with a keepalive, and sends no FULL packets in keep_alive * 1.5, they will be disconnected. Compliance statement MQTT-3.1.2-24 """ sessions = {} h = BasicHandler() r = Clock() t = StringTransport() p = MQTTServerTwistedProtocol(h, r, sessions) p.makeConnection(t) data = ( # CONNECT, with keepalive of 2 b"101300044d51545404020002000774657374313233") for x in iterbytes(unhexlify(data)): p.dataReceived(x) self.assertEqual(len(r.calls), 1) self.assertEqual(r.calls[0].func, p._lose_connection) self.assertEqual(r.calls[0].getTime(), 3.0) self.assertFalse(t.disconnecting) r.advance(2.9) self.assertFalse(t.disconnecting) data = ( # PINGREQ header, no body (incomplete packet) b"c0") for x in iterbytes(unhexlify(data)): p.dataReceived(x) # Timeout has not changed. If it reset the timeout on data recieved, # the delayed call's trigger time would instead be 2.9 + 3. self.assertEqual(len(r.calls), 1) self.assertEqual(r.calls[0].func, p._lose_connection) self.assertEqual(r.calls[0].getTime(), 3.0) r.advance(0.1) self.assertTrue(t.disconnecting)
def test_timeoutConnection(self): """ L{smtp.SMTPClient.timeoutConnection} calls the C{sendError} hook with a fatal L{SMTPTimeoutError} with the current line log. """ error = [] client = MySMTPClient() client.sendError = error.append client.makeConnection(StringTransport()) client.lineReceived("220 hello") client.timeoutConnection() self.assertIsInstance(error[0], smtp.SMTPTimeoutError) self.assertTrue(error[0].isFatal) self.assertEqual( str(error[0]), "Timeout waiting for SMTP server response\n" "<<< 220 hello\n" ">>> HELO foo.baz\n")
def test_on_headers_continue(self): with mock.patch.object(HTTPConnection, '_remote_ip', return_value=None) as m_obj: self.con = HTTPConnection() self.con.factory = Mock() self.con.transport = StringTransport() self.con.setRawMode = Mock() self.con._remote_ip = "127.0.0.1" self.con.connectionMade() data = \ b"GET / HTTP/1.1\r\n"\ b"Content-Length: 5\r\n"\ b"Expect: 100-continue"\ b"\r\n" self.con._on_headers(data) self.assertEqual(self.con.transport.io.getvalue().strip(), b"HTTP/1.1 100 (Continue)")
def test_firstWrite(self): """ For an HTTP 1.0 request, L{http.Request.write} sends an HTTP 1.0 Response-Line and whatever response headers are set. """ req = http.Request(DummyChannel(), None) trans = StringTransport() req.transport = trans req.setResponseCode(200) req.clientproto = "HTTP/1.0" req.responseHeaders.setRawHeaders("test", ["lemur"]) req.write('Hello') self.assertResponseEquals( trans.value(), [("HTTP/1.0 200 OK", "Test: lemur", "Hello")])
def test_data_and_disconnect(self): """ If the connection receives data and then is closed, no error results. """ clock = Clock() protocol = HangCheckProtocol( Protocol(), reactor=clock, ) transport = StringTransport() transport.protocol = protocol protocol.makeConnection(transport) protocol.dataReceived("some-data") protocol.connectionLost(Failure(ConnectionDone("Bye."))) assert_clock_idle(self, clock)
def setUp(self): self.handler = mock.Mock() directlyProvides(self.handler, ILogHandler) self.endpoint = mock.Mock() directlyProvides(self.endpoint, IStreamServerEndpoint) self.port = mock.Mock() def _listen(*args, **kwargs): return succeed(self.port) self.endpoint.listen.side_effect = _listen self.service = ScribeServerService(self.endpoint, self.handler) self.transport = StringTransport()
def test_receivedBytesLogged(self): """ When bytes are delivered through a protocol created by L{_TrafficLoggingFactory}, they are added to a log kept on that factory. """ protocol = self.factory.buildProtocol(None) # The factory should now have a new StringIO log file self.assertEqual(1, len(self.factory.logs)) transport = StringTransport() protocol.makeConnection(transport) protocol.dataReceived("hello, world") self.assertEqual("*\nC 0: 'hello, world'\n", self.factory.logs[0].getvalue())
def test_from_uri(self): """ It's possible to build an AMQEndpoint from an AMQP URI string. """ endpoint = AMQEndpoint.from_uri( self.reactor, "amqp://*****:*****@some.broker/foo?heartbeat=10") endpoint.connect(self.factory) self.assertEqual(("some.broker", 5672), self.reactor.tcpClients[0][:2]) # _WrappingFactory from twisted.internet.endpoints factory = self.reactor.tcpClients[0][2] protocol = factory.buildProtocol(None) protocol.makeConnection(StringTransport()) client = protocol._wrappedProtocol self.assertEqual("foo", client.vhost) self.assertEqual(10, client.heartbeatInterval) self.assertEqual({"LOGIN": "******", "PASSWORD": "******"}, client.response) self.assertEqual("AMQPLAIN", client.mechanism)
def require(packageName, fixName): if (packageName, fixName) in _alreadyInstalled: return if (packageName, fixName) == ('twisted', 'filepath_copyTo'): from twisted.python import filepath if filepath.FilePath('a') != filepath.FilePath('a'): from vmc.contrib.epsilon.hotfixes import filepath_copyTo filepath_copyTo.install() elif (packageName, fixName) == ('twisted', 'timeoutmixin_calllater'): from twisted.protocols import policies if not hasattr(policies.TimeoutMixin, 'callLater'): from vmc.contrib.epsilon.hotfixes import timeoutmixin_calllater timeoutmixin_calllater.install() elif (packageName, fixName) == ('twisted', 'delayedcall_seconds'): from twisted.internet import base args = inspect.getargs(base.DelayedCall.__init__.func_code)[0] if 'seconds' not in args: from vmc.contrib.epsilon.hotfixes import delayedcall_seconds delayedcall_seconds.install() elif (packageName, fixName) == ('twisted', 'deferredgenerator_tfailure'): from twisted.internet import defer result = [] def test(): d = defer.waitForDeferred(defer.succeed(1)) yield d result.append(d.getResult()) defer.deferredGenerator(test)() if result == [1]: from vmc.contrib.epsilon.hotfixes import deferredgenerator_tfailure deferredgenerator_tfailure.install() else: assert result == [None] elif (packageName, fixName) == ("twisted", "proto_helpers_stringtransport"): from twisted.test.proto_helpers import StringTransport st = StringTransport() try: st.write(u'foo') except TypeError, e: pass else: from vmc.contrib.epsilon.hotfixes import proto_helpers_stringtransport proto_helpers_stringtransport.install()
def test_rawsocket_with_no_factory(self): """ Trying to speak RawSocket with no RawSocket factory configured will drop the connection. """ t = StringTransport() f = UniSocketServerFactory() p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'\x7F0000000') self.assertFalse(t.connected)
def test_connection_made_send_cluster_status(self): """ When a connection is made the cluster status is sent to the new client. """ sent = [] self.patch( self.protocol, "callRemote", lambda *args, **kwargs: sent.append( (args, kwargs)) or succeed(None)) self.control_amp_service.configuration_service.save(TEST_DEPLOYMENT) self.control_amp_service.cluster_state.update_node_state(NODE_STATE) self.protocol.makeConnection(StringTransport()) cluster_state = self.control_amp_service.cluster_state.as_deployment() self.assertEqual( sent[0], (((ClusterStatusCommand, ), dict(configuration=TEST_DEPLOYMENT, state=cluster_state))))
def test_keepalive_full_packet_resets_timeout(self): """ If a client connects with a keepalive, and sends packets in under keep_alive * 1.5, the connection will remain, and the timeout will be reset. """ sessions = {} h = BasicHandler() r = Clock() t = StringTransport() p = MQTTServerTwistedProtocol(h, r, sessions) p.makeConnection(t) data = ( # CONNECT, with keepalive of 2 b"101300044d51545404020002000774657374313233") for x in iterbytes(unhexlify(data)): p.dataReceived(x) self.assertEqual(len(r.calls), 1) self.assertEqual(r.calls[0].func, p._lose_connection) self.assertEqual(r.calls[0].getTime(), 3.0) self.assertFalse(t.disconnecting) r.advance(2.9) self.assertFalse(t.disconnecting) data = ( # Full PINGREQ packet b"c000") for x in iterbytes(unhexlify(data)): p.dataReceived(x) # Timeout has changed, to be 2.9 (the time the packet was recieved) + 3 self.assertEqual(len(r.calls), 1) self.assertEqual(r.calls[0].func, p._lose_connection) self.assertEqual(r.calls[0].getTime(), 2.9 + 3.0) r.advance(0.1) self.assertFalse(t.disconnecting)
def test_lookupAddress(self): """ L{SecondaryAuthority.lookupAddress} returns a L{Deferred} that fires with the I{A} records the authority has cached from the primary. """ secondary = SecondaryAuthority.fromServerAddressAndDomain( ("192.168.1.2", 1234), b"example.com") secondary._reactor = reactor = MemoryReactorClock() secondary.transfer() host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0) proto = factory.buildProtocol((host, port)) transport = StringTransport() proto.makeConnection(transport) query = Message(answer=1, auth=1) query.decode(BytesIO(transport.value()[2:])) # Generate a response with some data we can check. soa = Record_SOA( mname=b"ns1.example.com", rname="admin.example.com", serial=123456, refresh=3600, minimum=4800, expire=7200, retry=9600, ttl=12000, ) a = Record_A(b"192.168.1.2", ttl=0) answer = Message(id=query.id, answer=1, auth=1) answer.answers.extend([ RRHeader(b"example.com", type=SOA, payload=soa), RRHeader(b"example.com", payload=a), RRHeader(b"example.com", type=SOA, payload=soa), ]) data = answer.toStr() proto.dataReceived(pack("!H", len(data)) + data) result = self.successResultOf(secondary.lookupAddress("example.com")) self.assertEqual( ([RRHeader(b"example.com", payload=a, auth=True)], [], []), result)
def test_json_error(self, return_value): """ Test what happens if invalid JSON is returned from the remote endpoint. """ test_d = defer.ensureDeferred(self.cl.get_json("testserv:8008", "foo/bar")) self.pump() # Nothing happened yet self.assertNoResult(test_d) # Make sure treq is trying to connect clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (host, port, factory, _timeout, _bindAddress) = clients[0] self.assertEqual(host, "1.2.3.4") self.assertEqual(port, 8008) # complete the connection and wire it up to a fake transport protocol = factory.buildProtocol(None) transport = StringTransport() protocol.makeConnection(transport) # that should have made it send the request to the transport self.assertRegex(transport.value(), b"^GET /foo/bar") self.assertRegex(transport.value(), b"Host: testserv:8008") # Deferred is still without a result self.assertNoResult(test_d) # Send it the HTTP response protocol.dataReceived( b"HTTP/1.1 200 OK\r\n" b"Server: Fake\r\n" b"Content-Type: application/json\r\n" b"Content-Length: %i\r\n" b"\r\n" b"%s" % (len(return_value), return_value) ) self.pump() f = self.failureResultOf(test_d) self.assertIsInstance(f.value, RequestSendFailed)
def test_getException(self): """ If the factory throws an exception, error code 400 must be returned. """ class ErrorFactory: """ Factory that raises an error on key lookup. """ def get(self, key): raise Exception('This is a test error') server = postfix.PostfixTCPMapServer() server.factory = ErrorFactory() server.transport = StringTransport() server.lineReceived(b'get example') self.assertEqual(server.transport.value(), b'400 This is a test error\n')
def runRequest(self, httpRequest, requestClass, success=1): httpRequest = httpRequest.replace("\n", "\r\n") b = StringTransport() a = http.HTTPChannel() a.requestFactory = requestClass a.makeConnection(b) # one byte at a time, to stress it. for byte in httpRequest: if a.transport.disconnecting: break a.dataReceived(byte) a.connectionLost(IOError("all done")) if success: self.assertEquals(self.didRequest, 1) del self.didRequest else: self.assert_(not hasattr(self, "didRequest")) return a
def test_acceptAfterDeferredButBeforeFlowTo(self): """ If the L{Deferred} returned by L{flowFountFromEndpoint} fires, but the callback doesn't immediately call C{flowTo} on the result, the listening port will be paused. """ endpoint, ports = fakeEndpointWithPorts() fffed = flowFountFromEndpoint(endpoint) fffed.callback(None) flowFount = self.successResultOf(fffed) self.assertEqual(ports[0].currentlyProducing, True) protocol = ports[0].factory.buildProtocol(None) aTransport = StringTransport() protocol.makeConnection(aTransport) self.assertEqual(ports[0].currentlyProducing, False) fd = FakeDrain() flowFount.flowTo(fd) self.assertEqual(ports[0].currentlyProducing, True)
def async_url_open(url, timeout=0, **kwargs): if url.startswith('http'): page = NamedTemporaryFile(delete=False) new_url = page.name yield downloadPage(encode(url), page, timeout=timeout) else: page, new_url = None, url f = yield async_get_file(new_url, StringTransport(), **kwargs) if not hasattr(f, 'name') and url.startswith('file'): f.name = url.split('://')[1] if page: page.close() remove(page.name) return_value(f)
def testLateBPR(self): """ This test makes sure that if a BPR response that was meant to be part of a SYN response (but came after the last LST) is received, the correct contact is updated and all is well """ self.client.makeConnection(StringTransport()) msn.NotificationClient.loggedIn(self.client, '*****@*****.**', 'foo', 1) lines = [ "SYN %s 100 1 1" % self.client.currentID, "GTC A", "BLP AL", "LSG 0 Other%20Contacts 0", "LST [email protected] Some%20Name 11 0", "BPR PHH 123%20456" ] map(self.client.lineReceived, lines) contact = self.client.factory.contacts.getContact( '*****@*****.**') self.failUnless(contact.homePhone == '123 456', "Did not update contact's phone number")
def connectSSHTransport(service, hostAddress=None, peerAddress=None): """ Connect a SSHTransport which is already connected to a remote peer to the channel under test. @param service: Service used over the connected transport. @type service: L{SSHService} @param hostAddress: Local address of the connected transport. @type hostAddress: L{interfaces.IAddress} @param peerAddress: Remote address of the connected transport. @type peerAddress: L{interfaces.IAddress} """ transport = SSHServerTransport() transport.makeConnection( StringTransport(hostAddress=hostAddress, peerAddress=peerAddress)) transport.setService(service)
def test_configuration_change(self): """ A configuration change results in connected protocols being notified of new cluster status. """ service = build_control_amp_service(self) service.startService() protocol = ControlAMP(service) protocol.makeConnection(StringTransport()) sent = [] self.patch( protocol, "callRemote", lambda *args, **kwargs: sent.append( (args, kwargs)) or succeed(None)) service.configuration_service.save(TEST_DEPLOYMENT) self.assertEqual(sent, [((ClusterStatusCommand, ), dict(configuration=TEST_DEPLOYMENT, state=Deployment(nodes=frozenset())))])