mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@cd1b911
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5ccf36c7ec
commit
2bdce358e6
53 changed files with 319 additions and 426 deletions
|
@ -7,11 +7,12 @@ environment:
|
||||||
install:
|
install:
|
||||||
- SET PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
- SET PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
||||||
- ruby --version
|
- ruby --version
|
||||||
|
- call "C:\Ruby23-x64\DevKit\devkitvars.bat"
|
||||||
- git clone https://github.com/ruby/mspec.git ../mspec
|
- git clone https://github.com/ruby/mspec.git ../mspec
|
||||||
build: off
|
build: off
|
||||||
test_script:
|
test_script:
|
||||||
- SET CHECK_LEAKS=true
|
- SET CHECK_LEAKS=true
|
||||||
- ../mspec/bin/mspec -ff command_line language core library
|
- ../mspec/bin/mspec -ff
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
|
@ -213,22 +213,6 @@ module KernelSpecs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module KernelBlockGiven
|
|
||||||
def self.accept_block
|
|
||||||
Kernel.block_given?
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.accept_block_as_argument(&block)
|
|
||||||
Kernel.block_given?
|
|
||||||
end
|
|
||||||
|
|
||||||
class << self
|
|
||||||
define_method(:defined_block) do
|
|
||||||
Kernel.block_given?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module SelfBlockGiven
|
module SelfBlockGiven
|
||||||
def self.accept_block
|
def self.accept_block
|
||||||
self.send(:block_given?)
|
self.send(:block_given?)
|
||||||
|
|
26
spec/rubyspec/core/kernel/yield_self_spec.rb
Normal file
26
spec/rubyspec/core/kernel/yield_self_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require File.expand_path('../../../spec_helper', __FILE__)
|
||||||
|
|
||||||
|
has_yield_self = VersionGuard.new("2.5").match? || PlatformGuard.implementation?(:truffleruby)
|
||||||
|
|
||||||
|
if has_yield_self
|
||||||
|
describe "Kernel#yield_self" do
|
||||||
|
it "yields self" do
|
||||||
|
object = Object.new
|
||||||
|
object.yield_self { |o| o.should equal object }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the block return value" do
|
||||||
|
object = Object.new
|
||||||
|
object.yield_self { 42 }.should equal 42
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a sized Enumerator when no block given" do
|
||||||
|
object = Object.new
|
||||||
|
enum = object.yield_self
|
||||||
|
enum.should be_an_instance_of Enumerator
|
||||||
|
enum.size.should equal 1
|
||||||
|
enum.peek.should equal object
|
||||||
|
enum.first.should equal object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -300,6 +300,10 @@ describe "String#split with Regexp" do
|
||||||
"AabB".split(/([a-z])+/).should == ["A", "b", "B"]
|
"AabB".split(/([a-z])+/).should == ["A", "b", "B"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "applies the limit to the number of split substrings, without counting captures" do
|
||||||
|
"aBaBa".split(/(B)()()/, 2).should == ["a", "B", "", "", "aBa"]
|
||||||
|
end
|
||||||
|
|
||||||
it "does not include non-matching captures in the result array" do
|
it "does not include non-matching captures in the result array" do
|
||||||
"hello".split(/(el)|(xx)/).should == ["h", "el", "lo"]
|
"hello".split(/(el)|(xx)/).should == ["h", "el", "lo"]
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,9 +8,9 @@ module NetFTPSpecs
|
||||||
# port number
|
# port number
|
||||||
attr_reader :server_port
|
attr_reader :server_port
|
||||||
|
|
||||||
def initialize(hostname = "localhost", server_port = 0)
|
def initialize
|
||||||
@hostname = hostname
|
@hostname = "localhost"
|
||||||
@server = TCPServer.new(@hostname, server_port)
|
@server = TCPServer.new(@hostname, 0)
|
||||||
@server_port = @server.addr[1]
|
@server_port = @server.addr[1]
|
||||||
|
|
||||||
@handlers = {}
|
@handlers = {}
|
||||||
|
|
|
@ -47,7 +47,8 @@ module NetHTTPSpecs
|
||||||
@server_thread = nil
|
@server_thread = nil
|
||||||
|
|
||||||
def port
|
def port
|
||||||
@server ? @server.config[:Port] : 3333
|
raise "server not started" unless @server
|
||||||
|
@server.config[:Port]
|
||||||
end
|
end
|
||||||
|
|
||||||
def start_server
|
def start_server
|
||||||
|
@ -79,9 +80,11 @@ module NetHTTPSpecs
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE
|
||||||
# Because WEBrick is not thread-safe and only catches IOError
|
# Because WEBrick is not thread-safe and only catches IOError
|
||||||
end
|
end
|
||||||
|
@server = nil
|
||||||
end
|
end
|
||||||
if @server_thread
|
if @server_thread
|
||||||
@server_thread.join
|
@server_thread.join
|
||||||
|
@server_thread = nil
|
||||||
end
|
end
|
||||||
timeout = WEBrick::Utils::TimeoutHandler
|
timeout = WEBrick::Utils::TimeoutHandler
|
||||||
timeout.terminate if timeout.respond_to?(:terminate)
|
timeout.terminate if timeout.respond_to?(:terminate)
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
require File.expand_path('../../../spec_helper', __FILE__)
|
require File.expand_path('../../../spec_helper', __FILE__)
|
||||||
|
|
||||||
unless MSpec.retrieve(:features).key?(:readline)
|
begin
|
||||||
begin
|
require 'readline'
|
||||||
require 'readline'
|
rescue LoadError
|
||||||
rescue LoadError
|
else
|
||||||
else
|
# rb-readline behaves quite differently
|
||||||
# rb-readline behaves quite differently
|
unless defined?(RbReadline)
|
||||||
if $".grep(/\brbreadline\.rb$/).empty?
|
MSpec.enable_feature :readline
|
||||||
MSpec.enable_feature :readline
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ require 'socket'
|
||||||
describe "Addrinfo#bind" do
|
describe "Addrinfo#bind" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@addrinfo = Addrinfo.tcp("127.0.0.1", SocketSpecs.port)
|
@addrinfo = Addrinfo.tcp("127.0.0.1", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "Socket::BasicSocket#close_read" do
|
describe "Socket::BasicSocket#close_read" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.port)
|
@server = TCPServer.new(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "Socket::BasicSocket#close_write" do
|
describe "Socket::BasicSocket#close_write" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.port)
|
@server = TCPServer.new(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "BasicSocket.do_not_reverse_lookup" do
|
describe "BasicSocket.do_not_reverse_lookup" do
|
||||||
before :each do
|
before :each do
|
||||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
@socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -21,7 +22,7 @@ describe "BasicSocket.do_not_reverse_lookup" do
|
||||||
it "causes 'peeraddr' to avoid name lookups" do
|
it "causes 'peeraddr' to avoid name lookups" do
|
||||||
@socket.do_not_reverse_lookup = true
|
@socket.do_not_reverse_lookup = true
|
||||||
BasicSocket.do_not_reverse_lookup = true
|
BasicSocket.do_not_reverse_lookup = true
|
||||||
@socket.peeraddr.should == ["AF_INET", SocketSpecs.port, "127.0.0.1", "127.0.0.1"]
|
@socket.peeraddr.should == ["AF_INET", @port, "127.0.0.1", "127.0.0.1"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "looks for hostnames when set to false" do
|
it "looks for hostnames when set to false" do
|
||||||
|
|
|
@ -4,7 +4,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "BasicSocket#for_fd" do
|
describe "BasicSocket#for_fd" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.port)
|
@server = TCPServer.new(0)
|
||||||
@s2 = nil
|
@s2 = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "Socket::BasicSocket#getpeername" do
|
describe "Socket::BasicSocket#getpeername" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@client = TCPSocket.new("127.0.0.1", @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -14,7 +15,7 @@ describe "Socket::BasicSocket#getpeername" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the sockaddr of the other end of the connection" do
|
it "returns the sockaddr of the other end of the connection" do
|
||||||
server_sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
server_sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1")
|
||||||
@client.getpeername.should == server_sockaddr
|
@client.getpeername.should == server_sockaddr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,16 @@ describe "Socket::BasicSocket#getsockname" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the sockaddr associacted with the socket" do
|
it "returns the sockaddr associacted with the socket" do
|
||||||
@socket = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@socket = TCPServer.new("127.0.0.1", 0)
|
||||||
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||||
sockaddr.should == [SocketSpecs.port, "127.0.0.1"]
|
sockaddr.should == [@socket.addr[1], "127.0.0.1"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "works on sockets listening in ipaddr_any" do
|
it "works on sockets listening in ipaddr_any" do
|
||||||
@socket = TCPServer.new(SocketSpecs.port)
|
@socket = TCPServer.new(0)
|
||||||
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||||
["::", "0.0.0.0", "::ffff:0.0.0.0"].include?(sockaddr[1]).should be_true
|
["::", "0.0.0.0", "::ffff:0.0.0.0"].include?(sockaddr[1]).should be_true
|
||||||
sockaddr[0].should == SocketSpecs.port
|
sockaddr[0].should == @socket.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns empty sockaddr for unbinded sockets" do
|
it "returns empty sockaddr for unbinded sockets" do
|
||||||
|
|
|
@ -5,7 +5,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "BasicSocket#recv" do
|
describe "BasicSocket#recv" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
|
@port = @server.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -23,7 +24,7 @@ describe "BasicSocket#recv" do
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
t.status.should_not be_nil
|
t.status.should_not be_nil
|
||||||
|
|
||||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
socket.send('hello', 0)
|
socket.send('hello', 0)
|
||||||
socket.close
|
socket.close
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ describe "BasicSocket#recv" do
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
t.status.should_not be_nil
|
t.status.should_not be_nil
|
||||||
|
|
||||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
socket.send('helloU', Socket::MSG_OOB)
|
socket.send('helloU', Socket::MSG_OOB)
|
||||||
socket.shutdown(1)
|
socket.shutdown(1)
|
||||||
t.join
|
t.join
|
||||||
|
@ -67,7 +68,7 @@ describe "BasicSocket#recv" do
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
t.status.should_not be_nil
|
t.status.should_not be_nil
|
||||||
|
|
||||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
socket.write("firstline\377secondline\377")
|
socket.write("firstline\377secondline\377")
|
||||||
socket.close
|
socket.close
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ describe "BasicSocket#recv" do
|
||||||
|
|
||||||
ruby_version_is "2.3" do
|
ruby_version_is "2.3" do
|
||||||
it "allows an output buffer as third argument" do
|
it "allows an output buffer as third argument" do
|
||||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
socket.write("data")
|
socket.write("data")
|
||||||
|
|
||||||
client = @server.accept
|
client = @server.accept
|
||||||
|
|
|
@ -3,8 +3,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "BasicSocket#send" do
|
describe "BasicSocket#send" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
@socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -74,7 +75,7 @@ describe "BasicSocket#send" do
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
t.status.should_not be_nil
|
t.status.should_not be_nil
|
||||||
|
|
||||||
sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1")
|
||||||
@socket.send('hello', 0, sockaddr).should == 5
|
@socket.send('hello', 0, sockaddr).should == 5
|
||||||
@socket.shutdown # indicate, that we are done sending
|
@socket.shutdown # indicate, that we are done sending
|
||||||
|
|
||||||
|
|
|
@ -23,29 +23,6 @@ module SocketSpecs
|
||||||
Socket.getaddrinfo(host, nil)[0][3]
|
Socket.getaddrinfo(host, nil)[0][3]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_available_port
|
|
||||||
begin
|
|
||||||
s = TCPServer.open(0)
|
|
||||||
port = s.addr[1]
|
|
||||||
s.close
|
|
||||||
port
|
|
||||||
rescue
|
|
||||||
43191
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.port
|
|
||||||
@port ||= find_available_port
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.str_port
|
|
||||||
port.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.local_port
|
|
||||||
find_available_port
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.reserved_unused_port
|
def self.reserved_unused_port
|
||||||
# https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
|
# https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
|
||||||
0
|
0
|
||||||
|
|
|
@ -4,7 +4,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "Socket::IPSocket#addr" do
|
describe "Socket::IPSocket#addr" do
|
||||||
before :each do
|
before :each do
|
||||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||||
@socket = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@socket = TCPServer.new("127.0.0.1", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -17,7 +17,7 @@ describe "Socket::IPSocket#addr" do
|
||||||
BasicSocket.do_not_reverse_lookup = false
|
BasicSocket.do_not_reverse_lookup = false
|
||||||
addrinfo = @socket.addr
|
addrinfo = @socket.addr
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should be_kind_of(Integer)
|
||||||
addrinfo[2].should == SocketSpecs.hostname
|
addrinfo[2].should == SocketSpecs.hostname
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
@ -27,7 +27,7 @@ describe "Socket::IPSocket#addr" do
|
||||||
BasicSocket.do_not_reverse_lookup = true
|
BasicSocket.do_not_reverse_lookup = true
|
||||||
addrinfo = @socket.addr
|
addrinfo = @socket.addr
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should be_kind_of(Integer)
|
||||||
addrinfo[2].should == "127.0.0.1"
|
addrinfo[2].should == "127.0.0.1"
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
@ -35,7 +35,7 @@ describe "Socket::IPSocket#addr" do
|
||||||
it "returns an address in the array if passed false" do
|
it "returns an address in the array if passed false" do
|
||||||
addrinfo = @socket.addr(false)
|
addrinfo = @socket.addr(false)
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should be_kind_of(Integer)
|
||||||
addrinfo[2].should == "127.0.0.1"
|
addrinfo[2].should == "127.0.0.1"
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "Socket::IPSocket#peeraddr" do
|
describe "Socket::IPSocket#peeraddr" do
|
||||||
before :each do
|
before :each do
|
||||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@client = TCPSocket.new("127.0.0.1", @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -23,7 +24,7 @@ describe "Socket::IPSocket#peeraddr" do
|
||||||
BasicSocket.do_not_reverse_lookup = false
|
BasicSocket.do_not_reverse_lookup = false
|
||||||
addrinfo = @client.peeraddr
|
addrinfo = @client.peeraddr
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should == @port
|
||||||
addrinfo[2].should == SocketSpecs.hostname
|
addrinfo[2].should == SocketSpecs.hostname
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
@ -33,7 +34,7 @@ describe "Socket::IPSocket#peeraddr" do
|
||||||
BasicSocket.do_not_reverse_lookup = true
|
BasicSocket.do_not_reverse_lookup = true
|
||||||
addrinfo = @client.peeraddr
|
addrinfo = @client.peeraddr
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should == @port
|
||||||
addrinfo[2].should == "127.0.0.1"
|
addrinfo[2].should == "127.0.0.1"
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
@ -41,7 +42,7 @@ describe "Socket::IPSocket#peeraddr" do
|
||||||
it "returns an IP instead of hostname if passed false" do
|
it "returns an IP instead of hostname if passed false" do
|
||||||
addrinfo = @client.peeraddr(false)
|
addrinfo = @client.peeraddr(false)
|
||||||
addrinfo[0].should == "AF_INET"
|
addrinfo[0].should == "AF_INET"
|
||||||
addrinfo[1].should == SocketSpecs.port
|
addrinfo[1].should == @port
|
||||||
addrinfo[2].should == "127.0.0.1"
|
addrinfo[2].should == "127.0.0.1"
|
||||||
addrinfo[3].should == "127.0.0.1"
|
addrinfo[3].should == "127.0.0.1"
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "Socket::IPSocket#recvfrom" do
|
describe "Socket::IPSocket#recvfrom" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@client = TCPSocket.new("127.0.0.1", @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
describe "partially closable sockets", shared: true do
|
describe "partially closable sockets", shared: true do
|
||||||
specify "if the write end is closed then the other side can read past EOF without blocking" do
|
it "if the write end is closed then the other side can read past EOF without blocking" do
|
||||||
@s1.write("foo")
|
@s1.write("foo")
|
||||||
@s1.close_write
|
@s1.close_write
|
||||||
@s2.read("foo".size + 1).should == "foo"
|
@s2.read("foo".size + 1).should == "foo"
|
||||||
end
|
end
|
||||||
|
|
||||||
specify "closing the write end ensures that the other side can read until EOF" do
|
it "closing the write end ensures that the other side can read until EOF" do
|
||||||
@s1.write("hello world")
|
@s1.write("hello world")
|
||||||
@s1.close_write
|
@s1.close_write
|
||||||
@s2.read.should == "hello world"
|
@s2.read.should == "hello world"
|
||||||
|
|
|
@ -10,7 +10,7 @@ describe :socket_recv_nonblock, shared: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an exception extending IO::WaitReadable if there's no data available" do
|
it "raises an exception extending IO::WaitReadable if there's no data available" do
|
||||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||||
lambda {
|
lambda {
|
||||||
@s1.recv_nonblock(5)
|
@s1.recv_nonblock(5)
|
||||||
}.should raise_error(IO::WaitReadable) { |e|
|
}.should raise_error(IO::WaitReadable) { |e|
|
||||||
|
@ -24,7 +24,7 @@ describe :socket_recv_nonblock, shared: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "receives data after it's ready" do
|
it "receives data after it's ready" do
|
||||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||||
@s2.send("aaa", 0, @s1.getsockname)
|
@s2.send("aaa", 0, @s1.getsockname)
|
||||||
IO.select([@s1], nil, nil, 2)
|
IO.select([@s1], nil, nil, 2)
|
||||||
@s1.recv_nonblock(5).should == "aaa"
|
@s1.recv_nonblock(5).should == "aaa"
|
||||||
|
@ -32,7 +32,7 @@ describe :socket_recv_nonblock, shared: true do
|
||||||
|
|
||||||
ruby_version_is "2.3" do
|
ruby_version_is "2.3" do
|
||||||
it "allows an output buffer as third argument" do
|
it "allows an output buffer as third argument" do
|
||||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||||
@s2.send("data", 0, @s1.getsockname)
|
@s2.send("data", 0, @s1.getsockname)
|
||||||
IO.select([@s1], nil, nil, 2)
|
IO.select([@s1], nil, nil, 2)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ describe :socket_recv_nonblock, shared: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not block if there's no data available" do
|
it "does not block if there's no data available" do
|
||||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||||
@s2.send("a", 0, @s1.getsockname)
|
@s2.send("a", 0, @s1.getsockname)
|
||||||
IO.select([@s1], nil, nil, 2)
|
IO.select([@s1], nil, nil, 2)
|
||||||
@s1.recv_nonblock(1).should == "a"
|
@s1.recv_nonblock(1).should == "a"
|
||||||
|
|
|
@ -5,8 +5,8 @@ include Socket::Constants
|
||||||
|
|
||||||
describe "Socket#bind on SOCK_DGRAM socket" do
|
describe "Socket#bind on SOCK_DGRAM socket" do
|
||||||
before :each do
|
before :each do
|
||||||
@sock = Socket.new(AF_INET, SOCK_DGRAM, 0);
|
@sock = Socket.new(AF_INET, SOCK_DGRAM, 0)
|
||||||
@sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1");
|
@sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -22,30 +22,30 @@ describe "Socket#bind on SOCK_DGRAM socket" do
|
||||||
@sock.bind(@sockaddr).should == 0
|
@sock.bind(@sockaddr).should == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EINVAL when binding to an already bound port" do
|
it "raises Errno::EINVAL when already bound" do
|
||||||
@sock.bind(@sockaddr);
|
@sock.bind(@sockaddr)
|
||||||
|
|
||||||
lambda { @sock.bind(@sockaddr); }.should raise_error(Errno::EINVAL);
|
lambda { @sock.bind(@sockaddr) }.should raise_error(Errno::EINVAL)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
||||||
sockaddr1 = Socket.pack_sockaddr_in(SocketSpecs.port, "4.3.2.1");
|
sockaddr1 = Socket.pack_sockaddr_in(0, "4.3.2.1")
|
||||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EADDRNOTAVAIL)
|
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||||
end
|
end
|
||||||
|
|
||||||
platform_is_not :windows, :cygwin do
|
platform_is_not :windows, :cygwin do
|
||||||
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
||||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1");
|
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1")
|
||||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EACCES)
|
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EACCES)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Socket#bind on SOCK_STREAM socket" do
|
describe "Socket#bind on SOCK_STREAM socket" do
|
||||||
before :each do
|
before :each do
|
||||||
@sock = Socket.new(AF_INET, SOCK_STREAM, 0);
|
@sock = Socket.new(AF_INET, SOCK_STREAM, 0)
|
||||||
@sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, true)
|
@sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, true)
|
||||||
@sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1");
|
@sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -61,21 +61,21 @@ describe "Socket#bind on SOCK_STREAM socket" do
|
||||||
@sock.bind(@sockaddr).should == 0
|
@sock.bind(@sockaddr).should == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EINVAL when binding to an already bound port" do
|
it "raises Errno::EINVAL when already bound" do
|
||||||
@sock.bind(@sockaddr);
|
@sock.bind(@sockaddr)
|
||||||
|
|
||||||
lambda { @sock.bind(@sockaddr); }.should raise_error(Errno::EINVAL);
|
lambda { @sock.bind(@sockaddr) }.should raise_error(Errno::EINVAL)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
||||||
sockaddr1 = Socket.pack_sockaddr_in(SocketSpecs.port, "4.3.2.1");
|
sockaddr1 = Socket.pack_sockaddr_in(0, "4.3.2.1")
|
||||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EADDRNOTAVAIL)
|
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||||
end
|
end
|
||||||
|
|
||||||
platform_is_not :windows, :cygwin do
|
platform_is_not :windows, :cygwin do
|
||||||
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
||||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1");
|
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1")
|
||||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EACCES)
|
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EACCES)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,8 @@ require 'socket'
|
||||||
describe "Socket#connect_nonblock" do
|
describe "Socket#connect_nonblock" do
|
||||||
before :each do
|
before :each do
|
||||||
@hostname = "127.0.0.1"
|
@hostname = "127.0.0.1"
|
||||||
@addr = Socket.sockaddr_in(SocketSpecs.port, @hostname)
|
@server = TCPServer.new(@hostname, 0) # started, but no accept
|
||||||
|
@addr = Socket.sockaddr_in(@server.addr[1], @hostname)
|
||||||
@socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
@socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
||||||
@thread = nil
|
@thread = nil
|
||||||
end
|
end
|
||||||
|
@ -17,27 +18,31 @@ describe "Socket#connect_nonblock" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "connects the socket to the remote side" do
|
it "connects the socket to the remote side" do
|
||||||
ready = false
|
port = nil
|
||||||
|
accept = false
|
||||||
@thread = Thread.new do
|
@thread = Thread.new do
|
||||||
server = TCPServer.new(@hostname, SocketSpecs.port)
|
server = TCPServer.new(@hostname, 0)
|
||||||
ready = true
|
port = server.addr[1]
|
||||||
|
Thread.pass until accept
|
||||||
conn = server.accept
|
conn = server.accept
|
||||||
conn << "hello!"
|
conn << "hello!"
|
||||||
conn.close
|
conn.close
|
||||||
server.close
|
server.close
|
||||||
end
|
end
|
||||||
|
|
||||||
Thread.pass while (@thread.status and @thread.status != 'sleep') or !ready
|
Thread.pass until port
|
||||||
|
|
||||||
|
addr = Socket.sockaddr_in(port, @hostname)
|
||||||
begin
|
begin
|
||||||
@socket.connect_nonblock(@addr)
|
@socket.connect_nonblock(addr)
|
||||||
rescue Errno::EINPROGRESS
|
rescue Errno::EINPROGRESS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
accept = true
|
||||||
IO.select nil, [@socket]
|
IO.select nil, [@socket]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@socket.connect_nonblock(@addr)
|
@socket.connect_nonblock(addr)
|
||||||
rescue Errno::EISCONN
|
rescue Errno::EISCONN
|
||||||
# Not all OS's use this errno, so we trap and ignore it
|
# Not all OS's use this errno, so we trap and ignore it
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,9 @@ require 'socket'
|
||||||
|
|
||||||
describe "Socket.for_fd" do
|
describe "Socket.for_fd" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
@client = TCPSocket.open("127.0.0.1", SocketSpecs.port)
|
@port = @server.addr[1]
|
||||||
|
@client = TCPSocket.open("127.0.0.1", @port)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -14,9 +14,9 @@ describe "Socket.getnameinfo" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets the name information and don't resolve it" do
|
it "gets the name information and don't resolve it" do
|
||||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||||
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
name_info.should == ['127.0.0.1', "3333"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_be_valid_dns_name(name)
|
def should_be_valid_dns_name(name)
|
||||||
|
@ -28,10 +28,10 @@ describe "Socket.getnameinfo" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets the name information and resolve the host" do
|
it "gets the name information and resolve the host" do
|
||||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||||
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICSERV)
|
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICSERV)
|
||||||
should_be_valid_dns_name(name_info[0])
|
should_be_valid_dns_name(name_info[0])
|
||||||
name_info[1].should == SocketSpecs.port.to_s
|
name_info[1].should == 3333.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets the name information and resolves the service" do
|
it "gets the name information and resolves the service" do
|
||||||
|
@ -44,8 +44,8 @@ describe "Socket.getnameinfo" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets a 3-element array and doesn't resolve hostname" do
|
it "gets a 3-element array and doesn't resolve hostname" do
|
||||||
name_info = Socket.getnameinfo(["AF_INET", SocketSpecs.port, '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
name_info = Socket.getnameinfo(["AF_INET", 3333, '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
name_info.should == ['127.0.0.1', "3333"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets a 3-element array and resolves the service" do
|
it "gets a 3-element array and resolves the service" do
|
||||||
|
@ -54,8 +54,8 @@ describe "Socket.getnameinfo" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets a 4-element array and doesn't resolve hostname" do
|
it "gets a 4-element array and doesn't resolve hostname" do
|
||||||
name_info = Socket.getnameinfo(["AF_INET", SocketSpecs.port, 'foo', '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
name_info = Socket.getnameinfo(["AF_INET", 3333, 'foo', '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
name_info.should == ['127.0.0.1', "3333"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets a 4-element array and resolves the service" do
|
it "gets a 4-element array and resolves the service" do
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe "Socket#listen" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "verifies we can listen for incoming connections" do
|
it "verifies we can listen for incoming connections" do
|
||||||
sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||||
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
||||||
@socket.bind(sockaddr)
|
@socket.bind(sockaddr)
|
||||||
@socket.listen(1).should == 0
|
@socket.listen(1).should == 0
|
||||||
|
|
|
@ -5,13 +5,13 @@ require 'socket'
|
||||||
describe "Socket.unpack_sockaddr_in" do
|
describe "Socket.unpack_sockaddr_in" do
|
||||||
|
|
||||||
it "decodes the host name and port number of a packed sockaddr_in" do
|
it "decodes the host name and port number of a packed sockaddr_in" do
|
||||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||||
Socket.unpack_sockaddr_in(sockaddr).should == [SocketSpecs.port, '127.0.0.1']
|
Socket.unpack_sockaddr_in(sockaddr).should == [3333, '127.0.0.1']
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets the hostname and port number from a passed Addrinfo" do
|
it "gets the hostname and port number from a passed Addrinfo" do
|
||||||
addrinfo = Addrinfo.tcp('127.0.0.1', SocketSpecs.port)
|
addrinfo = Addrinfo.tcp('127.0.0.1', 3333)
|
||||||
Socket.unpack_sockaddr_in(addrinfo).should == [SocketSpecs.port, '127.0.0.1']
|
Socket.unpack_sockaddr_in(addrinfo).should == [3333, '127.0.0.1']
|
||||||
end
|
end
|
||||||
|
|
||||||
platform_is_not :windows do
|
platform_is_not :windows do
|
||||||
|
|
|
@ -14,12 +14,12 @@ describe 'Socket.unpack_sockaddr_un' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an ArgumentError when the sin_family is not AF_UNIX' do
|
it 'raises an ArgumentError when the sin_family is not AF_UNIX' do
|
||||||
sockaddr = Socket.sockaddr_in(SocketSpecs.port, '127.0.0.1')
|
sockaddr = Socket.sockaddr_in(0, '127.0.0.1')
|
||||||
lambda { Socket.unpack_sockaddr_un(sockaddr) }.should raise_error(ArgumentError)
|
lambda { Socket.unpack_sockaddr_un(sockaddr) }.should raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an ArgumentError when passed addrinfo is not AF_UNIX' do
|
it 'raises an ArgumentError when passed addrinfo is not AF_UNIX' do
|
||||||
addrinfo = Addrinfo.tcp('127.0.0.1', SocketSpecs.port)
|
addrinfo = Addrinfo.tcp('127.0.0.1', 0)
|
||||||
lambda { Socket.unpack_sockaddr_un(addrinfo) }.should raise_error(ArgumentError)
|
lambda { Socket.unpack_sockaddr_un(addrinfo) }.should raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "Socket::TCPServer.accept_nonblock" do
|
describe "Socket::TCPServer.accept_nonblock" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
|
@port = @server.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -16,13 +17,13 @@ describe "Socket::TCPServer.accept_nonblock" do
|
||||||
@server.accept_nonblock
|
@server.accept_nonblock
|
||||||
}.should raise_error(IO::WaitReadable)
|
}.should raise_error(IO::WaitReadable)
|
||||||
|
|
||||||
c = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
c = TCPSocket.new("127.0.0.1", @port)
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
s = @server.accept_nonblock
|
s = @server.accept_nonblock
|
||||||
|
|
||||||
port, address = Socket.unpack_sockaddr_in(s.getsockname)
|
port, address = Socket.unpack_sockaddr_in(s.getsockname)
|
||||||
|
|
||||||
port.should == SocketSpecs.port
|
port.should == @port
|
||||||
address.should == "127.0.0.1"
|
address.should == "127.0.0.1"
|
||||||
s.should be_kind_of(TCPSocket)
|
s.should be_kind_of(TCPSocket)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "TCPServer#accept" do
|
describe "TCPServer#accept" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
|
@port = @server.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -22,7 +23,7 @@ describe "TCPServer#accept" do
|
||||||
end
|
end
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
|
|
||||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
socket = TCPSocket.new('127.0.0.1', @port)
|
||||||
socket.write('hello')
|
socket.write('hello')
|
||||||
socket.shutdown(1) # we are done with sending
|
socket.shutdown(1) # we are done with sending
|
||||||
socket.read.should == 'goodbye'
|
socket.read.should == 'goodbye'
|
||||||
|
@ -38,14 +39,12 @@ describe "TCPServer#accept" do
|
||||||
|
|
||||||
# kill thread, ensure it dies in a reasonable amount of time
|
# kill thread, ensure it dies in a reasonable amount of time
|
||||||
t.kill
|
t.kill
|
||||||
a = 1
|
a = 0
|
||||||
while a < 2000
|
while t.alive? and a < 5000
|
||||||
break unless t.alive?
|
sleep 0.001
|
||||||
Thread.pass
|
|
||||||
sleep 0.2
|
|
||||||
a += 1
|
a += 1
|
||||||
end
|
end
|
||||||
a.should < 2000
|
a.should < 5000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can be interrupted by Thread#raise" do
|
it "can be interrupted by Thread#raise" do
|
||||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "TCPServer#gets" do
|
describe "TCPServer#gets" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -5,7 +5,7 @@ require 'socket'
|
||||||
|
|
||||||
describe 'TCPServer#listen' do
|
describe 'TCPServer#listen' do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
|
|
@ -7,7 +7,7 @@ describe "TCPServer.new" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds to a host and a port" do
|
it "binds to a host and a port" do
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
addr = @server.addr
|
addr = @server.addr
|
||||||
addr[0].should == 'AF_INET'
|
addr[0].should == 'AF_INET'
|
||||||
addr[1].should be_kind_of(Fixnum)
|
addr[1].should be_kind_of(Fixnum)
|
||||||
|
@ -18,53 +18,52 @@ describe "TCPServer.new" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds to localhost and a port with either IPv4 or IPv6" do
|
it "binds to localhost and a port with either IPv4 or IPv6" do
|
||||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||||
addr = @server.addr
|
addr = @server.addr
|
||||||
|
addr[1].should be_kind_of(Fixnum)
|
||||||
if addr[0] == 'AF_INET'
|
if addr[0] == 'AF_INET'
|
||||||
addr[1].should == SocketSpecs.port
|
|
||||||
addr[2].should =~ /^#{SocketSpecs.hostname}\b/
|
addr[2].should =~ /^#{SocketSpecs.hostname}\b/
|
||||||
addr[3].should == '127.0.0.1'
|
addr[3].should == '127.0.0.1'
|
||||||
else
|
else
|
||||||
addr[1].should == SocketSpecs.port
|
|
||||||
addr[2].should =~ /^#{SocketSpecs.hostnamev6}\b/
|
addr[2].should =~ /^#{SocketSpecs.hostnamev6}\b/
|
||||||
addr[3].should == '::1'
|
addr[3].should == '::1'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds to INADDR_ANY if the hostname is empty" do
|
it "binds to INADDR_ANY if the hostname is empty" do
|
||||||
@server = TCPServer.new('', SocketSpecs.port)
|
@server = TCPServer.new('', 0)
|
||||||
addr = @server.addr
|
addr = @server.addr
|
||||||
addr[0].should == 'AF_INET'
|
addr[0].should == 'AF_INET'
|
||||||
addr[1].should == SocketSpecs.port
|
addr[1].should be_kind_of(Fixnum)
|
||||||
addr[2].should == '0.0.0.0'
|
addr[2].should == '0.0.0.0'
|
||||||
addr[3].should == '0.0.0.0'
|
addr[3].should == '0.0.0.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds to INADDR_ANY if the hostname is empty and the port is a string" do
|
it "binds to INADDR_ANY if the hostname is empty and the port is a string" do
|
||||||
@server = TCPServer.new('', SocketSpecs.port.to_s)
|
@server = TCPServer.new('', 0)
|
||||||
addr = @server.addr
|
addr = @server.addr
|
||||||
addr[0].should == 'AF_INET'
|
addr[0].should == 'AF_INET'
|
||||||
addr[1].should == SocketSpecs.port
|
addr[1].should be_kind_of(Fixnum)
|
||||||
addr[2].should == '0.0.0.0'
|
addr[2].should == '0.0.0.0'
|
||||||
addr[3].should == '0.0.0.0'
|
addr[3].should == '0.0.0.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "coerces port to string, then determines port from that number or service name" do
|
it "coerces port to string, then determines port from that number or service name" do
|
||||||
t = Object.new
|
lambda { TCPServer.new(SocketSpecs.hostname, Object.new) }.should raise_error(TypeError)
|
||||||
lambda { TCPServer.new(SocketSpecs.hostname, t) }.should raise_error(TypeError)
|
|
||||||
|
|
||||||
def t.to_str; SocketSpecs.port.to_s; end
|
port = Object.new
|
||||||
|
port.should_receive(:to_str).and_return("0")
|
||||||
|
|
||||||
@server = TCPServer.new(SocketSpecs.hostname, t)
|
@server = TCPServer.new(SocketSpecs.hostname, port)
|
||||||
addr = @server.addr
|
addr = @server.addr
|
||||||
addr[1].should == SocketSpecs.port
|
addr[1].should be_kind_of(Fixnum)
|
||||||
|
|
||||||
# TODO: This should also accept strings like 'https', but I don't know how to
|
# TODO: This should also accept strings like 'https', but I don't know how to
|
||||||
# pick such a service port that will be able to reliably bind...
|
# pick such a service port that will be able to reliably bind...
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EADDRNOTAVAIL when the adress is unknown" do
|
it "raises Errno::EADDRNOTAVAIL when the adress is unknown" do
|
||||||
lambda { TCPServer.new("1.2.3.4", 4000) }.should raise_error(Errno::EADDRNOTAVAIL)
|
lambda { TCPServer.new("1.2.3.4", 0) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||||
end
|
end
|
||||||
|
|
||||||
# There is no way to make this fail-proof on all machines, because
|
# There is no way to make this fail-proof on all machines, because
|
||||||
|
@ -73,15 +72,15 @@ describe "TCPServer.new" do
|
||||||
quarantine! do
|
quarantine! do
|
||||||
it "raises a SocketError when the host is unknown" do
|
it "raises a SocketError when the host is unknown" do
|
||||||
lambda {
|
lambda {
|
||||||
TCPServer.new("--notavalidname", 4000)
|
TCPServer.new("--notavalidname", 0)
|
||||||
}.should raise_error(SocketError)
|
}.should raise_error(SocketError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises Errno::EADDRINUSE when address is already in use" do
|
it "raises Errno::EADDRINUSE when address is already in use" do
|
||||||
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
lambda {
|
lambda {
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', @server.addr[1])
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
|
||||||
}.should raise_error(Errno::EADDRINUSE)
|
}.should raise_error(Errno::EADDRINUSE)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,7 +88,7 @@ describe "TCPServer.new" do
|
||||||
# A known bug in AIX. getsockopt(2) does not properly set
|
# A known bug in AIX. getsockopt(2) does not properly set
|
||||||
# the fifth argument for SO_REUSEADDR.
|
# the fifth argument for SO_REUSEADDR.
|
||||||
it "sets SO_REUSEADDR on the resulting server" do
|
it "sets SO_REUSEADDR on the resulting server" do
|
||||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
@server = TCPServer.new('127.0.0.1', 0)
|
||||||
@server.getsockopt(:SOCKET, :REUSEADDR).data.should_not == "\x00\x00\x00\x00"
|
@server.getsockopt(:SOCKET, :REUSEADDR).data.should_not == "\x00\x00\x00\x00"
|
||||||
@server.getsockopt(:SOCKET, :REUSEADDR).int.should_not == 0
|
@server.getsockopt(:SOCKET, :REUSEADDR).int.should_not == 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
|
||||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
||||||
|
|
||||||
describe "TCPServer#<<" do
|
|
||||||
after :each do
|
|
||||||
@server.close if @server
|
|
||||||
@socket.close if @socket
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
|
||||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
||||||
|
|
||||||
describe "TCPServer#readpartial" do
|
|
||||||
after :each do
|
|
||||||
@server.close if @server
|
|
||||||
@socket.close if @socket
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,7 +5,8 @@ require 'socket'
|
||||||
|
|
||||||
describe "TCPServer#sysaccept" do
|
describe "TCPServer#sysaccept" do
|
||||||
before :each do
|
before :each do
|
||||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||||
|
@port = @server.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@ -18,7 +19,7 @@ describe "TCPServer#sysaccept" do
|
||||||
|
|
||||||
it 'returns file descriptor of an accepted connection' do
|
it 'returns file descriptor of an accepted connection' do
|
||||||
begin
|
begin
|
||||||
sock = TCPSocket.new(SocketSpecs.hostname, SocketSpecs.port)
|
sock = TCPSocket.new(SocketSpecs.hostname, @port)
|
||||||
|
|
||||||
fd = @server.sysaccept
|
fd = @server.sysaccept
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,8 @@ require File.expand_path('../../shared/partially_closable_sockets', __FILE__)
|
||||||
describe "TCPSocket partial closability" do
|
describe "TCPSocket partial closability" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
port = SocketSpecs.find_available_port
|
@server = TCPServer.new("127.0.0.1", 0)
|
||||||
@server = TCPServer.new("127.0.0.1", port)
|
@s1 = TCPSocket.new("127.0.0.1", @server.addr[1])
|
||||||
@s1 = TCPSocket.new("127.0.0.1", port)
|
|
||||||
@s2 = @server.accept
|
@s2 = @server.accept
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,14 @@ describe :tcpsocket_new, shared: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "connects to a server when passed local_host and local_port arguments" do
|
it "connects to a server when passed local_host and local_port arguments" do
|
||||||
|
server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||||
|
begin
|
||||||
|
available_port = server.addr[1]
|
||||||
|
ensure
|
||||||
|
server.close
|
||||||
|
end
|
||||||
@socket = TCPSocket.send(@method, @hostname, @server.port,
|
@socket = TCPSocket.send(@method, @hostname, @server.port,
|
||||||
@hostname, SocketSpecs.local_port)
|
@hostname, available_port)
|
||||||
@socket.should be_an_instance_of(TCPSocket)
|
@socket.should be_an_instance_of(TCPSocket)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,24 +12,31 @@ describe "UDPSocket.bind" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds the socket to a port" do
|
it "binds the socket to a port" do
|
||||||
@socket.bind(SocketSpecs.hostname, SocketSpecs.port)
|
@socket.bind(SocketSpecs.hostname, 0)
|
||||||
|
@socket.addr[1].should be_kind_of(Integer)
|
||||||
|
end
|
||||||
|
|
||||||
lambda { @socket.bind(SocketSpecs.hostname, SocketSpecs.port) }.should raise_error
|
it "raises Errno::EINVAL when already bound" do
|
||||||
|
@socket.bind(SocketSpecs.hostname, 0)
|
||||||
|
|
||||||
|
lambda {
|
||||||
|
@socket.bind(SocketSpecs.hostname, @socket.addr[1])
|
||||||
|
}.should raise_error(Errno::EINVAL)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "receives a hostname and a port" do
|
it "receives a hostname and a port" do
|
||||||
@socket.bind(SocketSpecs.hostname, SocketSpecs.port)
|
@socket.bind(SocketSpecs.hostname, 0)
|
||||||
|
|
||||||
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||||
|
|
||||||
host.should == "127.0.0.1"
|
host.should == "127.0.0.1"
|
||||||
port.should == SocketSpecs.port
|
port.should == @socket.addr[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "binds to INADDR_ANY if the hostname is empty" do
|
it "binds to INADDR_ANY if the hostname is empty" do
|
||||||
@socket.bind("", SocketSpecs.port)
|
@socket.bind("", 0)
|
||||||
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||||
host.should == "0.0.0.0"
|
host.should == "0.0.0.0"
|
||||||
port.should == SocketSpecs.port
|
port.should == @socket.addr[1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
|
||||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
|
@ -1,2 +0,0 @@
|
||||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
|
||||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
|
@ -3,12 +3,12 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
|
|
||||||
describe "UDPSocket.send" do
|
describe "UDPSocket.send" do
|
||||||
before :each do
|
before :each do
|
||||||
@ready = false
|
@port = nil
|
||||||
@server_thread = Thread.new do
|
@server_thread = Thread.new do
|
||||||
@server = UDPSocket.open
|
@server = UDPSocket.open
|
||||||
begin
|
begin
|
||||||
@server.bind(nil, SocketSpecs.port)
|
@server.bind(nil, 0)
|
||||||
@ready = true
|
@port = @server.addr[1]
|
||||||
begin
|
begin
|
||||||
@msg = @server.recvfrom_nonblock(64)
|
@msg = @server.recvfrom_nonblock(64)
|
||||||
rescue IO::WaitReadable
|
rescue IO::WaitReadable
|
||||||
|
@ -19,12 +19,16 @@ describe "UDPSocket.send" do
|
||||||
@server.close if !@server.closed?
|
@server.close if !@server.closed?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Thread.pass while @server_thread.status and !@ready
|
Thread.pass while @server_thread.status and !@port
|
||||||
|
end
|
||||||
|
|
||||||
|
after :each do
|
||||||
|
@server_thread.join
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends data in ad hoc mode" do
|
it "sends data in ad hoc mode" do
|
||||||
@socket = UDPSocket.open
|
@socket = UDPSocket.open
|
||||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.port)
|
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port)
|
||||||
@socket.close
|
@socket.close
|
||||||
@server_thread.join
|
@server_thread.join
|
||||||
|
|
||||||
|
@ -36,7 +40,7 @@ describe "UDPSocket.send" do
|
||||||
|
|
||||||
it "sends data in ad hoc mode (with port given as a String)" do
|
it "sends data in ad hoc mode (with port given as a String)" do
|
||||||
@socket = UDPSocket.open
|
@socket = UDPSocket.open
|
||||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.str_port)
|
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port.to_s)
|
||||||
@socket.close
|
@socket.close
|
||||||
@server_thread.join
|
@server_thread.join
|
||||||
|
|
||||||
|
@ -48,7 +52,7 @@ describe "UDPSocket.send" do
|
||||||
|
|
||||||
it "sends data in connection mode" do
|
it "sends data in connection mode" do
|
||||||
@socket = UDPSocket.open
|
@socket = UDPSocket.open
|
||||||
@socket.connect(SocketSpecs.hostname, SocketSpecs.port)
|
@socket.connect(SocketSpecs.hostname, @port)
|
||||||
@socket.send("connection-based", 0)
|
@socket.send("connection-based", 0)
|
||||||
@socket.close
|
@socket.close
|
||||||
@server_thread.join
|
@server_thread.join
|
||||||
|
@ -63,10 +67,10 @@ describe "UDPSocket.send" do
|
||||||
@socket = UDPSocket.open
|
@socket = UDPSocket.open
|
||||||
begin
|
begin
|
||||||
lambda do
|
lambda do
|
||||||
@socket.send('1' * 100_000, 0, SocketSpecs.hostname, SocketSpecs.str_port)
|
@socket.send('1' * 100_000, 0, SocketSpecs.hostname, @port.to_s)
|
||||||
end.should raise_error(Errno::EMSGSIZE)
|
end.should raise_error(Errno::EMSGSIZE)
|
||||||
ensure
|
ensure
|
||||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.port)
|
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port)
|
||||||
@socket.close
|
@socket.close
|
||||||
@server_thread.join
|
@server_thread.join
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,11 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
||||||
describe "UDPSocket#write" do
|
describe "UDPSocket#write" do
|
||||||
it "raises EMSGSIZE if msg is too long" do
|
it "raises EMSGSIZE if msg is too long" do
|
||||||
begin
|
begin
|
||||||
host, port = SocketSpecs.hostname, SocketSpecs.port
|
host = SocketSpecs.hostname
|
||||||
s1 = UDPSocket.new
|
s1 = UDPSocket.new
|
||||||
s1.bind(host, port)
|
s1.bind(host, 0)
|
||||||
s2 = UDPSocket.new
|
s2 = UDPSocket.new
|
||||||
s2.connect(host, port)
|
s2.connect(host, s1.addr[1])
|
||||||
|
|
||||||
lambda do
|
lambda do
|
||||||
s2.write('1' * 100_000)
|
s2.write('1' * 100_000)
|
||||||
|
|
|
@ -5,53 +5,50 @@ platform_is_not :windows do
|
||||||
describe "UNIXServer#accept" do
|
describe "UNIXServer#accept" do
|
||||||
before :each do
|
before :each do
|
||||||
@path = SocketSpecs.socket_path
|
@path = SocketSpecs.socket_path
|
||||||
|
@server = UNIXServer.open(@path)
|
||||||
end
|
end
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
|
@server.close if @server
|
||||||
SocketSpecs.rm_socket @path
|
SocketSpecs.rm_socket @path
|
||||||
end
|
end
|
||||||
|
|
||||||
it "accepts what is written by the client" do
|
it "accepts what is written by the client" do
|
||||||
server = UNIXServer.open(@path)
|
|
||||||
client = UNIXSocket.open(@path)
|
client = UNIXSocket.open(@path)
|
||||||
|
|
||||||
client.send('hello', 0)
|
client.send('hello', 0)
|
||||||
|
|
||||||
sock = server.accept
|
sock = @server.accept
|
||||||
data, info = sock.recvfrom(5)
|
begin
|
||||||
|
data, info = sock.recvfrom(5)
|
||||||
|
|
||||||
data.should == 'hello'
|
data.should == 'hello'
|
||||||
info.should_not be_empty
|
info.should_not be_empty
|
||||||
|
ensure
|
||||||
server.close
|
sock.close
|
||||||
client.close
|
client.close
|
||||||
sock.close
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can be interrupted by Thread#kill" do
|
it "can be interrupted by Thread#kill" do
|
||||||
server = UNIXServer.new(@path)
|
|
||||||
t = Thread.new {
|
t = Thread.new {
|
||||||
server.accept
|
@server.accept
|
||||||
}
|
}
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
|
|
||||||
# kill thread, ensure it dies in a reasonable amount of time
|
# kill thread, ensure it dies in a reasonable amount of time
|
||||||
t.kill
|
t.kill
|
||||||
a = 1
|
a = 0
|
||||||
while a < 2000
|
while t.alive? and a < 5000
|
||||||
break unless t.alive?
|
sleep 0.001
|
||||||
Thread.pass
|
|
||||||
sleep 0.2
|
|
||||||
a += 1
|
a += 1
|
||||||
end
|
end
|
||||||
a.should < 2000
|
a.should < 5000
|
||||||
server.close
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can be interrupted by Thread#raise" do
|
it "can be interrupted by Thread#raise" do
|
||||||
server = UNIXServer.new(@path)
|
|
||||||
t = Thread.new {
|
t = Thread.new {
|
||||||
server.accept
|
@server.accept
|
||||||
}
|
}
|
||||||
Thread.pass while t.status and t.status != "sleep"
|
Thread.pass while t.status and t.status != "sleep"
|
||||||
|
|
||||||
|
@ -59,7 +56,6 @@ platform_is_not :windows do
|
||||||
ex = Exception.new
|
ex = Exception.new
|
||||||
t.raise ex
|
t.raise ex
|
||||||
lambda { t.join }.should raise_error(Exception)
|
lambda { t.join }.should raise_error(Exception)
|
||||||
server.close
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#ifndef RUBYSPEC_CAPI_JRUBY_H
|
|
||||||
#define RUBYSPEC_CAPI_JRUBY_H
|
|
||||||
|
|
||||||
/* #undef any HAVE_ defines that JRuby does not have. */
|
|
||||||
#undef HAVE_RB_DEFINE_HOOKED_VARIABLE
|
|
||||||
#undef HAVE_RB_DEFINE_VARIABLE
|
|
||||||
|
|
||||||
#undef HAVE_RB_EXEC_RECURSIVE
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef RUBYSPEC_CAPI_RUBINIUS_H
|
|
||||||
#define RUBYSPEC_CAPI_RUBINIUS_H
|
|
||||||
|
|
||||||
/* #undef any HAVE_ defines that Rubinius does not have. */
|
|
||||||
#undef HAVE_RB_DEFINE_HOOKED_VARIABLE
|
|
||||||
#undef HAVE_RB_DEFINE_VARIABLE
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -595,19 +595,4 @@
|
||||||
/* Util */
|
/* Util */
|
||||||
#define HAVE_RB_SCAN_ARGS 1
|
#define HAVE_RB_SCAN_ARGS 1
|
||||||
|
|
||||||
/* Now, create the differential set. The format of the preprocessor directives
|
|
||||||
* is significant. The alternative implementations should define RUBY because
|
|
||||||
* some extensions depend on that. But only one alternative implementation
|
|
||||||
* macro should be defined at a time. The conditional is structured so that if
|
|
||||||
* no alternative implementation is defined then MRI is assumed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(RUBINIUS)
|
|
||||||
#include "rubinius.h"
|
|
||||||
#elif defined(JRUBY)
|
|
||||||
#include "jruby.h"
|
|
||||||
#elif defined(TRUFFLERUBY)
|
|
||||||
#include "truffleruby.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef RUBYSPEC_CAPI_TRUFFLERUBY_H
|
|
||||||
#undef RUBYSPEC_CAPI_TRUFFLERUBY_H
|
|
||||||
|
|
||||||
// All features are available
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -62,16 +62,18 @@ describe "CApiModule" do
|
||||||
mod = @m.rb_define_module_under(CApiModuleSpecs, "ModuleSpecsModuleUnder2")
|
mod = @m.rb_define_module_under(CApiModuleSpecs, "ModuleSpecsModuleUnder2")
|
||||||
mod.name.should == "CApiModuleSpecs::ModuleSpecsModuleUnder2"
|
mod.name.should == "CApiModuleSpecs::ModuleSpecsModuleUnder2"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_define_module_under" do
|
||||||
|
before :each do
|
||||||
|
compile_extension("module_under_autoload")
|
||||||
|
end
|
||||||
|
|
||||||
it "defines a module for an existing Autoload with an extension" do
|
it "defines a module for an existing Autoload with an extension" do
|
||||||
compile_extension("module_under_autoload")
|
|
||||||
|
|
||||||
CApiModuleSpecs::ModuleUnderAutoload.name.should == "CApiModuleSpecs::ModuleUnderAutoload"
|
CApiModuleSpecs::ModuleUnderAutoload.name.should == "CApiModuleSpecs::ModuleUnderAutoload"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "defines a module for an existing Autoload with a ruby object" do
|
it "defines a module for an existing Autoload with a ruby object" do
|
||||||
compile_extension("module_under_autoload")
|
|
||||||
|
|
||||||
CApiModuleSpecs::RubyUnderAutoload.name.should == "CApiModuleSpecs::RubyUnderAutoload"
|
CApiModuleSpecs::RubyUnderAutoload.name.should == "CApiModuleSpecs::RubyUnderAutoload"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
require File.expand_path('../../../spec_helper', __FILE__)
|
require File.expand_path('../../../spec_helper', __FILE__)
|
||||||
|
|
||||||
|
# MRI magic to use built but not installed ruby
|
||||||
$extmk = false
|
$extmk = false
|
||||||
|
|
||||||
require 'rbconfig'
|
require 'rbconfig'
|
||||||
|
|
||||||
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_NAME}/#{RUBY_VERSION}", __FILE__)
|
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_ENGINE}/#{RUBY_VERSION}", __FILE__)
|
||||||
mkdir_p(OBJDIR)
|
mkdir_p(OBJDIR)
|
||||||
|
|
||||||
def extension_path
|
def extension_path
|
||||||
|
@ -15,130 +17,59 @@ def object_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_extension(name)
|
def compile_extension(name)
|
||||||
preloadenv = RbConfig::CONFIG["PRELOADENV"] || "LD_PRELOAD"
|
debug = false
|
||||||
preload, ENV[preloadenv] = ENV[preloadenv], nil if preloadenv
|
run_mkmf_in_process = RUBY_ENGINE == 'truffleruby'
|
||||||
|
|
||||||
path = extension_path
|
|
||||||
objdir = object_path
|
|
||||||
|
|
||||||
# TODO use rakelib/ext_helper.rb?
|
|
||||||
arch_hdrdir = nil
|
|
||||||
|
|
||||||
if RUBY_NAME == 'rbx'
|
|
||||||
hdrdir = RbConfig::CONFIG["rubyhdrdir"]
|
|
||||||
elsif RUBY_NAME =~ /^ruby/
|
|
||||||
hdrdir = RbConfig::CONFIG["rubyhdrdir"]
|
|
||||||
arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"]
|
|
||||||
elsif RUBY_NAME == 'jruby'
|
|
||||||
require 'mkmf'
|
|
||||||
hdrdir = $hdrdir
|
|
||||||
elsif RUBY_NAME == "maglev"
|
|
||||||
require 'mkmf'
|
|
||||||
hdrdir = $hdrdir
|
|
||||||
elsif RUBY_NAME == 'truffleruby'
|
|
||||||
return compile_truffleruby_extconf_make(name, path, objdir)
|
|
||||||
else
|
|
||||||
raise "Don't know how to build C extensions with #{RUBY_NAME}"
|
|
||||||
end
|
|
||||||
|
|
||||||
ext = "#{name}_spec"
|
|
||||||
source = File.join(path, "#{ext}.c")
|
|
||||||
obj = File.join(objdir, "#{ext}.#{RbConfig::CONFIG['OBJEXT']}")
|
|
||||||
lib = File.join(objdir, "#{ext}.#{RbConfig::CONFIG['DLEXT']}")
|
|
||||||
|
|
||||||
ruby_header = File.join(hdrdir, "ruby.h")
|
|
||||||
rubyspec_header = File.join(path, "rubyspec.h")
|
|
||||||
|
|
||||||
return lib if File.exist?(lib) and File.mtime(lib) > File.mtime(source) and
|
|
||||||
File.mtime(lib) > File.mtime(ruby_header) and
|
|
||||||
File.mtime(lib) > File.mtime(rubyspec_header) and
|
|
||||||
true # sentinel
|
|
||||||
|
|
||||||
# avoid problems where compilation failed but previous shlib exists
|
|
||||||
File.delete lib if File.exist? lib
|
|
||||||
|
|
||||||
cc = RbConfig::CONFIG["CC"]
|
|
||||||
cflags = (ENV["CFLAGS"] || RbConfig::CONFIG["CFLAGS"]).dup
|
|
||||||
cflags += " #{RbConfig::CONFIG["ARCH_FLAG"]}" if RbConfig::CONFIG["ARCH_FLAG"]
|
|
||||||
cflags += " #{RbConfig::CONFIG["CCDLFLAGS"]}" if RbConfig::CONFIG["CCDLFLAGS"]
|
|
||||||
cppflags = (ENV["CPPFLAGS"] || RbConfig::CONFIG["CPPFLAGS"]).dup
|
|
||||||
incflags = "-I#{path}"
|
|
||||||
incflags << " -I#{arch_hdrdir}" if arch_hdrdir
|
|
||||||
incflags << " -I#{hdrdir}"
|
|
||||||
csrcflag = RbConfig::CONFIG["CSRCFLAG"]
|
|
||||||
coutflag = RbConfig::CONFIG["COUTFLAG"]
|
|
||||||
|
|
||||||
compile_cmd = "#{cc} #{incflags} #{cflags} #{cppflags} #{coutflag}#{obj} -c #{csrcflag}#{source}"
|
|
||||||
output = `#{compile_cmd}`
|
|
||||||
|
|
||||||
unless $?.success? and File.exist?(obj)
|
|
||||||
puts "\nERROR:\n#{compile_cmd}\n#{output}"
|
|
||||||
puts "incflags=#{incflags}"
|
|
||||||
puts "cflags=#{cflags}"
|
|
||||||
puts "cppflags=#{cppflags}"
|
|
||||||
raise "Unable to compile \"#{source}\""
|
|
||||||
end
|
|
||||||
|
|
||||||
ldshared = RbConfig::CONFIG["LDSHARED"]
|
|
||||||
ldshared += " #{RbConfig::CONFIG["ARCH_FLAG"]}" if RbConfig::CONFIG["ARCH_FLAG"]
|
|
||||||
libs = RbConfig::CONFIG["LIBS"]
|
|
||||||
dldflags = "#{RbConfig::CONFIG["LDFLAGS"]} #{RbConfig::CONFIG["DLDFLAGS"]} #{RbConfig::CONFIG["EXTDLDFLAGS"]}"
|
|
||||||
dldflags.sub!(/-Wl,-soname,\S+/, '')
|
|
||||||
|
|
||||||
if /mswin/ =~ RUBY_PLATFORM
|
|
||||||
dldflags.sub!("$(LIBPATH)", RbConfig::CONFIG["LIBPATHFLAG"] % path)
|
|
||||||
libs += RbConfig::CONFIG["LIBRUBY"]
|
|
||||||
outflag = RbConfig::CONFIG["OUTFLAG"]
|
|
||||||
|
|
||||||
link_cmd = "#{ldshared} #{outflag}#{lib} #{obj} #{libs} -link #{dldflags} /export:Init_#{ext}"
|
|
||||||
else
|
|
||||||
libpath = "-L#{path}"
|
|
||||||
dldflags.sub!("$(TARGET_ENTRY)", "Init_#{ext}")
|
|
||||||
|
|
||||||
link_cmd = "#{ldshared} #{obj} #{libpath} #{dldflags} #{libs} -o #{lib}"
|
|
||||||
end
|
|
||||||
output = `#{link_cmd}`
|
|
||||||
|
|
||||||
unless $?.success?
|
|
||||||
puts "\nERROR:\n#{link_cmd}\n#{output}"
|
|
||||||
raise "Unable to link \"#{source}\""
|
|
||||||
end
|
|
||||||
|
|
||||||
lib
|
|
||||||
ensure
|
|
||||||
ENV[preloadenv] = preload if preloadenv
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile_truffleruby_extconf_make(name, path, objdir)
|
|
||||||
ext = "#{name}_spec"
|
ext = "#{name}_spec"
|
||||||
file = "#{ext}.c"
|
lib = "#{object_path}/#{ext}.#{RbConfig::CONFIG['DLEXT']}"
|
||||||
source = "#{path}/#{ext}.c"
|
ruby_header = "#{RbConfig::CONFIG['rubyhdrdir']}/ruby.h"
|
||||||
lib = "#{objdir}/#{ext}.#{RbConfig::CONFIG['DLEXT']}"
|
|
||||||
|
return lib if File.exist?(lib) and
|
||||||
|
File.mtime(lib) > File.mtime("#{extension_path}/rubyspec.h") and
|
||||||
|
File.mtime(lib) > File.mtime("#{extension_path}/#{ext}.c") and
|
||||||
|
File.mtime(lib) > File.mtime(ruby_header) and
|
||||||
|
true # sentinel
|
||||||
|
|
||||||
# Copy needed source files to tmpdir
|
# Copy needed source files to tmpdir
|
||||||
tmpdir = tmp("cext_#{name}")
|
tmpdir = tmp("cext_#{name}")
|
||||||
Dir.mkdir tmpdir
|
Dir.mkdir(tmpdir)
|
||||||
begin
|
begin
|
||||||
["rubyspec.h", "truffleruby.h", "#{ext}.c"].each do |file|
|
["rubyspec.h", "#{ext}.c"].each do |file|
|
||||||
cp "#{path}/#{file}", "#{tmpdir}/#{file}"
|
cp "#{extension_path}/#{file}", "#{tmpdir}/#{file}"
|
||||||
end
|
end
|
||||||
|
|
||||||
Dir.chdir(tmpdir) do
|
Dir.chdir(tmpdir) do
|
||||||
required = require 'mkmf'
|
if run_mkmf_in_process
|
||||||
# Reinitialize mkmf if already required
|
required = require 'mkmf'
|
||||||
init_mkmf unless required
|
# Reinitialize mkmf if already required
|
||||||
create_makefile(ext, tmpdir)
|
init_mkmf unless required
|
||||||
system "make"
|
create_makefile(ext, tmpdir)
|
||||||
|
else
|
||||||
copy_exts = RbConfig::CONFIG.values_at('OBJEXT', 'DLEXT')
|
File.write("extconf.rb", "require 'mkmf'\n" +
|
||||||
Dir.glob("*.{#{copy_exts.join(',')}}") do |file|
|
"$ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')\n" +
|
||||||
cp file, "#{objdir}/#{file}"
|
# MRI magic to consider building non-bundled extensions
|
||||||
|
"$extout = nil\n" +
|
||||||
|
"create_makefile(#{ext.inspect})\n")
|
||||||
|
output = ruby_exe("extconf.rb")
|
||||||
|
raise "extconf failed:\n#{output}" unless $?.success?
|
||||||
|
$stderr.puts output if debug
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make = RbConfig::CONFIG['host_os'].include?("mswin") ? "nmake" : "make"
|
||||||
|
ENV.delete "MAKEFLAGS" # Fix make warning when invoked with -j in MRI
|
||||||
|
|
||||||
|
# Do not capture stderr as we want to show compiler warnings
|
||||||
|
output = `#{make} V=1`
|
||||||
|
raise "#{make} failed:\n#{output}" unless $?.success?
|
||||||
|
$stderr.puts output if debug
|
||||||
|
|
||||||
|
cp File.basename(lib), lib
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
rm_r tmpdir
|
rm_r tmpdir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
File.chmod(0755, lib)
|
||||||
lib
|
lib
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -501,7 +501,7 @@ describe "C-API String function" do
|
||||||
describe "rb_str_hash" do
|
describe "rb_str_hash" do
|
||||||
it "hashes the string into a number" do
|
it "hashes the string into a number" do
|
||||||
s = "hello"
|
s = "hello"
|
||||||
@s.rb_str_hash(s).should == s.hash
|
@s.rb_str_hash(s).should be_kind_of(Integer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -165,28 +165,30 @@ describe "CApiTimeSpecs" do
|
||||||
usec.should == 500000
|
usec.should == 500000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timeval for a negative Fixnum" do
|
platform_is_not :mingw32 do
|
||||||
sec, usec = @s.rb_time_timeval(-1232141421)
|
it "creates a timeval for a negative Fixnum" do
|
||||||
sec.should be_kind_of(Integer)
|
sec, usec = @s.rb_time_timeval(-1232141421)
|
||||||
sec.should == -1232141421
|
sec.should be_kind_of(Integer)
|
||||||
usec.should be_kind_of(Integer)
|
sec.should == -1232141421
|
||||||
usec.should == 0
|
usec.should be_kind_of(Integer)
|
||||||
end
|
usec.should == 0
|
||||||
|
end
|
||||||
|
|
||||||
it "creates a timeval for a negative Float" do
|
it "creates a timeval for a negative Float" do
|
||||||
sec, usec = @s.rb_time_timeval(-1.5)
|
sec, usec = @s.rb_time_timeval(-1.5)
|
||||||
sec.should be_kind_of(Integer)
|
sec.should be_kind_of(Integer)
|
||||||
sec.should == -2
|
sec.should == -2
|
||||||
usec.should be_kind_of(Integer)
|
usec.should be_kind_of(Integer)
|
||||||
usec.should == 500000
|
usec.should == 500000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timeval for a negative Rational" do
|
it "creates a timeval for a negative Rational" do
|
||||||
sec, usec = @s.rb_time_timeval(Rational(-3, 2))
|
sec, usec = @s.rb_time_timeval(Rational(-3, 2))
|
||||||
sec.should be_kind_of(Integer)
|
sec.should be_kind_of(Integer)
|
||||||
sec.should == -2
|
sec.should == -2
|
||||||
usec.should be_kind_of(Integer)
|
usec.should be_kind_of(Integer)
|
||||||
usec.should == 500000
|
usec.should == 500000
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timeval from a Time object" do
|
it "creates a timeval from a Time object" do
|
||||||
|
@ -222,28 +224,30 @@ describe "CApiTimeSpecs" do
|
||||||
nsec.should == 500000000
|
nsec.should == 500000000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timespec for a negative Fixnum" do
|
platform_is_not :mingw32 do
|
||||||
sec, nsec = @s.rb_time_timespec(-1232141421)
|
it "creates a timespec for a negative Fixnum" do
|
||||||
sec.should be_kind_of(Integer)
|
sec, nsec = @s.rb_time_timespec(-1232141421)
|
||||||
sec.should == -1232141421
|
sec.should be_kind_of(Integer)
|
||||||
nsec.should be_kind_of(Integer)
|
sec.should == -1232141421
|
||||||
nsec.should == 0
|
nsec.should be_kind_of(Integer)
|
||||||
end
|
nsec.should == 0
|
||||||
|
end
|
||||||
|
|
||||||
it "creates a timespec for a negative Float" do
|
it "creates a timespec for a negative Float" do
|
||||||
sec, nsec = @s.rb_time_timespec(-1.5)
|
sec, nsec = @s.rb_time_timespec(-1.5)
|
||||||
sec.should be_kind_of(Integer)
|
sec.should be_kind_of(Integer)
|
||||||
sec.should == -2
|
sec.should == -2
|
||||||
nsec.should be_kind_of(Integer)
|
nsec.should be_kind_of(Integer)
|
||||||
nsec.should == 500000000
|
nsec.should == 500000000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timespec for a negative Rational" do
|
it "creates a timespec for a negative Rational" do
|
||||||
sec, nsec = @s.rb_time_timespec(Rational(-3, 2))
|
sec, nsec = @s.rb_time_timespec(Rational(-3, 2))
|
||||||
sec.should be_kind_of(Integer)
|
sec.should be_kind_of(Integer)
|
||||||
sec.should == -2
|
sec.should == -2
|
||||||
nsec.should be_kind_of(Integer)
|
nsec.should be_kind_of(Integer)
|
||||||
nsec.should == 500000000
|
nsec.should == 500000000
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a timespec from a Time object" do
|
it "creates a timespec from a Time object" do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue