~divmod-dev/divmod.org/trunk

« back to all changes in this revision

Viewing changes to Epsilon/epsilon/test/iosim.py

  • Committer: Jean-Paul Calderone
  • Date: 2014-06-29 20:33:04 UTC
  • mfrom: (2749.1.1 remove-epsilon-1325289)
  • Revision ID: exarkun@twistedmatrix.com-20140629203304-gdkmbwl1suei4m97
mergeĀ lp:~exarkun/divmod.org/remove-epsilon-1325289

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
"""Utilities and helpers for simulating a network
3
 
"""
4
 
 
5
 
from cStringIO import StringIO
6
 
 
7
 
from twisted.internet import error
8
 
 
9
 
from epsilon.test import utils
10
 
 
11
 
 
12
 
def readAndDestroy(iodata):
13
 
    try:
14
 
        iodata.seek(0)
15
 
        result = iodata.read()
16
 
        iodata.seek(0)
17
 
        iodata.truncate()
18
 
    except ValueError:
19
 
        print '<bug in FileTransport, early close>'
20
 
        result = ''
21
 
    return result
22
 
 
23
 
 
24
 
class IOPump:
25
 
    """Utility to pump data between clients and servers for protocol testing.
26
 
 
27
 
    Perhaps this is a utility worthy of being in protocol.py?
28
 
    """
29
 
    def __init__(self, client, server, clientIO, serverIO, debug):
30
 
        self.client = client
31
 
        self.server = server
32
 
        self.clientIO = clientIO
33
 
        self.serverIO = serverIO
34
 
        self.debug = debug
35
 
 
36
 
    def flush(self, debug=False):
37
 
        """Pump until there is no more input or output.
38
 
 
39
 
        Returns whether any data was moved.
40
 
        """
41
 
        result = False
42
 
        for x in range(1000):
43
 
            if self.pump(debug):
44
 
                result = True
45
 
            else:
46
 
                break
47
 
        else:
48
 
            assert 0, "Too long"
49
 
        return result
50
 
 
51
 
 
52
 
    def pump(self, debug=False):
53
 
        """Move data back and forth.
54
 
 
55
 
        Returns whether any data was moved.
56
 
        """
57
 
        if self.debug or debug:
58
 
            print '-- GLUG --'
59
 
        sData = readAndDestroy(self.serverIO)
60
 
        cData = readAndDestroy(self.clientIO)
61
 
        self.client.transport._checkProducer()
62
 
        self.server.transport._checkProducer()
63
 
        if self.debug or debug:
64
 
            print '.'
65
 
            # XXX slightly buggy in the face of incremental output
66
 
            if cData:
67
 
                for line in cData.split('\r\n'):
68
 
                    print 'C: '+line
69
 
            if sData:
70
 
                for line in sData.split('\r\n'):
71
 
                    print 'S: '+line
72
 
        if cData:
73
 
            self.server.dataReceived(cData)
74
 
        if sData:
75
 
            self.client.dataReceived(sData)
76
 
        if cData or sData:
77
 
            return True
78
 
        if self.server.transport.disconnecting and not self.server.transport.disconnected:
79
 
            if self.debug or debug:
80
 
                print '* C'
81
 
            self.server.transport.disconnected = True
82
 
            self.client.transport.disconnecting = True
83
 
            self.client.connectionLost(error.ConnectionDone("Connection done"))
84
 
            return True
85
 
        if self.client.transport.disconnecting and not self.client.transport.disconnected:
86
 
            if self.debug or debug:
87
 
                print '* S'
88
 
            self.client.transport.disconnected = True
89
 
            self.server.transport.disconnecting = True
90
 
            self.server.connectionLost(error.ConnectionDone("Connection done"))
91
 
            return True
92
 
        return False
93
 
 
94
 
 
95
 
def connectedServerAndClient(ServerClass, ClientClass,
96
 
                             clientTransportWrapper=utils.FileWrapper,
97
 
                             serverTransportWrapper=utils.FileWrapper,
98
 
                             debug=False):
99
 
    """Returns a 3-tuple: (client, server, pump)
100
 
    """
101
 
    c = ClientClass()
102
 
    s = ServerClass()
103
 
    cio = StringIO()
104
 
    sio = StringIO()
105
 
    c.makeConnection(clientTransportWrapper(cio))
106
 
    s.makeConnection(serverTransportWrapper(sio))
107
 
    pump = IOPump(c, s, cio, sio, debug)
108
 
    # kick off server greeting, etc
109
 
    pump.flush()
110
 
    return c, s, pump