@ -13,8 +13,10 @@
# limitations under the License.
""" The classes and predicates to assist validate test config for test cases. """
from dataclasses import dataclass
import enum
import logging
import re
from typing import Callable
from typing import Callable , Optional
import unittest
from packaging import version as pkg_version
@ -22,35 +24,75 @@ from packaging import version as pkg_version
from framework import xds_flags
from framework import xds_k8s_flags
logger = logging . getLogger ( __name__ )
def _get_lang ( image_name : str ) - > str :
return re . search ( r ' /( \ w+)-(client|server): ' , image_name ) . group ( 1 )
class Lang ( enum . Flag ) :
UNKNOWN = enum . auto ( )
CPP = enum . auto ( )
GO = enum . auto ( )
JAVA = enum . auto ( )
PYTHON = enum . auto ( )
NODE = enum . auto ( )
def _parse_version ( s : str ) - > pkg_version . Version :
if s . endswith ( " .x " ) :
s = s [ : - 2 ]
return pkg_version . Version ( s )
def __str__ ( self ) :
return str ( self . name ) . lower ( )
@classmethod
def from_string ( cls , lang : str ) :
try :
return cls [ lang . upper ( ) ]
except KeyError :
return cls . UNKNOWN
@dataclass
class TestConfig :
""" Describes the config for the test suite. """
client_lang : str
server_lang : str
version : str
client_lang : Lang
server_lang : Lang
version : Optional [ str ]
def version_ge ( self , another : str ) - > bool :
def version_gt e ( self , another : str ) - > bool :
""" Returns a bool for whether the version is >= another one.
A version is greater than or equal to another version means its version
number is greater than or equal to another version ' s number. Version
" master " is always considered latest . E . g . , master > = v1 .41 . x > = v1 .40 . x
> = v1 .9 . x .
" master " is always considered latest .
E . g . , master > = v1 .41 . x > = v1 .40 . x > = v1 .9 . x .
Unspecified version is treated as ' master ' , but isn ' t explicitly set.
"""
if self . version == ' master ' :
if self . version == ' master ' or self . version is None :
return True
return _parse_version ( self . version ) > = _parse_version ( another )
return self . _parse_version ( self . version ) > = self . _parse_version ( another )
def version_lt ( self , another : str ) - > bool :
""" Returns a bool for whether the version is < another one.
Version " master " is always considered latest .
E . g . , v1 .9 . x < v1 .40 . x < v1 .41 . x < master .
Unspecified version is treated as ' master ' , but isn ' t explicitly set.
"""
if self . version == ' master ' or self . version is None :
return False
return self . _parse_version ( self . version ) < self . _parse_version ( another )
def __str__ ( self ) :
return ( f " TestConfig(client_lang= ' { self . client_lang } ' , "
f " server_lang= ' { self . server_lang } ' , version= { self . version !r} ) " )
@staticmethod
def _parse_version ( s : str ) - > pkg_version . Version :
if s . endswith ( " .x " ) :
s = s [ : - 2 ]
return pkg_version . Version ( s )
def _get_lang ( image_name : str ) - > Lang :
return Lang . from_string (
re . search ( r ' /( \ w+)-(client|server): ' , image_name ) . group ( 1 ) )
def evaluate_test_config ( check : Callable [ [ TestConfig ] , bool ] ) - > None :
@ -64,4 +106,7 @@ def evaluate_test_config(check: Callable[[TestConfig], bool]) -> None:
server_lang = _get_lang ( xds_k8s_flags . SERVER_IMAGE . value ) ,
version = xds_flags . TESTING_VERSION . value )
if not check ( test_config ) :
logger . info ( ' Skipping %s ' , test_config )
raise unittest . SkipTest ( f ' Unsupported test config: { test_config } ' )
logger . info ( ' Detected language and version: %s ' , test_config )