[Python-checkins] r46810 - in sandbox/trunk/pdb: README.txt mconnection.py mpdb.py test test/tcptest.py

matt.fleming python-checkins at python.org
Sat Jun 10 03:14:26 CEST 2006


Author: matt.fleming
Date: Sat Jun 10 03:14:26 2006
New Revision: 46810

Added:
   sandbox/trunk/pdb/test/
   sandbox/trunk/pdb/test/tcptest.py
Modified:
   sandbox/trunk/pdb/README.txt
   sandbox/trunk/pdb/mconnection.py
   sandbox/trunk/pdb/mpdb.py
Log:
Added a unit test for the connection library. Worked a 'generic' output
method into the MPdb class and changed the abstract classes for both the
MClientConnectionInterface and MServerConnectionInterface so that they must
implemented a read() and write() method on the connection.


Modified: sandbox/trunk/pdb/README.txt
==============================================================================
--- sandbox/trunk/pdb/README.txt	(original)
+++ sandbox/trunk/pdb/README.txt	Sat Jun 10 03:14:26 2006
@@ -9,7 +9,7 @@
 aims to correct this wish.
 
 -=[TODO]=-
-* Write unittests
+* Write more unit tests
 * sort out the namespace corruption - 
 	 """
          c:\soc\pdb\test.py(3)x()

Modified: sandbox/trunk/pdb/mconnection.py
==============================================================================
--- sandbox/trunk/pdb/mconnection.py	(original)
+++ sandbox/trunk/pdb/mconnection.py	Sat Jun 10 03:14:26 2006
@@ -35,6 +35,18 @@
         """
         raise NotImplementedError, NotImplementedMessage
 
+    def write(self, msg):
+        """ This method is used to write to a debugger that is
+        connected to this server.
+        """
+        raise NotImplementedError, NotImplementedMessage
+
+    def read(self, bufsize=1024):
+        """ This method is reads a maximum of 'bufsize' bytes from a
+        connected debugger.
+        """
+        raise NotImplementedError, NotImplementedMessage
+
 class MClientConnectionInterface(object):
     """ This is the interface that a client connection should implement.
     """
@@ -42,6 +54,20 @@
         """ This method is called by a debugger to connect to a server. """
         raise NotImplementedError, NotImplementedMessage
 
+
+    def write(self, msg):
+        """ This method is called by a debugger to write 'msg' to the
+        server it is connected to.
+        """
+        raise NotImplementedError, NotImplementedMessage
+
+
+    def read(self, bufsize=1024):
+        """ This method reads a maximum of 'bufsize' bytes from the connection
+        to the server.
+        """
+        raise NotImplementedError, NotImplementedMessage
+    
     def disconnect(self):
         """ This method is called by a debugger to disconnect from a
         server.
@@ -67,6 +93,12 @@
     def accept(self, debugger, addr):
         pass
 
+    def write(self, msg):
+        self.output.write(msg)
+
+    def read(self, bufsize=1024):
+        return self.input.read()
+
     def disconnect(self):
         self.output.close()
         self.input.close()
@@ -94,15 +126,24 @@
         self.listen()
         
     def listen(self):
-        self._sock.listen(5)
+        """ This method is not usually called except by this object's
+        setup() method.
+        """
+        self._sock.listen(1)
         debugger, addr = self._sock.accept()
         self.accept(debugger, addr)
 
     def accept(self, debugger, addr):
-        self.output = debugger.makefile('w')
+        self.output = debugger
+        self.input = debugger
+
+    def write(self, msg):
+        self.output.sendall(msg)
 
+    def read(self, bufsize=1024):
+        return self.input.recv(bufsize)
+    
     def disconnect(self):
-        self.output.flush()
         self.output.close()
         self._sock.close()
 
@@ -117,7 +158,6 @@
         self._dev = device
         self.input = None
         self.output = None
-        self.setup()
 
     def setup(self):
         """ Create our fileobject by opening the serial device for
@@ -140,15 +180,20 @@
         h, p = addr.split(':')
         self.host = h
         self.port = int(p)
-        self.setup()
 
     def setup(self):
-        """ Connect to the server. """
+        """ Connect to the server. 'input' reads data from the
+        server. 'output' writes data to the server.
+        """
         self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self._sock.connect((self.host, self.port))
-        self.output = self._sock.makefile('w')
 
+    def write(self, msg):
+        self._sock.send(msg)
+
+    def read(self, bufsize=1024):
+        return self._sock.recv(bufsize)
+    
     def disconnect(self):
         """ Close the socket to the server. """
-        self.output.close()
         self._sock.close()

Modified: sandbox/trunk/pdb/mpdb.py
==============================================================================
--- sandbox/trunk/pdb/mpdb.py	(original)
+++ sandbox/trunk/pdb/mpdb.py	Sat Jun 10 03:14:26 2006
@@ -4,7 +4,8 @@
 # Student: Matthew J. Fleming
 # Mentor: Robert L. Bernstein
 """
-This module provides improvements over the Python Debugger (Pdb).
+This module provides improvements over the Python Debugger (Pdb) by building
+on the work done by Rocky Bernstein in The Extended Python Debugger.
 This module allows,
 
 - debugging of applications running in a separate process to the debugger
@@ -15,16 +16,14 @@
 
 import os
 from optparse import OptionParser
-import pdb
+import pydb
 import socket
 import sys
 import traceback
 
-# Need custom safe Repr just like pdb
-_saferepr = pdb._repr.repr
 line_prefix = '\n-> '
 
-class MPdb(pdb.Pdb):
+class MPdb(pydb.Pdb):
     """ This class extends the command set and functionality of the
     Python debugger and provides support for,
 
@@ -42,17 +41,15 @@
         specify alternate input and output file objects; if not specified,
         sys.stdin and sys.stdout are used.
         """
-        pdb.Pdb.__init__(self, completekey, stdin, stdout)
+        pydb.Pdb.__init__(self, completekey, stdin, stdout)
         self.prompt = '(MPdb)'
 
     def _rebind_input(self, new_input):
 	""" This method rebinds the debugger's input to the object specified
 	by 'new_input'.
 	"""
-        self.raw_input = 1
         self.stdin.flush()
 	self.stdin = new_input
-        self.stdin.flush()
 
     def  _rebind_output(self, new_output):
 	""" This method rebinds the debugger's output to the object specified
@@ -60,7 +57,21 @@
 	"""
         self.stdout.flush()
         self.stdout = new_output
-        self.stdout.flush()
+
+    def msg_nocr(self, msg, out=None):
+        """Common routine for reporting messages (no carriage return).
+        Derived classed may want to override this to capture output.
+        """
+        do_print = True
+        if self.logging:
+            if self.logging_fileobj is not None:
+                print >> self.logging_fileobj, msg,
+            do_print = not self.logging_redirect
+        if do_print:
+            if out is None:
+                out = self.stdout
+            print >> out, msg,
+            out.flush()
 
     # Debugger commands
     def do_attach(self, addr):
@@ -88,9 +99,7 @@
 List of target subcommands:
 
 target serial -- Use a remote computer via a serial line
-target tcp -- Use a remote computer via a TCP connection
-target udp -- Use a remote computer via a UDP connection
-target xml -- Use a remote computer via the xmlrpc lib
+target socket -- Use a remote computer via a socket connection
 """
         cls, addr = args.split(' ')
         if '.' in cls:
@@ -99,7 +108,7 @@
             exec 'from ' + base + ' import ' + cls
         else:
             __import__(cls)
-        self.connection = eval(mod+'(addr)')
+        self.connection = eval(cls+'(addr)')
         self.connection.setup()
         # XXX currently this method doesn't do anything
 

Added: sandbox/trunk/pdb/test/tcptest.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/pdb/test/tcptest.py	Sat Jun 10 03:14:26 2006
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+import os
+import sys
+import socket
+import time
+import unittest
+
+__addr__ = 'localhost:8000'
+
+sys.path.append("..")
+from mconnection import MServerConnectionTCP, MClientConnectionTCP
+
+class TestTCPConnections(unittest.TestCase):
+    def testClientConnectAndRead(self):
+        # We need to exercise finer control over the server's socket so we're
+        # not using the setup() method.
+        self.client = MClientConnectionTCP(__addr__)
+        self.server = MServerConnectionTCP(__addr__)
+        self.server._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.server._sock.bind((self.server.host, self.server.port))
+        self.server._sock.listen(1)
+        pid = os.fork()
+        for i in range(30):
+            try:
+                self.client.setup()
+                break
+            except socket.error:
+                pass
+            time.sleep(5)
+        debugger, addr = self.server._sock.accept()
+        self.server.accept(debugger, addr)
+        self.server.write("good")
+        line = self.client.read()
+        self.assertEqual("good", line, "Could not read from server")
+        self.client.disconnect()
+        self.server.disconnect()
+
+
+        
+if __name__ == '__main__':
+    unittest.main()


More information about the Python-checkins mailing list