Skip to content

Commit

Permalink
fix product-line instability
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel committed Dec 4, 2023
1 parent fdeb1a4 commit 8342b63
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
43 changes: 30 additions & 13 deletions unit-tests/py/rspy/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,17 @@ def load_specs_from_file( filename ):
return exceptions


def by_configuration( config, exceptions = None ):
def by_configuration( config, exceptions=None, inclusions=None ):
"""
Yields the serial numbers fitting the given configuration. If configuration includes an 'each' directive
will yield all fitting serial numbers one at a time. Otherwise yields one set of serial numbers fitting the configuration
:param config: A test:device line collection of arguments (e.g., [L515 D400*]) or serial numbers
:param exceptions: A collection of serial-numbers that serve as exceptions that will never get matched
:param inclusions: A collection of serial-numbers from which to match - nothing else will get matched
If no device matches the configuration devices specified, a RuntimeError will be
raised!
If no device matches the configuration devices specified, a RuntimeError will be raised unless
'inclusions' is provided and the configuration is simple, and an empty set yielded to signify.
"""
exceptions = exceptions or set()
# split the current config to two lists:
Expand All @@ -413,33 +414,49 @@ def by_configuration( config, exceptions = None ):
else:
new_config.append(p)

nothing_matched = True
if len( new_config ) > 0 and re.fullmatch( r'each\(.+\)', new_config[0], re.IGNORECASE ):
spec = new_config[0][5:-1]
for sn in by_spec( spec, ignored_products ):
if sn not in exceptions:
yield { sn }
if sn in exceptions:
continue
if inclusions and sn not in inclusions:
continue
nothing_matched = False
yield { sn }
else:
sns = set()
for spec in new_config:
old_len = len(sns)
for sn in by_spec( spec, ignored_products ):
if sn in exceptions:
continue
if inclusions and sn not in inclusions:
continue
if sn not in sns:
sns.add( sn )
break
new_len = len(sns)
if new_len == old_len:
error = 'no device matches configuration "' + spec + '"'
if old_len:
error += ' (after already matching ' + str(sns) + ')'
if ignored_products:
error += ' (!' + str(ignored_products) + ')'
if exceptions:
error += ' (-' + str(exceptions) + ')'
raise RuntimeError( error )
# No new device matches the spec:
# - if no inclusions were specified, this is always an error
# - with inclusions, it's not an error only if it's the only spec
if not inclusions or len(new_config) > 1:
error = 'no device matches configuration "' + spec + '"'
if old_len:
error += ' (after already matching ' + str(sns) + ')'
if ignored_products:
error += ' (!' + str(ignored_products) + ')'
if exceptions:
error += ' (-' + str(exceptions) + ')'
if inclusions:
error += ' (+' + str(inclusions) + ')'
raise RuntimeError( error )
if sns:
nothing_matched = False
yield sns
if nothing_matched and inclusions:
yield set() # let the caller decide how to deal with it


def get_first( sns ):
Expand Down
30 changes: 12 additions & 18 deletions unit-tests/run-unit-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def serial_numbers_to_string( sns ):
return ' '.join( [f'{devices.get(sn).name}_{sn}' for sn in sns] )


def configuration_str( configuration, repetition=1, retry=0, sns=None, prefix='', suffix='' ):
def configuration_str( configuration, repetition=0, retry=0, sns=None, prefix='', suffix='' ):
""" Return a string repr (with a prefix and/or suffix) of the configuration or '' if it's None """
s = ''
if configuration is not None:
Expand Down Expand Up @@ -394,20 +394,11 @@ def devices_by_test_config( test, exceptions ):
global forced_configurations, device_set
for configuration in ( forced_configurations or test.config.configurations ):
try:
for serial_numbers in devices.by_configuration( configuration, exceptions ):
if device_set is not None:
# We're asked to look only at certain devices and ignore configurations that do
# not use them - without any errors!
for sn in serial_numbers:
dev = devices.get(sn)
if dev is not None and dev.serial_number in device_set:
break # Device was asked for; use this config
else:
# No device in the configuration is part of the set that was asked for;
# skip this configuration!
log.d( f'configuration: {configuration} devices do not match --device directive: {serial_numbers_to_string( serial_numbers )}' )
continue
yield configuration, serial_numbers
for serial_numbers in devices.by_configuration( configuration, exceptions, device_set ):
if not serial_numbers:
log.d( 'configuration:', configuration_str( configuration ), 'has no matching device; ignoring' )
else:
yield configuration, serial_numbers
except RuntimeError as e:
if devices.acroname:
log.e( log.red + test.name + log.reset + ': ' + str( e ) )
Expand Down Expand Up @@ -490,9 +481,12 @@ def test_wrapper( test, configuration=None, repetition=1, sns=None ):
sns = set() # convert the list of specs to a list of serial numbers
ignored_list = list()
for spec in device_set:
sns.update( devices.by_spec( spec, ignored_list ) )
included_devices = [sn for sn in devices.by_spec( spec, ignored_list )]
if not included_devices:
log.f( f'No match for --device "{spec}"' )
sns.update( included_devices )
device_set = sns
log.d( f'ignoring any configuration not using --device serial numbers: {" ".join( device_set )}' )
log.d( f'ignoring devices other than: {serial_numbers_to_string( device_set )}' )
#
log.progress()
#
Expand Down Expand Up @@ -575,7 +569,7 @@ def test_wrapper( test, configuration=None, repetition=1, sns=None ):
for configuration, serial_numbers in devices_by_test_config( test, exceptions ):
for repetition in range(repeat):
try:
log.d( 'configuration:', configuration_str( configuration, repetition=repetition, sns=serial_numbers ) )
log.d( 'configuration:', configuration_str( configuration, repetition, sns=serial_numbers ) )
log.debug_indent()
if not no_reset:
devices.enable_only( serial_numbers, recycle=True )
Expand Down

0 comments on commit 8342b63

Please sign in to comment.