Esempio n. 1
0
	def test_failAll(self):
		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		h = QANHelper(None, None, sendQANFrame, None)
		d1 = h.ask("going to the theater?")
		d2 = h.ask("mu?")

		self.assertEqual([
			Question("going to the theater?", 1),
			Question("mu?", 2),
		], sent.getNew())

		h.failAll("just because")
		self.assertTrue(d1.called)
		d1_ = self.assertFailure(d1, QuestionFailed)
		d1_.addCallback(lambda e: self.assertEqual("just because", str(e)))
		assert d1_.called

		self.assertTrue(d2.called)
		d2_ = self.assertFailure(d2, QuestionFailed)
		d2_.addCallback(lambda e: self.assertEqual("just because", str(e)))
		assert d2_.called

		# Peer can still send an answer to the failed Questions
		h.handleQANFrame(OkayAnswer("no", 1))
		h.handleQANFrame(KnownErrorAnswer("what?", 2))
Esempio n. 2
0
	def __init__(self, request=None):
		self.log = ListLog()
		self.pretendGotHello()
		if request:
			self.writable = request
			self._isHttp = True
		else:
			self._isHttp = False
Esempio n. 3
0
	def test_questionReceivedDuplicateQid(self):
		received = ListLog()
		def bodyReceived(body, isQuestion):
			received.append((body, isQuestion))
			return defer.Deferred()

		nonlocal = dict(fatalReason=None)
		def fatalError(reason):
			nonlocal['fatalReason'] = reason

		h = QANHelper(bodyReceived, None, None, fatalError)
		h.handleQANFrame(Question("what?", 1))
		h.handleQANFrame(Question("where?", 1))

		self.assertEqual([("what?", True)], received.getNew())

		self.assertEqual("Received Question with duplicate qid: 1", nonlocal['fatalReason'])
Esempio n. 4
0
class FrameDecodingTcpTransport(DummyTCPTransport):
	"""
	A TCP transport that first decodes bytes with a parser,
	then decodes the Minerva frames with decodeFrameFromServer.
	"""
	def __init__(self, parser):
		self.parser = parser
		self.log = ListLog()


	def getNew(self):
		return self.log.getNew()


	def write(self, data):
		frames, code = strictGetNewFrames(self.parser, data)
		self.log.extend(decodeFrameFromServer(
			StringFragment(f, 0, len(f)) if isinstance(f, str) else f) for f in frames)
Esempio n. 5
0
	def streamStarted(self, stream):
		self.factory.instances.add(self)
		self.log = ListLog()
		self.log.append(['streamStarted', stream])
		self.stream = stream
		if 'streamStarted' in self._callFrom:
			self._callStuff()
		if 'streamStarted' in self._raiseFrom:
			raise self._raiseWhat()
Esempio n. 6
0
class _MockStringProtocol(object):
	implements(IStringProtocol)

	def __init__(self, callFrom=(), callWhat=(), raiseFrom=(), raiseWhat=None):
		assert isinstance(callFrom, tuple), callFrom
		assert isinstance(callWhat, tuple), callWhat
		assert isinstance(raiseFrom, tuple), raiseFrom

		self._callFrom = callFrom
		self._callWhat = callWhat
		self._raiseFrom = raiseFrom
		self._raiseWhat = raiseWhat


	def _callStuff(self):
		if 'sendString' in self._callWhat:
			self.stream.sendString("s2cstring0")
			self.stream.sendString("s2cstring1")
			self.stream.sendString("s2cstring2")
		if 'reset' in self._callWhat:
			self.stream.reset('reset forced by mock protocol')


	def streamStarted(self, stream):
		self.factory.instances.add(self)
		self.log = ListLog()
		self.log.append(['streamStarted', stream])
		self.stream = stream
		if 'streamStarted' in self._callFrom:
			self._callStuff()
		if 'streamStarted' in self._raiseFrom:
			raise self._raiseWhat()


	def getNew(self):
		return self.log.getNew()


	def streamReset(self, reasonString, applicationLevel):
		self.log.append(['streamReset', reasonString, applicationLevel])
		if 'streamReset' in self._raiseFrom:
			raise self._raiseWhat()
Esempio n. 7
0
	def __init__(self, clock=None, streamId=None, streamProtocolFactory=None):
		## if streamId is None: # make a random one?
		self._notifications = []
		self.streamId = streamId
		self.streamProtocolFactory = streamProtocolFactory
		self.log = ListLog()
		self._incoming = Incoming()
		self.queue = Queue()
		self._transports = set()
		self.allSeenTransports = []
		self.lastSackSeenByServer = SACK(-1, ())
Esempio n. 8
0
	def test_notificationCausesException(self):
		"""
		A Notification that causes bodyReceived to raise an exception leads
		to a call to logError, and no response sent to the peer.
		"""
		loggedErrors = []
		def logError(message, failure):
			loggedErrors.append((message, failure))

		def bodyReceived(body, isQuestion):
			raise ValueError("bodyReceived did something wrong")

		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		h = QANHelper(bodyReceived, logError, sendQANFrame, None)
		h.handleQANFrame(Notification("You've got more mail"))

		self.assertEqual("Peer's Notification caused uncaught exception", loggedErrors[0][0])
		self.assertIsInstance(loggedErrors[0][1], failure.Failure)

		self.assertEqual([], sent.getNew())
Esempio n. 9
0
	def test_weCancel(self):
		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		h = QANHelper(None, None, sendQANFrame, None)
		d = h.ask("going to the theater?")

		self.assertEqual([
			Question("going to the theater?", 1),
		], sent.getNew())

		d.cancel()

		self.assertEqual([
			Cancellation(1),
		], sent.getNew())

		self.assertTrue(d.called)
		d2 = self.assertFailure(d, defer.CancelledError)
		assert d2.called

		# Peer always sends an answer, which QANHelper must ignore.
		h.handleQANFrame(OkayAnswer("nope", 1))
Esempio n. 10
0
	def test_questionCausesException(self):
		"""
		A Question that causes bodyReceived to raise an exception leads
		to a call to logError, and an UnknownErrorResponse("Uncaught exception")
		sent to the peer.
		"""
		loggedErrors = []
		def logError(message, failure):
			loggedErrors.append((message, failure))

		def bodyReceived(body, isQuestion):
			raise ValueError("bodyReceived did something wrong")

		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		h = QANHelper(bodyReceived, logError, sendQANFrame, None)
		h.handleQANFrame(Question("How much wood would a wood chuck chuck?", 1))

		self.assertEqual("Peer's Question #1 caused uncaught exception", loggedErrors[0][0])
		self.assertIsInstance(loggedErrors[0][1], failure.Failure)

		self.assertEqual([UnknownErrorAnswer("Uncaught exception", 1)], sent.getNew())
Esempio n. 11
0
class MockServerStream(object):
	streamId = "a stream id of unusual length"

	def __init__(self, clock=None, streamId=None, streamProtocolFactory=None):
		## if streamId is None: # make a random one?
		self._notifications = []
		self.streamId = streamId
		self.streamProtocolFactory = streamProtocolFactory
		self.log = ListLog()
		self._incoming = Incoming()
		self.queue = Queue()
		self._transports = set()
		self.allSeenTransports = []
		self.lastSackSeenByServer = SACK(-1, ())


	def getNew(self):
		return self.log.getNew()


	def sendString(self, string):
		self.log.append(['sendString', string])


	def reset(self, reasonString):
		self.log.append(['reset', reasonString])


	def resetFromPeer(self, reasonString, applicationLevel):
		self.log.append(['resetFromPeer', reasonString, applicationLevel])
		for t in self._transports.copy():
			t.closeGently()


	def stringsReceived(self, transport, strings):
		self.log.append(['stringsReceived', transport, strings])
		self._incoming.give(strings)


	def sackReceived(self, sack):
		"""
		Returns C{True} if SACK was bad, C{False} otherwise.
		"""
		self.log.append(['sackReceived', sack])
		self.lastSackSeenByServer = sack
		return self.queue.handleSACK(sack)


	def transportOnline(self, transport, wantsStrings, succeedsTransport):
		self.allSeenTransports.append(transport)
		self.log.append(['transportOnline', transport, wantsStrings, succeedsTransport])
		assert transport not in self._transports
		self._transports.add(transport)


	def transportOffline(self, transport):
		self.log.append(['transportOffline', transport])
		self._transports.remove(transport)


	def serverShuttingDown(self, transport):
		self.log.append(['serverShuttingDown', transport])


	def pauseProducing(self):
		self.log.append(['pauseProducing'])


	def resumeProducing(self):
		self.log.append(['resumeProducing'])


	def stopProducing(self):
		self.log.append(['stopProducing'])


	def getSACK(self):
		self.log.append(['getSACK'])
		return self._incoming.getSACK()


	def notifyFinish(self):
		"""
		Notify when finishing the request

		@return: A deferred.  The deferred will be triggered when the
		stream is finished -- always with a C{None} value.
		"""
		self.log.append(['notifyFinish'])
		self._notifications.append(defer.Deferred())
		return self._notifications[-1]


	def _pretendFinish(self):
		for d in self._notifications:
			d.callback(None)
		self._notifications = None
Esempio n. 12
0
	def __init__(self, parser):
		self.parser = parser
		self.log = ListLog()
Esempio n. 13
0
class DummySocketLikeTransport(object):
	request = None
	globalCounter = [-1]
	ourSeqNum = -1
	_paused = False

	def __init__(self, request=None):
		self.log = ListLog()
		self.pretendGotHello()
		if request:
			self.writable = request
			self._isHttp = True
		else:
			self._isHttp = False


	def getNew(self):
		return self.log.getNew()


	def isHttp(self):
		return self._isHttp


	def pretendGotHello(self):
		self.globalCounter[0] += 1
		self.transportNumber = self.globalCounter[0]


	def closeGently(self):
		self.log.append(['closeGently'])


	def causedRwinOverflow(self):
		self.log.append(['causedRwinOverflow'])


	def writeReset(self, reasonString, applicationLevel):
		self.log.append(['writeReset', reasonString, applicationLevel])


	def writeStrings(self, queue, start):
		self.log.append(['writeStrings', queue, start])

		lastString = self.ourSeqNum
		for seqNum, string in queue.iterItems(start=start):
			if lastString == -1 or lastString + 1 != seqNum:
				pass
				##toSend += self._encodeFrame(SeqNumFrame(seqNum))
			##toSend += self._encodeFrame(StringFrame(string))
			lastString = seqNum
		self.ourSeqNum = lastString


	def registerProducer(self, producer, streaming):
		self.log.append(['registerProducer', producer, streaming])


	def unregisterProducer(self):
		self.log.append(['unregisterProducer'])


	def pauseProducing(self):
		self._paused = True


	def getHost(self):
		return None # TODO: return a real host


	def isStreamingFromPeer(self):
		return True


	def isStreamingToPeer(self):
		return True
Esempio n. 14
0
	def test_ask(self):
		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		answers = ListLog()
		def gotOkayAnswer(answer):
			answers.append((answer, 'okay'))

		def gotErrorAnswerExpect(expectedFailure):
			def gotErrorAnswer(failure):
				failure.trap(expectedFailure)
				answers.append((failure.value[0], 'error'))
			return gotErrorAnswer

		fatalErrors = ListLog()
		def fatalError(msg):
			fatalErrors.append(msg)

		h = QANHelper(None, None, sendQANFrame, fatalError)
		d1 = h.ask("what?")
		d1.addCallbacks(gotOkayAnswer, gotErrorAnswerExpect(None))

		# Make sure QANHelper wrote something to the peer
		self.assertEqual([
			Question("what?", 1),
		], sent.getNew())

		# We shouldn't have an answer yet
		self.assertEqual([], answers.getNew())

		# An answer with a wrong QID calls fatalError
		self.assertEqual([], fatalErrors.getNew())
		h.handleQANFrame(OkayAnswer("answer with wrong qid", 100))
		self.assertEqual(["Received an answer with invalid qid: 100"], fatalErrors.getNew())

		### TODO: we might have to set up a new QANHelper after the fatalError;
		### the current implementation is lenient.

		# Feed this "OkayAnswer from the peer" into QANHelper
		h.handleQANFrame(OkayAnswer("no.", 1))

		self.assertEqual([('no.', 'okay')], answers.getNew())


		d2 = h.ask("I want a KnownError response to this one")
		d2.addCallbacks(gotOkayAnswer, gotErrorAnswerExpect(KnownError))

		# Feed this "KnownErrorAnswer from the peer" into QANHelper
		h.handleQANFrame(KnownErrorAnswer("KnownErrorAnswer as asked", 2))

		self.assertEqual([('KnownErrorAnswer as asked', 'error')], answers.getNew())


		d3 = h.ask("I want an UnknownError response to this one")
		d3.addCallbacks(gotOkayAnswer, gotErrorAnswerExpect(UnknownError))

		# Feed this "UnknownErrorAnswer from the peer" into QANHelper
		h.handleQANFrame(UnknownErrorAnswer("UnknownErrorAnswer as asked", 3))

		self.assertEqual([('UnknownErrorAnswer as asked', 'error')], answers.getNew())
Esempio n. 15
0
	def test_theyCancel(self):
		nonlocal = dict(
			cancellerDoesErrbackCalled=False,
			cancellerDoesCallbackCalled=False,
		)
		def cancellerDoesErrback(d):
			nonlocal['cancellerDoesErrbackCalled'] = True
			d.errback(KnownError("okay, you'll never know"))

		def cancellerDoesCallback(d):
			nonlocal['cancellerDoesCallbackCalled'] = True
			d.callback("maybe a little warm")

		received = []
		answerDs = [
			defer.Deferred(),
			defer.Deferred(cancellerDoesErrback),
			defer.Deferred(),
			defer.Deferred(cancellerDoesCallback),
		]
		def bodyReceived(body, isQuestion):
			received.append((body, isQuestion))
			return answerDs.pop(0)

		sent = ListLog()
		def sendQANFrame(frame):
			sent.append(frame)

		h = QANHelper(bodyReceived, None, sendQANFrame, None)
		d1 = answerDs[0]
		d2 = answerDs[1]
		d3 = answerDs[2]
		d4 = answerDs[3]
		h.handleQANFrame(Question("the weather?", 1))
		h.handleQANFrame(Question("how about now?", 2))
		h.handleQANFrame(Question("and now?", 3))
		h.handleQANFrame(Question("this evening?", 4))
		self.assertEqual([
			('the weather?', True),
			('how about now?', True),
			('and now?', True),
			('this evening?', True),
		], received)

		self.assertEqual([], sent.getNew())

		self.assertEqual(False, nonlocal['cancellerDoesErrbackCalled'])
		self.assertEqual(False, nonlocal['cancellerDoesCallbackCalled'])

		# Cancel Question #2
		h.handleQANFrame(Cancellation(2))
		self.assertTrue(nonlocal['cancellerDoesErrbackCalled'])
		self.assertEqual([
			KnownErrorAnswer("okay, you'll never know", 2),
		], sent.getNew())

		# Cancel Question #4
		h.handleQANFrame(Cancellation(4))
		self.assertTrue(nonlocal['cancellerDoesCallbackCalled'])
		self.assertEqual([
			OkayAnswer("maybe a little warm", 4)
		], sent.getNew())

		# Cancel Question #1, which has no canceller
		h.handleQANFrame(Cancellation(1))
		self.assertEqual([
			UnknownErrorAnswer("CancelledError", 1),
		], sent.getNew())

		d3.errback(KnownError("weather station is broken"))
		self.assertEqual([
			KnownErrorAnswer("weather station is broken", 3),
		], sent.getNew())