Skip to content

IPv6 changes possibly causing director unit-spec flake(s) #2676

@aramprice

Description

@aramprice

There have been intermittent failures around IP calculations. Most recently:

  1) Bosh::Director::DeploymentPlan::IpRepo allocate_dynamic_ip when existing ips overlap with restricted ips clears similar ips with smaller prefix
     Failure/Error: expect(ip_address).to eq(expected_ip_address)
     
       expected: #<Bosh::Director::IpAddrOrCidr:0x0000738b0c393658 @ipaddr=#<IPAddr: IPv4:192.168.1.13/255.255.255.255>>
            got: #<Bosh::Director::IpAddrOrCidr:0x0000738b0c397730 @ipaddr=#<IPAddr: IPv4:192.168.1.9/255.255.255.255>>
     
       (compared using ==)
     
       Diff:
       @@ -1,2 +1,2 @@
       -#<Bosh::Director::IpAddrOrCidr:0x0000738b0c393658
       - @ipaddr=#<IPAddr: IPv4:192.168.1.13/255.255.255.255>>
       +#<Bosh::Director::IpAddrOrCidr:0x0000738b0c397730
       + @ipaddr=#<IPAddr: IPv4:192.168.1.9/255.255.255.255>>
       
     # ./spec/unit/bosh/director/deployment_plan/ip_provider/ip_repo_spec.rb:299:in `block (4 levels) in <module:DeploymentPlan>'
     # ./spec/spec_helper.rb:67:in `block in reset_database'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/database/transactions.rb:257:in `_transaction'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/database/transactions.rb:239:in `block in transaction'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/connection_pool/timed_queue.rb:90:in `hold'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/database/connecting.rb:283:in `synchronize'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/database/transactions.rb:197:in `transaction'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/core.rb:395:in `block (2 levels) in transaction'
     # /usr/local/bundle/ruby/3.3.0/gems/sequel-5.101.0/lib/sequel/core.rb:403:in `transaction'
     # ./spec/spec_helper.rb:66:in `reset_database'
     # ./spec/spec_helper.rb:156:in `block (2 levels) in <top (required)>'
     # /usr/local/bundle/ruby/3.3.0/gems/webmock-3.26.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'

Finished in 26 minutes 12 seconds (files took 10.41 seconds to load)
7502 examples, 1 failure, 1 pending

Failed examples:

rspec ./spec/unit/bosh/director/deployment_plan/ip_provider/ip_repo_spec.rb:292 # Bosh::Director::DeploymentPlan::IpRepo allocate_dynamic_ip when existing ips overlap with restricted ips clears similar ips with smaller prefix

An AI analysis posited that either #eql? or #hash implementations on IpAddrOrCidr could be at issue.

Looking closer at https://github.com/cloudfoundry/bosh/blob/main/src/bosh-director/lib/bosh/director/ip_addr_or_cidr.rb it looks like the class both delegates, and overrides the following methods:

  • :succ
  • :<=>

The AI analysis suggests that either the #hash or #eql? implementations are impacting the behavior of collection interactions (like reject, sort_by, and Set). The recommendation is either to update #eql? to be:

def eql?(other)
  return false unless other.is_a?(IpAddrOrCidr)
  @ipaddr.eql?(other.instance_variable_get(:@ipaddr))
end

Or to update #hash as follows:

def hash
  [@ipaddr.to_i, @ipaddr.family].hash
end

It seems like perhaps both of these methods should instead be delegated to Ruby's IPAddr but it isn't clear whether or not this is viable in light of the July 2025 changes for IPv6.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Inbox

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions