@@ -97,13 +97,18 @@ def _is_unsupported(self, lines: List[str]) -> bool:
9797 "exit status 127" in str (line ) for line in lines
9898 )
9999
100- def _check_impl_is_compliant (self , name : str ) -> bool :
101- """check if an implementation return UNSUPPORTED for unknown test cases"""
102- if name in self .compliant :
100+ def _check_impl_is_compliant (self , name : str , role : Perspective ) -> bool :
101+ """Check if an implementation returns UNSUPPORTED for unknown test cases. """
102+ if name in self .compliant and role in self . compliant [ name ] :
103103 logging .debug (
104- "%s already tested for compliance: %s" , name , str (self .compliant )
104+ "%s already tested for %s compliance: %s" ,
105+ name ,
106+ role .name .lower (),
107+ str (self .compliant [name ][role ]),
105108 )
106- return self .compliant [name ]
109+ return self .compliant [name ][role ]
110+
111+ self .compliant .setdefault (name , {})
107112
108113 client_log_dir = tempfile .TemporaryDirectory (dir = "/tmp" , prefix = "logs_client_" )
109114 www_dir = tempfile .TemporaryDirectory (dir = "/tmp" , prefix = "compliance_www_" )
@@ -114,60 +119,65 @@ def _check_impl_is_compliant(self, name: str) -> bool:
114119
115120 testcases .generate_cert_chain (certs_dir .name )
116121
117- # check that the client is capable of returning UNSUPPORTED
118- logging .debug ("Checking compliance of %s client" , name )
119- cmd = (
120- "CERTS=" + certs_dir .name + " "
121- "TESTCASE_CLIENT=" + generate_slug () + " "
122- "SERVER_LOGS=/dev/null "
123- "CLIENT_LOGS=" + client_log_dir .name + " "
124- "WWW=" + www_dir .name + " "
125- "DOWNLOADS=" + downloads_dir .name + " "
126- 'SCENARIO="simple-p2p --delay=15ms --bandwidth=10Mbps --queue=25" '
127- "CLIENT=" + self ._implementations [name ]["image" ] + " "
128- "SERVER="
129- + self ._implementations [name ]["image" ]
130- + " " # only needed so docker compose doesn't complain
131- "docker compose --env-file empty.env up --timeout 0 --abort-on-container-exit -V sim client"
132- )
133- output = subprocess .run (
134- cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
135- )
136- if not self ._is_unsupported (output .stdout .splitlines ()):
137- logging .error ("%s client not compliant." , name )
138- logging .debug ("%s" , output .stdout .decode ("utf-8" , errors = "replace" ))
139- self .compliant [name ] = False
140- return False
141- logging .debug ("%s client compliant." , name )
142-
143- # check that the server is capable of returning UNSUPPORTED
144- logging .debug ("Checking compliance of %s server" , name )
145- server_log_dir = tempfile .TemporaryDirectory (dir = "/tmp" , prefix = "logs_server_" )
146- cmd = (
147- "CERTS=" + certs_dir .name + " "
148- "TESTCASE_SERVER=" + generate_slug () + " "
149- "SERVER_LOGS=" + server_log_dir .name + " "
150- "CLIENT_LOGS=/dev/null "
151- "WWW=" + www_dir .name + " "
152- "DOWNLOADS=" + downloads_dir .name + " "
153- "CLIENT="
154- + self ._implementations [name ]["image" ]
155- + " " # only needed so docker compose doesn't complain
156- "SERVER=" + self ._implementations [name ]["image" ] + " "
157- "docker compose --env-file empty.env up -V server"
158- )
159- output = subprocess .run (
160- cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
161- )
162- if not self ._is_unsupported (output .stdout .splitlines ()):
163- logging .error ("%s server not compliant." , name )
164- logging .debug ("%s" , output .stdout .decode ("utf-8" , errors = "replace" ))
165- self .compliant [name ] = False
166- return False
167- logging .debug ("%s server compliant." , name )
168-
169- # remember compliance test outcome
170- self .compliant [name ] = True
122+ if role == Perspective .CLIENT :
123+ # check that the client is capable of returning UNSUPPORTED
124+ logging .debug ("Checking compliance of %s client" , name )
125+ cmd = (
126+ "CERTS=" + certs_dir .name + " "
127+ "TESTCASE_CLIENT=" + generate_slug () + " "
128+ "SERVER_LOGS=/dev/null "
129+ "CLIENT_LOGS=" + client_log_dir .name + " "
130+ "WWW=" + www_dir .name + " "
131+ "DOWNLOADS=" + downloads_dir .name + " "
132+ 'SCENARIO="simple-p2p --delay=15ms --bandwidth=10Mbps --queue=25" '
133+ "CLIENT=" + self ._implementations [name ]["image" ] + " "
134+ "SERVER="
135+ + self ._implementations [name ]["image" ]
136+ + " " # only needed so docker compose doesn't complain
137+ "docker compose --env-file empty.env up --timeout 0 --abort-on-container-exit -V sim client"
138+ )
139+ output = subprocess .run (
140+ cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
141+ )
142+ if not self ._is_unsupported (output .stdout .splitlines ()):
143+ logging .error ("%s client not compliant." , name )
144+ logging .debug ("%s" , output .stdout .decode ("utf-8" , errors = "replace" ))
145+ self .compliant [name ][role ] = False
146+ return False
147+ logging .debug ("%s client compliant." , name )
148+ elif role == Perspective .SERVER :
149+ # check that the server is capable of returning UNSUPPORTED
150+ logging .debug ("Checking compliance of %s server" , name )
151+ server_log_dir = tempfile .TemporaryDirectory (
152+ dir = "/tmp" , prefix = "logs_server_"
153+ )
154+ cmd = (
155+ "CERTS=" + certs_dir .name + " "
156+ "TESTCASE_SERVER=" + generate_slug () + " "
157+ "SERVER_LOGS=" + server_log_dir .name + " "
158+ "CLIENT_LOGS=/dev/null "
159+ "WWW=" + www_dir .name + " "
160+ "DOWNLOADS=" + downloads_dir .name + " "
161+ "CLIENT="
162+ + self ._implementations [name ]["image" ]
163+ + " " # only needed so docker compose doesn't complain
164+ "SERVER=" + self ._implementations [name ]["image" ] + " "
165+ "docker compose --env-file empty.env up -V server"
166+ )
167+ output = subprocess .run (
168+ cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
169+ )
170+ if not self ._is_unsupported (output .stdout .splitlines ()):
171+ logging .error ("%s server not compliant." , name )
172+ logging .debug ("%s" , output .stdout .decode ("utf-8" , errors = "replace" ))
173+ self .compliant [name ][role ] = False
174+ return False
175+ logging .debug ("%s server compliant." , name )
176+ else :
177+ raise ValueError (f"Unknown perspective for compliance check: { role } " )
178+
179+ # remember compliance test outcome for this role
180+ self .compliant [name ][role ] = True
171181 return True
172182
173183 def _postprocess_results (self ):
@@ -535,8 +545,8 @@ def run(self):
535545 self ._implementations [client ]["image" ],
536546 )
537547 if not (
538- self ._check_impl_is_compliant (server )
539- and self ._check_impl_is_compliant (client )
548+ self ._check_impl_is_compliant (server , Perspective . SERVER )
549+ and self ._check_impl_is_compliant (client , Perspective . CLIENT )
540550 ):
541551 logging .info ("Not compliant, skipping" )
542552 continue
0 commit comments