diff options
Diffstat (limited to 'spec/ruby/library/socket/basicsocket')
23 files changed, 785 insertions, 250 deletions
diff --git a/spec/ruby/library/socket/basicsocket/close_read_spec.rb b/spec/ruby/library/socket/basicsocket/close_read_spec.rb index c989fcaf72..35bec203d7 100644 --- a/spec/ruby/library/socket/basicsocket/close_read_spec.rb +++ b/spec/ruby/library/socket/basicsocket/close_read_spec.rb @@ -12,32 +12,32 @@ describe "Socket::BasicSocket#close_read" do it "closes the reading end of the socket" do @server.close_read - lambda { @server.read }.should raise_error(IOError) + -> { @server.read }.should.raise(IOError) end it 'does not raise when called on a socket already closed for reading' do @server.close_read @server.close_read - lambda { @server.read }.should raise_error(IOError) + -> { @server.read }.should.raise(IOError) end it 'does not fully close the socket' do @server.close_read - @server.closed?.should be_false + @server.closed?.should == false end it "fully closes the socket if it was already closed for writing" do @server.close_write @server.close_read - @server.closed?.should be_true + @server.closed?.should == true end it 'raises IOError when called on a fully closed socket' do @server.close - lambda { @server.close_read }.should raise_error(IOError) + -> { @server.close_read }.should.raise(IOError) end it "returns nil" do - @server.close_read.should be_nil + @server.close_read.should == nil end end diff --git a/spec/ruby/library/socket/basicsocket/close_write_spec.rb b/spec/ruby/library/socket/basicsocket/close_write_spec.rb index f37e0e5074..c1b6d9e9ef 100644 --- a/spec/ruby/library/socket/basicsocket/close_write_spec.rb +++ b/spec/ruby/library/socket/basicsocket/close_write_spec.rb @@ -12,18 +12,18 @@ describe "Socket::BasicSocket#close_write" do it "closes the writing end of the socket" do @server.close_write - lambda { @server.write("foo") }.should raise_error(IOError) + -> { @server.write("foo") }.should.raise(IOError) end it 'does not raise when called on a socket already closed for writing' do @server.close_write @server.close_write - lambda { @server.write("foo") }.should raise_error(IOError) + -> { @server.write("foo") }.should.raise(IOError) end it 'does not fully close the socket' do @server.close_write - @server.closed?.should be_false + @server.closed?.should == false end it "does not prevent reading" do @@ -34,15 +34,15 @@ describe "Socket::BasicSocket#close_write" do it "fully closes the socket if it was already closed for reading" do @server.close_read @server.close_write - @server.closed?.should be_true + @server.closed?.should == true end it 'raises IOError when called on a fully closed socket' do @server.close - lambda { @server.close_write }.should raise_error(IOError) + -> { @server.close_write }.should.raise(IOError) end it "returns nil" do - @server.close_write.should be_nil + @server.close_write.should == nil end end diff --git a/spec/ruby/library/socket/basicsocket/connect_address_spec.rb b/spec/ruby/library/socket/basicsocket/connect_address_spec.rb index 18baac7f17..e330b6e1be 100644 --- a/spec/ruby/library/socket/basicsocket/connect_address_spec.rb +++ b/spec/ruby/library/socket/basicsocket/connect_address_spec.rb @@ -10,7 +10,7 @@ describe 'Socket#connect_address' do it 'raises SocketError' do @sock = Socket.new(:INET, :STREAM) - lambda { @sock.connect_address }.should raise_error(SocketError) + -> { @sock.connect_address }.should.raise(SocketError) end end @@ -25,7 +25,7 @@ describe 'Socket#connect_address' do end it 'returns an Addrinfo' do - @sock.connect_address.should be_an_instance_of(Addrinfo) + @sock.connect_address.should.instance_of?(Addrinfo) end it 'uses 127.0.0.1 as the IP address' do @@ -65,7 +65,7 @@ describe 'Socket#connect_address' do end it 'returns an Addrinfo' do - @sock.connect_address.should be_an_instance_of(Addrinfo) + @sock.connect_address.should.instance_of?(Addrinfo) end it 'uses ::1 as the IP address' do @@ -94,61 +94,59 @@ describe 'Socket#connect_address' do end end - with_feature :unix_socket do - platform_is_not :aix do - describe 'using an unbound UNIX socket' do - before do - @path = SocketSpecs.socket_path - @server = UNIXServer.new(@path) - @client = UNIXSocket.new(@path) - end - - after do - @client.close - @server.close - rm_r(@path) - end - - it 'raises SocketError' do - lambda { @client.connect_address }.should raise_error(SocketError) - end - end - end - - describe 'using a bound UNIX socket' do + platform_is_not :aix do + describe 'using an unbound UNIX socket' do before do @path = SocketSpecs.socket_path - @sock = UNIXServer.new(@path) + @server = UNIXServer.new(@path) + @client = UNIXSocket.new(@path) end after do - @sock.close + @client.close + @server.close rm_r(@path) end - it 'returns an Addrinfo' do - @sock.connect_address.should be_an_instance_of(Addrinfo) + it 'raises SocketError' do + -> { @client.connect_address }.should.raise(SocketError) end + end + end - it 'uses the correct socket path' do - @sock.connect_address.unix_path.should == @path - end + describe 'using a bound UNIX socket' do + before do + @path = SocketSpecs.socket_path + @sock = UNIXServer.new(@path) + end - it 'uses AF_UNIX as the address family' do - @sock.connect_address.afamily.should == Socket::AF_UNIX - end + after do + @sock.close + rm_r(@path) + end - it 'uses PF_UNIX as the protocol family' do - @sock.connect_address.pfamily.should == Socket::PF_UNIX - end + it 'returns an Addrinfo' do + @sock.connect_address.should.instance_of?(Addrinfo) + end - it 'uses SOCK_STREAM as the socket type' do - @sock.connect_address.socktype.should == Socket::SOCK_STREAM - end + it 'uses the correct socket path' do + @sock.connect_address.unix_path.should == @path + end - it 'uses 0 as the protocol' do - @sock.connect_address.protocol.should == 0 - end + it 'uses AF_UNIX as the address family' do + @sock.connect_address.afamily.should == Socket::AF_UNIX + end + + it 'uses PF_UNIX as the protocol family' do + @sock.connect_address.pfamily.should == Socket::PF_UNIX + end + + it 'uses SOCK_STREAM as the socket type' do + @sock.connect_address.socktype.should == Socket::SOCK_STREAM + end + + it 'uses 0 as the protocol' do + @sock.connect_address.protocol.should == 0 end end end diff --git a/spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb b/spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb index 85a66275f8..36338bfd59 100644 --- a/spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb +++ b/spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb @@ -16,7 +16,7 @@ describe "BasicSocket.do_not_reverse_lookup" do end it "defaults to true" do - BasicSocket.do_not_reverse_lookup.should be_true + BasicSocket.do_not_reverse_lookup.should == true end it "causes 'peeraddr' to avoid name lookups" do @@ -37,3 +37,67 @@ describe "BasicSocket.do_not_reverse_lookup" do @socket.peeraddr[2].should == "127.0.0.1" end end + +describe :socket_do_not_reverse_lookup, shared: true do + it "inherits from BasicSocket.do_not_reverse_lookup when the socket is created" do + @socket = @method.call + reverse = BasicSocket.do_not_reverse_lookup + @socket.do_not_reverse_lookup.should == reverse + + BasicSocket.do_not_reverse_lookup = !reverse + @socket.do_not_reverse_lookup.should == reverse + end + + it "is true when BasicSocket.do_not_reverse_lookup is true" do + BasicSocket.do_not_reverse_lookup = true + @socket = @method.call + @socket.do_not_reverse_lookup.should == true + end + + it "is false when BasicSocket.do_not_reverse_lookup is false" do + BasicSocket.do_not_reverse_lookup = false + @socket = @method.call + @socket.do_not_reverse_lookup.should == false + end + + it "can be changed with #do_not_reverse_lookup=" do + @socket = @method.call + reverse = @socket.do_not_reverse_lookup + @socket.do_not_reverse_lookup = !reverse + @socket.do_not_reverse_lookup.should == !reverse + end +end + +describe "BasicSocket#do_not_reverse_lookup" do + before :each do + @do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + end + + after :each do + @server.close unless @server.closed? + @socket.close if @socket && !@socket.closed? + BasicSocket.do_not_reverse_lookup = @do_not_reverse_lookup + end + + describe "for an TCPSocket.new socket" do + it_behaves_like :socket_do_not_reverse_lookup, -> { + TCPSocket.new('127.0.0.1', @port) + } + end + + describe "for an TCPServer#accept socket" do + before :each do + @client = TCPSocket.new('127.0.0.1', @port) + end + + after :each do + @client.close if @client && !@client.closed? + end + + it_behaves_like :socket_do_not_reverse_lookup, -> { + @server.accept + } + end +end diff --git a/spec/ruby/library/socket/basicsocket/for_fd_spec.rb b/spec/ruby/library/socket/basicsocket/for_fd_spec.rb index 9c9e6a8b55..8d5b71cfa9 100644 --- a/spec/ruby/library/socket/basicsocket/for_fd_spec.rb +++ b/spec/ruby/library/socket/basicsocket/for_fd_spec.rb @@ -15,7 +15,7 @@ describe "BasicSocket.for_fd" do it "return a Socket instance wrapped around the descriptor" do @s2 = TCPServer.for_fd(@server.fileno) @s2.autoclose = false - @s2.should be_kind_of(TCPServer) + @s2.should.is_a?(TCPServer) @s2.fileno.should == @server.fileno end @@ -24,7 +24,7 @@ describe "BasicSocket.for_fd" do socket2 = Socket.for_fd(@socket1.fileno) socket2.autoclose = false - socket2.should be_an_instance_of(Socket) + socket2.should.instance_of?(Socket) socket2.fileno.should == @socket1.fileno end @@ -33,6 +33,6 @@ describe "BasicSocket.for_fd" do socket2 = Socket.for_fd(@socket1.fileno) socket2.autoclose = false - socket2.binmode?.should be_true + socket2.binmode?.should == true end end diff --git a/spec/ruby/library/socket/basicsocket/getpeereid_spec.rb b/spec/ruby/library/socket/basicsocket/getpeereid_spec.rb index 9eeb6d0e0b..b9851bae15 100644 --- a/spec/ruby/library/socket/basicsocket/getpeereid_spec.rb +++ b/spec/ruby/library/socket/basicsocket/getpeereid_spec.rb @@ -2,7 +2,7 @@ require_relative '../spec_helper' require_relative '../fixtures/classes' describe 'BasicSocket#getpeereid' do - with_feature :unix_socket do + platform_is_not :windows do describe 'using a UNIXSocket' do before do @path = SocketSpecs.socket_path @@ -30,7 +30,7 @@ describe 'BasicSocket#getpeereid' do it 'raises NoMethodError' do @sock = TCPServer.new('127.0.0.1', 0) - lambda { @sock.getpeereid }.should raise_error(NoMethodError) + -> { @sock.getpeereid }.should.raise(NoMethodError) end end end diff --git a/spec/ruby/library/socket/basicsocket/getpeername_spec.rb b/spec/ruby/library/socket/basicsocket/getpeername_spec.rb index 23c73056cd..7e2f6f2e7b 100644 --- a/spec/ruby/library/socket/basicsocket/getpeername_spec.rb +++ b/spec/ruby/library/socket/basicsocket/getpeername_spec.rb @@ -20,6 +20,6 @@ describe "Socket::BasicSocket#getpeername" do end it 'raises Errno::ENOTCONN for a disconnected socket' do - lambda { @server.getpeername }.should raise_error(Errno::ENOTCONN) + -> { @server.getpeername }.should.raise(Errno::ENOTCONN) end end diff --git a/spec/ruby/library/socket/basicsocket/getsockname_spec.rb b/spec/ruby/library/socket/basicsocket/getsockname_spec.rb index b33db088b6..a54626647e 100644 --- a/spec/ruby/library/socket/basicsocket/getsockname_spec.rb +++ b/spec/ruby/library/socket/basicsocket/getsockname_spec.rb @@ -3,7 +3,7 @@ require_relative '../fixtures/classes' describe "Socket::BasicSocket#getsockname" do after :each do - @socket.closed?.should be_false + @socket.closed?.should == false @socket.close end @@ -16,7 +16,7 @@ describe "Socket::BasicSocket#getsockname" do it "works on sockets listening in ipaddr_any" do @socket = TCPServer.new(0) 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 == true sockaddr[0].should == @socket.addr[1] end diff --git a/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb b/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb index aad21ca535..744297ad02 100644 --- a/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb +++ b/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb @@ -7,7 +7,7 @@ describe "BasicSocket#getsockopt" do end after :each do - @sock.closed?.should be_false + @sock.closed?.should == false @sock.close end @@ -41,13 +41,13 @@ describe "BasicSocket#getsockopt" do end it "raises a SystemCallError with an invalid socket option" do - lambda { @sock.getsockopt Socket::SOL_SOCKET, -1 }.should raise_error(Errno::ENOPROTOOPT) + -> { @sock.getsockopt Socket::SOL_SOCKET, -1 }.should.raise(Errno::ENOPROTOOPT) end it 'returns a Socket::Option using a constant' do opt = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE) - opt.should be_an_instance_of(Socket::Option) + opt.should.instance_of?(Socket::Option) end it 'returns a Socket::Option for a boolean option' do @@ -59,7 +59,7 @@ describe "BasicSocket#getsockopt" do it 'returns a Socket::Option for a numeric option' do opt = @sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL) - opt.int.should be_kind_of(Integer) + opt.int.should.is_a?(Integer) end it 'returns a Socket::Option for a struct option' do @@ -69,7 +69,7 @@ describe "BasicSocket#getsockopt" do end it 'raises Errno::ENOPROTOOPT when requesting an invalid option' do - lambda { @sock.getsockopt(Socket::SOL_SOCKET, -1) }.should raise_error(Errno::ENOPROTOOPT) + -> { @sock.getsockopt(Socket::SOL_SOCKET, -1) }.should.raise(Errno::ENOPROTOOPT) end describe 'using Symbols as arguments' do @@ -171,7 +171,7 @@ describe "BasicSocket#getsockopt" do opt = @sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL).to_s array = opt.unpack('i') - array[0].should be_kind_of(Integer) + array[0].should.is_a?(Integer) array[0].should > 0 end diff --git a/spec/ruby/library/socket/basicsocket/local_address_spec.rb b/spec/ruby/library/socket/basicsocket/local_address_spec.rb new file mode 100644 index 0000000000..0bd60a44cd --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/local_address_spec.rb @@ -0,0 +1,10 @@ +require_relative '../spec_helper' +require_relative '../shared/address' + +describe 'BasicSocket#local_address' do + it_behaves_like :socket_local_remote_address, :local_address, -> socket { + a2 = BasicSocket.for_fd(socket.fileno) + a2.autoclose = false + a2.local_address + } +end diff --git a/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb new file mode 100644 index 0000000000..ea5e65da5c --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb @@ -0,0 +1,74 @@ +require_relative '../spec_helper' +require_relative '../fixtures/classes' + +describe "BasicSocket#read_nonblock" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @r = Socket.new(family, :DGRAM) + @w = Socket.new(family, :DGRAM) + + @r.bind(Socket.pack_sockaddr_in(0, ip_address)) + @w.send("aaa", 0, @r.getsockname) + end + + after :each do + @r.close unless @r.closed? + @w.close unless @w.closed? + end + + it "receives data after it's ready" do + IO.select([@r], nil, nil, 2) + @r.read_nonblock(5).should == "aaa" + end + + platform_is_not :windows do + it 'returned data is binary encoded regardless of the external encoding' do + IO.select([@r], nil, nil, 2) + @r.read_nonblock(1).encoding.should == Encoding::BINARY + + @w.send("bbb", 0, @r.getsockname) + @r.set_encoding(Encoding::ISO_8859_1) + IO.select([@r], nil, nil, 2) + buffer = @r.read_nonblock(3) + buffer.should == "bbb" + buffer.encoding.should == Encoding::BINARY + end + end + + it 'replaces the content of the provided buffer without changing its encoding' do + buffer = "initial data".dup.force_encoding(Encoding::UTF_8) + + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3, buffer) + buffer.should == "aaa" + buffer.encoding.should == Encoding::UTF_8 + + @w.send("bbb", 0, @r.getsockname) + @r.set_encoding(Encoding::ISO_8859_1) + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3, buffer) + buffer.should == "bbb" + buffer.encoding.should == Encoding::UTF_8 + end + + platform_is :linux do + it 'does not set the IO in nonblock mode' do + require 'io/nonblock' + @r.nonblock = false + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3).should == "aaa" + @r.should_not.nonblock? + end + end + + platform_is_not :linux, :windows do + it 'sets the IO in nonblock mode' do + require 'io/nonblock' + @r.nonblock = false + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3).should == "aaa" + @r.should.nonblock? + end + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/read_spec.rb b/spec/ruby/library/socket/basicsocket/read_spec.rb new file mode 100644 index 0000000000..ba9de7d5cf --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/read_spec.rb @@ -0,0 +1,47 @@ +require_relative '../spec_helper' +require_relative '../fixtures/classes' + +describe "BasicSocket#read" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @r = Socket.new(family, :DGRAM) + @w = Socket.new(family, :DGRAM) + + @r.bind(Socket.pack_sockaddr_in(0, ip_address)) + @w.send("aaa", 0, @r.getsockname) + end + + after :each do + @r.close unless @r.closed? + @w.close unless @w.closed? + end + + it "receives data after it's ready" do + @r.read(3).should == "aaa" + end + + it 'returned data is binary encoded regardless of the external encoding' do + @r.read(3).encoding.should == Encoding::BINARY + + @w.send("bbb", 0, @r.getsockname) + @r.set_encoding(Encoding::UTF_8) + buffer = @r.read(3) + buffer.should == "bbb" + buffer.encoding.should == Encoding::BINARY + end + + it 'replaces the content of the provided buffer without changing its encoding' do + buffer = "initial data".dup.force_encoding(Encoding::UTF_8) + + @r.read(3, buffer) + buffer.should == "aaa" + buffer.encoding.should == Encoding::UTF_8 + + @w.send("bbb", 0, @r.getsockname) + @r.set_encoding(Encoding::ISO_8859_1) + @r.read(3, buffer) + buffer.should == "bbb" + buffer.encoding.should == Encoding::UTF_8 + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb index 1b6027d26c..8aca7d0332 100644 --- a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb @@ -16,25 +16,30 @@ describe "Socket::BasicSocket#recv_nonblock" do platform_is_not :windows do describe 'using an unbound socket' do it 'raises an exception extending IO::WaitReadable' do - lambda { @s1.recv_nonblock(1) }.should raise_error(IO::WaitReadable) + -> { @s1.recv_nonblock(1) }.should.raise(IO::WaitReadable) end end end it "raises an exception extending IO::WaitReadable if there's no data available" do @s1.bind(Socket.pack_sockaddr_in(0, ip_address)) - lambda { + -> { @s1.recv_nonblock(5) - }.should raise_error(IO::WaitReadable) { |e| + }.should.raise(IO::WaitReadable) { |e| platform_is_not :windows do - e.should be_kind_of(Errno::EAGAIN) + e.should.is_a?(Errno::EAGAIN) end platform_is :windows do - e.should be_kind_of(Errno::EWOULDBLOCK) + e.should.is_a?(Errno::EWOULDBLOCK) end } end + it "returns :wait_readable with exception: false" do + @s1.bind(Socket.pack_sockaddr_in(0, ip_address)) + @s1.recv_nonblock(5, exception: false).should == :wait_readable + end + it "receives data after it's ready" do @s1.bind(Socket.pack_sockaddr_in(0, ip_address)) @s2.send("aaa", 0, @s1.getsockname) @@ -47,9 +52,19 @@ describe "Socket::BasicSocket#recv_nonblock" do @s2.send("data", 0, @s1.getsockname) IO.select([@s1], nil, nil, 2) - buf = "foo" - @s1.recv_nonblock(5, 0, buf) - buf.should == "data" + buffer = +"foo" + @s1.recv_nonblock(5, 0, buffer).should.equal?(buffer) + buffer.should == "data" + end + + it "preserves the encoding of the given buffer" do + @s1.bind(Socket.pack_sockaddr_in(0, ip_address)) + @s2.send("data", 0, @s1.getsockname) + IO.select([@s1], nil, nil, 2) + + buffer = ''.encode(Encoding::ISO_8859_1) + @s1.recv_nonblock(5, 0, buffer) + buffer.encoding.should == Encoding::ISO_8859_1 end it "does not block if there's no data available" do @@ -57,9 +72,71 @@ describe "Socket::BasicSocket#recv_nonblock" do @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) + }.should.raise(IO::WaitReadable) + end + end + + SocketSpecs.each_ip_protocol do |family, ip_address| + describe 'using a connected but not bound socket' do + before do + @server = Socket.new(family, :STREAM) + end + + after do + @server.close + end + + it "raises Errno::ENOTCONN" do + -> { @server.recv_nonblock(1) }.should.raise { |e| + [Errno::ENOTCONN, Errno::EINVAL].should.include?(e.class) + } + -> { @server.recv_nonblock(1, exception: false) }.should.raise { |e| + [Errno::ENOTCONN, Errno::EINVAL].should.include?(e.class) + } + end + end + end +end + +describe "Socket::BasicSocket#recv_nonblock" do + context "when recvfrom(2) returns 0 (if no messages are available to be received and the peer has performed an orderly shutdown)" do + describe "stream socket" do + before :each do + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + end + + after :each do + @server.close unless @server.closed? + end + + it "returns nil on a closed stream socket" do + ready = false + + t = Thread.new do + client = @server.accept + + Thread.pass while !ready + begin + client.recv_nonblock(10) + rescue IO::EAGAINWaitReadable + retry + end + ensure + client.close if client + end + + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + socket = TCPSocket.new('127.0.0.1', @port) + socket.close + ready = true + + t.value.should == nil + end end end end diff --git a/spec/ruby/library/socket/basicsocket/recv_spec.rb b/spec/ruby/library/socket/basicsocket/recv_spec.rb index a277dc2d97..5c393218bc 100644 --- a/spec/ruby/library/socket/basicsocket/recv_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recv_spec.rb @@ -1,4 +1,4 @@ -# -*- encoding: binary -*- +# encoding: binary require_relative '../spec_helper' require_relative '../fixtures/classes' @@ -22,7 +22,7 @@ describe "BasicSocket#recv" do client.close end Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil + t.status.should_not == nil socket = TCPSocket.new('127.0.0.1', @port) socket.send('hello', 0) @@ -32,28 +32,26 @@ describe "BasicSocket#recv" do ScratchPad.recorded.should == 'hello' end - platform_is_not :solaris do - it "accepts flags to specify unusual receiving behaviour" do - t = Thread.new do - client = @server.accept + it "accepts flags to specify unusual receiving behaviour" do + t = Thread.new do + client = @server.accept - # in-band data (TCP), doesn't receive the flag. - ScratchPad.record client.recv(10) + # in-band data (TCP), doesn't receive the flag. + ScratchPad.record client.recv(10) - # this recv is important (TODO: explain) - client.recv(10) - client.close - end - Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil - - socket = TCPSocket.new('127.0.0.1', @port) - socket.send('helloU', Socket::MSG_OOB) - socket.shutdown(1) - t.join - socket.close - ScratchPad.recorded.should == 'hello' + # this recv is important (TODO: explain) + client.recv(10) + client.close end + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + socket = TCPSocket.new('127.0.0.1', @port) + socket.send('helloU', Socket::MSG_OOB) + socket.shutdown(1) + t.join + socket.close + ScratchPad.recorded.should == 'hello' end it "gets lines delimited with a custom separator" do @@ -66,7 +64,7 @@ describe "BasicSocket#recv" do client.close end Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil + t.status.should_not == nil socket = TCPSocket.new('127.0.0.1', @port) socket.write("firstline\377secondline\377") @@ -81,13 +79,29 @@ describe "BasicSocket#recv" do socket.write("data") client = @server.accept - buf = "foo" + buffer = +"foo" + begin + client.recv(4, 0, buffer).should.equal?(buffer) + ensure + client.close + end + buffer.should == "data" + + socket.close + end + + it "preserves the encoding of the given buffer" do + socket = TCPSocket.new('127.0.0.1', @port) + socket.write("data") + + client = @server.accept + buffer = ''.encode(Encoding::ISO_8859_1) begin - client.recv(4, 0, buf) + client.recv(4, 0, buffer) ensure client.close end - buf.should == "data" + buffer.encoding.should == Encoding::ISO_8859_1 socket.close end @@ -107,7 +121,7 @@ describe 'BasicSocket#recv' do describe 'using an unbound socket' do it 'blocks the caller' do - lambda { @server.recv(4) }.should block_caller + -> { @server.recv(4) }.should block_caller end end @@ -118,7 +132,7 @@ describe 'BasicSocket#recv' do describe 'without any data available' do it 'blocks the caller' do - lambda { @server.recv(4) }.should block_caller + -> { @server.recv(4) }.should block_caller end end @@ -144,7 +158,7 @@ describe 'BasicSocket#recv' do @server.recv(2).should == 'he' - lambda { @server.recv(4) }.should block_caller + -> { @server.recv(4) }.should block_caller end it 'takes a peek at the data when using the MSG_PEEK flag' do @@ -157,3 +171,59 @@ describe 'BasicSocket#recv' do end end end + +describe "BasicSocket#recv" do + context "when recvfrom(2) returns 0 (if no messages are available to be received and the peer has performed an orderly shutdown)" do + describe "stream socket" do + before :each do + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + end + + after :each do + @server.close unless @server.closed? + end + + it "returns nil on a closed stream socket" do + t = Thread.new do + client = @server.accept + client.recv(10) + ensure + client.close if client + end + + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + socket = TCPSocket.new('127.0.0.1', @port) + socket.close + + t.value.should == nil + end + end + + describe "datagram socket" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @server = UDPSocket.new(family) + @client = UDPSocket.new(family) + end + + after :each do + @server.close unless @server.closed? + @client.close unless @client.closed? + end + + it "returns empty String" do + @server.bind(ip_address, 0) + addr = @server.connect_address + @client.connect(addr.ip_address, addr.ip_port) + + @client.send('', 0) + + @server.recv(1).should == "" + end + end + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb index 8f6b75029c..9d77f5df6b 100644 --- a/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb @@ -17,7 +17,7 @@ describe 'BasicSocket#recvmsg_nonblock' do platform_is_not :windows do describe 'using an unbound socket' do it 'raises an exception extending IO::WaitReadable' do - lambda { @server.recvmsg_nonblock }.should raise_error(IO::WaitReadable) + -> { @server.recvmsg_nonblock }.should.raise(IO::WaitReadable) end end end @@ -29,7 +29,11 @@ describe 'BasicSocket#recvmsg_nonblock' do describe 'without any data available' do it 'raises an exception extending IO::WaitReadable' do - lambda { @server.recvmsg_nonblock }.should raise_error(IO::WaitReadable) + -> { @server.recvmsg_nonblock }.should.raise(IO::WaitReadable) + end + + it 'returns :wait_readable with exception: false' do + @server.recvmsg_nonblock(exception: false).should == :wait_readable end end @@ -43,7 +47,7 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'returns an Array containing the data, an Addrinfo and the flags' do - @server.recvmsg_nonblock.should be_an_instance_of(Array) + @server.recvmsg_nonblock.should.instance_of?(Array) end describe 'without a maximum message length' do @@ -70,12 +74,12 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'stores an Addrinfo at index 1' do - @array[1].should be_an_instance_of(Addrinfo) + @array[1].should.instance_of?(Addrinfo) end platform_is_not :windows do it 'stores the flags at index 2' do - @array[2].should be_kind_of(Integer) + @array[2].should.is_a?(Integer) end end @@ -110,6 +114,21 @@ describe 'BasicSocket#recvmsg_nonblock' do end platform_is_not :windows do + describe 'using a connected but not bound socket' do + before do + @server = Socket.new(family, :STREAM) + end + + after do + @server.close + end + + it "raises Errno::ENOTCONN" do + -> { @server.recvmsg_nonblock }.should.raise(Errno::ENOTCONN) + -> { @server.recvmsg_nonblock(exception: false) }.should.raise(Errno::ENOTCONN) + end + end + describe 'using a connected socket' do before do @client = Socket.new(family, :STREAM) @@ -128,14 +147,14 @@ describe 'BasicSocket#recvmsg_nonblock' do describe 'without any data available' do it 'raises IO::WaitReadable' do - lambda { + -> { socket, _ = @server.accept begin socket.recvmsg_nonblock ensure socket.close end - }.should raise_error(IO::WaitReadable) + }.should.raise(IO::WaitReadable) end end @@ -152,7 +171,7 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'returns an Array containing the data, an Addrinfo and the flags' do - @socket.recvmsg_nonblock.should be_an_instance_of(Array) + @socket.recvmsg_nonblock.should.instance_of?(Array) end describe 'the returned Array' do @@ -165,11 +184,11 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'stores an Addrinfo at index 1' do - @array[1].should be_an_instance_of(Addrinfo) + @array[1].should.instance_of?(Addrinfo) end it 'stores the flags at index 2' do - @array[2].should be_kind_of(Integer) + @array[2].should.is_a?(Integer) end describe 'the returned Addrinfo' do @@ -178,7 +197,7 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'raises when receiving the ip_address message' do - lambda { @addr.ip_address }.should raise_error(SocketError) + -> { @addr.ip_address }.should.raise(SocketError) end it 'uses the correct address family' do @@ -194,7 +213,7 @@ describe 'BasicSocket#recvmsg_nonblock' do end it 'raises when receiving the ip_port message' do - lambda { @addr.ip_port }.should raise_error(SocketError) + -> { @addr.ip_port }.should.raise(SocketError) end end end @@ -203,3 +222,46 @@ describe 'BasicSocket#recvmsg_nonblock' do end end end + +describe 'BasicSocket#recvmsg_nonblock' do + context "when recvfrom(2) returns 0 (if no messages are available to be received and the peer has performed an orderly shutdown)" do + describe "stream socket" do + before :each do + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + end + + after :each do + @server.close unless @server.closed? + end + + platform_is_not :windows do + it "returns nil on a closed stream socket" do + ready = false + + t = Thread.new do + client = @server.accept + + Thread.pass while !ready + begin + client.recvmsg_nonblock(10) + rescue IO::EAGAINWaitReadable + retry + end + ensure + client.close if client + end + + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + socket = TCPSocket.new('127.0.0.1', @port) + socket.close + ready = true + + t.value.should == nil + end + end + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/recvmsg_spec.rb b/spec/ruby/library/socket/basicsocket/recvmsg_spec.rb index 58eb8d0360..eabfb9dd18 100644 --- a/spec/ruby/library/socket/basicsocket/recvmsg_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recvmsg_spec.rb @@ -17,7 +17,7 @@ describe 'BasicSocket#recvmsg' do platform_is_not :windows do describe 'using an unbound socket' do it 'blocks the caller' do - lambda { @server.recvmsg }.should block_caller + -> { @server.recvmsg }.should block_caller end end end @@ -29,7 +29,7 @@ describe 'BasicSocket#recvmsg' do describe 'without any data available' do it 'blocks the caller' do - lambda { @server.recvmsg }.should block_caller + -> { @server.recvmsg }.should block_caller end end @@ -41,7 +41,7 @@ describe 'BasicSocket#recvmsg' do end it 'returns an Array containing the data, an Addrinfo and the flags' do - @server.recvmsg.should be_an_instance_of(Array) + @server.recvmsg.should.instance_of?(Array) end describe 'without a maximum message length' do @@ -66,12 +66,12 @@ describe 'BasicSocket#recvmsg' do end it 'stores an Addrinfo at index 1' do - @array[1].should be_an_instance_of(Addrinfo) + @array[1].should.instance_of?(Addrinfo) end platform_is_not :windows do it 'stores the flags at index 2' do - @array[2].should be_kind_of(Integer) + @array[2].should.is_a?(Integer) end end @@ -126,7 +126,7 @@ describe 'BasicSocket#recvmsg' do it 'blocks the caller' do socket, _ = @server.accept begin - lambda { socket.recvmsg }.should block_caller + -> { socket.recvmsg }.should block_caller ensure socket.close end @@ -144,7 +144,7 @@ describe 'BasicSocket#recvmsg' do end it 'returns an Array containing the data, an Addrinfo and the flags' do - @socket.recvmsg.should be_an_instance_of(Array) + @socket.recvmsg.should.instance_of?(Array) end describe 'the returned Array' do @@ -157,11 +157,11 @@ describe 'BasicSocket#recvmsg' do end it 'stores an Addrinfo at index 1' do - @array[1].should be_an_instance_of(Addrinfo) + @array[1].should.instance_of?(Addrinfo) end it 'stores the flags at index 2' do - @array[2].should be_kind_of(Integer) + @array[2].should.is_a?(Integer) end describe 'the returned Addrinfo' do @@ -170,7 +170,7 @@ describe 'BasicSocket#recvmsg' do end it 'raises when receiving the ip_address message' do - lambda { @addr.ip_address }.should raise_error(SocketError) + -> { @addr.ip_address }.should.raise(SocketError) end it 'uses the correct address family' do @@ -186,7 +186,7 @@ describe 'BasicSocket#recvmsg' do end it 'raises when receiving the ip_port message' do - lambda { @addr.ip_port }.should raise_error(SocketError) + -> { @addr.ip_port }.should.raise(SocketError) end end end @@ -195,3 +195,63 @@ describe 'BasicSocket#recvmsg' do end end end + +describe 'BasicSocket#recvmsg' do + context "when recvfrom(2) returns 0 (if no messages are available to be received and the peer has performed an orderly shutdown)" do + describe "stream socket" do + before :each do + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + end + + after :each do + @server.close unless @server.closed? + end + + platform_is_not :windows do + it "returns nil on a closed stream socket" do + t = Thread.new do + client = @server.accept + client.recvmsg(10) + ensure + client.close if client + end + + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + socket = TCPSocket.new('127.0.0.1', @port) + socket.close + + t.value.should == nil + end + end + end + + describe "datagram socket" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @server = UDPSocket.new(family) + @client = UDPSocket.new(family) + end + + after :each do + @server.close unless @server.closed? + @client.close unless @client.closed? + end + + it "returns an empty String as received data" do + @server.bind(ip_address, 0) + addr = @server.connect_address + @client.connect(addr.ip_address, addr.ip_port) + + @client.send('', 0) + message = @server.recvmsg(1) + + message.should.is_a? Array + message[0].should == "" + end + end + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/remote_address_spec.rb b/spec/ruby/library/socket/basicsocket/remote_address_spec.rb new file mode 100644 index 0000000000..439bf31592 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/remote_address_spec.rb @@ -0,0 +1,10 @@ +require_relative '../spec_helper' +require_relative '../shared/address' + +describe 'BasicSocket#remote_address' do + it_behaves_like :socket_local_remote_address, :remote_address, -> socket { + a2 = BasicSocket.for_fd(socket.fileno) + a2.autoclose = false + a2.remote_address + } +end diff --git a/spec/ruby/library/socket/basicsocket/send_spec.rb b/spec/ruby/library/socket/basicsocket/send_spec.rb index c4845fc09e..a2c2ee8de9 100644 --- a/spec/ruby/library/socket/basicsocket/send_spec.rb +++ b/spec/ruby/library/socket/basicsocket/send_spec.rb @@ -9,36 +9,36 @@ describe "BasicSocket#send" do end after :each do - @server.closed?.should be_false - @socket.closed?.should be_false + @server.closed?.should == false + @socket.closed?.should == false @server.close @socket.close end - it "sends a message to another socket and returns the number of bytes sent" do - data = "" - t = Thread.new do - client = @server.accept - loop do - got = client.recv(5) - break if got.empty? - data << got - end - client.close - end - Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil - - @socket.send('hello', 0).should == 5 - @socket.shutdown(1) # indicate, that we are done sending - @socket.recv(10) - - t.join - data.should == 'hello' - end - - platform_is_not :solaris, :windows do + it "sends a message to another socket and returns the number of bytes sent" do + data = +"" + t = Thread.new do + client = @server.accept + loop do + got = client.recv(5) + break if got.nil? || got.empty? + data << got + end + client.close + end + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + @socket.send('hello', 0).should == 5 + @socket.shutdown(1) # indicate, that we are done sending + @socket.recv(10) + + t.join + data.should == 'hello' + end + + platform_is_not :windows do it "accepts flags to specify unusual sending behaviour" do data = nil peek_data = nil @@ -50,7 +50,7 @@ describe "BasicSocket#send" do client.close end Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil + t.status.should_not == nil @socket.send('helloU', Socket::MSG_PEEK | Socket::MSG_OOB).should == 6 @socket.shutdown # indicate, that we are done sending @@ -62,25 +62,25 @@ describe "BasicSocket#send" do end it "accepts a sockaddr as recipient address" do - data = "" - t = Thread.new do - client = @server.accept - loop do - got = client.recv(5) - break if got.empty? - data << got - end - client.close - end - Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil - - sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1") - @socket.send('hello', 0, sockaddr).should == 5 - @socket.shutdown # indicate, that we are done sending - - t.join - data.should == 'hello' + data = +"" + t = Thread.new do + client = @server.accept + loop do + got = client.recv(5) + break if got.nil? || got.empty? + data << got + end + client.close + end + Thread.pass while t.status and t.status != "sleep" + t.status.should_not == nil + + sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1") + @socket.send('hello', 0, sockaddr).should == 5 + @socket.shutdown # indicate, that we are done sending + + t.join + data.should == 'hello' end end @@ -99,9 +99,17 @@ describe 'BasicSocket#send' do @server.close end + describe 'with an object implementing #to_str' do + it 'returns the amount of sent bytes' do + data = mock('message') + data.should_receive(:to_str).and_return('hello') + @client.send(data, 0, @server.getsockname).should == 5 + end + end + describe 'without a destination address' do it "raises #{SocketSpecs.dest_addr_req_error}" do - lambda { @client.send('hello', 0) }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { @client.send('hello', 0) }.should.raise(SocketSpecs.dest_addr_req_error) end end @@ -113,7 +121,7 @@ describe 'BasicSocket#send' do it 'does not persist the connection after writing to the socket' do @client.send('hello', 0, @server.getsockname) - lambda { @client.send('hello', 0) }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { @client.send('hello', 0) }.should.raise(SocketSpecs.dest_addr_req_error) end end @@ -161,7 +169,7 @@ describe 'BasicSocket#send' do it 'sends the message to the given address instead' do @client.send('hello', 0, @alt_server.getsockname).should == 5 - lambda { @server.recv(5) }.should block_caller + -> { @server.recv(5) }.should block_caller @alt_server.recv(5).should == 'hello' end diff --git a/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb index de5e2aa749..4cd6e8bdca 100644 --- a/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb @@ -18,7 +18,12 @@ describe 'BasicSocket#sendmsg_nonblock' do describe 'without a destination address' do it "raises #{SocketSpecs.dest_addr_req_error}" do - lambda { @client.sendmsg_nonblock('hello') }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { + @client.sendmsg_nonblock('hello') + }.should.raise(SocketSpecs.dest_addr_req_error) + -> { + @client.sendmsg_nonblock('hello', exception: false) + }.should.raise(SocketSpecs.dest_addr_req_error) end end @@ -70,7 +75,7 @@ describe 'BasicSocket#sendmsg_nonblock' do it 'sends the message to the given address instead' do @client.sendmsg_nonblock('hello', 0, @alt_server.getsockname).should == 5 - lambda { @server.recv(5) }.should block_caller + -> { @server.recv(5) }.should block_caller @alt_server.recv(5).should == 'hello' end end @@ -94,9 +99,18 @@ describe 'BasicSocket#sendmsg_nonblock' do end it 'raises IO::WaitWritable when the underlying buffer is full' do - lambda { + -> { 10.times { @client.sendmsg_nonblock('hello' * 1_000_000) } - }.should raise_error(IO::WaitWritable) + }.should.raise(IO::WaitWritable) + end + + it 'returns :wait_writable when the underlying buffer is full with exception: false' do + ret = nil + 10.times { + ret = @client.sendmsg_nonblock('hello' * 1_000_000, exception: false) + break unless ret.is_a?(Integer) + } + ret.should == :wait_writable end end end diff --git a/spec/ruby/library/socket/basicsocket/sendmsg_spec.rb b/spec/ruby/library/socket/basicsocket/sendmsg_spec.rb index f2c11f443a..dc999b32df 100644 --- a/spec/ruby/library/socket/basicsocket/sendmsg_spec.rb +++ b/spec/ruby/library/socket/basicsocket/sendmsg_spec.rb @@ -19,7 +19,7 @@ describe 'BasicSocket#sendmsg' do platform_is_not :windows do describe 'without a destination address' do it "raises #{SocketSpecs.dest_addr_req_error}" do - lambda { @client.sendmsg('hello') }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { @client.sendmsg('hello') }.should.raise(SocketSpecs.dest_addr_req_error) end end end @@ -74,7 +74,7 @@ describe 'BasicSocket#sendmsg' do it 'sends the message to the given address instead' do @client.sendmsg('hello', 0, @alt_server.getsockname).should == 5 - lambda { @server.recv(5) }.should block_caller + -> { @server.recv(5) }.should block_caller @alt_server.recv(5).should == 'hello' end @@ -101,7 +101,7 @@ describe 'BasicSocket#sendmsg' do it 'blocks when the underlying buffer is full' do # Buffer sizes may differ per platform, so sadly this is the only # reliable way of testing blocking behaviour. - lambda do + -> do 10.times { @client.sendmsg('hello' * 1_000_000) } end.should block_caller end diff --git a/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb b/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb index 1471b03798..e306581aa3 100644 --- a/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb +++ b/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb @@ -38,9 +38,9 @@ describe "BasicSocket#setsockopt" do platform_is_not :windows do it "raises EINVAL if passed wrong linger value" do - lambda do + -> do @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, 0) - end.should raise_error(Errno::EINVAL) + end.should.raise(Errno::EINVAL) end end @@ -70,9 +70,9 @@ describe "BasicSocket#setsockopt" do n.should_not == [0].pack("i") platform_is_not :windows do - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) end @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "blah").should == 0 @@ -80,9 +80,9 @@ describe "BasicSocket#setsockopt" do n.should_not == [0].pack("i") platform_is_not :windows do - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "0") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) end @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00\x00").should == 0 @@ -90,15 +90,15 @@ describe "BasicSocket#setsockopt" do n.should == [0].pack("i") platform_is_not :windows do - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "1") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) end platform_is_not :windows do - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) end @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, [1].pack('i')).should == 0 @@ -125,9 +125,9 @@ describe "BasicSocket#setsockopt" do n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s n.unpack('i')[0].should >= 1 - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, nil).should == 0 - }.should raise_error(TypeError) + }.should.raise(TypeError) @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 1).should == 0 n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s @@ -137,25 +137,25 @@ describe "BasicSocket#setsockopt" do n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s n.unpack('i')[0].should >= 2 - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "bla") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "0") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "1") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) - lambda { + -> { @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "\x00\x00\x00") - }.should raise_error(SystemCallError) + }.should.raise(SystemCallError) @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "\x00\x00\x01\x00").should == 0 n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s @@ -207,7 +207,7 @@ describe "BasicSocket#setsockopt" do onoff, seconds = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).linger seconds.should == 10 # Both results can be produced depending on the OS and value of Socket::SO_LINGER - [true, Socket::SO_LINGER].should include(onoff) + [true, Socket::SO_LINGER].should.include?(onoff) end end end @@ -224,7 +224,7 @@ describe 'BasicSocket#setsockopt' do describe 'using separate arguments with Symbols' do it 'raises TypeError when the first argument is nil' do - lambda { @socket.setsockopt(nil, :REUSEADDR, true) }.should raise_error(TypeError) + -> { @socket.setsockopt(nil, :REUSEADDR, true) }.should.raise(TypeError) end it 'sets a boolean option' do @@ -251,7 +251,7 @@ describe 'BasicSocket#setsockopt' do platform_is_not :windows do it 'raises Errno::EINVAL when setting an invalid option value' do - lambda { @socket.setsockopt(:SOCKET, :OOBINLINE, 'bla') }.should raise_error(Errno::EINVAL) + -> { @socket.setsockopt(:SOCKET, :OOBINLINE, 'bla') }.should.raise(Errno::EINVAL) end end end @@ -305,32 +305,30 @@ describe 'BasicSocket#setsockopt' do it 'raises ArgumentError when passing 2 arguments' do option = Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true) - lambda { @socket.setsockopt(option, :REUSEADDR) }.should raise_error(ArgumentError) + -> { @socket.setsockopt(option, :REUSEADDR) }.should.raise(ArgumentError) end it 'raises TypeError when passing 3 arguments' do option = Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true) - lambda { @socket.setsockopt(option, :REUSEADDR, true) }.should raise_error(TypeError) + -> { @socket.setsockopt(option, :REUSEADDR, true) }.should.raise(TypeError) end end end - with_feature :unix_socket do - describe 'using a UNIX socket' do - before do - @path = SocketSpecs.socket_path - @server = UNIXServer.new(@path) - end + describe 'using a UNIX socket' do + before do + @path = SocketSpecs.socket_path + @server = UNIXServer.new(@path) + end - after do - @server.close - rm_r @path - end + after do + @server.close + rm_r @path + end - it 'sets a boolean option' do - @server.setsockopt(:SOCKET, :REUSEADDR, true) - @server.getsockopt(:SOCKET, :REUSEADDR).bool.should == true - end + it 'sets a boolean option' do + @server.setsockopt(:SOCKET, :REUSEADDR, true) + @server.getsockopt(:SOCKET, :REUSEADDR).bool.should == true end end end diff --git a/spec/ruby/library/socket/basicsocket/shutdown_spec.rb b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb index 87a32ae1dc..c96c62abe1 100644 --- a/spec/ruby/library/socket/basicsocket/shutdown_spec.rb +++ b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb @@ -23,25 +23,25 @@ platform_is_not :windows do # hangs it 'shuts down a socket for reading' do @client.shutdown(Socket::SHUT_RD) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for writing' do @client.shutdown(Socket::SHUT_WR) - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'shuts down a socket for reading and writing' do @client.shutdown(Socket::SHUT_RDWR) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'raises ArgumentError when using an invalid option' do - lambda { @server.shutdown(666) }.should raise_error(ArgumentError) + -> { @server.shutdown(666) }.should.raise(ArgumentError) end end @@ -49,37 +49,37 @@ platform_is_not :windows do # hangs it 'shuts down a socket for reading using :RD' do @client.shutdown(:RD) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for reading using :SHUT_RD' do @client.shutdown(:SHUT_RD) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for writing using :WR' do @client.shutdown(:WR) - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'shuts down a socket for writing using :SHUT_WR' do @client.shutdown(:SHUT_WR) - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'shuts down a socket for reading and writing' do @client.shutdown(:RDWR) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'raises ArgumentError when using an invalid option' do - lambda { @server.shutdown(:Nope) }.should raise_error(SocketError) + -> { @server.shutdown(:Nope) }.should.raise(SocketError) end end @@ -87,29 +87,29 @@ platform_is_not :windows do # hangs it 'shuts down a socket for reading using "RD"' do @client.shutdown('RD') - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for reading using "SHUT_RD"' do @client.shutdown('SHUT_RD') - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for writing using "WR"' do @client.shutdown('WR') - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'shuts down a socket for writing using "SHUT_WR"' do @client.shutdown('SHUT_WR') - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end it 'raises ArgumentError when using an invalid option' do - lambda { @server.shutdown('Nope') }.should raise_error(SocketError) + -> { @server.shutdown('Nope') }.should.raise(SocketError) end end @@ -123,7 +123,7 @@ platform_is_not :windows do # hangs @client.shutdown(@dummy) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for reading using "SHUT_RD"' do @@ -131,7 +131,7 @@ platform_is_not :windows do # hangs @client.shutdown(@dummy) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? end it 'shuts down a socket for reading and writing' do @@ -139,15 +139,15 @@ platform_is_not :windows do # hangs @client.shutdown(@dummy) - @client.recv(1).should be_empty + @client.recv(1).to_s.should.empty? - lambda { @client.write('hello') }.should raise_error(Errno::EPIPE) + -> { @client.write('hello') }.should.raise(Errno::EPIPE) end end describe 'using an object that does not respond to #to_str' do it 'raises TypeError' do - lambda { @server.shutdown(mock(:dummy)) }.should raise_error(TypeError) + -> { @server.shutdown(mock(:dummy)) }.should.raise(TypeError) end end end diff --git a/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb new file mode 100644 index 0000000000..523e732959 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb @@ -0,0 +1,43 @@ +require_relative '../spec_helper' +require_relative '../fixtures/classes' + +describe "BasicSocket#write_nonblock" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @r = Socket.new(family, :DGRAM) + @w = Socket.new(family, :DGRAM) + + @r.bind(Socket.pack_sockaddr_in(0, ip_address)) + @w.connect(@r.getsockname) + end + + after :each do + @r.close unless @r.closed? + @w.close unless @w.closed? + end + + it "sends data" do + @w.write_nonblock("aaa").should == 3 + IO.select([@r], nil, nil, 2) + @r.recv_nonblock(5).should == "aaa" + end + + platform_is :linux do + it 'does not set the IO in nonblock mode' do + require 'io/nonblock' + @w.nonblock = false + @w.write_nonblock("aaa").should == 3 + @w.should_not.nonblock? + end + end + + platform_is_not :linux, :windows do + it 'sets the IO in nonblock mode' do + require 'io/nonblock' + @w.nonblock = false + @w.write_nonblock("aaa").should == 3 + @w.should.nonblock? + end + end + end +end |
