diff options
Diffstat (limited to 'spec/ruby/library/socket/basicsocket')
13 files changed, 701 insertions, 0 deletions
diff --git a/spec/ruby/library/socket/basicsocket/close_read_spec.rb b/spec/ruby/library/socket/basicsocket/close_read_spec.rb new file mode 100644 index 0000000000..c71e1acaf9 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/close_read_spec.rb @@ -0,0 +1,43 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#close_read" do + before :each do + @server = TCPServer.new(0) + end + + after :each do + @server.close unless @server.closed? + end + + it "closes the reading end of the socket" do + @server.close_read + lambda { @server.read }.should raise_error(IOError) + end + + it "it works on sockets with closed ends" do + @server.close_read + lambda { @server.close_read }.should_not raise_error(Exception) + lambda { @server.read }.should raise_error(IOError) + end + + it "does not close the socket" do + @server.close_read + @server.closed?.should be_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 + end + + it "raises IOError on closed socket" do + @server.close + lambda { @server.close_read }.should raise_error(IOError) + end + + it "returns nil" do + @server.close_read.should be_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 new file mode 100644 index 0000000000..a00f5d5870 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/close_write_spec.rb @@ -0,0 +1,48 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#close_write" do + before :each do + @server = TCPServer.new(0) + end + + after :each do + @server.close unless @server.closed? + end + + it "closes the writing end of the socket" do + @server.close_write + lambda { @server.write("foo") }.should raise_error(IOError) + end + + it "works on sockets with closed write ends" do + @server.close_write + lambda { @server.close_write }.should_not raise_error(Exception) + lambda { @server.write("foo") }.should raise_error(IOError) + end + + it "does not close the socket" do + @server.close_write + @server.closed?.should be_false + end + + it "does not prevent reading" do + @server.close_write + @server.read(0).should == "" + end + + it "fully closes the socket if it was already closed for reading" do + @server.close_read + @server.close_write + @server.closed?.should be_true + end + + it "raises IOError on closed socket" do + @server.close + lambda { @server.close_write }.should raise_error(IOError) + end + + it "returns nil" do + @server.close_write.should be_nil + 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 new file mode 100644 index 0000000000..3ef3a686e2 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb @@ -0,0 +1,39 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +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] + @socket = TCPSocket.new('127.0.0.1', @port) + end + + after :each do + @server.close unless @server.closed? + @socket.close unless @socket.closed? + BasicSocket.do_not_reverse_lookup = @do_not_reverse_lookup + end + + it "defaults to true" do + BasicSocket.do_not_reverse_lookup.should be_true + end + + it "causes 'peeraddr' to avoid name lookups" do + @socket.do_not_reverse_lookup = true + BasicSocket.do_not_reverse_lookup = true + @socket.peeraddr.should == ["AF_INET", @port, "127.0.0.1", "127.0.0.1"] + end + + it "looks for hostnames when set to false" do + @socket.do_not_reverse_lookup = false + BasicSocket.do_not_reverse_lookup = false + @socket.peeraddr[2].should == SocketSpecs.hostname + end + + it "looks for numeric addresses when set to true" do + @socket.do_not_reverse_lookup = true + BasicSocket.do_not_reverse_lookup = true + @socket.peeraddr[2].should == "127.0.0.1" + end +end diff --git a/spec/ruby/library/socket/basicsocket/for_fd_spec.rb b/spec/ruby/library/socket/basicsocket/for_fd_spec.rb new file mode 100644 index 0000000000..164e4dc93c --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/for_fd_spec.rb @@ -0,0 +1,21 @@ + +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "BasicSocket#for_fd" do + before :each do + @server = TCPServer.new(0) + @s2 = nil + end + + after :each do + @server.close if @server + end + + 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.fileno.should == @server.fileno + end +end diff --git a/spec/ruby/library/socket/basicsocket/getpeername_spec.rb b/spec/ruby/library/socket/basicsocket/getpeername_spec.rb new file mode 100644 index 0000000000..cecf590092 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/getpeername_spec.rb @@ -0,0 +1,26 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#getpeername" do + + before :each do + @server = TCPServer.new("127.0.0.1", 0) + @port = @server.addr[1] + @client = TCPSocket.new("127.0.0.1", @port) + end + + after :each do + @server.close unless @server.closed? + @client.close unless @client.closed? + end + + it "returns the sockaddr of the other end of the connection" do + server_sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1") + @client.getpeername.should == server_sockaddr + end + + # Catch general exceptions to prevent NotImplementedError + it "raises an error if socket's not connected" do + lambda { @server.getpeername }.should raise_error(Exception) + end +end diff --git a/spec/ruby/library/socket/basicsocket/getsockname_spec.rb b/spec/ruby/library/socket/basicsocket/getsockname_spec.rb new file mode 100644 index 0000000000..cb3a45eb5f --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/getsockname_spec.rb @@ -0,0 +1,28 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#getsockname" do + after :each do + @socket.closed?.should be_false + @socket.close + end + + it "returns the sockaddr associacted with the socket" do + @socket = TCPServer.new("127.0.0.1", 0) + sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname) + sockaddr.should == [@socket.addr[1], "127.0.0.1"] + end + + 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 + sockaddr[0].should == @socket.addr[1] + end + + it "returns empty sockaddr for unbinded sockets" do + @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) + sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname) + sockaddr.should == [0, "0.0.0.0"] + end +end diff --git a/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb b/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb new file mode 100644 index 0000000000..dc4fffa5c1 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/getsockopt_spec.rb @@ -0,0 +1,46 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "BasicSocket#getsockopt" do + before :each do + @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) + end + + after :each do + @sock.closed?.should be_false + @sock.close + end + + platform_is_not :aix do + # A known bug in AIX. getsockopt(2) does not properly set + # the fifth argument for SO_TYPE, SO_OOBINLINE, SO_BROADCAST, etc. + + it "gets a socket option Socket::SO_TYPE" do + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE).to_s + n.should == [Socket::SOCK_STREAM].pack("i") + end + + it "gets a socket option Socket::SO_OOBINLINE" do + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should == [0].pack("i") + end + end + + it "gets a socket option Socket::SO_LINGER" do + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s + if (n.size == 8) # linger struct on some platforms, not just a value + n.should == [0, 0].pack("ii") + else + n.should == [0].pack("i") + end + end + + it "gets a socket option Socket::SO_SNDBUF" do + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s + n.unpack('i')[0].should > 0 + end + + it "raises a SystemCallError with an invalid socket option" do + lambda { @sock.getsockopt Socket::SOL_SOCKET, -1 }.should raise_error(Errno::ENOPROTOOPT) + end +end diff --git a/spec/ruby/library/socket/basicsocket/ioctl_spec.rb b/spec/ruby/library/socket/basicsocket/ioctl_spec.rb new file mode 100644 index 0000000000..9a7f535317 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/ioctl_spec.rb @@ -0,0 +1,43 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require 'socket' + +describe "Socket::BasicSocket#ioctl" do + platform_is :linux do + it "passes data from and to a String correctly" do + s = Socket.new Socket::AF_INET, Socket::SOCK_DGRAM, 0 + # /usr/include/net/if.h, structure ifreq + # The structure is 32 bytes on x86, 40 bytes on x86_64 + if_name = ['lo'].pack('a16') + buffer = if_name + 'z' * 24 + # SIOCGIFADDR in /usr/include/bits/ioctls.h + s.ioctl 0x8915, buffer + s.close + + # Interface name should remain unchanged. + buffer[0, 16].should == if_name + # lo should have an IPv4 address of 127.0.0.1 + buffer[16, 2].unpack('S!').first.should == Socket::AF_INET + buffer[20, 4].should == "\x7f\0\0\x01" + end + end + + platform_is :freebsd do + it "passes data from and to a String correctly" do + s = Socket.new Socket::AF_INET, Socket::SOCK_DGRAM, 0 + # /usr/include/net/if.h, structure ifreq + # The structure is 32 bytes on x86, 40 bytes on x86_64 + if_name = ['lo0'].pack('a16') + buffer = if_name + 'z' * 24 + # SIOCGIFADDR in /usr/include/bits/ioctls.h + s.ioctl 0xc0206921, buffer + s.close + + # Interface name should remain unchanged. + buffer[0, 16].should == if_name + # lo should have an IPv4 address of 127.0.0.1 + buffer[16, 1].unpack('C').first.should == 16 + buffer[17, 1].unpack('C').first.should == Socket::AF_INET + buffer[20, 4].should == "\x7f\0\0\x01" + 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 new file mode 100644 index 0000000000..2c948eaa2f --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb @@ -0,0 +1,7 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../shared/recv_nonblock', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#recv_nonblock" do + it_behaves_like :socket_recv_nonblock, :recv_nonblock +end diff --git a/spec/ruby/library/socket/basicsocket/recv_spec.rb b/spec/ruby/library/socket/basicsocket/recv_spec.rb new file mode 100644 index 0000000000..5891bf9c87 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/recv_spec.rb @@ -0,0 +1,96 @@ +# -*- encoding: binary -*- +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "BasicSocket#recv" 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? + ScratchPad.clear + end + + it "receives a specified number of bytes of a message from another socket" do + t = Thread.new do + client = @server.accept + ScratchPad.record client.recv(10) + client.recv(1) # this recv is important + 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('hello', 0) + socket.close + + t.join + 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 + + # 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' + end + end + + it "gets lines delimited with a custom separator" do + t = Thread.new do + client = @server.accept + ScratchPad.record client.gets("\377") + + # this call is important (TODO: explain) + client.gets(nil) + 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.write("firstline\377secondline\377") + socket.close + + t.join + ScratchPad.recorded.should == "firstline\377" + end + + ruby_version_is "2.3" do + it "allows an output buffer as third argument" do + socket = TCPSocket.new('127.0.0.1', @port) + socket.write("data") + + client = @server.accept + buf = "foo" + begin + client.recv(4, 0, buf) + ensure + client.close + end + buf.should == "data" + + socket.close + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/send_spec.rb b/spec/ruby/library/socket/basicsocket/send_spec.rb new file mode 100644 index 0000000000..4df0d04a10 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/send_spec.rb @@ -0,0 +1,85 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "BasicSocket#send" do + before :each do + @server = TCPServer.new('127.0.0.1', 0) + @port = @server.addr[1] + @socket = TCPSocket.new('127.0.0.1', @port) + end + + after :each do + @server.closed?.should be_false + @socket.closed?.should be_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 "accepts flags to specify unusual sending behaviour" do + data = nil + peek_data = nil + t = Thread.new do + client = @server.accept + peek_data = client.recv(6, Socket::MSG_PEEK) + data = client.recv(6) + client.recv(10) # this recv is important + client.close + end + Thread.pass while t.status and t.status != "sleep" + t.status.should_not be_nil + + @socket.send('helloU', Socket::MSG_PEEK | Socket::MSG_OOB).should == 6 + @socket.shutdown # indicate, that we are done sending + + t.join + peek_data.should == "hello" + data.should == 'hello' + end + 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' + end +end diff --git a/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb b/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb new file mode 100644 index 0000000000..523a22d957 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/setsockopt_spec.rb @@ -0,0 +1,213 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "BasicSocket#setsockopt" do + + before :each do + @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) + end + + after :each do + @sock.close unless @sock.closed? + end + + it "sets the socket linger to 0" do + linger = [0, 0].pack("ii") + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s + + if (n.size == 8) # linger struct on some platforms, not just a value + n.should == [0, 0].pack("ii") + else + n.should == [0].pack("i") + end + end + + it "sets the socket linger to some positive value" do + linger = [64, 64].pack("ii") + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s + if (n.size == 8) # linger struct on some platforms, not just a value + a = n.unpack('ii') + a[0].should_not == 0 + a[1].should == 64 + else + n.should == [64].pack("i") + end + end + + platform_is_not :windows do + it "raises EINVAL if passed wrong linger value" do + lambda do + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, 0) + end.should raise_error(Errno::EINVAL) + end + end + + platform_is_not :aix do + # A known bug in AIX. getsockopt(2) does not properly set + # the fifth argument for SO_TYPE, SO_OOBINLINE, SO_BROADCAST, etc. + + it "sets the socket option Socket::SO_OOBINLINE" do + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, true).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should_not == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, false).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 1).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should_not == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 0).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 2).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should_not == [0].pack("i") + + platform_is_not :windows do + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "") + }.should raise_error(SystemCallError) + end + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "blah").should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + 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) + end + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00\x00").should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should == [0].pack("i") + + platform_is_not :windows do + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "1") + }.should raise_error(SystemCallError) + end + + platform_is_not :windows do + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00") + }.should raise_error(SystemCallError) + end + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, [1].pack('i')).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should_not == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, [0].pack('i')).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should == [0].pack("i") + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, [1000].pack('i')).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s + n.should_not == [0].pack("i") + end + end + + it "sets the socket option Socket::SO_SNDBUF" do + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 4000).should == 0 + sndbuf = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s + # might not always be possible to set to exact size + sndbuf.unpack('i')[0].should >= 4000 + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, true).should == 0 + 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) + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 1).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s + n.unpack('i')[0].should >= 1 + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 2).should == 0 + 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) + + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "bla") + }.should raise_error(SystemCallError) + + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "0") + }.should raise_error(SystemCallError) + + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "1") + }.should raise_error(SystemCallError) + + lambda { + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "\x00\x00\x00") + }.should raise_error(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 + n.unpack('i')[0].should >= "\x00\x00\x01\x00".unpack('i')[0] + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, [4000].pack('i')).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s + n.unpack('i')[0].should >= 4000 + + @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, [1000].pack('i')).should == 0 + n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s + n.unpack('i')[0].should >= 1000 + end + + platform_is_not :aix do + describe 'accepts Socket::Option as argument' do + it 'boolean' do + option = Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true) + @sock.setsockopt(option).should == 0 + @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE).bool.should == true + end + + it 'int' do + option = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1) + @sock.setsockopt(option).should == 0 + @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE).bool.should == true + end + end + end + + platform_is :aix do + describe 'accepts Socket::Option as argument' do + it 'boolean' do + option = Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true) + @sock.setsockopt(option).should == 0 + end + + it 'int' do + option = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1) + @sock.setsockopt(option).should == 0 + end + end + end + + describe 'accepts Socket::Option as argument' do + it 'linger' do + option = Socket::Option.linger(true, 10) + @sock.setsockopt(option).should == 0 + 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) + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/shutdown_spec.rb b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb new file mode 100644 index 0000000000..c874f08697 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb @@ -0,0 +1,6 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/classes', __FILE__) + +describe "Socket::BasicSocket#shutdown" do + +end |