On 6/23/26 10:47 AM, Ales Musil wrote:
> The update_test() function only remapped hardcoded
> table=NUMBER values in the range [LOG_EGRESS_PIPELINE,
> SAVE_INPORT).  Tables beyond SAVE_INPORT, such as
> CHK_LB_AFFINITY (78 -> 102), were not patched.  This
> caused all LB affinity upgrade tests to fail when
> upgrading from branch-24.03 because the old test files
> use hardcoded table=78 while the new ovn-controller
> puts learned flows in table 102.
> 
> Keep the range-based shift for in-pipeline tables
> [LOG_EGRESS, SAVE_INPORT) since tests use hardcoded
> offsets within the pipeline, and add exact remapping
> for every OFTABLE_ define that changed outside
> that range.
> 
> Fixes: 9b2645580c78 ("ci: Run system tests in upgrade scenario.")
> Assisted-by: Claude Opus 4.6, OpenCode
> Signed-off-by: Ales Musil <[email protected]>
> ---

Hi Ales,

Thanks for the fix!

>  .ci/ovn_upgrade_utils.py | 77 ++++++++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 23 deletions(-)
> 
> diff --git a/.ci/ovn_upgrade_utils.py b/.ci/ovn_upgrade_utils.py
> index f5ae787cb..982bf440b 100755
> --- a/.ci/ovn_upgrade_utils.py
> +++ b/.ci/ovn_upgrade_utils.py
> @@ -410,14 +410,28 @@ def ovn_upgrade_save_ovn_debug(binaries_dir):
>      return True
>  
>  
> -def update_test(old_start, old_end, shift, test_file):
> +def _parse_oftable_defines(lines):
> +    """Return {name: int_value} for all OFTABLE_ #defines."""
> +    result = {}
> +    for line in lines:
> +        parts = line.split()
> +        if len(parts) >= 3 and parts[0] == '#define' \
> +                and parts[1].startswith('OFTABLE_'):
> +            try:
> +                result[parts[1]] = int(parts[2])

Nit: I think this breaks on stuff like:

#define OFTABLE_BLAH_VERY_LOOOOONG_NAME \
    42

But we shouldn't try to roll out a full C parser here so maybe it's fine
to leave it as is.  It was already the case in ovn_upgrade_extract_info().

> +            except ValueError:
> +                pass
> +    return result
> +
> +
> +def update_test(table_remap, test_file):
>      with open(test_file, encoding='utf-8') as f:
>          content = f.read()
>  
>      def replace_table(match):
>          table_num = int(match.group(1))
> -        if old_start <= table_num < old_end:
> -            return f"table={table_num + shift}"
> +        if table_num in table_remap:
> +            return f"table={table_remap[table_num]}"
>          return match.group(0)
>  
>      # Replace all table=NUMBER patterns
> @@ -430,44 +444,61 @@ def update_test(old_start, old_end, shift, test_file):
>  def ovn_upgrade_table_numbers_in_tests_patch(config):
>      lflow_h = Path('controller/lflow.h')
>  
> -    if not config.file.new_egress.exists():
> -        log("No LOG_EGRESS")
> +    if not config.file.ofctl_defines.exists():
> +        log("No ofctl defines file")
>          return False
>  
>      if not lflow_h.exists():
>          log("Controller/lflow.h not found")
>          return False
>  
> -    with open(config.file.new_egress, encoding='utf-8') as f:
> -        new_log_egress = int(f.read().strip())
> +    # Get new OFTABLE values (saved from the current version).
> +    with open(config.file.ofctl_defines, encoding='utf-8') as f:
> +        new_defines = _parse_oftable_defines(f.readlines())
>  
> -    # Get old values from base version's lflow.h
> +    # Get old OFTABLE values from the base version's lflow.h.
>      with open(lflow_h, encoding='utf-8') as f:
> -        content = [
> -            line.strip() for line in f if line.startswith('#define OFTABLE_')
> -        ]
> +        old_defines = _parse_oftable_defines(f.readlines())
>  
> -    old_log_egress, old_save_inport = extract_oftable_values(content)
> +    old_log_egress, old_save_inport = extract_oftable_values(
> +        [f"#define {k} {v}" for k, v in old_defines.items()])

This feels like over-engineering it TBH.  Isn't this simpler and also
correct?

old_log_egress = old_defines.get('OFTABLE_LOG_EGRESS_PIPELINE')
old_save_inport = old_defines.get('OFTABLE_SAVE_INPORT')

With this addressed, the rest looks good to me, thanks!

Acked-by: Dumitru Ceara <[email protected]>

Regards,
Dumitru

>  
> -    if (not old_log_egress or not old_save_inport
> -            or old_log_egress == new_log_egress):
> -        log(f"No change in test files as old_log_egress={old_log_egress}, "
> -            f"old_save_inport={old_save_inport} and "
> -            f"new_log_egress={new_log_egress}")
> -        # No change needed is success.
> -        return True
> +    if not old_log_egress or not old_save_inport:
> +        log("Could not extract LOG_EGRESS / SAVE_INPORT from base")
> +        return False
> +
> +    new_log_egress = new_defines.get('OFTABLE_LOG_EGRESS_PIPELINE')
> +
> +    # Build {old_value: new_value} remap for all changed tables.
> +    table_remap = {}
>  
> -    shift = new_log_egress - old_log_egress
> +    # Range-based shift for in-pipeline tables [LOG_EGRESS, SAVE_INPORT).
> +    # These include hardcoded offsets that are not OFTABLE_ defines.
> +    if new_log_egress and new_log_egress != old_log_egress:
> +        shift = new_log_egress - old_log_egress
> +        for t in range(old_log_egress, old_save_inport):
> +            table_remap[t] = t + shift
> +
> +    # Exact remap for every OFTABLE_ define that changed and is
> +    # outside the pipeline range (e.g. CHK_LB_AFFINITY, ECMP_NH).
> +    for name, old_val in old_defines.items():
> +        if name in new_defines and new_defines[name] != old_val:
> +            if old_val not in table_remap:
> +                table_remap[old_val] = new_defines[name]
> +
> +    if not table_remap:
> +        log("No table number changes detected")
> +        return True
>  
> -    log(f"Updating hardcoded table numbers in tests (shift: +{shift} for "
> -        f"tables {old_log_egress}-{old_save_inport - 1})")
> +    log(f"Updating hardcoded table numbers in tests "
> +        f"({len(table_remap)} table(s) remapped)")
>  
>      # Update test files
>      for test_file in ['tests/system-ovn.at', 'tests/system-ovn-kmod.at',
>                        'tests/system-ovn-netlink.at']:
>          if Path(test_file).exists():
>              log(f"Updating {test_file}")
> -            update_test(old_log_egress, old_save_inport, shift, test_file)
> +            update_test(table_remap, test_file)
>      return True
>  
>  

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to