def testRemoveTimer(self): def itsTime(): pass reactor = Reactor() token1 = reactor.addTimer(0.05, itsTime) token2 = reactor.addTimer(0.051, itsTime) reactor.removeTimer(token1) self.assertEquals(1, len(reactor._timers))
def testRemoveTimerWithSameTimestamp(self): reactor = Reactor() token1 = reactor.addTimer(1, lambda: None) token2 = reactor.addTimer(1, lambda: None) token2.time = token1.time reactor.removeTimer(token2) self.assertEquals([id(token1)], [id(t) for t in reactor._timers]) reactor.removeTimer(token1) self.assertEquals([], reactor._timers)
def testRemoveTimerById(self): def itsTime(): pass reactor = Reactor() token1 = reactor.addTimer(0.051, itsTime) token2 = reactor.addTimer(0.051, itsTime) token3 = reactor.addTimer(0.051, itsTime) token3.time = token2.time = token1.time # whiteboxing, can happen in real code, not easy to reproduce in a test situation. self.assertEquals(token1.callback, token2.callback) self.assertEquals(token2.callback, token3.callback) reactor.removeTimer(token2) self.assertEquals([token1, token3], reactor._timers)
class WeightlessTestCase(TestCase): def setUp(self): self.tempdir = mkdtemp() fd, self.tempfile = mkstemp() os.close(fd) self.reactor = Reactor() self.mockreactor = Reactor(lambda r, w, o, t: (r, w, o)) self.port = randint(2**15, 2**16) def tearDown(self): t0 = time() if hasattr(self, 'httpd') and hasattr(self.httpd, 'shutdown'): self.httpd.shutdown() self.assertEquals({}, self.reactor._readers) self.assertEquals({}, self.reactor._writers) self.assertEquals({}, self.reactor._suspended) #self.assertEquals([], self.reactor._processes) for t in self.reactor._timers: cb = t.callback code = cb.func_code print 'WARNING: dangling timer in reactor. Remaining timout: %s with callback to %s() in %s at line %s.' \ % (t.time-t0, cb.func_name, code.co_filename, code.co_firstlineno) self.assertEquals([], self.reactor._timers) self.reactor.shutdown() rmtree(self.tempdir) os.remove(self.tempfile) def select(self, aString, index): while index < len(aString): char = aString[index] index = index + 1 if not char in string.whitespace: return char, index return '', index def cursor(self, aString, index): return aString[:index - 1] + "---->" + aString[index - 1:] def assertEqualsWS(self, s1, s2): index1 = 0 index2 = 0 while True: char1, index1 = self.select(s1, index1) char2, index2 = self.select(s2, index2) if char1 != char2: self.fail('%s != %s' % (self.cursor(s1, index1), self.cursor(s2, index2))) if not char1 or not char2: break def send(self, host, port, message): sok = socket() sok.connect((host, port)) sok.sendall(message) return sok def httpGet(self, host, port, path): return self.send(host, port, 'GET %(path)s HTTP/1.0\r\n\r\n' % locals()) def httpPost(self, host='localhost', port=None, path='/', data='', contentType='text/plain'): return self.send(host, port or self.port, 'POST %s HTTP/1.0\r\n' % path + 'Content-Type: %s; charset=\"utf-8\"\r\n' % contentType + 'Content-Length: %s\r\n' % len(data) + '\r\n' + data) @contextmanager def loopingReactor(self, timeOutInSec = 3): blockEnd = False timerHasFired = [] def timeOut(): timerHasFired.append(True) timer = self.reactor.addTimer(timeOutInSec, timeOut) def loop(): while not(timerHasFired or blockEnd): t = self.reactor.addTimer(0.01, lambda: None) try: self.reactor.step() finally: try: self.reactor.removeTimer(t) except ValueError: pass thread = Thread(None, loop) thread.start() try: yield finally: blockEnd = True assert not timerHasFired self.reactor.removeTimer(timer) thread.join() @contextmanager def stderr_replaced(self): oldstderr = sys.stderr mockStderr = StringIO() sys.stderr = mockStderr try: yield mockStderr finally: sys.stderr = oldstderr @contextmanager def stdout_replaced(self): oldstdout = sys.stdout mockStdout = StringIO() sys.stdout = mockStdout try: yield mockStdout finally: sys.stdout = oldstdout def referenceHttpServer(self, port, request): def server(httpd): httpd.serve_forever() class Handler(BaseHTTPRequestHandler): def log_message(*args, **kwargs): pass def do_GET(self, *args, **kwargs): request.append({ 'command': self.command, 'path': self.path, 'headers': self.headers}) self.send_response(200, "GET RESPONSE") def do_POST(self, *args, **kwargs): request.append({ 'command': self.command, 'path': self.path, 'headers': self.headers, 'body': self.rfile.read(int(self.headers["Content-Length"]))}) self.send_response(200, "POST RESPONSE") self.httpd = TCPServer(("", port), Handler) thread=Thread(None, lambda: server(self.httpd)) thread.start()
class WeightlessTestCase(TestCase): def setUp(self): self.tempdir = mkdtemp() fd, self.tempfile = mkstemp() os.close(fd) self.reactor = Reactor() self.mockreactor = Reactor(lambda r, w, o, t: (r, w, o)) self.port = randint(2**15, 2**16) def tearDown(self): t0 = time() if hasattr(self, 'httpd') and hasattr(self.httpd, 'shutdown'): self.httpd.shutdown() self.assertEquals({}, self.reactor._readers) self.assertEquals({}, self.reactor._writers) self.assertEquals({}, self.reactor._suspended) #self.assertEquals([], self.reactor._processes) for t in self.reactor._timers: cb = t.callback code = cb.func_code print 'WARNING: dangling timer in reactor. Remaining timout: %s with callback to %s() in %s at line %s.' \ % (t.time-t0, cb.func_name, code.co_filename, code.co_firstlineno) self.assertEquals([], self.reactor._timers) self.reactor.shutdown() rmtree(self.tempdir) os.remove(self.tempfile) def select(self, aString, index): while index < len(aString): char = aString[index] index = index + 1 if not char in string.whitespace: return char, index return '', index def cursor(self, aString, index): return aString[:index - 1] + "---->" + aString[index - 1:] def assertEqualsWS(self, s1, s2): index1 = 0 index2 = 0 while True: char1, index1 = self.select(s1, index1) char2, index2 = self.select(s2, index2) if char1 != char2: self.fail('%s != %s' % (self.cursor(s1, index1), self.cursor(s2, index2))) if not char1 or not char2: break def send(self, host, port, message): sok = socket() sok.connect((host, port)) sok.sendall(message) return sok def httpGet(self, host, port, path): return self.send(host, port, 'GET %(path)s HTTP/1.0\r\n\r\n' % locals()) def httpPost(self, host='localhost', port=None, path='/', data='', contentType='text/plain'): return self.send( host, port or self.port, 'POST %s HTTP/1.0\r\n' % path + 'Content-Type: %s; charset=\"utf-8\"\r\n' % contentType + 'Content-Length: %s\r\n' % len(data) + '\r\n' + data) @contextmanager def loopingReactor(self, timeOutInSec=3): blockEnd = False timerHasFired = [] def timeOut(): timerHasFired.append(True) timer = self.reactor.addTimer(timeOutInSec, timeOut) def loop(): while not (timerHasFired or blockEnd): t = self.reactor.addTimer(0.01, lambda: None) try: self.reactor.step() finally: try: self.reactor.removeTimer(t) except ValueError: pass thread = Thread(None, loop) thread.start() try: yield finally: blockEnd = True assert not timerHasFired self.reactor.removeTimer(timer) thread.join() @contextmanager def stderr_replaced(self): oldstderr = sys.stderr mockStderr = StringIO() sys.stderr = mockStderr try: yield mockStderr finally: sys.stderr = oldstderr @contextmanager def stdout_replaced(self): oldstdout = sys.stdout mockStdout = StringIO() sys.stdout = mockStdout try: yield mockStdout finally: sys.stdout = oldstdout def referenceHttpServer(self, port, request): def server(httpd): httpd.serve_forever() class Handler(BaseHTTPRequestHandler): def log_message(*args, **kwargs): pass def do_GET(self, *args, **kwargs): request.append({ 'command': self.command, 'path': self.path, 'headers': self.headers }) self.send_response(200, "GET RESPONSE") def do_POST(self, *args, **kwargs): request.append({ 'command': self.command, 'path': self.path, 'headers': self.headers, 'body': self.rfile.read(int(self.headers["Content-Length"])) }) self.send_response(200, "POST RESPONSE") self.httpd = TCPServer(("", port), Handler) thread = Thread(None, lambda: server(self.httpd)) thread.start()