def test_at_close(self): """Verify _at_close() works as expected""" negotiator = _Negotiator() negotiator._finalize_response = lambda m, ln: None negotiator._send_response = lambda m: None negotiator.register("abc", None) for _ in range(3): stream = Stream(self) stream.peername = ("abc", 3456) m = { "stream": stream, "ident": sha1stream(stream), "module": "abc", } # To test the delay queue too for _ in range(2): negotiator.negotiate(m) negotiator._at_close(stream, None) self.assertTrue(stream not in negotiator._queue) self.assertTrue(stream not in negotiator._known) self.assertTrue(stream not in negotiator._delay) self.assertTrue(len(negotiator._delay) == 0)
def test_negotiate_add(self): """Verify negotiate behavior when we add a new stream""" stream = Stream(None) stream.peername = ("abc", 3456) m = { "stream": stream, "ident": sha1stream(stream), "module": "abc", } negotiator = _Negotiator() negotiator._finalize_response = lambda m, ln: None negotiator._send_response = lambda m: None negotiator.register("abc", None) negotiator.negotiate(m) # Do we keep track of the new stream? self.assertTrue(stream in negotiator._queue) self.assertTrue(stream in negotiator._known) # Is the watchdog correctly initialized? self.assertTrue(negotiator._at_close in stream.atclosev) self.assertEqual(stream.watchdog, 300) self.assertTrue(utils.ticks() - stream.created < 1) #XXX
def test_200_collect(self): """Verify behavior when the URI is /collect""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() message = Message(uri="/collect/abc") func = lambda m: \ self.assertEquals(m, { "code": "200", "keepalive": True, "mimetype": "application/json", "reason": "Ok", "response_body": "", "ident": sha1stream(None), "request_body": {}, "request": message, "parent": server, "stream": None, "module": "abc", }) # # In this case, differently from negotiate, both # functions are invoked so make sure they both receive # what we expect. # server.negotiator.collect = func server.send_response = func server.process_request(None, message)
def test_200_negotiate(self): """Verify behavior when the URI is /negotiate""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() message = Message(uri="/negotiate/abc") server.negotiator.negotiate = lambda m: \ self.assertEquals(m, { "code": "200", "keepalive": True, "mimetype": "application/json", "reason": "Ok", "response_body": "", "ident": sha1stream(None), "request_body": {}, "request": message, "parent": server, "stream": None, "module": "abc", }) # # Since send_response() should not be invoked, make # a wrong comparison so that we notice it if the func # is invoked unexpectedly. # server.send_response = lambda m: \ self.assertEquals(m, {}) server.process_request(None, message)
def test_below_min(self): """Verify behavior when len(queue) < MIN""" n = _Negotiator() for _ in range(int(n._red)): n._queue.append(None) # # Reject if rnd() < threshold where threshold is # less than 0 when len(queue) < MIN. # reject = n._random_early_discard(rnd=lambda: 0) self.assertFalse(reject)
def test_above_max(self): """Verify behavior when len(queue) > MAX""" n = _Negotiator() for _ in range(2 * int(n._red)): n._queue.append(None) n._queue.append(None) # # Reject if rnd() < threshold where threshold is # more than 1 when len(queue) > MAX. # reject = n._random_early_discard(rnd=lambda: 1) self.assertTrue(reject)
def test_between_min_and_max(self): """Verify behavior when MIN < len(queue) < MAX""" v = [0, 0] n = _Negotiator() for idx in range(2 * int(n._red)): n._queue.append(None) if idx > n._red: reject = n._random_early_discard() v[reject] += 1 self.assertTrue(v[0] > 0 and v[1] > 0)
def test_body_not_a_dictionary(self): """Make sure we raise ValueError if we cannot parse request body""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() message = Message() message.compose(pathquery="/collect/abcdefg", body=StringIO.StringIO("abc"), mimetype="application/json") self.assertRaises(ValueError, server.process_request, None, message)
def test_negotiate_except(self): """Verify negotiate raises KeyError if the module is unknown""" stream = Stream(None) stream.peername = ("abc", 3456) m = { "stream": stream, "ident": sha1stream(stream), "module": "abc", } negotiator = _Negotiator() self.assertRaises(KeyError, negotiator.negotiate, m)
def test_body_empty(self): """Make sure we correctly read empty incoming bodies""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() d = {} server.send_response = lambda m: self.assertEquals(d, m["request_body"]) message = Message() message.compose(pathquery="/collect/abcdefg") server.process_request(None, message)
def test_choke(self): """Verify finalize_response() when choke""" dummy = [False] module = NegotiatorModule() module.unchoke = lambda m: dummy.pop() negotiator = _Negotiator() negotiator.register("abc", module) m = { "response_body": {}, "module": "abc" } negotiator._finalize_response(m, 21) self.assertEqual(json.loads(m["response_body"]), { u"unchoked": False, u"queue_pos": 21 }) self.assertEqual(len(dummy), 1)
def test_body_a_dictionary(self): """Make sure we correctly read incoming dictionaries""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() d = {"abc": 12, "k": "s", "uuu": 1.74} server.send_response = lambda m: self.assertEquals(d, m["request_body"]) message = Message() message.compose(pathquery="/collect/abcdefg", body=StringIO.StringIO(json.dumps(d)), mimetype="application/json") server.process_request(None, message)
def test_body_invalid_mime(self): """Make sure we raise RuntimeError if the MIME type is wrong""" server = _ServerNegotiate(None) server.negotiator = _Negotiator() message = Message() message.compose(pathquery="/collect/abcdefg", body=StringIO.StringIO("abc")) self.assertRaises(RuntimeError, server.process_request, None, message) message = Message() message.compose(pathquery="/collect/abcdefg", body=StringIO.StringIO("abc"), mimetype="text/plain") self.assertRaises(RuntimeError, server.process_request, None, message)
def test_negotiate_delay(self): """Verify negotiate behavior when we delay response""" stream = Stream(None) stream.peername = ("abc", 3456) m = { "stream": stream, "ident": sha1stream(stream), "module": "abc", } negotiator = _Negotiator() negotiator._finalize_response = lambda m, ln: None negotiator._send_response = lambda m: None negotiator.register("abc", None) for _ in range(2): negotiator.negotiate(m) self.assertTrue(stream in negotiator._delay)
def runTest(self): """Simulate clients behavior to stress the Negotiator""" # Log file #fp = open("simulation.txt", "w") # Fake negotiator negotiator = _Negotiator() negotiator.register("A", FakeNegotiatorModule()) negotiator.register("B", FakeNegotiatorModule()) negotiator.register("C", FakeNegotiatorModule()) # Simulated streams streams = [] for _ in range(8192): stream = Stream(FakePoller()) stream.parent = Object() stream.parent.connection_lost = lambda s: None stream.sock = Object() stream.sock.soclose = lambda: None stream.peername = str((str(hash(stream)), 7)) stream.logname = str((str(hash(stream)), 7)) streams.append(stream) # Track streams we have notified notified = set() self.send_response = lambda m: notified.add(m["stream"]) # Track streams that have negotiated negotiated = set() while streams: # # Select stream # idx = random.randrange(len(streams)) stream = streams[idx] # # Select event # 60% negotiate 20% collect 20% close # rnd = random.random() if rnd < 0.6: # Negotiate m = { "stream": stream, "ident": sha1stream(stream), "module": chr(random.randrange(ord("A"), ord("A") +3)), "parent": self, #XXX } notified.clear() # EOF if random early discard try: negotiator.negotiate(m) except NegotiatorEOF: #fp.write("%s random-early-discard\n" % sha1stream(stream)) streams.remove(stream) stream.close() else: self.assertTrue(stream in negotiator._queue) self.assertTrue(stream in negotiator._known) # Not notified? So must be in the delayed queue if stream not in notified: #fp.write("%s negotiate-delay\n" % sha1stream(stream)) self.assertTrue(stream in negotiator._delay) else: #fp.write("%s negotiate-send\n" % sha1stream(stream)) pass negotiated.add(stream) elif rnd < 0.8: # Collect m = { "stream": stream, "request_body": "{}", "module": chr(random.randrange(ord("A"), ord("A") +3)), "response_body": "", } # EOF if not authorized try: negotiator.collect(m) except NegotiatorEOF: #fp.write("%s collect-no-auth\n" % sha1stream(stream)) streams.remove(stream) stream.close() else: #fp.write("%s collect-ok\n" % sha1stream(stream)) pass else: # XXX Don't waste streams w/o a good reason if stream not in negotiated: continue #fp.write("%s close\n" % sha1stream(stream)) streams.remove(stream) # Remember streams to be notified orig = set(negotiator._delay.keys()) notified.clear() stream.close() # Make sure we removed stream self.assertTrue(stream not in negotiator._queue) self.assertTrue(stream not in negotiator._known) self.assertTrue(stream not in negotiator._delay) # Make sure we notified all self.assertEqual(notified, orig - set([stream])) # Make sure negotiator is empty self.assertEqual(len(negotiator._queue), 0) self.assertEqual(len(negotiator._known), 0) self.assertEqual(len(negotiator._delay), 0) # Make sure modules are empty self.assertEqual(len(negotiator._mods["A"]._allow), 0) self.assertEqual(len(negotiator._mods["B"]._allow), 0) self.assertEqual(len(negotiator._mods["C"]._allow), 0)
def runTest(self): """Check that register() works""" mod = object() negotiator = _Negotiator() negotiator.register("abc", mod) self.assertEquals(negotiator._mods["abc"], mod)