[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