From fd32ae68608c6f0113b38bd7c3f27fa288d32b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:46:49 -0300 Subject: [PATCH 1/2] refactor(dbobjutils): reuse only-if matcher for table routing --- perl-xCAT/xCAT/DBobjUtils.pm | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/perl-xCAT/xCAT/DBobjUtils.pm b/perl-xCAT/xCAT/DBobjUtils.pm index 8036e0e5a..f0eeec592 100644 --- a/perl-xCAT/xCAT/DBobjUtils.pm +++ b/perl-xCAT/xCAT/DBobjUtils.pm @@ -1090,17 +1090,12 @@ sub setobjdefs next; } - my $grp_matches_check_value = 0; - foreach my $tmpgrp (@tmplgrplist) { - if ($DBgroupsattr{$tmpgrp}{$check_attr} && $DBgroupsattr{$tmpgrp}{$check_attr} =~ /\b$check_value\b/) { - $grp_matches_check_value = 1; - last; - } - } - - my $obj_val = $objhash{$objname}{$check_attr} || ''; - my $db_val = $DBattrvals{$objname}{$check_attr} || ''; - if (!($obj_val =~ /\b$check_value\b/) && !($db_val =~ /\b$check_value\b/) && !$grp_matches_check_value) { + if (!_only_if_value_matches( + $objhash{$objname}, + $DBattrvals{$objname}, + \%DBgroupsattr, + $check_attr, + $check_value)) { if ($invalidattr->{$attr_name}->{valid} != 1) { $invalidattr->{$attr_name}->{valid} = 0; $invalidattr->{$attr_name}->{condition}=$check_attr; From 8a4fe18cbff8255ab837c17493dfd77eb612b0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:48:15 -0300 Subject: [PATCH 2/2] test(dbobjutils): cover literal only-if routing --- xCAT-test/unit/dbobjutils_only_if.t | 92 +++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/xCAT-test/unit/dbobjutils_only_if.t b/xCAT-test/unit/dbobjutils_only_if.t index b3d0740c8..8f9ffe02e 100644 --- a/xCAT-test/unit/dbobjutils_only_if.t +++ b/xCAT-test/unit/dbobjutils_only_if.t @@ -49,4 +49,96 @@ my %groupattrs = (openbmcgrp => { mgt => 'openbmc' }); @failures = xCAT::DBobjUtils->validate_only_if_attrs('node01', 'node', \%group_openbmc, {}, \%groupattrs); is(scalar @failures, 0, 'group mgt=openbmc satisfies bmc only_if validation'); +{ + package DBobjUtilsOnlyIf::TableRecorder; + + sub setAttribs { + my ($self, $keys, $updates) = @_; + push @{ $self->{writes} }, { + table => $self->{table}, + keys => { %$keys }, + updates => { %$updates }, + }; + return (1, undef); + } + + sub commit { return 1; } +} + +sub check_literal_only_if_routing { + my ($source) = @_; + my @writes; + + local $xCAT::Schema::defspec{routing_fixture} = { + objkey => 'name', + attrhash => {}, + attrs => [ + { + attr_name => 'groups', + tabentry => 'route_source.groups', + access_tabentry => 'route_source.node=attr:name', + }, + { + attr_name => 'selector', + tabentry => 'route_source.selector', + access_tabentry => 'route_source.node=attr:name', + }, + { + attr_name => 'payload', + only_if => 'selector=a.b', + tabentry => 'route_wrong.payload', + access_tabentry => 'route_wrong.node=attr:name', + }, + { + attr_name => 'payload', + only_if => 'selector=axb', + tabentry => 'route_expected.payload', + access_tabentry => 'route_expected.node=attr:name', + }, + ], + }; + + no warnings 'redefine'; + local *xCAT::DBobjUtils::getobjdefs = sub { + my ($class, $objects) = @_; + + return (node01 => { selector => 'axb' }) + if $source eq 'database' && exists $objects->{node01}; + return (literalgroup => { selector => 'axb' }) + if $source eq 'group' && exists $objects->{literalgroup}; + return (); + }; + local *xCAT::Table::getTableSchema = sub { + return { keys => ['node'] }; + }; + local *xCAT::Table::new = sub { + my ($class, $table) = @_; + return bless { + table => $table, + writes => \@writes, + }, 'DBobjUtilsOnlyIf::TableRecorder'; + }; + + my %attrs = ( + objtype => 'routing_fixture', + payload => 'stored', + ); + $attrs{selector} = 'axb' if $source eq 'explicit'; + $attrs{groups} = 'literalgroup' if $source eq 'group'; + + my %objects = (node01 => \%attrs); + my $rc = xCAT::DBobjUtils->setobjdefs(\%objects); + + is($rc, 0, "$source source passes only_if validation"); + my @payload_tables = sort map { $_->{table} } + grep { exists $_->{updates}{payload} } @writes; + is_deeply( + \@payload_tables, + ['route_expected'], + "$source source routes through only the literal-matching only_if entry", + ); +} + +check_literal_only_if_routing($_) for qw(explicit database group); + done_testing();