|
From: <zy...@us...> - 2010-10-06 22:00:30
|
Revision: 7137
http://jython.svn.sourceforge.net/jython/?rev=7137&view=rev
Author: zyasoft
Date: 2010-10-06 22:00:23 +0000 (Wed, 06 Oct 2010)
Log Message:
-----------
Added socket server test (navie multithreaded server, thread pool
using client) to verify that the memory leak for #1662 remains fixed.
Modified Paths:
--------------
trunk/jython/Lib/test/test_threading_jy.py
Added Paths:
-----------
trunk/jython/Lib/test/socketserver_test.py
Added: trunk/jython/Lib/test/socketserver_test.py
===================================================================
--- trunk/jython/Lib/test/socketserver_test.py (rev 0)
+++ trunk/jython/Lib/test/socketserver_test.py 2010-10-06 22:00:23 UTC (rev 7137)
@@ -0,0 +1,59 @@
+# Used by test_threading_jy.py to verify no memory leaks in using a
+# relatively large number of threads. This is of course an absolutely
+# silly way to write real code on the JVM :), use a thread pool. So
+# just for testing.
+#
+# However, the client here does use a thread pool.
+#
+# TODO monitor heap consumption too from appropriate MBean. Then we
+# could presumably be adaptive or something clever like that.
+#
+# Test for http://bugs.jython.org/issue1660
+
+import socket
+import threading
+import SocketServer
+import time
+from java.lang import Runtime
+from java.util.concurrent import Executors, ExecutorCompletionService
+
+class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
+
+ def handle(self):
+ data = self.request.recv(1024)
+ cur_thread = threading.currentThread()
+ response = "%s: %s" % (cur_thread.getName(), data)
+ self.request.send(response)
+
+class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+ "mix together"
+
+def client(ip, port, message):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.connect((ip, port))
+ sock.send(message)
+ response = sock.recv(1024)
+ # print threading.currentThread().getName(), response
+ sock.close()
+
+if __name__ == "__main__":
+ # ephemeral ports should work on every Java system now
+ HOST, PORT = "localhost", 0
+
+ server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
+ ip, port = server.server_address
+
+ # Start a daemon thread with the server -- that thread will then start one
+ # more thread for each request
+ server_thread = threading.Thread(target=server.serve_forever)
+ server_thread.setDaemon(True)
+ server_thread.start()
+
+ # create a client pool to run all client requests
+ pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1)
+ ecs = ExecutorCompletionService(pool)
+ for i in xrange(4000): # empirically, this will exhaust heap when run with 16m heap
+ ecs.submit(lambda: client(ip, port, "Hello World %i" % i))
+ ecs.take() # wait until we have a thread available in the pool
+ pool.shutdown()
+
Modified: trunk/jython/Lib/test/test_threading_jy.py
===================================================================
--- trunk/jython/Lib/test/test_threading_jy.py 2010-10-05 22:26:34 UTC (rev 7136)
+++ trunk/jython/Lib/test/test_threading_jy.py 2010-10-06 22:00:23 UTC (rev 7137)
@@ -4,11 +4,15 @@
"""
from __future__ import with_statement
+import random
+import subprocess
+import sys
+import threading
+import time
import unittest
+
+from subprocess import PIPE, Popen
from test import test_support
-import threading
-import time
-import random
from threading import Condition, Lock, Thread
from java.lang import Thread as JThread, InterruptedException
@@ -84,8 +88,24 @@
self.assertEqual(joined_threads, num_threads)
+class MemoryLeakTestCase(unittest.TestCase):
+ def test_socket_server(self):
+ # run socketserver with a small amount of memory; verify it exits cleanly
+
+
+ rc = subprocess.call([sys.executable,
+ "-J-Xmx32m",
+ test_support.findfile("socketserver_test.py")])
+ # stdout=PIPE)
+ self.assertEquals(rc, 0)
+
+
def test_main():
- test_support.run_unittest(JavaIntegrationTestCase, ThreadingTestCase, TwistedTestCase)
+ test_support.run_unittest(
+ JavaIntegrationTestCase,
+ MemoryLeakTestCase,
+ ThreadingTestCase,
+ TwistedTestCase)
if __name__ == "__main__":
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|