SF.net SVN: jython:[7137] trunk/jython/Lib/test

[email protected] Wed, 06 Oct 2010 22:00:24 +0000
Newsgroups gmane.comp.lang.jython.cvs
Message-ID <[email protected]>
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.

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb