2121# Run the C examples and verify that they behave as expected.
2222# Example executables must be in PATH
2323
24+ import socket
25+ import subprocess
2426import unittest
2527
2628from test_subprocess import Popen , Server , TestProcessError , check_output
2729
28- MESSAGES = 10
30+ MESSAGES = 10
2931
30- def receive_expect_messages (n = MESSAGES ): return '' .join (['{"sequence"=%s}\n ' % i for i in range (1 , n + 1 )])
31- def receive_expect_total (n = MESSAGES ): return "%s messages received\n " % n
32- def receive_expect (n = MESSAGES ): return receive_expect_messages (n )+ receive_expect_total (n )
32+
33+ def receive_expect_messages (n = MESSAGES ): return '' .join (['{"sequence"=%s}\n ' % i for i in range (1 , n + 1 )])
34+ def receive_expect_total (n = MESSAGES ): return "%s messages received\n " % n
35+ def receive_expect (n = MESSAGES ): return receive_expect_messages (n ) + receive_expect_total (n )
3336def send_expect (n = MESSAGES ): return "%s messages sent and acknowledged\n " % n
3437def send_abort_expect (n = MESSAGES ): return "%s messages started and aborted\n " % n
3538
39+
3640class Broker (Server ):
3741 def __init__ (self ):
3842 super (Broker , self ).__init__ (["broker" , "" , "0" ], kill_me = True )
3943
44+
4045class ExampleTest (unittest .TestCase ):
4146
42- def runex (self , name , port , messages = MESSAGES ):
47+ def runex (self , name , port , messages : int = MESSAGES ) -> str :
4348 """Run an example with standard arguments, return output"""
4449 return check_output ([name , "" , port , "xtest" , str (messages )])
4550
46- def startex (self , name , port , messages = MESSAGES ):
51+ def startex (self , name , port , messages : int = MESSAGES ) -> Popen :
4752 """Start an example sub-process with standard arguments"""
4853 return Popen ([name , "" , port , "xtest" , str (messages )])
4954
@@ -68,7 +73,7 @@ class ExampleTest(unittest.TestCase):
6873
6974 def test_receive_direct (self ):
7075 """Receive from direct server"""
71- d = Server (["direct" , "" , "0" ])
76+ d = Server (["direct" , "" , "0" ])
7277 self .assertMultiLineEqual (receive_expect (), self .runex ("receive" , d .port ))
7378 self .assertEqual ("10 messages sent and acknowledged\n " , d .communicate ()[0 ])
7479
@@ -80,16 +85,16 @@ class ExampleTest(unittest.TestCase):
8085 for i in range (MESSAGES ):
8186 self .assertEqual ("Message aborted\n " , b .stdout .readline ())
8287 self .assertEqual (send_expect (), self .runex ("send" , b .port ))
83- expect = receive_expect_messages (MESSAGES )+ receive_expect_messages (MESSAGES )+ receive_expect_total (20 )
84- self .assertMultiLineEqual (expect , self .runex ("receive" , b .port , "20" ))
88+ expect = receive_expect_messages (MESSAGES ) + receive_expect_messages (MESSAGES ) + receive_expect_total (20 )
89+ self .assertMultiLineEqual (expect , self .runex ("receive" , b .port , 20 ))
8590
8691 def test_send_abort_direct (self ):
8792 """Send aborted messages to the direct server"""
8893 d = Server (["direct" , "" , "0" , "examples" , "20" ])
8994 self .assertEqual (send_expect (), self .runex ("send" , d .port ))
9095 self .assertEqual (send_abort_expect (), self .runex ("send-abort" , d .port ))
9196 self .assertEqual (send_expect (), self .runex ("send" , d .port ))
92- expect = receive_expect_messages () + "Message aborted\n " * MESSAGES + receive_expect_messages ()+ receive_expect_total (20 )
97+ expect = receive_expect_messages () + "Message aborted\n " * MESSAGES + receive_expect_messages () + receive_expect_total (20 )
9398 self .maxDiff = None
9499 self .assertMultiLineEqual (expect , d .communicate ()[0 ])
95100
@@ -107,5 +112,41 @@ class ExampleTest(unittest.TestCase):
107112 else :
108113 raise
109114
115+ def test_raw_connect (self ):
116+ message = b"At thee! Have at thee!\n "
117+
118+ with Server (["./raw_echo" , "" , "0" ], kill_me = True ) as server :
119+ client = subprocess .Popen (args = ["./raw_connect" , "" , server .port ],
120+ stdin = subprocess .PIPE , stdout = subprocess .PIPE )
121+ client .stdin .write (message )
122+ client .stdin .flush ()
123+ stdout , _ = client .communicate ()
124+
125+ expected_brief = b'**raw connection connected\n ' + message + b'**raw connection disconnected\n '
126+ expected_polite = b'**raw connection connected\n ' + message + b'** Goodbye ****raw connection disconnected\n '
127+
128+ expected = expected_polite if b'Goodbye' in stdout else expected_brief
129+
130+ self .assertEqual (expected , stdout )
131+ self .assertEqual (client .returncode , 0 )
132+
133+ def test_raw_echo (self ):
134+ """raw_echo example implements a TCP echo server"""
135+ message = b"Hello world\n "
136+
137+ with Server (["./raw_echo" , "" , "0" ], kill_me = True ) as server :
138+ s = socket .socket ()
139+ s .connect (("localhost" , int (server .port )))
140+ s .sendall (message )
141+
142+ data = b""
143+ while len (data ) != len (message ):
144+ buf = s .recv (1024 )
145+ data += buf
146+
147+ self .assertEqual (message , data )
148+ s .close ()
149+
150+
110151if __name__ == "__main__" :
111152 unittest .main ()
0 commit comments