summaryrefslogtreecommitdiff
path: root/spec/ruby/library/socket/shared
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/library/socket/shared')
-rw-r--r--spec/ruby/library/socket/shared/address.rb249
-rw-r--r--spec/ruby/library/socket/shared/pack_sockaddr.rb67
-rw-r--r--spec/ruby/library/socket/shared/partially_closable_sockets.rb2
-rw-r--r--spec/ruby/library/socket/shared/recv_nonblock.rb54
-rw-r--r--spec/ruby/library/socket/shared/socketpair.rb115
5 files changed, 59 insertions, 428 deletions
diff --git a/spec/ruby/library/socket/shared/address.rb b/spec/ruby/library/socket/shared/address.rb
deleted file mode 100644
index f3be9cfb99..0000000000
--- a/spec/ruby/library/socket/shared/address.rb
+++ /dev/null
@@ -1,249 +0,0 @@
-require_relative '../fixtures/classes'
-
-describe :socket_local_remote_address, shared: true do
- describe 'using TCPSocket' do
- before :each do
- @s = TCPServer.new('127.0.0.1', 0)
- @a = TCPSocket.new('127.0.0.1', @s.addr[1])
- @b = @s.accept
- @addr = @object.call(@a)
- end
-
- after :each do
- [@b, @a, @s].each(&:close)
- end
-
- it 'uses AF_INET as the address family' do
- @addr.afamily.should == Socket::AF_INET
- end
-
- it 'uses PF_INET as the protocol family' do
- @addr.pfamily.should == Socket::PF_INET
- end
-
- it 'uses SOCK_STREAM as the socket type' do
- @addr.socktype.should == Socket::SOCK_STREAM
- end
-
- it 'uses the correct IP address' do
- @addr.ip_address.should == '127.0.0.1'
- end
-
- it 'uses the correct port' do
- if @method == :local_address
- @addr.ip_port.should != @s.addr[1]
- else
- @addr.ip_port.should == @s.addr[1]
- end
- end
-
- it 'equals address of peer socket' do
- if @method == :local_address
- @addr.to_s.should == @b.remote_address.to_s
- else
- @addr.to_s.should == @b.local_address.to_s
- end
- end
-
- it 'returns an Addrinfo' do
- @addr.should be_an_instance_of(Addrinfo)
- end
-
- it 'uses 0 as the protocol' do
- @addr.protocol.should == 0
- end
-
- it 'can be used to connect to the server' do
- skip if @method == :local_address
- b = @addr.connect
- begin
- b.remote_address.to_s.should == @addr.to_s
- ensure
- b.close
- end
- end
- end
-
- guard -> { SocketSpecs.ipv6_available? } do
- describe 'using IPv6' do
- before :each do
- @s = TCPServer.new('::1', 0)
- @a = TCPSocket.new('::1', @s.addr[1])
- @b = @s.accept
- @addr = @object.call(@a)
- end
-
- after :each do
- [@b, @a, @s].each(&:close)
- end
-
- it 'uses AF_INET6 as the address family' do
- @addr.afamily.should == Socket::AF_INET6
- end
-
- it 'uses PF_INET6 as the protocol family' do
- @addr.pfamily.should == Socket::PF_INET6
- end
-
- it 'uses SOCK_STREAM as the socket type' do
- @addr.socktype.should == Socket::SOCK_STREAM
- end
-
- it 'uses the correct IP address' do
- @addr.ip_address.should == '::1'
- end
-
- it 'uses the correct port' do
- if @method == :local_address
- @addr.ip_port.should != @s.addr[1]
- else
- @addr.ip_port.should == @s.addr[1]
- end
- end
-
- it 'equals address of peer socket' do
- if @method == :local_address
- @addr.to_s.should == @b.remote_address.to_s
- else
- @addr.to_s.should == @b.local_address.to_s
- end
- end
-
- it 'returns an Addrinfo' do
- @addr.should be_an_instance_of(Addrinfo)
- end
-
- it 'uses 0 as the protocol' do
- @addr.protocol.should == 0
- end
-
- it 'can be used to connect to the server' do
- skip if @method == :local_address
- b = @addr.connect
- begin
- b.remote_address.to_s.should == @addr.to_s
- ensure
- b.close
- end
- end
- end
- end
-
- with_feature :unix_socket do
- describe 'using UNIXSocket' do
- before :each do
- @path = SocketSpecs.socket_path
- @s = UNIXServer.new(@path)
- @a = UNIXSocket.new(@path)
- @b = @s.accept
- @addr = @object.call(@a)
- end
-
- after :each do
- [@b, @a, @s].each(&:close)
- rm_r(@path)
- end
-
- it 'uses AF_UNIX as the address family' do
- @addr.afamily.should == Socket::AF_UNIX
- end
-
- it 'uses PF_UNIX as the protocol family' do
- @addr.pfamily.should == Socket::PF_UNIX
- end
-
- it 'uses SOCK_STREAM as the socket type' do
- @addr.socktype.should == Socket::SOCK_STREAM
- end
-
- it 'uses the correct socket path' do
- if @method == :local_address
- @addr.unix_path.should == ""
- else
- @addr.unix_path.should == @path
- end
- end
-
- it 'equals address of peer socket' do
- if @method == :local_address
- @addr.to_s.should == @b.remote_address.to_s
- else
- @addr.to_s.should == @b.local_address.to_s
- end
- end
-
- it 'returns an Addrinfo' do
- @addr.should be_an_instance_of(Addrinfo)
- end
-
- it 'uses 0 as the protocol' do
- @addr.protocol.should == 0
- end
-
- it 'can be used to connect to the server' do
- skip if @method == :local_address
- b = @addr.connect
- begin
- b.remote_address.to_s.should == @addr.to_s
- ensure
- b.close
- end
- end
- end
- end
-
- describe 'using UDPSocket' do
- before :each do
- @s = UDPSocket.new
- @s.bind("127.0.0.1", 0)
- @a = UDPSocket.new
- @a.connect("127.0.0.1", @s.addr[1])
- @addr = @object.call(@a)
- end
-
- after :each do
- [@a, @s].each(&:close)
- end
-
- it 'uses the correct address family' do
- @addr.afamily.should == Socket::AF_INET
- end
-
- it 'uses the correct protocol family' do
- @addr.pfamily.should == Socket::PF_INET
- end
-
- it 'uses SOCK_DGRAM as the socket type' do
- @addr.socktype.should == Socket::SOCK_DGRAM
- end
-
- it 'uses the correct IP address' do
- @addr.ip_address.should == '127.0.0.1'
- end
-
- it 'uses the correct port' do
- if @method == :local_address
- @addr.ip_port.should != @s.addr[1]
- else
- @addr.ip_port.should == @s.addr[1]
- end
- end
-
- it 'returns an Addrinfo' do
- @addr.should be_an_instance_of(Addrinfo)
- end
-
- it 'uses 0 as the protocol' do
- @addr.protocol.should == 0
- end
-
- it 'can be used to connect to the peer' do
- b = @addr.connect
- begin
- b.remote_address.to_s.should == @addr.to_s
- ensure
- b.close
- end
- end
- end
-end
diff --git a/spec/ruby/library/socket/shared/pack_sockaddr.rb b/spec/ruby/library/socket/shared/pack_sockaddr.rb
index 26fdf682b1..4ffa02a8d8 100644
--- a/spec/ruby/library/socket/shared/pack_sockaddr.rb
+++ b/spec/ruby/library/socket/shared/pack_sockaddr.rb
@@ -17,52 +17,11 @@ describe :socket_pack_sockaddr_in, shared: true do
sockaddr_in = Socket.public_send(@method, nil, '127.0.0.1')
Socket.unpack_sockaddr_in(sockaddr_in).should == [0, '127.0.0.1']
-
- sockaddr_in = Socket.public_send(@method, 80, Socket::INADDR_ANY)
- Socket.unpack_sockaddr_in(sockaddr_in).should == [80, '0.0.0.0']
- end
-
- platform_is_not :solaris do
- it 'resolves the service name to a port' do
- sockaddr_in = Socket.public_send(@method, 'http', '127.0.0.1')
- Socket.unpack_sockaddr_in(sockaddr_in).should == [80, '127.0.0.1']
- end
- end
-
- describe 'using an IPv4 address' do
- it 'returns a String of 16 bytes' do
- str = Socket.public_send(@method, 80, '127.0.0.1')
-
- str.should be_an_instance_of(String)
- str.bytesize.should == 16
- end
- end
-
- platform_is_not :solaris do
- describe 'using an IPv6 address' do
- it 'returns a String of 28 bytes' do
- str = Socket.public_send(@method, 80, '::1')
-
- str.should be_an_instance_of(String)
- str.bytesize.should == 28
- end
- end
- end
-
- platform_is :solaris do
- describe 'using an IPv6 address' do
- it 'returns a String of 32 bytes' do
- str = Socket.public_send(@method, 80, '::1')
-
- str.should be_an_instance_of(String)
- str.bytesize.should == 32
- end
- end
end
end
describe :socket_pack_sockaddr_un, shared: true do
- with_feature :unix_socket do
+ platform_is_not :windows do
it 'should be idempotent' do
bytes = Socket.public_send(@method, '/tmp/foo').bytes
bytes[2..9].should == [47, 116, 109, 112, 47, 102, 111, 111]
@@ -81,29 +40,11 @@ describe :socket_pack_sockaddr_un, shared: true do
end
end
- platform_is :linux do
- it 'returns a String of 110 bytes' do
- str = Socket.public_send(@method, '/tmp/test.sock')
-
- str.should be_an_instance_of(String)
- str.bytesize.should == 110
- end
- end
-
- platform_is :bsd do
- it 'returns a String of 106 bytes' do
- str = Socket.public_send(@method, '/tmp/test.sock')
-
- str.should be_an_instance_of(String)
- str.bytesize.should == 106
- end
- end
-
platform_is_not :windows, :aix do
- it "raises ArgumentError for paths that are too long" do
+ it "raises if path length exceeds max size" do
# AIX doesn't raise error
- long_path = 'a' * 110
- -> { Socket.public_send(@method, long_path) }.should raise_error(ArgumentError)
+ long_path = Array.new(512, 0).join
+ lambda { Socket.public_send(@method, long_path) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/library/socket/shared/partially_closable_sockets.rb b/spec/ruby/library/socket/shared/partially_closable_sockets.rb
index b1c2ebabe1..1bdff08bf6 100644
--- a/spec/ruby/library/socket/shared/partially_closable_sockets.rb
+++ b/spec/ruby/library/socket/shared/partially_closable_sockets.rb
@@ -1,4 +1,4 @@
-describe :partially_closable_sockets, shared: true do
+describe "partially closable sockets", shared: true do
it "if the write end is closed then the other side can read past EOF without blocking" do
@s1.write("foo")
@s1.close_write
diff --git a/spec/ruby/library/socket/shared/recv_nonblock.rb b/spec/ruby/library/socket/shared/recv_nonblock.rb
new file mode 100644
index 0000000000..a5f6c6812e
--- /dev/null
+++ b/spec/ruby/library/socket/shared/recv_nonblock.rb
@@ -0,0 +1,54 @@
+describe :socket_recv_nonblock, shared: true do
+ before :each do
+ @s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
+ @s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
+ end
+
+ after :each do
+ @s1.close unless @s1.closed?
+ @s2.close unless @s2.closed?
+ end
+
+ it "raises an exception extending IO::WaitReadable if there's no data available" do
+ @s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
+ lambda {
+ @s1.recv_nonblock(5)
+ }.should raise_error(IO::WaitReadable) { |e|
+ platform_is_not :windows do
+ e.should be_kind_of(Errno::EAGAIN)
+ end
+ platform_is :windows do
+ e.should be_kind_of(Errno::EWOULDBLOCK)
+ end
+ }
+ end
+
+ it "receives data after it's ready" do
+ @s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
+ @s2.send("aaa", 0, @s1.getsockname)
+ IO.select([@s1], nil, nil, 2)
+ @s1.recv_nonblock(5).should == "aaa"
+ end
+
+ ruby_version_is "2.3" do
+ it "allows an output buffer as third argument" do
+ @s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
+ @s2.send("data", 0, @s1.getsockname)
+ IO.select([@s1], nil, nil, 2)
+
+ buf = "foo"
+ @s1.recv_nonblock(5, 0, buf)
+ buf.should == "data"
+ end
+ end
+
+ it "does not block if there's no data available" do
+ @s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
+ @s2.send("a", 0, @s1.getsockname)
+ IO.select([@s1], nil, nil, 2)
+ @s1.recv_nonblock(1).should == "a"
+ lambda {
+ @s1.recv_nonblock(5)
+ }.should raise_error(IO::WaitReadable)
+ end
+end
diff --git a/spec/ruby/library/socket/shared/socketpair.rb b/spec/ruby/library/socket/shared/socketpair.rb
index 25146cfff6..03ee0e1a52 100644
--- a/spec/ruby/library/socket/shared/socketpair.rb
+++ b/spec/ruby/library/socket/shared/socketpair.rb
@@ -19,120 +19,5 @@ describe :socket_socketpair, shared: true do
s2.close
end
end
-
- describe 'using an Integer as the 1st and 2nd argument' do
- it 'returns two Socket objects' do
- s1, s2 = Socket.public_send(@method, Socket::AF_UNIX, Socket::SOCK_STREAM)
-
- s1.should be_an_instance_of(Socket)
- s2.should be_an_instance_of(Socket)
- s1.close
- s2.close
- end
- end
-
- describe 'using a Symbol as the 1st and 2nd argument' do
- it 'returns two Socket objects' do
- s1, s2 = Socket.public_send(@method, :UNIX, :STREAM)
-
- s1.should be_an_instance_of(Socket)
- s2.should be_an_instance_of(Socket)
- s1.close
- s2.close
- end
-
- it 'raises SocketError for an unknown address family' do
- -> { Socket.public_send(@method, :CATS, :STREAM) }.should raise_error(SocketError)
- end
-
- it 'raises SocketError for an unknown socket type' do
- -> { Socket.public_send(@method, :UNIX, :CATS) }.should raise_error(SocketError)
- end
- end
-
- describe 'using a String as the 1st and 2nd argument' do
- it 'returns two Socket objects' do
- s1, s2 = Socket.public_send(@method, 'UNIX', 'STREAM')
-
- s1.should be_an_instance_of(Socket)
- s2.should be_an_instance_of(Socket)
- s1.close
- s2.close
- end
-
- it 'raises SocketError for an unknown address family' do
- -> { Socket.public_send(@method, 'CATS', 'STREAM') }.should raise_error(SocketError)
- end
-
- it 'raises SocketError for an unknown socket type' do
- -> { Socket.public_send(@method, 'UNIX', 'CATS') }.should raise_error(SocketError)
- end
- end
-
- describe 'using an object that responds to #to_str as the 1st and 2nd argument' do
- it 'returns two Socket objects' do
- family = mock(:family)
- type = mock(:type)
-
- family.stub!(:to_str).and_return('UNIX')
- type.stub!(:to_str).and_return('STREAM')
-
- s1, s2 = Socket.public_send(@method, family, type)
-
- s1.should be_an_instance_of(Socket)
- s2.should be_an_instance_of(Socket)
- s1.close
- s2.close
- end
-
- it 'raises TypeError when #to_str does not return a String' do
- family = mock(:family)
- type = mock(:type)
-
- family.stub!(:to_str).and_return(Socket::AF_UNIX)
- type.stub!(:to_str).and_return(Socket::SOCK_STREAM)
-
- -> { Socket.public_send(@method, family, type) }.should raise_error(TypeError)
- end
-
- it 'raises SocketError for an unknown address family' do
- family = mock(:family)
- type = mock(:type)
-
- family.stub!(:to_str).and_return('CATS')
- type.stub!(:to_str).and_return('STREAM')
-
- -> { Socket.public_send(@method, family, type) }.should raise_error(SocketError)
- end
-
- it 'raises SocketError for an unknown socket type' do
- family = mock(:family)
- type = mock(:type)
-
- family.stub!(:to_str).and_return('UNIX')
- type.stub!(:to_str).and_return('CATS')
-
- -> { Socket.public_send(@method, family, type) }.should raise_error(SocketError)
- end
- end
-
- it 'accepts a custom protocol as an Integer as the 3rd argument' do
- s1, s2 = Socket.public_send(@method, :UNIX, :STREAM, Socket::IPPROTO_IP)
- s1.should be_an_instance_of(Socket)
- s2.should be_an_instance_of(Socket)
- s1.close
- s2.close
- end
-
- it 'connects the returned Socket objects' do
- s1, s2 = Socket.public_send(@method, :UNIX, :STREAM)
- begin
- s1.write('hello')
- s2.recv(5).should == 'hello'
- ensure
- s1.close
- s2.close
- end
- end
end
end