dia 1.5 → 2.0.0
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.
- data/{LICENSE → COPYING} +0 -0
- data/README.mkd +67 -0
- data/dia.gemspec +49 -0
- data/lib/dia.rb +11 -8
- data/lib/dia/application.rb +49 -0
- data/lib/dia/exception_struct.rb +7 -0
- data/lib/dia/exceptions.rb +5 -0
- data/lib/dia/functions.rb +8 -0
- data/lib/dia/profiles.rb +2 -6
- data/lib/dia/ruby_block.rb +319 -0
- data/lib/dia/shared_features.rb +91 -0
- data/test/setup.rb +5 -4
- data/test/suite/lib/dia/exception_struct.rb +40 -0
- data/test/suite/lib/dia/ruby_block.rb +561 -0
- data/test/suite/lib/dia/shared_features.rb +236 -0
- metadata +31 -42
- data/.yardopts +0 -4
- data/HACKING.md +0 -13
- data/NEWS.md +0 -61
- data/README.md +0 -170
- data/TODO.md +0 -8
- data/lib/dia/commonapi.rb +0 -7
- data/lib/dia/sandbox.rb +0 -208
- data/test/suite/check_if_sandbox_is_alive_test.rb +0 -29
- data/test/suite/exception()_test.rb +0 -55
- data/test/suite/exception_raised?_test.rb +0 -22
- data/test/suite/exceptions_test.rb +0 -12
- data/test/suite/exit_status_test.rb +0 -16
- data/test/suite/passing_parameters_to_constructer_test.rb +0 -34
- data/test/suite/run_block_in_sandbox_test.rb +0 -132
- data/test/suite/terminate_sandbox_test.rb +0 -29
data/TODO.md
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
## TODO
|
2
|
-
|
3
|
-
### 1.4
|
4
|
-
* Dia::Sandbox.run() doesn't use @app to launch a process, but uses @app\_path which was removed in 1.3
|
5
|
-
* If you're going to run a block under a sandbox, make Dia::Sandbox#run accept *args so they may be passed onto the block.
|
6
|
-
|
7
|
-
### 1.3
|
8
|
-
* Remove link to experimental branch in gemspec before release
|
data/lib/dia/commonapi.rb
DELETED
data/lib/dia/sandbox.rb
DELETED
@@ -1,208 +0,0 @@
|
|
1
|
-
module Dia
|
2
|
-
|
3
|
-
class Sandbox
|
4
|
-
|
5
|
-
require('io/wait')
|
6
|
-
|
7
|
-
include Dia::CommonAPI
|
8
|
-
|
9
|
-
attr_reader :app
|
10
|
-
attr_reader :profile
|
11
|
-
attr_reader :pid
|
12
|
-
attr_reader :blk
|
13
|
-
|
14
|
-
# The constructer accepts a profile as the first parameter, and an
|
15
|
-
# application path _or_ block as its second parameter.
|
16
|
-
#
|
17
|
-
# @example
|
18
|
-
#
|
19
|
-
# # Passing an application to the constructer ..
|
20
|
-
# sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES, 'ping google.com')
|
21
|
-
#
|
22
|
-
# # Passing a block to the constructer ..
|
23
|
-
# sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
24
|
-
# File.open('foo.txt', 'w') do |f|
|
25
|
-
# f.puts "bar"
|
26
|
-
# end
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# @see Dia::Sandbox#run See Dia::Sandbox#run for executing the sandbox.
|
30
|
-
#
|
31
|
-
# @param [Constant] Profile The profile to be used when creating a
|
32
|
-
# sandbox.
|
33
|
-
#
|
34
|
-
# @param [Proc] Proc A proc object you want to run under a
|
35
|
-
# sandbox.
|
36
|
-
# Omit the "Application" parameter if
|
37
|
-
# passed.
|
38
|
-
#
|
39
|
-
# @param [String] Application The path to an application you want
|
40
|
-
# to run under a sandbox.
|
41
|
-
# Omit the "Proc" parameter if passed.
|
42
|
-
# @return [Dia::SandBox] Returns an instance of Dia::SandBox
|
43
|
-
|
44
|
-
def initialize(profile, app=nil, &blk)
|
45
|
-
if (app && blk) || (app.nil? && blk.nil?)
|
46
|
-
raise ArgumentError, 'Application or Proc object expected'
|
47
|
-
end
|
48
|
-
|
49
|
-
@app = app
|
50
|
-
@blk = blk
|
51
|
-
@profile = profile
|
52
|
-
@pid = nil
|
53
|
-
initialize_streams()
|
54
|
-
end
|
55
|
-
|
56
|
-
# The #exception_raised?() method returns true if an exception has been
|
57
|
-
# raised in the last call to #run(), and false otherwise.
|
58
|
-
#
|
59
|
-
# @return [Boolean] Returns true or false.
|
60
|
-
# @since 1.5
|
61
|
-
def exception_raised?()
|
62
|
-
!!exception()
|
63
|
-
end
|
64
|
-
|
65
|
-
# The exception() method returns the last exception raised after a
|
66
|
-
# a call to #run(), or nil.
|
67
|
-
#
|
68
|
-
# Every call to #run() resets the variable storing the exception object
|
69
|
-
# to nil, and it will only be a non-nil value if the last call to #run()
|
70
|
-
# raised an exception.
|
71
|
-
#
|
72
|
-
# This method can be used if you need access(from the parent process)
|
73
|
-
# to an exception raised in your sandbox.
|
74
|
-
#
|
75
|
-
# If the sandbox raises an exception rather quickly, you might need to
|
76
|
-
# sleep(X) (0.3-0.5s on my machine) before the parent process
|
77
|
-
# recieves the exception.
|
78
|
-
#
|
79
|
-
# @return [Exception, nil] Returns an instance or subclass instance of
|
80
|
-
# Exception when successful, and nil when
|
81
|
-
# there is no exception available.
|
82
|
-
# @since 1.5
|
83
|
-
def exception()
|
84
|
-
@write.close()
|
85
|
-
if @read.ready?()
|
86
|
-
@e = Marshal.load(@read.readlines().join())
|
87
|
-
end
|
88
|
-
@read.close()
|
89
|
-
initialize_streams()
|
90
|
-
@e
|
91
|
-
end
|
92
|
-
|
93
|
-
# The run method will spawn a child process and run the application _or_
|
94
|
-
# block supplied to the constructer under a sandbox.
|
95
|
-
# This method will not block.
|
96
|
-
#
|
97
|
-
# @param [Arguments] Arguments A variable amount of arguments that will
|
98
|
-
# be passed onto the block supplied to the
|
99
|
-
# constructer. Optional.
|
100
|
-
#
|
101
|
-
# @raise [SystemCallError] In the case of running a block, a number
|
102
|
-
# of subclasses of SystemCallError may be
|
103
|
-
# raised if the block violates sandbox
|
104
|
-
# restrictions.
|
105
|
-
# The parent process will not be affected
|
106
|
-
# and if you wish to catch exceptions you
|
107
|
-
# should do so in your block.
|
108
|
-
#
|
109
|
-
# @raise [Dia::SandboxException] Will raise Dia::SandboxException in a
|
110
|
-
# child process and exit if the sandbox
|
111
|
-
# could not be initiated.
|
112
|
-
#
|
113
|
-
# @return [Fixnum] The Process ID(PID) that the sandboxed
|
114
|
-
# application is being run under.
|
115
|
-
def run(*args)
|
116
|
-
@e = nil
|
117
|
-
initialize_streams()
|
118
|
-
@pid = fork do
|
119
|
-
begin
|
120
|
-
if sandbox_init(FFI::MemoryPointer.from_string(@profile),
|
121
|
-
0x0001,
|
122
|
-
err = FFI::MemoryPointer.new(:pointer)) == -1
|
123
|
-
|
124
|
-
raise(Dia::SandboxException, "Failed to initialize sandbox" \
|
125
|
-
"(#{err.read_pointer.read_string})")
|
126
|
-
end
|
127
|
-
|
128
|
-
if @app
|
129
|
-
exec(@app)
|
130
|
-
else
|
131
|
-
@blk.call(*args)
|
132
|
-
end
|
133
|
-
|
134
|
-
rescue SystemExit, Interrupt => e
|
135
|
-
raise(e)
|
136
|
-
rescue Exception => e
|
137
|
-
@write.write(Marshal.dump(e))
|
138
|
-
ensure
|
139
|
-
@write.close()
|
140
|
-
@read.close()
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# parent ..
|
145
|
-
@thr = Process.detach(@pid)
|
146
|
-
@pid
|
147
|
-
end
|
148
|
-
|
149
|
-
# The exit_status method will return the exit status of the child process
|
150
|
-
# running in a sandbox.
|
151
|
-
# This method *will* block until the child process exits.
|
152
|
-
#
|
153
|
-
# @return [Fixnum, nil] Returns the exit status of the process that ran
|
154
|
-
# under a sandbox.
|
155
|
-
# Returns nil if Dia::Sandbox#run has not
|
156
|
-
# been called yet, or if the process stopped
|
157
|
-
# abnormally(ie: through SIGKILL, or #terminate).
|
158
|
-
# @since 1.5
|
159
|
-
def exit_status()
|
160
|
-
@thr.value().exitstatus() unless @thr.nil?
|
161
|
-
end
|
162
|
-
|
163
|
-
# The terminate method will send SIGKILL to a process running in a sandbox.
|
164
|
-
# By doing so, it effectively terminates the sandbox.
|
165
|
-
#
|
166
|
-
# @raise [SystemCallError] It may raise a number of subclasses of
|
167
|
-
# SystemCallError if a call to Process.kill
|
168
|
-
# was unsuccessful ..
|
169
|
-
#
|
170
|
-
# @return [Fixnum, nil] It will return 1 when successful, and
|
171
|
-
# it will return "nil" if Dia::Sandbox#run()
|
172
|
-
# has not been called yet.
|
173
|
-
def terminate()
|
174
|
-
Process.kill('SIGKILL', @pid) unless @pid.nil?
|
175
|
-
end
|
176
|
-
|
177
|
-
# The running? method will return true if a sandbox is running,
|
178
|
-
# and false otherwise.
|
179
|
-
#
|
180
|
-
# @raise [SystemCallError] It may raise a subclass of SystemCallError if
|
181
|
-
# you do not have permission to send a signal
|
182
|
-
# to the process running in a sandbox.
|
183
|
-
#
|
184
|
-
# @return [Boolean,nil] It will return true or false if the sandbox
|
185
|
-
# is running or not, and it will return "nil"
|
186
|
-
# if Dia::Sandbox#run has not been called yet.
|
187
|
-
def running?()
|
188
|
-
if @pid.nil?
|
189
|
-
nil
|
190
|
-
else
|
191
|
-
begin
|
192
|
-
Process.kill(0, @pid)
|
193
|
-
true
|
194
|
-
rescue Errno::ESRCH
|
195
|
-
false
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
private
|
201
|
-
|
202
|
-
def initialize_streams()
|
203
|
-
@read, @write = IO.pipe()
|
204
|
-
end
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
BareTest.suite "Dia::Sandbox#running?", :tags => [ :running? ] do
|
2
|
-
|
3
|
-
assert 'Confirm that Dia::Sandbox#running? returns true when a sandbox is running' do
|
4
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
5
|
-
sleep(20)
|
6
|
-
end
|
7
|
-
|
8
|
-
sandbox.run
|
9
|
-
equal(true, sandbox.running?)
|
10
|
-
sandbox.terminate
|
11
|
-
end
|
12
|
-
|
13
|
-
assert 'Confirm that Dia::Sandbox#running? returns false when a sandbox is not running' do
|
14
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
15
|
-
sleep(20)
|
16
|
-
end
|
17
|
-
sandbox.run
|
18
|
-
sandbox.terminate
|
19
|
-
sleep(1)
|
20
|
-
equal(false, sandbox.running?)
|
21
|
-
end
|
22
|
-
|
23
|
-
assert("nil will be returned if Dia::Sandbox#run hasn't been called before a call to #running?()") do
|
24
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do
|
25
|
-
# ...
|
26
|
-
end
|
27
|
-
equal(nil, sandbox.running?)
|
28
|
-
end
|
29
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
BareTest.suite('Dia::Sandbox#exception()') do
|
2
|
-
assert('#exception() will return an exception raised in the sandbox') do
|
3
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
4
|
-
raise()
|
5
|
-
end
|
6
|
-
|
7
|
-
sandbox.run()
|
8
|
-
sleep(0.1)
|
9
|
-
equal(RuntimeError, sandbox.exception.class())
|
10
|
-
end
|
11
|
-
|
12
|
-
assert('#exception() returns nil if called before ' \
|
13
|
-
'Dia::Sandbox#run()') do
|
14
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
15
|
-
# ...
|
16
|
-
end
|
17
|
-
equal(nil, sandbox.exception())
|
18
|
-
end
|
19
|
-
|
20
|
-
assert('#exception() returns an exception object the first' \
|
21
|
-
' and second time it is called after a single call to #run()') do
|
22
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
23
|
-
raise()
|
24
|
-
end
|
25
|
-
|
26
|
-
sandbox.run()
|
27
|
-
sleep(0.1)
|
28
|
-
equal(RuntimeError, sandbox.exception().class)
|
29
|
-
equal(RuntimeError, sandbox.exception().class)
|
30
|
-
end
|
31
|
-
|
32
|
-
assert('#exception() will be set to nil after the first call to ' \
|
33
|
-
'#run raises an exception, and the second does not') do
|
34
|
-
|
35
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
36
|
-
raise()
|
37
|
-
end
|
38
|
-
|
39
|
-
sandbox.run()
|
40
|
-
sleep(0.1)
|
41
|
-
equal(RuntimeError, sandbox.exception().class)
|
42
|
-
sandbox.instance_variable_set("@blk", proc { })
|
43
|
-
sandbox.run()
|
44
|
-
equal(nil, sandbox.exception())
|
45
|
-
end
|
46
|
-
|
47
|
-
assert('#exception() can marshal data containing one or more \n') do
|
48
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
49
|
-
fork {}
|
50
|
-
end
|
51
|
-
sandbox.run()
|
52
|
-
sleep(0.5)
|
53
|
-
equal(Errno::EPERM, sandbox.exception().class)
|
54
|
-
end
|
55
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
BareTest.suite('Dia::Sandbox#exception_raised?()',
|
2
|
-
:tags => [ :exception_raised] ) do
|
3
|
-
assert('#exception_raised?() returns false when no exception has been ' \
|
4
|
-
'raised') do
|
5
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
6
|
-
# ...
|
7
|
-
end
|
8
|
-
sandbox.run()
|
9
|
-
sleep(0.1)
|
10
|
-
equal(false, sandbox.exception_raised?())
|
11
|
-
end
|
12
|
-
|
13
|
-
assert('#exception_raised?() returns true when an exception has been ' \
|
14
|
-
'raised') do
|
15
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
16
|
-
raise(StandardError, 'Exception')
|
17
|
-
end
|
18
|
-
sandbox.run()
|
19
|
-
sleep(0.1)
|
20
|
-
equal(true, sandbox.exception_raised?())
|
21
|
-
end
|
22
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
BareTest.suite('Exceptions', :tags => [ :sandbox_init_exception ]) do
|
2
|
-
assert('Dia::SandboxException is raised if a call to sandbox_init() fails') do
|
3
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
4
|
-
# ...
|
5
|
-
end
|
6
|
-
sandbox.instance_variable_set("@profile", "i am going to break")
|
7
|
-
sandbox.run
|
8
|
-
sleep(0.1)
|
9
|
-
equal(Dia::SandboxException, sandbox.exception().class)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
@@ -1,16 +0,0 @@
|
|
1
|
-
BareTest.suite('Dia::Sandbox#exit_status') do
|
2
|
-
assert('The exit status of a child process running under a sandbox is returned.') do
|
3
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do
|
4
|
-
exit(10)
|
5
|
-
end
|
6
|
-
sandbox.run
|
7
|
-
equal(10, sandbox.exit_status)
|
8
|
-
end
|
9
|
-
|
10
|
-
assert("nil will be returned if Dia::Sandbox#run hasn't been called before a call to #exit_status") do
|
11
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do
|
12
|
-
end
|
13
|
-
equal(nil, sandbox.exit_status)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# See /test/suite/run_block_in_sandbox_test.rb for tests that confirm sandboxes are successfully created ..
|
2
|
-
BareTest.suite 'Dia::Sandbox.new', :tags => [ :new ] do
|
3
|
-
|
4
|
-
assert 'Passing no arguments to the constructer will raise an ArgumentError' do
|
5
|
-
raises(ArgumentError) do
|
6
|
-
Dia::Sandbox.new
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
assert 'Passing only a profile to the constructer will raise an ArgumentError' do
|
11
|
-
raises(ArgumentError) do
|
12
|
-
Dia::Sandbox.new(Dia::Profiles::NO_INTERNET)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
assert 'Passing a profile, application path, and a block will raise an ArgumentError' do
|
17
|
-
raises(ArgumentError) do
|
18
|
-
Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES, 'ls') do
|
19
|
-
puts "foo"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
assert 'Passing an application path and a profile will raise nothing' do
|
25
|
-
Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES, 'ls')
|
26
|
-
end
|
27
|
-
|
28
|
-
assert 'Passing a block and a profile will raise nothing' do
|
29
|
-
Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
30
|
-
puts "foo"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
# TODO: Add assertion for Dia::Profiles::NO_OS_SERVICES
|
2
|
-
|
3
|
-
BareTest.suite 'Dia::Sandbox#run', :tags => [ :run ] do
|
4
|
-
|
5
|
-
setup do
|
6
|
-
@reader, @writer = IO.pipe
|
7
|
-
end
|
8
|
-
|
9
|
-
assert 'A Ruby block will not be able to access the internet' do
|
10
|
-
|
11
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do
|
12
|
-
begin
|
13
|
-
@reader.close
|
14
|
-
TCPSocket.open('http://www.google.com', 80)
|
15
|
-
@writer.write('false')
|
16
|
-
rescue SocketError, SystemCallError => e
|
17
|
-
@writer.write('true')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# a child process is spawned, and the block passed to the constructer executed.
|
22
|
-
sandbox.run
|
23
|
-
|
24
|
-
# back in the parent.
|
25
|
-
@writer.close
|
26
|
-
successful = @reader.gets
|
27
|
-
@reader.close
|
28
|
-
|
29
|
-
equal('true', successful)
|
30
|
-
end
|
31
|
-
|
32
|
-
assert 'A Ruby block will not be able to write the filesystem' do
|
33
|
-
|
34
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_FILESYSTEM_WRITE) do
|
35
|
-
begin
|
36
|
-
@reader.close
|
37
|
-
File.open('foo.txt', 'w')
|
38
|
-
@writer.write('false')
|
39
|
-
rescue SystemCallError => e
|
40
|
-
@writer.write('true')
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# a child process is spawned, and the block passed to the constructer executed.
|
45
|
-
sandbox.run
|
46
|
-
|
47
|
-
# back in the parent.
|
48
|
-
@writer.close
|
49
|
-
successful = @reader.gets
|
50
|
-
@reader.close
|
51
|
-
|
52
|
-
equal('true', successful)
|
53
|
-
end
|
54
|
-
|
55
|
-
assert 'A Ruby block will not be able to write to the filesystem except when writing to /tmp' do
|
56
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_FILESYSTEM_WRITE_EXCEPT_TMP) do
|
57
|
-
marshal = []
|
58
|
-
begin
|
59
|
-
marshal = Marshal.dump(marshal)
|
60
|
-
@reader.close
|
61
|
-
File.open('foo.txt', 'w')
|
62
|
-
@writer.write('false')
|
63
|
-
rescue SystemCallError => e
|
64
|
-
marshal = Marshal.dump(Marshal.load(marshal) << 'true')
|
65
|
-
end
|
66
|
-
|
67
|
-
begin
|
68
|
-
File.open('/tmp/foo.txt', 'w') do |f|
|
69
|
-
f.puts 'foo'
|
70
|
-
end
|
71
|
-
@writer.write(marshal = Marshal.dump(Marshal.load(marshal) << 'true'))
|
72
|
-
rescue SystemCallError => e
|
73
|
-
@writer.write('false')
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# a child process is spawned, and the block passed to the constructer executed.
|
78
|
-
sandbox.run
|
79
|
-
|
80
|
-
# back in the parent.
|
81
|
-
@writer.close
|
82
|
-
successful = Marshal.load(@reader.gets)
|
83
|
-
@reader.close
|
84
|
-
|
85
|
-
equal(['true', 'true'], successful)
|
86
|
-
end
|
87
|
-
|
88
|
-
assert 'A Ruby block will not be able to do any socket based communication' do
|
89
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_NETWORKING) do
|
90
|
-
begin
|
91
|
-
@reader.close
|
92
|
-
TCPSocket.open('http://www.youtube.com', 80)
|
93
|
-
@writer.write('false')
|
94
|
-
rescue SocketError => e
|
95
|
-
@writer.write('true')
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# a child process is spawned, and the block passed to the constructer executed.
|
100
|
-
sandbox.run
|
101
|
-
|
102
|
-
# back in the parent.
|
103
|
-
@writer.close
|
104
|
-
successful = @reader.gets
|
105
|
-
@reader.close
|
106
|
-
|
107
|
-
equal('true', successful)
|
108
|
-
end
|
109
|
-
|
110
|
-
assert 'A Ruby block will be able to receive arguments through #run' do
|
111
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do |foo, bar|
|
112
|
-
@reader.close
|
113
|
-
@writer.write(foo+bar)
|
114
|
-
@writer.close
|
115
|
-
end
|
116
|
-
sandbox.run('foo', 'bar')
|
117
|
-
|
118
|
-
# back in the parent..
|
119
|
-
@writer.close
|
120
|
-
answer = @reader.gets
|
121
|
-
@reader.close
|
122
|
-
|
123
|
-
equal('foobar', answer)
|
124
|
-
end
|
125
|
-
|
126
|
-
assert('A Ruby block will return the PID of the spawned child process after executing #run') do
|
127
|
-
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_INTERNET) do
|
128
|
-
# ...
|
129
|
-
end
|
130
|
-
equal(Fixnum, sandbox.run.class)
|
131
|
-
end
|
132
|
-
end
|