|
74 | 74 | it "should support the timeout accessor for read" do |
75 | 75 | @socket.timeout = 3 |
76 | 76 | @socket.open |
77 | | - expect(IO).to receive(:select).with([@handle], nil, nil, 3).and_return([[@handle], [], []]) |
78 | | - expect(@handle).to receive(:readpartial).with(17).and_return("test data") |
| 77 | + expect(@handle).to receive(:read_nonblock).with(17).and_raise(IO::EAGAINWaitReadable) |
| 78 | + expect(IO).to receive(:select) do |rd, wr, err, timeout| |
| 79 | + expect(rd).to eq([@handle]) |
| 80 | + expect(wr).to be_nil |
| 81 | + expect(err).to be_nil |
| 82 | + expect(timeout).to be > 0 |
| 83 | + expect(timeout).to be <= 3 |
| 84 | + [[@handle], [], []] |
| 85 | + end |
| 86 | + expect(@handle).to receive(:read_nonblock).with(17).and_return("test data") |
79 | 87 | expect(@socket.read(17)).to eq("test data") |
80 | 88 | end |
81 | 89 |
|
82 | 90 | it "should support the timeout accessor for write" do |
83 | 91 | @socket.timeout = 3 |
84 | 92 | @socket.open |
85 | | - expect(IO).to receive(:select).with(nil, [@handle], nil, 3).twice.and_return([[], [@handle], []]) |
86 | | - expect(@handle).to receive(:write_nonblock).with("test data").and_return(4) |
87 | | - expect(@handle).to receive(:write_nonblock).with(" data").and_return(5) |
| 93 | + write_calls = 0 |
| 94 | + expect(@handle).to receive(:write_nonblock).exactly(3).times do |chunk| |
| 95 | + write_calls += 1 |
| 96 | + case write_calls |
| 97 | + when 1 |
| 98 | + expect(chunk).to eq("test data") |
| 99 | + raise IO::EAGAINWaitWritable |
| 100 | + when 2 |
| 101 | + expect(chunk).to eq("test data") |
| 102 | + 4 |
| 103 | + when 3 |
| 104 | + expect(chunk).to eq(" data") |
| 105 | + 5 |
| 106 | + end |
| 107 | + end |
| 108 | + expect(IO).to receive(:select) do |rd, wr, err, timeout| |
| 109 | + expect(rd).to be_nil |
| 110 | + expect(wr).to eq([@handle]) |
| 111 | + expect(err).to be_nil |
| 112 | + expect(timeout).to be > 0 |
| 113 | + expect(timeout).to be <= 3 |
| 114 | + [[], [@handle], []] |
| 115 | + end |
88 | 116 | expect(@socket.write("test data")).to eq(9) |
89 | 117 | end |
90 | 118 |
|
91 | 119 | it "should raise an error when read times out" do |
92 | 120 | @socket.timeout = 0.5 |
93 | 121 | @socket.open |
94 | | - expect(IO).to receive(:select).once {sleep(0.5); nil} |
| 122 | + expect(@handle).to receive(:read_nonblock).with(17).and_raise(IO::EAGAINWaitReadable) |
| 123 | + expect(IO).to receive(:select).once { sleep(0.6); nil } |
95 | 124 | expect { @socket.read(17) }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::TIMED_OUT) } |
96 | 125 | end |
97 | 126 |
|
98 | 127 | it "should raise an error when write times out" do |
99 | 128 | @socket.timeout = 0.5 |
100 | 129 | @socket.open |
101 | | - allow(IO).to receive(:select).with(nil, [@handle], nil, 0.5).and_return(nil) |
| 130 | + expect(@handle).to receive(:write_nonblock).with("test data").and_raise(IO::EAGAINWaitWritable) |
| 131 | + expect(IO).to receive(:select).once { sleep(0.6); nil } |
102 | 132 | expect { @socket.write("test data") }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::TIMED_OUT) } |
103 | 133 | end |
| 134 | + |
| 135 | + it "should read buffered SSL data without waiting on the raw socket again" do |
| 136 | + @socket.timeout = 1 |
| 137 | + @socket.open |
| 138 | + |
| 139 | + expect(@handle).to receive(:read_nonblock).with(4).ordered.and_raise(IO::EAGAINWaitReadable) |
| 140 | + expect(IO).to receive(:select).once.ordered do |rd, wr, err, timeout| |
| 141 | + expect(rd).to eq([@handle]) |
| 142 | + expect(wr).to be_nil |
| 143 | + expect(err).to be_nil |
| 144 | + expect(timeout).to be > 0 |
| 145 | + expect(timeout).to be <= 1 |
| 146 | + [[@handle], [], []] |
| 147 | + end |
| 148 | + expect(@handle).to receive(:read_nonblock).with(4).ordered.and_return("ABCD") |
| 149 | + expect(@handle).to receive(:read_nonblock).with(5).ordered.and_return("12345") |
| 150 | + |
| 151 | + expect(@socket.read(4)).to eq("ABCD") |
| 152 | + expect(@socket.read(5)).to eq("12345") |
| 153 | + end |
| 154 | + |
| 155 | + it "should read without timeout using the blocking path" do |
| 156 | + @socket.timeout = nil |
| 157 | + @socket.open |
| 158 | + |
| 159 | + expect(IO).not_to receive(:select) |
| 160 | + expect(@handle).not_to receive(:read_nonblock) |
| 161 | + expect(@handle).to receive(:readpartial).with(4).ordered.and_return("ABCD") |
| 162 | + expect(@handle).to receive(:readpartial).with(5).ordered.and_return("12345") |
| 163 | + |
| 164 | + expect(@socket.read(4)).to eq("ABCD") |
| 165 | + expect(@socket.read(5)).to eq("12345") |
| 166 | + end |
104 | 167 | end |
0 commit comments