# $tree ... rados osd tree (passing the tree makes it easy to test)
sub osd_belongs_to_node {
my ($tree, $nodename, $osdid) = @_;
+ return 0 if !($tree && $tree->{nodes});
- die "No tree nodes found\n" if !($tree && $tree->{nodes});
- my $allNodes = $tree->{nodes};
+ my $node_map = {};
+ for my $el (grep { defined($_->{type}) && $_->{type} eq 'host' } @{$tree->{nodes}}) {
+ my $name = $el->{name};
+ die "internal error: duplicate host name found '$name'\n" if $node_map->{$name};
+ $node_map->{$name} = $el;
+ }
- my @match = grep($_->{name} eq $nodename, @$allNodes);
- my $node = shift @match; # contains rados information about $nodename
- die "There must not be more than one such node in the list" if @match;
+ my $osds = $node_map->{$nodename}->{children};
+ return 0 if !$osds;
- my $osds = $node->{children};
return grep($_ == $osdid, @$osds);
}
use Data::Dumper;
+# NOTE: not exhausive, reduced to actually required fields!
my $tree = {
nodes => [
{
id => -3,
name => 'pveA',
children => [ 0,1,2,3 ],
- }, {
+ type => 'host',
+ },
+ {
id => -5,
name => 'pveB',
children => [ 4,5,6,7 ],
- }, {
+ type => 'host',
+ },
+ {
id => -7,
name => 'pveC',
children => [ 8,9,10,11 ],
+ type => 'host',
},
],
};
nodes => [
{
name => 'pveA',
+ type => 'host',
},
{
name => 'pveA',
+ type => 'host',
}
]
};
eval { PVE::API2::Ceph::OSD::osd_belongs_to_node($double_nodes_tree, 'pveA') };
-like($@, qr/not be more than one/, "Die if node occurs too often");
+like($@, qr/duplicate host name found/, "Die if node occurs too often");
-my $tree_without_nodes = {
- dummy => 'dummy',
-};
-eval { PVE::API2::Ceph::OSD::osd_belongs_to_node(undef) };
-like($@, qr/No tree nodes/, "Die if tree has no nodes");
+is (
+ PVE::API2::Ceph::OSD::osd_belongs_to_node(undef),
+ 0,
+ "Early-return false if there's no/empty node tree",
+);
-done_testing(@belong_to_B + @not_belong_to_B + 2);
\ No newline at end of file
+done_testing(@belong_to_B + @not_belong_to_B + 2);