CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/acceptance/child_process_spec.rb
Views: 11766
1
require 'acceptance_spec_helper'
2
3
RSpec.describe Acceptance::ChildProcess do
4
context 'when a process is opened successfully' do
5
let(:stdin_pipes) { ::IO.pipe }
6
let(:stdin_reader) { stdin_pipes[0] }
7
let(:stdin_writer) { stdin_pipes[1] }
8
let(:stdout_and_stderr_pipes) { ::IO.pipe }
9
let(:stdout_and_stderr_pipes_reader) { stdout_and_stderr_pipes[0] }
10
let(:stdout_and_stderr_pipes_writer) { stdout_and_stderr_pipes[1] }
11
let(:wait_thread) { double(:wait_thread, alive?: true, pid: nil) }
12
13
subject(:mock_process) do
14
clazz = Class.new(described_class) do
15
attr_reader :mock_stdin_reader
16
attr_reader :mock_stdout_and_stderr_writer
17
18
def run(stdin, stdout_and_stderr, wait_thread)
19
self.stdin = stdin
20
self.stdout_and_stderr = stdout_and_stderr
21
self.stdin.sync = true
22
self.stdout_and_stderr.sync = true
23
self.wait_thread = wait_thread
24
end
25
end
26
clazz.new
27
end
28
29
def mock_write(data)
30
stdout_and_stderr_pipes_writer.write(data)
31
end
32
33
before(:each) do
34
mock_process.run(stdin_writer, stdout_and_stderr_pipes_reader, wait_thread)
35
end
36
37
after(:each) do
38
subject.close
39
end
40
41
describe '#readline' do
42
context 'when there is exactly one line available' do
43
it 'reads one line' do
44
mock_write("hello world\n")
45
expect(subject.readline).to eq("hello world\n")
46
end
47
end
48
49
context 'when there are multiple lines available' do
50
it 'reads one line' do
51
mock_write("hello world\nfoo bar\n")
52
expect(subject.readline).to eq("hello world\n")
53
end
54
55
it 'reads multiple lines' do
56
mock_write("hello world\nfoo bar\n")
57
expect(subject.readline).to eq("hello world\n")
58
expect(subject.readline).to eq("foo bar\n")
59
end
60
end
61
end
62
63
describe '#recv_available' do
64
context 'when there is exactly one line available' do
65
it 'reads one line' do
66
mock_write("hello world\n")
67
expect(subject.recv_available).to eq("hello world\n")
68
end
69
end
70
71
context 'when there are multiple lines available' do
72
it 'reads one line' do
73
mock_write("hello world\nfoo bar\n")
74
expect(subject.recv_available).to eq("hello world\nfoo bar\n")
75
end
76
end
77
end
78
79
describe '#recvuntil' do
80
context 'when there are multiple lines of data available' do
81
it 'reads one line' do
82
mock_write <<~EOF
83
motd
84
login:
85
EOF
86
expect(subject.recvuntil("login:")).to eq("motd\nlogin:")
87
end
88
end
89
end
90
91
describe '#sendline' do
92
it 'writes the available data' do
93
subject.sendline("hello world")
94
95
expect(stdin_reader.read_nonblock(1024)).to eq("hello world\n")
96
end
97
end
98
99
describe '#alive?' do
100
it 'returns the wait thread status' do
101
expect(subject.alive?).to eq(wait_thread.alive?)
102
end
103
end
104
end
105
end
106
107