summaryrefslogtreecommitdiff
path: root/spec/rubyspec/library/socket/socket/connect_nonblock_spec.rb
blob: fd92c0740cf15b850d16d9ce4cc2bbefe2f79f43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
require File.expand_path('../../../../spec_helper', __FILE__)
require File.expand_path('../../fixtures/classes', __FILE__)

require 'socket'

describe "Socket#connect_nonblock" do
  before :each do
    @hostname = "127.0.0.1"
    @server = TCPServer.new(@hostname, 0) # started, but no accept
    @addr = Socket.sockaddr_in(@server.addr[1], @hostname)
    @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    @thread = nil
  end

  after :each do
    @socket.close
    @thread.join if @thread
  end

  it "connects the socket to the remote side" do
    port = nil
    accept = false
    @thread = Thread.new do
      server = TCPServer.new(@hostname, 0)
      port = server.addr[1]
      Thread.pass until accept
      conn = server.accept
      conn << "hello!"
      conn.close
      server.close
    end

    Thread.pass until port

    addr = Socket.sockaddr_in(port, @hostname)
    begin
      @socket.connect_nonblock(addr)
    rescue Errno::EINPROGRESS
    end

    accept = true
    IO.select nil, [@socket]

    begin
      @socket.connect_nonblock(addr)
    rescue Errno::EISCONN
      # Not all OS's use this errno, so we trap and ignore it
    end

    @socket.read(6).should == "hello!"
  end

  platform_is_not :freebsd, :solaris, :aix do
    it "raises Errno::EINPROGRESS when the connect would block" do
      lambda do
        @socket.connect_nonblock(@addr)
      end.should raise_error(Errno::EINPROGRESS)
    end

    it "raises Errno::EINPROGRESS with IO::WaitWritable mixed in when the connect would block" do
      lambda do
        @socket.connect_nonblock(@addr)
      end.should raise_error(IO::WaitWritable)
    end

    ruby_version_is "2.3" do
      it "returns :wait_writable in exceptionless mode when the connect would block" do
        @socket.connect_nonblock(@addr, exception: false).should == :wait_writable
      end
    end
  end
end