1- #!/usr/bin/env python2
1+ #!/usr/bin/env python3
22
33import docker
44import unittest
88# Regex patterns used for testing
99
1010# Checks if TLS 1.3 was negotiated
11- RE_PATTERN_HELLO_TLS_13_NORESUME = "^.*Hello TLS 1.3 \(draft .*\) _o/$|^.*Hello TLS 1.3 _o/$"
11+ RE_PATTERN_HELLO_TLS_13_NORESUME = r "^.*Hello TLS 1.3 \(draft .*\) _o/$|^.*Hello TLS 1.3 _o/$"
1212# Checks if TLS 1.3 was resumed
13- RE_PATTERN_HELLO_TLS_13_RESUME = "Hello TLS 1.3 \[resumed\] _o/"
13+ RE_PATTERN_HELLO_TLS_13_RESUME = r "Hello TLS 1.3 \[resumed\] _o/"
1414# Checks if 0-RTT was used and NOT confirmed
15- RE_PATTERN_HELLO_0RTT = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT\] _o/$"
15+ RE_PATTERN_HELLO_0RTT = r "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT\] _o/$"
1616# Checks if 0-RTT was used and confirmed
17- RE_PATTERN_HELLO_0RTT_CONFIRMED = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT confirmed\] _o/$"
17+ RE_PATTERN_HELLO_0RTT_CONFIRMED = r "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT confirmed\] _o/$"
1818# ALPN
1919RE_PATTERN_ALPN = "ALPN protocol: npn_proto$"
2020# Successful TLS establishement from TRIS
@@ -27,27 +27,47 @@ class Docker(object):
2727 def __init__ (self ):
2828 self .d = docker .from_env ()
2929
30+ def close (self ):
31+ self .d .close ()
32+
3033 def get_ip (self , server ):
3134 tris_localserver_container = self .d .containers .get (server )
3235 return tris_localserver_container .attrs ['NetworkSettings' ]['IPAddress' ]
3336
3437 def run_client (self , image_name , cmd ):
3538 ''' Runs client and returns tuple (status_code, logs) '''
36- c = self .d .containers .create (image = image_name , command = cmd )
37- c .start ()
39+ c = self .d .containers .run (image = image_name , detach = True , command = cmd )
3840 res = c .wait ()
39- ret = c .logs ()
41+ ret = c .logs (). decode ( 'utf8' )
4042 c .remove ()
4143 return (res ['StatusCode' ], ret )
4244
4345 def run_server (self , image_name , cmd = None , ports = None , entrypoint = None ):
4446 ''' Starts server and returns docker container '''
45- c = self .d .containers .create (image = image_name , detach = True , command = cmd , ports = ports , entrypoint = entrypoint )
46- c .start ()
47- # TODO: maybe can be done better?
48- time .sleep (3 )
47+ c = self .d .containers .run (image = image_name , auto_remove = True , detach = True , command = cmd , ports = ports , entrypoint = entrypoint )
48+ self .wait_for_ports (c )
4949 return c
5050
51+ def wait_for_ports (self , c ):
52+ ''' Waits until all services from the image are ready. '''
53+ check_ports = set (int (portproto .split ('/' )[0 ]) for portproto in c .attrs ['NetworkSettings' ]['Ports' ])
54+ for i in range (0 , 100 ):
55+ # 'ss -Htln' is the modern form, but boringssl image only includes
56+ # netstat (via busybox).
57+ info = c .exec_run ('sh -c "ss -Htln 2>/dev/null || netstat -tln"' )
58+ if info .exit_code != 0 :
59+ print ('Unable to check for open ports, sleeping for a fixed time' )
60+ time .sleep (3 )
61+ return
62+ tcp_listen_info = [line for line in info .output .decode ('utf8' ).splitlines () if 'LISTEN' in line ]
63+ if tcp_listen_info :
64+ tcp_ports = set (int (line .split ()[3 ].split (':' )[- 1 ]) for line in tcp_listen_info )
65+ check_ports -= tcp_ports
66+ if not check_ports :
67+ return
68+ time .sleep (.1 )
69+ print ('WARNING: services from %s are not ready, missing %s' % (c .image . check_ports ))
70+
5171class RegexSelfTest (unittest .TestCase ):
5272 ''' Ensures that those regexe's actually work '''
5373
@@ -100,7 +120,7 @@ def setUpClass(self):
100120 @classmethod
101121 def tearDownClass (self ):
102122 self .server .kill ()
103- self .server . remove ()
123+ self .d . close ()
104124
105125 @property
106126 def server_ip (self ):
@@ -195,13 +215,13 @@ def setUpClass(self):
195215 self .d = Docker ()
196216 self .server = self .d .run_server (
197217 self .SERVER_NAME ,
198- ports = { '1443/tcp' : 1443 , '2443/tcp' : 2443 , '6443/tcp' : 6443 , '7443/tcp' : 7443 },
218+ ports = { '1443/tcp' : None , '2443/tcp' : None , '6443/tcp' : None , '7443/tcp' : None },
199219 entrypoint = "/server.sh" )
200220
201221 @classmethod
202222 def tearDownClass (self ):
203223 self .server .kill ()
204- self .server . remove ()
224+ self .d . close ()
205225
206226 @property
207227 def server_ip (self ):
0 commit comments