Issue #8159 has been updated by naruse (Yui NARUSE).


I create an experimental patch as following for failures on Linux:
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20130324T210202Z.log.html.gz

diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 1ddaea9..44703c1 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -1585,7 +1585,9 @@ socket_s_ip_address_list(VALUE self)
     for (p = ifp; p; p = p->ifa_next) {
         if (p->ifa_addr != NULL && IS_IP_FAMILY(p->ifa_addr->sa_family)) {
             struct sockaddr *addr = p->ifa_addr;
-            rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
+            ai = sockaddr_obj(addr, sockaddr_len(addr));
+            rb_ivar_set(ai, rb_intern("@ifa_name"), rb_str_new_cstr(p->ifa_name));
+            rb_ary_push(list, ai);
         }
     }
 
@@ -1856,6 +1858,12 @@ socket_s_ip_address_list(VALUE self)
 #define socket_s_ip_address_list rb_f_notimplement
 #endif
 
+VALUE
+sock_s_if_nametoindex(VALUE klass, VALUE name)
+{
+    return UINT2NUM(if_nametoindex(StringValueCStr(name)));
+}
+
 void
 Init_socket()
 {
@@ -1999,6 +2007,7 @@ Init_socket()
     rb_define_singleton_method(rb_cSocket, "gethostbyaddr", sock_s_gethostbyaddr, -1);
     rb_define_singleton_method(rb_cSocket, "getservbyname", sock_s_getservbyname, -1);
     rb_define_singleton_method(rb_cSocket, "getservbyport", sock_s_getservbyport, -1);
+    rb_define_singleton_method(rb_cSocket, "if_nametoindex", sock_s_if_nametoindex, 1);
     rb_define_singleton_method(rb_cSocket, "getaddrinfo", sock_s_getaddrinfo, -1);
     rb_define_singleton_method(rb_cSocket, "getnameinfo", sock_s_getnameinfo, -1);
     rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2);
diff --git a/lib/rinda/ring.rb b/lib/rinda/ring.rb
index 9b3e273..b87800c 100644
--- a/lib/rinda/ring.rb
+++ b/lib/rinda/ring.rb
@@ -59,6 +59,8 @@ module Rinda
       end
     end
 
+    attr_accessor :multicast_interface
+
     ##
     # Advertises +ts+ on the given +addresses+ at +port+.
     #
@@ -84,6 +86,7 @@ module Rinda
 
       @w_services = write_services
       @r_service  = reply_service
+      @multicast_interface = 0
     end
 
     ##
@@ -111,6 +114,9 @@ module Rinda
           mreq = IPAddr.new(addrinfo.ip_address).hton + [0].pack('I')
 
           socket.setsockopt(:IPPROTO_IPV6, :IPV6_JOIN_GROUP, mreq)
+          sa = addrinfo.to_sockaddr
+          sa[-4, 4] = [@multicast_interface].pack('I')
+          addrinfo = Addrinfo.new(sa)
         end
       end
 
diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb
index 65df228..9aaeb66 100644
--- a/test/rinda/test_rinda.rb
+++ b/test/rinda/test_rinda.rb
@@ -525,7 +525,24 @@ class TupleSpaceProxyTest < Test::Unit::TestCase
   @server = DRb.primary_server || DRb.start_service
 end
 
+module RingIPv6
+  def prepare_ipv6(r)
+    Socket.ip_address_list.any? do |addrinfo|
+      if addrinfo.ipv6? && ipv6_global_unicast?(addrinfo)
+        r.multicast_interface = Socket.if_nametoindex(addrinfo.instance_variable_get(:@ifa_name))
+        return
+      end
+    end
+    skip 'IPv6 not available'
+  end
+
+  def ipv6_global_unicast?(ai)
+    (ai.ip_address[0].to_i & 0b1110) == 0b0010
+  end
+end
+
 class TestRingServer < Test::Unit::TestCase
+  include RingIPv6
 
   def setup
     @port = Rinda::Ring_PORT
@@ -560,14 +577,8 @@ class TestRingServer < Test::Unit::TestCase
   end
 
   def test_make_socket_ipv6_multicast
-    skip 'IPv6 not available' unless
-      Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? }
-
-    begin
-      v6mc = @rs.make_socket('ff02::1')
-    rescue Errno::EADDRNOTAVAIL
-      return # IPv6 address for multicast not available
-    end
+    prepare_ipv6(@rs)
+    v6mc = @rs.make_socket('ff02::1')
 
     if Socket.const_defined?(:SO_REUSEPORT) then
       assert v6mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool
@@ -575,7 +586,7 @@ class TestRingServer < Test::Unit::TestCase
       assert v6mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool
     end
 
-    assert_equal('ff02::1',  v6mc.local_address.ip_address)
+    assert_match(/\Aff02::1(?:%|\z)/,  v6mc.local_address.ip_address)
     assert_equal(@port, v6mc.local_address.ip_port)
   end
 
@@ -588,22 +599,10 @@ class TestRingServer < Test::Unit::TestCase
 end
 
 class TestRingFinger < Test::Unit::TestCase
+  include RingIPv6
 
   def setup
     @rf = Rinda::RingFinger.new
-    ifindex = nil
-    10.times do |i|
-      begin
-        addrinfo = Addrinfo.udp('ff02::1', Rinda::Ring_PORT)
-        soc = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol)
-        soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_IF,
-                       [i].pack('I'))
-        ifindex = i
-        break
-      rescue
-      end
-    end
-    @rf.multicast_interface = ifindex
   end
 
   def test_make_socket_unicast
@@ -620,26 +619,23 @@ class TestRingFinger < Test::Unit::TestCase
   end
 
   def test_make_socket_ipv6_multicast
-    skip 'IPv6 not available' unless
-      Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? }
-
+    prepare_ipv6(@rf)
     v6mc = @rf.make_socket('ff02::1')
 
     assert_equal(1, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_LOOP).int)
     assert_equal(1, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS).int)
   end
 
-  def test_make_socket_multicast_hops
+  def test_make_socket_ipv4_multicast_hops
     @rf.multicast_hops = 2
-
     v4mc = @rf.make_socket('239.0.0.1')
-
     assert_equal(2, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).int)
+  end
 
-    return unless Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? }
-
+  def test_make_socket_ipv6_multicast_hops
+    prepare_ipv6(@rf)
+    @rf.multicast_hops = 2
     v6mc = @rf.make_socket('ff02::1')
-
     assert_equal(2, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS).int)
   end
 
----------------------------------------
Bug #8159: Build failure introduced by Rinda changes
https://bugs.ruby-lang.org/issues/8159#change-37914

Author: luislavena (Luis Lavena)
Status: Assigned
Priority: Normal
Assignee: drbrain (Eric Hodel)
Category: test
Target version: next minor
ruby -v: ruby 2.1.0dev (2013-03-24 trunk 39905) [x64-mingw32]


=begin

Seems latest Rinda-related changes affected build under Windows:

http://ci.rubyinstaller.org/job/ruby-trunk-x64-test-all/936/console

   2) Error:
 test_take_bug_8215(Rinda::TupleSpaceProxyTest):
 NotImplementedError: fork() function is unimplemented on this machine
     C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/rinda/test_rinda.rb:486:in `fork'
     C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/rinda/test_rinda.rb:486:in `test_take_bug_8215'

   3) Error:
 test_make_socket_ipv4_multicast(Rinda::TestRingServer):
 Errno::EADDRNOTAVAIL: The requested address is not valid in its context. - bind(2)
     C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/lib/rinda/ring.rb:117:in `bind'
     C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/lib/rinda/ring.rb:117:in `make_socket'
     C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/rinda/test_rinda.rb:542:in `test_make_socket_ipv4_multicast'

r39895 seems to have introduced a test that is not skipping on non-fork() platforms.

=end


-- 
http://bugs.ruby-lang.org/