expect-pty 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +28 -19
- data/docs/API.md +88 -0
- data/docs/MIGRATION.md +15 -0
- data/lib/expect/cleanup.rb +33 -0
- data/lib/expect/configuration.rb +87 -66
- data/lib/expect/interaction.rb +226 -209
- data/lib/expect/logging.rb +157 -156
- data/lib/expect/matcher.rb +30 -29
- data/lib/expect/pattern.rb +8 -2
- data/lib/expect/pattern_list.rb +35 -5
- data/lib/expect/redactor.rb +11 -4
- data/lib/expect/relay.rb +97 -73
- data/lib/expect/relay_writer.rb +2 -1
- data/lib/expect/result.rb +32 -8
- data/lib/expect/session.rb +508 -0
- data/lib/expect/session_resources.rb +10 -2
- data/lib/expect/terminal.rb +78 -78
- data/lib/expect/version.rb +1 -1
- data/lib/expect.rb +333 -520
- data/sig/expect.rbs +355 -0
- metadata +13 -106
- data/.rubocop.yml +0 -66
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -28
- data/Rakefile +0 -38
- data/benchmark/matching.rb +0 -98
- data/benchmark/redactor.rb +0 -64
- data/benchmark/relay.rb +0 -48
- data/benchmark/scaling.rb +0 -70
- data/benchmark/send_slow.rb +0 -41
- data/benchmark/support.rb +0 -114
- data/docs/COMPATIBILITY.md +0 -98
- data/docs/INTERNAL_CONTRACTS.md +0 -154
- data/docs/PERFORMANCE.md +0 -165
- data/docs/RELEASING.md +0 -84
- data/docs/VERIFICATION.md +0 -456
- data/examples/dialogue.rb +0 -30
- data/examples/kibitz/README.md +0 -81
- data/examples/kibitz/kibitz.rb +0 -142
- data/examples/kibitz/test_kibitz.rb +0 -37
- data/examples/ssh_auto.rb +0 -94
- data/examples/ssh_interact.rb +0 -159
- data/examples/ssh_login.rb +0 -64
- data/expect-pty.gemspec +0 -33
- data/script/ci +0 -121
- data/script/release.rb +0 -319
- data/test/buffer_accounting_test.rb +0 -83
- data/test/cleanup_test.rb +0 -251
- data/test/compare_upstream.rb +0 -157
- data/test/configuration_test.rb +0 -133
- data/test/deadline_test.rb +0 -237
- data/test/diagnostics_test.rb +0 -353
- data/test/edge_case_test.rb +0 -262
- data/test/fixtures/ssh_scripts/01_identity.sh +0 -4
- data/test/fixtures/ssh_scripts/02_output.sh +0 -5
- data/test/fixtures/ssh_scripts/03_delayed.sh +0 -6
- data/test/fixtures/ssh_scripts/04_failure.sh +0 -2
- data/test/fixtures/ssh_scripts/05_recovery.sh +0 -3
- data/test/initialization_failure_test.rb +0 -92
- data/test/integration/README.md +0 -109
- data/test/integration/ssh_scripts.rb +0 -94
- data/test/interact_test.rb +0 -253
- data/test/interconnect_test.rb +0 -425
- data/test/io_test.rb +0 -321
- data/test/kibitz_test.rb +0 -45
- data/test/lifecycle_contract_test.rb +0 -71
- data/test/literal_scan_test.rb +0 -97
- data/test/matching_test.rb +0 -211
- data/test/multi_session_test.rb +0 -66
- data/test/ownership_sequence_test.rb +0 -208
- data/test/pattern_offset_test.rb +0 -43
- data/test/process_interruption_test.rb +0 -296
- data/test/process_test.rb +0 -291
- data/test/redactor_test.rb +0 -183
- data/test/relay_recovery_test.rb +0 -451
- data/test/relay_reentrancy_test.rb +0 -159
- data/test/release_test.rb +0 -375
- data/test/ruby_api_test.rb +0 -515
- data/test/scan_reuse_test.rb +0 -109
- data/test/script_logging_test.rb +0 -124
- data/test/support/interact_probe.rb +0 -125
- data/test/support/kibitz_probe.rb +0 -177
- data/test/support/script_probe.rb +0 -158
- data/test/terminal_cleanup_test.rb +0 -349
- data/test/test_helper.rb +0 -58
- data/test/timeout_test.rb +0 -289
- data/test/write_contract_test.rb +0 -105
data/test/interconnect_test.rb
DELETED
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "test_helper"
|
|
4
|
-
|
|
5
|
-
class InterconnectTest < ExpectTest
|
|
6
|
-
def test_escape_callback_can_match_new_input_and_return_its_tail
|
|
7
|
-
session, writer = pipe_session
|
|
8
|
-
output = StringIO.new
|
|
9
|
-
session.listeners = [output]
|
|
10
|
-
result = nil
|
|
11
|
-
session.on_sequence("!") do
|
|
12
|
-
writer.write("ready tail")
|
|
13
|
-
result = session.expect("ready", timeout: 0.05)
|
|
14
|
-
false
|
|
15
|
-
end
|
|
16
|
-
session.buffer = "!"
|
|
17
|
-
|
|
18
|
-
assert_same(session, bounded { Expect.interconnect(session, timeout: 1) })
|
|
19
|
-
assert_equal 1, result
|
|
20
|
-
assert_equal " tail", session.buffer
|
|
21
|
-
assert_empty output.string
|
|
22
|
-
Expect.interconnect(session, timeout: 0)
|
|
23
|
-
assert_equal " tail", output.string
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def test_escape_callback_can_match_previously_read_tail
|
|
27
|
-
session, = pipe_session
|
|
28
|
-
result = nil
|
|
29
|
-
session.on_sequence("!") do
|
|
30
|
-
result = session.expect("ready", timeout: 0)
|
|
31
|
-
false
|
|
32
|
-
end
|
|
33
|
-
session.buffer = "!ready tail"
|
|
34
|
-
|
|
35
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
36
|
-
assert_equal 1, result
|
|
37
|
-
assert_equal " tail", session.buffer
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def test_callback_match_failure_returns_unconsumed_bytes_to_relay
|
|
41
|
-
session, writer = pipe_session
|
|
42
|
-
session.on_sequence("!") do
|
|
43
|
-
writer.write("\xff".b)
|
|
44
|
-
session.expect(/ready/u, timeout: 0.05)
|
|
45
|
-
end
|
|
46
|
-
session.buffer = "!prefix"
|
|
47
|
-
|
|
48
|
-
assert_raises(EncodingError) { bounded { Expect.interconnect(session, timeout: 1) } }
|
|
49
|
-
assert_equal "prefix\xff".b, session.buffer
|
|
50
|
-
assert_nil session.__send__(:interaction_buffer)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def test_timeout_flush_leaves_blocked_output_pending_without_reading_after_deadline
|
|
54
|
-
reader, writer = IO.pipe
|
|
55
|
-
sink, sink_writer = IO.pipe
|
|
56
|
-
@ios.push(reader, writer, sink, sink_writer)
|
|
57
|
-
loop { break if sink_writer.write_nonblock("x" * 4096, exception: false) == :wait_writable }
|
|
58
|
-
session = Expect.open(reader, writer: sink_writer, write_timeout: 1)
|
|
59
|
-
@sessions << session
|
|
60
|
-
# A loopback listener must not wait or read more input after the deadline.
|
|
61
|
-
session.listeners = [session]
|
|
62
|
-
session.on_sequence("STOP")
|
|
63
|
-
session.buffer = "ST"
|
|
64
|
-
writer.write("tail")
|
|
65
|
-
original = IO.method(:select)
|
|
66
|
-
poll = true
|
|
67
|
-
select = lambda do |*arguments|
|
|
68
|
-
if poll
|
|
69
|
-
poll = false
|
|
70
|
-
nil
|
|
71
|
-
else
|
|
72
|
-
original.call(*arguments)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
IO.stub(:select, select) { assert_nil Expect.interconnect(session, timeout: 0) }
|
|
77
|
-
assert session.pending_output?
|
|
78
|
-
assert_empty session.buffer
|
|
79
|
-
session.listeners = []
|
|
80
|
-
assert_equal 1, session.expect("tail", timeout: 0)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_backpressure_reads_still_apply_escape_sequences
|
|
84
|
-
source, = pipe_session
|
|
85
|
-
reader, writer = IO.pipe
|
|
86
|
-
sink, sink_writer = IO.pipe
|
|
87
|
-
@ios.push(reader, writer, sink, sink_writer)
|
|
88
|
-
loop { break if sink_writer.write_nonblock("x" * 4096, exception: false) == :wait_writable }
|
|
89
|
-
target = Expect.open(reader, writer: sink_writer, write_timeout: 1)
|
|
90
|
-
@sessions << target
|
|
91
|
-
output = StringIO.new
|
|
92
|
-
received = Queue.new
|
|
93
|
-
target.log_to { received << true }
|
|
94
|
-
target.listeners = [output]
|
|
95
|
-
target.on_sequence("STOP")
|
|
96
|
-
source.listeners = [target]
|
|
97
|
-
source.buffer = "request"
|
|
98
|
-
writer.write("beforeSTOPtail")
|
|
99
|
-
background do
|
|
100
|
-
received.pop
|
|
101
|
-
sink.readpartial(65_536)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
assert_same(target, bounded { Expect.interconnect(target, source, timeout: 0.2) })
|
|
105
|
-
assert_equal "before", output.string
|
|
106
|
-
assert_equal "tail", target.buffer
|
|
107
|
-
target.log_output = nil
|
|
108
|
-
writer.write("ready")
|
|
109
|
-
assert_equal 1, target.expect("ready", timeout: 1)
|
|
110
|
-
assert_equal "tail", target.before
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def test_interconnect_forwards_and_strips_split_escape
|
|
114
|
-
session, writer = pipe_session
|
|
115
|
-
listener = StringIO.new
|
|
116
|
-
session.listeners = [listener]
|
|
117
|
-
session.on_sequence("STOP")
|
|
118
|
-
background do
|
|
119
|
-
writer.write("helloST")
|
|
120
|
-
sleep 0.03
|
|
121
|
-
writer.write("OPtail")
|
|
122
|
-
end
|
|
123
|
-
assert_same(session, bounded { Expect.interconnect(session) })
|
|
124
|
-
assert_equal "hello", listener.string
|
|
125
|
-
assert_equal "tail", session.buffer
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def test_sequence_callback_parameters_and_resume
|
|
129
|
-
session, writer = pipe_session
|
|
130
|
-
listener = StringIO.new
|
|
131
|
-
values = []
|
|
132
|
-
session.listeners = [listener]
|
|
133
|
-
session.on_sequence("!") do
|
|
134
|
-
values << :event
|
|
135
|
-
true
|
|
136
|
-
end
|
|
137
|
-
session.on_sequence("?")
|
|
138
|
-
writer.write("one!two?three")
|
|
139
|
-
Expect.interconnect(session, timeout: 1)
|
|
140
|
-
assert_equal "onetwo", listener.string
|
|
141
|
-
assert_equal [:event], values
|
|
142
|
-
assert_equal "three", session.buffer
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def test_zero_is_truthy_and_uppercase_eof_is_a_literal_sequence
|
|
146
|
-
session, writer = pipe_session
|
|
147
|
-
output = StringIO.new
|
|
148
|
-
session.listeners = [output]
|
|
149
|
-
session.on_sequence("!") { 0 }
|
|
150
|
-
session.on_sequence("EOF")
|
|
151
|
-
writer.write("one!twoEOFtail")
|
|
152
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
153
|
-
assert_equal "onetwo", output.string
|
|
154
|
-
assert_equal "tail", session.buffer
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def test_eof_flushes_partial_escape
|
|
158
|
-
session, writer = pipe_session
|
|
159
|
-
listener = StringIO.new
|
|
160
|
-
session.listeners = [listener]
|
|
161
|
-
session.on_sequence("STOP")
|
|
162
|
-
writer.write("helloST")
|
|
163
|
-
writer.close
|
|
164
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
165
|
-
assert_equal "helloST", listener.string
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def test_eof_handler_can_continue_other_sessions
|
|
169
|
-
first, first_writer = pipe_session
|
|
170
|
-
second, second_writer = pipe_session
|
|
171
|
-
listener = StringIO.new
|
|
172
|
-
second.listeners = [listener]
|
|
173
|
-
seen = []
|
|
174
|
-
first.on_sequence(:eof) do
|
|
175
|
-
seen << :first
|
|
176
|
-
true
|
|
177
|
-
end
|
|
178
|
-
second.on_sequence("!")
|
|
179
|
-
first_writer.close
|
|
180
|
-
second_writer.write("second!")
|
|
181
|
-
assert_same second, Expect.interconnect(first, second, timeout: 1)
|
|
182
|
-
assert_equal [:first], seen
|
|
183
|
-
assert_equal "second", listener.string
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def test_interact_roundtrip_escape_and_restored_settings
|
|
187
|
-
session = child(<<~'RUBY', raw_pty: true)
|
|
188
|
-
while (value = STDIN.gets)
|
|
189
|
-
puts "reply:#{value.strip}"
|
|
190
|
-
end
|
|
191
|
-
RUBY
|
|
192
|
-
source, writer = pipe_session
|
|
193
|
-
sink = StringIO.new
|
|
194
|
-
listener = StringIO.new
|
|
195
|
-
session.listeners = [listener]
|
|
196
|
-
session.log_listeners = false
|
|
197
|
-
source.on_sequence("original")
|
|
198
|
-
background do
|
|
199
|
-
writer.write("hello\n")
|
|
200
|
-
# 收到真实响应后才发送退出键,避免将子进程启动速度当成交互完成条件。
|
|
201
|
-
bounded { sleep 0.001 until sink.string == "reply:hello\n" }
|
|
202
|
-
writer.write("\x1dtail")
|
|
203
|
-
end
|
|
204
|
-
assert_same(source, bounded { session.interact(input: source, escape: "\x1d", output: sink, timeout: 2) })
|
|
205
|
-
assert_equal "reply:hello\n", sink.string
|
|
206
|
-
assert_equal "tail", source.buffer
|
|
207
|
-
assert_equal [listener], session.listeners
|
|
208
|
-
refute session.log_listeners
|
|
209
|
-
assert_equal ["original"], source.instance_variable_get(:@sequences).keys
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def test_interconnect_leaves_terminal_modes_to_the_caller
|
|
213
|
-
session = child('print "!"; sleep 30')
|
|
214
|
-
original = terminal_configuration(session)
|
|
215
|
-
seen = nil
|
|
216
|
-
session.on_sequence("!") do
|
|
217
|
-
seen = terminal_configuration(session)
|
|
218
|
-
raise "stop"
|
|
219
|
-
end
|
|
220
|
-
assert_raises(RuntimeError) { Expect.interconnect(session, timeout: 1) }
|
|
221
|
-
assert_equal original, seen
|
|
222
|
-
assert_equal original, terminal_configuration(session)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def test_manual_stty_leaves_terminal_mode_to_caller
|
|
226
|
-
session = child('print "!"; sleep 30')
|
|
227
|
-
session.raw_terminal = false
|
|
228
|
-
original = session.stty
|
|
229
|
-
seen = nil
|
|
230
|
-
session.on_sequence("!") do
|
|
231
|
-
seen = session.stty
|
|
232
|
-
false
|
|
233
|
-
end
|
|
234
|
-
Expect.interconnect(session, timeout: 1)
|
|
235
|
-
assert_equal original, seen
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def test_timeout_flushes_pending_escape_prefix
|
|
239
|
-
session, writer = pipe_session
|
|
240
|
-
listener = StringIO.new
|
|
241
|
-
session.listeners = [listener]
|
|
242
|
-
session.on_sequence("STOP")
|
|
243
|
-
writer.write("helloST")
|
|
244
|
-
assert_nil Expect.interconnect(session, timeout: 0.02)
|
|
245
|
-
assert_equal "helloST", listener.string
|
|
246
|
-
assert_empty session.buffer
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
def test_interconnect_retries_an_interrupted_select
|
|
250
|
-
session, writer = pipe_session
|
|
251
|
-
output = StringIO.new
|
|
252
|
-
session.listeners = [output]
|
|
253
|
-
session.on_sequence("!")
|
|
254
|
-
writer.write("ready!")
|
|
255
|
-
original = IO.method(:select)
|
|
256
|
-
interrupted = true
|
|
257
|
-
select = lambda do |*arguments|
|
|
258
|
-
if interrupted
|
|
259
|
-
interrupted = false
|
|
260
|
-
raise Errno::EINTR
|
|
261
|
-
end
|
|
262
|
-
original.call(*arguments)
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
IO.stub(:select, select) do
|
|
266
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
267
|
-
end
|
|
268
|
-
assert_equal "ready", output.string
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def test_interconnect_retries_an_interrupted_read
|
|
272
|
-
session, writer = pipe_session
|
|
273
|
-
output = StringIO.new
|
|
274
|
-
session.listeners = [output]
|
|
275
|
-
session.on_sequence("!")
|
|
276
|
-
writer.write("ready!")
|
|
277
|
-
original = session.to_io.method(:read_nonblock)
|
|
278
|
-
interrupted = true
|
|
279
|
-
read = lambda do |*arguments, **options|
|
|
280
|
-
if interrupted
|
|
281
|
-
interrupted = false
|
|
282
|
-
raise Errno::EINTR
|
|
283
|
-
end
|
|
284
|
-
original.call(*arguments, **options)
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
session.to_io.stub(:read_nonblock, read) do
|
|
288
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
289
|
-
end
|
|
290
|
-
assert_equal "ready", output.string
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
def test_regexp_escape_matches_and_preserves_trailing_input
|
|
294
|
-
session, writer = pipe_session
|
|
295
|
-
output = StringIO.new
|
|
296
|
-
session.listeners = [output]
|
|
297
|
-
session.on_sequence(/STOP\d+;/)
|
|
298
|
-
writer.write("beforeSTOP42;after")
|
|
299
|
-
assert_same session, Expect.interconnect(session, timeout: 1)
|
|
300
|
-
assert_equal "before", output.string
|
|
301
|
-
assert_equal "after", session.buffer
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
def test_regexp_escape_tracks_prior_reads_without_delaying_forwarding
|
|
305
|
-
session, writer = pipe_session
|
|
306
|
-
seen = []
|
|
307
|
-
output = StringIO.new
|
|
308
|
-
session.listeners = [output]
|
|
309
|
-
session.on_sequence(/STOP\d+;/) do
|
|
310
|
-
seen << :stopped
|
|
311
|
-
false
|
|
312
|
-
end
|
|
313
|
-
# Await actual forwarding before writing the continuation, ensuring the
|
|
314
|
-
# test cannot accidentally pass with a single combined read.
|
|
315
|
-
background do
|
|
316
|
-
writer.write("beforeSTOP")
|
|
317
|
-
bounded { sleep 0.001 until output.string == "beforeSTOP" }
|
|
318
|
-
writer.write("42;after")
|
|
319
|
-
end
|
|
320
|
-
assert_same(session, bounded { Expect.interconnect(session, timeout: 1) })
|
|
321
|
-
assert_equal [:stopped], seen
|
|
322
|
-
assert_equal "beforeSTOP", output.string
|
|
323
|
-
assert_equal "after", session.buffer
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
def test_regexp_escape_history_has_a_finite_default_window
|
|
327
|
-
session, = pipe_session
|
|
328
|
-
session.on_sequence(/UNLIKELY_ESCAPE/)
|
|
329
|
-
buffers = { session => "".b }
|
|
330
|
-
|
|
331
|
-
5.times do
|
|
332
|
-
buffers[session] << ("x" * 16_384)
|
|
333
|
-
Expect.send(:relay_buffer, session, buffers)
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
assert_operator session.__send__(:relay_history).bytesize, :<=, 65_536
|
|
337
|
-
assert_empty buffers.fetch(session)
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
def test_utf8_regexp_escape_history_keeps_a_valid_leading_character
|
|
341
|
-
session, = pipe_session
|
|
342
|
-
session.on_sequence(/终止/u)
|
|
343
|
-
buffers = { session => "".b }
|
|
344
|
-
|
|
345
|
-
6.times do
|
|
346
|
-
buffers[session] << ("中" * 5461).b
|
|
347
|
-
assert Expect.send(:relay_buffer, session, buffers)
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
assert_operator session.__send__(:relay_history).bytesize, :<=, 65_536
|
|
351
|
-
assert session.__send__(:relay_history).dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
|
352
|
-
buffers[session] << "终止".b
|
|
353
|
-
refute Expect.send(:relay_buffer, session, buffers)
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
def test_regexp_escape_continuation_does_not_rematch_history
|
|
357
|
-
session, writer = pipe_session
|
|
358
|
-
seen = []
|
|
359
|
-
output = StringIO.new
|
|
360
|
-
session.listeners = [output]
|
|
361
|
-
session.on_sequence(/\[[0-9]+\]/) do
|
|
362
|
-
seen << :hit
|
|
363
|
-
true
|
|
364
|
-
end
|
|
365
|
-
session.on_sequence("!")
|
|
366
|
-
writer.write("one[12]two[34]three!tail")
|
|
367
|
-
Expect.interconnect(session, timeout: 1)
|
|
368
|
-
assert_equal %i[hit hit], seen
|
|
369
|
-
assert_equal "onetwothree", output.string
|
|
370
|
-
assert_equal "tail", session.buffer
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
def test_zero_width_regexp_escape_is_rejected_without_spinning
|
|
374
|
-
session, writer = pipe_session
|
|
375
|
-
session.on_sequence(/(?=a)/) { true }
|
|
376
|
-
writer.write("abc")
|
|
377
|
-
assert_raises(ArgumentError) { bounded { Expect.interconnect(session, timeout: 1) } }
|
|
378
|
-
assert_equal "abc", session.buffer
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
def test_log_failure_preserves_received_bytes_for_recovery
|
|
382
|
-
session, writer = pipe_session
|
|
383
|
-
session.log_to { raise IOError, "log failed" }
|
|
384
|
-
writer.write("before!tail")
|
|
385
|
-
|
|
386
|
-
error = assert_raises(IOError) { Expect.interconnect(session, timeout: 1) }
|
|
387
|
-
assert_equal "log failed", error.message
|
|
388
|
-
assert_equal "before!tail", session.buffer
|
|
389
|
-
refute session.eof?
|
|
390
|
-
|
|
391
|
-
session.log_output = nil
|
|
392
|
-
assert_equal 1, session.expect("before!", timeout: 0)
|
|
393
|
-
assert_equal "tail", session.buffer
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
def test_logs_received_bytes_once_across_expect_interconnect_and_expect
|
|
397
|
-
session, writer = pipe_session
|
|
398
|
-
log = StringIO.new
|
|
399
|
-
output = StringIO.new
|
|
400
|
-
session.log_to(log)
|
|
401
|
-
session.listeners = [output]
|
|
402
|
-
session.on_sequence("!")
|
|
403
|
-
writer.write("prompt>before!")
|
|
404
|
-
session.expect("prompt>", timeout: 1)
|
|
405
|
-
Expect.interconnect(session, timeout: 1)
|
|
406
|
-
writer.write("after")
|
|
407
|
-
session.expect("after", timeout: 1)
|
|
408
|
-
assert_equal "prompt>before!after", log.string
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
def test_log_includes_escape_and_tail_before_next_expect
|
|
412
|
-
session, writer = pipe_session
|
|
413
|
-
log = StringIO.new
|
|
414
|
-
output = StringIO.new
|
|
415
|
-
session.log_to(log)
|
|
416
|
-
session.listeners = [output]
|
|
417
|
-
session.on_sequence("!")
|
|
418
|
-
writer.write("before!tail")
|
|
419
|
-
Expect.interconnect(session, timeout: 1)
|
|
420
|
-
assert_equal "before", output.string
|
|
421
|
-
assert_equal "before!tail", log.string
|
|
422
|
-
assert_equal 1, session.expect("tail", timeout: 0)
|
|
423
|
-
assert_equal "before!tail", log.string
|
|
424
|
-
end
|
|
425
|
-
end
|