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
@@ -0,0 +1,91 @@
|
|
1
|
+
module Dia
|
2
|
+
|
3
|
+
module SharedFeatures
|
4
|
+
|
5
|
+
# @return [Fixnum, nil] Returns the Process ID(PID) of the last child process that was
|
6
|
+
# used to execute a sandbox.
|
7
|
+
# Returns nil if #run or #run_nonblock has not been called yet.
|
8
|
+
def pid
|
9
|
+
@pid
|
10
|
+
end
|
11
|
+
|
12
|
+
# The exit_status method will return the exit status of your sandbox.
|
13
|
+
# This method *will* block until the child process(your sandbox) exits
|
14
|
+
# when being used with #run_nonblock.
|
15
|
+
#
|
16
|
+
# @return [Fixnum, nil] Returns the exit status of your sandbox as a
|
17
|
+
# Fixnum.
|
18
|
+
# Returns nil if #run or #run_nonblock has not
|
19
|
+
# been called yet.
|
20
|
+
# Returns nil if the process hasn't exited yet and
|
21
|
+
# #run is being used.
|
22
|
+
# @since 1.5
|
23
|
+
def exit_status()
|
24
|
+
unless @exit_status.nil?
|
25
|
+
Thread === @exit_status ? @exit_status.value().exitstatus() :
|
26
|
+
@exit_status.exitstatus()
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# The terminate method will send the SIGKILL signal to your sandbox.
|
31
|
+
#
|
32
|
+
# To prevent the possible accumulation of zombies, this method will
|
33
|
+
# wait to collect the exit status of your sandbox if it doesn't appear
|
34
|
+
# to have left the process table after sending SIGKILL.
|
35
|
+
#
|
36
|
+
# This is a rare event, and when it does happen #terminate shouldn't block
|
37
|
+
# for more than one second.
|
38
|
+
#
|
39
|
+
# @raise [SystemCallError] It may raise a number of subclasses of
|
40
|
+
# SystemCallError if a call to Process.kill
|
41
|
+
# was unsuccessful
|
42
|
+
#
|
43
|
+
# @return [Fixnum, nil] Returns 1 when successful.
|
44
|
+
# Returns nil if #run or #run_nonblock has not
|
45
|
+
# been called yet.
|
46
|
+
def terminate()
|
47
|
+
ret = Process.kill('SIGKILL', @pid) unless @pid.nil?
|
48
|
+
# precaution against the collection of zombie processes.
|
49
|
+
_ , @exit_status = Process.wait2(@pid) if running?
|
50
|
+
ret
|
51
|
+
end
|
52
|
+
|
53
|
+
# This method will tell you if your sandbox is still running by returning a boolean.
|
54
|
+
#
|
55
|
+
# @raise [SystemCallError] It may raise a number of subclasses of SystemCallError
|
56
|
+
# if a signal cannot be sent to the process running
|
57
|
+
# a sandbox.
|
58
|
+
#
|
59
|
+
# @return [Boolean,nil] Returns true, false, or nil.
|
60
|
+
# Returns nil if #run or #run_nonblock has
|
61
|
+
# not been called yet.
|
62
|
+
def running?()
|
63
|
+
if @pid.nil?
|
64
|
+
nil
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
Process.kill(0, @pid)
|
68
|
+
true
|
69
|
+
rescue Errno::ESRCH
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# @api private
|
78
|
+
def initialize_sandbox
|
79
|
+
if Dia::Functions.sandbox_init(FFI::MemoryPointer.from_string(@profile),
|
80
|
+
0x0001,
|
81
|
+
err = FFI::MemoryPointer.new(:pointer)) \
|
82
|
+
== -1
|
83
|
+
|
84
|
+
raise(Dia::Exceptions::SandboxException, "Failed to initialize sandbox" \
|
85
|
+
"(#{err.read_pointer.read_string})")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/test/setup.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require('rubygems')
|
2
|
+
require('socket')
|
3
|
+
require('baretest')
|
4
|
+
require(File.expand_path('../lib/dia', File.dirname(__FILE__)))
|
5
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
suite('Dia::ExceptionStruct') do
|
2
|
+
|
3
|
+
setup do
|
4
|
+
@sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
5
|
+
raise(RuntimeError, 'Example')
|
6
|
+
end
|
7
|
+
@sandbox.rescue_exception = true
|
8
|
+
end
|
9
|
+
|
10
|
+
suite('#klass') do
|
11
|
+
exercise('@rescue is set to true. A RuntimeError is raised in a sandbox. ') do
|
12
|
+
@sandbox.run
|
13
|
+
end
|
14
|
+
|
15
|
+
verify('#klass returns RuntimeError as a String') do
|
16
|
+
@sandbox.exception.klass == 'RuntimeError'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
suite('#message') do
|
21
|
+
exercise('@rescue is set to true. A RuntimeError is raised in a sandbox. ') do
|
22
|
+
@sandbox.run
|
23
|
+
end
|
24
|
+
|
25
|
+
verify("#message returns 'Example' as a String") do
|
26
|
+
@sandbox.exception.message == 'Example'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
suite('#backtrace') do
|
31
|
+
exercise('@rescue is set to true. A RuntimeError is raised in a sandbox. ') do
|
32
|
+
@sandbox.run
|
33
|
+
end
|
34
|
+
|
35
|
+
verify('#backtrace returns a string') do
|
36
|
+
@sandbox.exception.backtrace.class == String
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,561 @@
|
|
1
|
+
suite('Dia::RubyBlock') do
|
2
|
+
|
3
|
+
suite('misc') do
|
4
|
+
|
5
|
+
exercise("An invalid profile is passed to Dia::RubyBlock.new, and #run is called.") do
|
6
|
+
sandbox = Dia::RubyBlock.new('invalid_profile') { }
|
7
|
+
sandbox.rescue_exception = true
|
8
|
+
sandbox.run
|
9
|
+
@result = sandbox.exception.klass
|
10
|
+
end
|
11
|
+
|
12
|
+
verify('Dia::RubyBlock#exception returns an instance of Dia::Exceptions::SandboxException') do
|
13
|
+
@result == "Dia::Exceptions::SandboxException"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
suite('#initialize') do
|
19
|
+
|
20
|
+
setup do
|
21
|
+
@result = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
exercise('No block is passed to the constructor. ') do
|
25
|
+
begin
|
26
|
+
Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES)
|
27
|
+
rescue ArgumentError => e
|
28
|
+
@result = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
verify('ArgumentError is raised.') do
|
33
|
+
@result
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
suite('#pid') do
|
39
|
+
|
40
|
+
exercise('#run is called, then #pid is called. ') do
|
41
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) { }
|
42
|
+
sandbox.run
|
43
|
+
@result = sandbox.pid
|
44
|
+
end
|
45
|
+
|
46
|
+
verify('#pid returns a Fixnum object') do
|
47
|
+
@result.class == Fixnum
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
suite('#stderr') do
|
53
|
+
|
54
|
+
exercise('@rescue set to true, @redirect_stderr set to true, #run called, ' \
|
55
|
+
'$stderr written to. ') do
|
56
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
57
|
+
$stderr.print "Hello, world $stderr!"
|
58
|
+
end
|
59
|
+
sandbox.rescue_exception = true
|
60
|
+
sandbox.redirect_stderr = true
|
61
|
+
sandbox.run
|
62
|
+
@result = sandbox.stderr
|
63
|
+
end
|
64
|
+
|
65
|
+
verify('#stderr returns the contents of $stderr.') do
|
66
|
+
@result == 'Hello, world $stderr!'
|
67
|
+
end
|
68
|
+
|
69
|
+
exercise('@rescue set to true, @redirect_stderr set to true, #run called, ' \
|
70
|
+
'STDERR written to. ') do
|
71
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
72
|
+
STDERR.print "Hello, world STDERR!"
|
73
|
+
end
|
74
|
+
sandbox.rescue_exception = true
|
75
|
+
sandbox.redirect_stderr = true
|
76
|
+
sandbox.run
|
77
|
+
@result = sandbox.stderr
|
78
|
+
end
|
79
|
+
|
80
|
+
verify('#stderr returns the contents of STDERR.') do
|
81
|
+
@result == 'Hello, world STDERR!'
|
82
|
+
end
|
83
|
+
|
84
|
+
exercise('@rescue set to false, @redirect_stderr set to true, #run called, ' \
|
85
|
+
'$stderr written to. ') do
|
86
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
87
|
+
$stderr.print "Hello, world $stderr!"
|
88
|
+
end
|
89
|
+
sandbox.redirect_stderr = true
|
90
|
+
sandbox.run
|
91
|
+
@result = sandbox.stderr
|
92
|
+
end
|
93
|
+
|
94
|
+
verify('#stderr returns the contents of $stderr.') do
|
95
|
+
@result == 'Hello, world $stderr!'
|
96
|
+
end
|
97
|
+
|
98
|
+
exercise('@rescue set to false, @redirect_stderr set to true, #run called, ' \
|
99
|
+
'STDOUT written to. ') do
|
100
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
101
|
+
STDERR.print "Hello, world STDERR!"
|
102
|
+
end
|
103
|
+
sandbox.redirect_stderr = true
|
104
|
+
sandbox.run
|
105
|
+
@result = sandbox.stderr
|
106
|
+
end
|
107
|
+
|
108
|
+
verify('#stderr returns the contents of STDERR.') do
|
109
|
+
@result == 'Hello, world STDERR!'
|
110
|
+
end
|
111
|
+
|
112
|
+
exercise('@redirect_stderr set to false, #run called. ') do
|
113
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
114
|
+
$stderr.print ""
|
115
|
+
STDERR.print ""
|
116
|
+
end
|
117
|
+
sandbox.run
|
118
|
+
@result = sandbox.stderr
|
119
|
+
end
|
120
|
+
|
121
|
+
verify('#stderr returns nil') do
|
122
|
+
@result == nil
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
suite('#stdout') do
|
128
|
+
|
129
|
+
setup do
|
130
|
+
@result = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
exercise('@rescue set to true, @redirect_stdout set to true, #run called, ' \
|
134
|
+
'$stdout written to. ') do
|
135
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
136
|
+
$stdout.print "Hello, world!"
|
137
|
+
end
|
138
|
+
sandbox.rescue_exception = true
|
139
|
+
sandbox.redirect_stdout = true
|
140
|
+
sandbox.run
|
141
|
+
@result = sandbox.stdout
|
142
|
+
end
|
143
|
+
|
144
|
+
verify('#stdout returns the contents of $stdout.') do
|
145
|
+
@result == 'Hello, world!'
|
146
|
+
end
|
147
|
+
|
148
|
+
exercise('@rescue set to true, @redirect_stdout set to true, #run called, ' \
|
149
|
+
'STDOUT written to.') do
|
150
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
151
|
+
STDOUT.print "Goodbye, world!"
|
152
|
+
end
|
153
|
+
sandbox.rescue_exception = true
|
154
|
+
sandbox.redirect_stdout = true
|
155
|
+
sandbox.run
|
156
|
+
@result = sandbox.stdout
|
157
|
+
end
|
158
|
+
|
159
|
+
verify('#stdout returns the contents of stdout of STDOUT') do
|
160
|
+
@result == 'Goodbye, world!'
|
161
|
+
end
|
162
|
+
|
163
|
+
exercise('@rescue set to false, @redirect_stdout set to true, #run called, ' \
|
164
|
+
'$stdout written to. ') do
|
165
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
166
|
+
$stdout.print "Hello, world!"
|
167
|
+
end
|
168
|
+
sandbox.redirect_stdout = true
|
169
|
+
sandbox.run
|
170
|
+
@result = sandbox.stdout
|
171
|
+
end
|
172
|
+
|
173
|
+
verify('#stdout returns the contents of $stdout') do
|
174
|
+
@result == 'Hello, world!'
|
175
|
+
end
|
176
|
+
|
177
|
+
exercise('@rescue set to false, @redirect_stdout set to true, #run called, ' \
|
178
|
+
'STDOUT written to. ') do
|
179
|
+
|
180
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
181
|
+
STDOUT.print "Goodbye, world!"
|
182
|
+
end
|
183
|
+
sandbox.redirect_stdout = true
|
184
|
+
sandbox.run
|
185
|
+
@result = sandbox.stdout
|
186
|
+
end
|
187
|
+
|
188
|
+
verify('#stdout returns the contents of STDOUT') do
|
189
|
+
@result == 'Goodbye, world!'
|
190
|
+
end
|
191
|
+
|
192
|
+
exercise('@redirect_stdout set to false, #run called. ') do
|
193
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
194
|
+
$stdout.print ""
|
195
|
+
STDOUT.print ""
|
196
|
+
end
|
197
|
+
sandbox.run
|
198
|
+
@result = sandbox.stdout
|
199
|
+
end
|
200
|
+
|
201
|
+
verify('#stdout returns nil') do
|
202
|
+
@result == nil
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
suite('#rescue_exception?') do
|
208
|
+
|
209
|
+
setup do
|
210
|
+
@result = nil
|
211
|
+
@sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) { }
|
212
|
+
end
|
213
|
+
|
214
|
+
exercise('@rescue is set to false. ') do
|
215
|
+
@result = @sandbox.rescue_exception?
|
216
|
+
end
|
217
|
+
|
218
|
+
verify('#rescue_exception? returns false') do
|
219
|
+
@result == false
|
220
|
+
end
|
221
|
+
|
222
|
+
exercise('@rescue is set to true. ') do
|
223
|
+
@sandbox.rescue_exception = true
|
224
|
+
@result = @sandbox.rescue_exception?
|
225
|
+
end
|
226
|
+
|
227
|
+
verify('#rescue_exception? returns true') do
|
228
|
+
@result == true
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
suite('#exception', :tags => [ :exception ] ) do
|
234
|
+
|
235
|
+
setup do
|
236
|
+
@result = nil
|
237
|
+
@sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) do
|
238
|
+
raise
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
exercise('@rescue is set to false, #run is called, no exception is raised. ') do
|
243
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) do
|
244
|
+
begin
|
245
|
+
raise
|
246
|
+
rescue => e
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
@result = sandbox.exception
|
251
|
+
end
|
252
|
+
|
253
|
+
verify('#exception returns nil to the parent process.') do
|
254
|
+
@result == nil
|
255
|
+
end
|
256
|
+
|
257
|
+
exercise('@rescue is set to true, #run is called, an exception is raised. ') do
|
258
|
+
@sandbox.rescue_exception = true
|
259
|
+
@sandbox.run
|
260
|
+
@result = @sandbox.exception.klass
|
261
|
+
end
|
262
|
+
|
263
|
+
verify('#exception returns raised exception to the parent process.') do
|
264
|
+
@result == "RuntimeError"
|
265
|
+
end
|
266
|
+
|
267
|
+
exercise('@rescue is set to true, #run is called, an is exception raised, ' \
|
268
|
+
'@rescue is set to false. ') do
|
269
|
+
@sandbox.rescue_exception = true
|
270
|
+
@sandbox.run
|
271
|
+
@sandbox.rescue_exception = false
|
272
|
+
@result = @sandbox.exception.klass
|
273
|
+
end
|
274
|
+
|
275
|
+
verify('#exception returns raised exception to parent process') do
|
276
|
+
@result == "RuntimeError"
|
277
|
+
end
|
278
|
+
|
279
|
+
exercise('Exception object created, re-define #message with code that will cause ' \
|
280
|
+
'another exception when Dia tries to serialize exception data.') do
|
281
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) do
|
282
|
+
e = Exception.new
|
283
|
+
def e.message
|
284
|
+
raise(StandardError, 'profit')
|
285
|
+
end
|
286
|
+
raise(e)
|
287
|
+
end
|
288
|
+
sandbox.rescue_exception = true
|
289
|
+
sandbox.run
|
290
|
+
@result = sandbox.exception
|
291
|
+
end
|
292
|
+
|
293
|
+
verify('Second exception is captured and returned by #exception') do
|
294
|
+
@result
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
suite('#run') do
|
300
|
+
|
301
|
+
setup do
|
302
|
+
@result = nil
|
303
|
+
@reader, @writer = IO.pipe
|
304
|
+
end
|
305
|
+
|
306
|
+
exercise('Confirm the profile ' \
|
307
|
+
'Dia::Profiles::NO_INTERNET ' \
|
308
|
+
'is creating a working sandbox environment.') do
|
309
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
310
|
+
begin
|
311
|
+
@reader.close
|
312
|
+
TCPSocket.open('http://www.google.com', 80)
|
313
|
+
@writer.write('false')
|
314
|
+
rescue SocketError, SystemCallError => e
|
315
|
+
@writer.write('true')
|
316
|
+
ensure
|
317
|
+
@writer.close
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
sandbox.run
|
322
|
+
|
323
|
+
@writer.close
|
324
|
+
@result = @reader.gets
|
325
|
+
@reader.close
|
326
|
+
end
|
327
|
+
|
328
|
+
verify(nil) do
|
329
|
+
@result == 'true'
|
330
|
+
end
|
331
|
+
|
332
|
+
exercise('Confirm the profile ' \
|
333
|
+
'Dia::Profiles::NO_FILESYSTEM_WRITE ' \
|
334
|
+
'is creating a working sandbox environment.') do
|
335
|
+
|
336
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_FILESYSTEM_WRITE) do
|
337
|
+
begin
|
338
|
+
@reader.close
|
339
|
+
File.open('/tmp/foo.txt', 'w') { |f| f.puts('fail') }
|
340
|
+
@writer.write('false')
|
341
|
+
rescue SocketError, SystemCallError => e
|
342
|
+
@writer.write('true')
|
343
|
+
ensure
|
344
|
+
@writer.close
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
|
349
|
+
sandbox.run
|
350
|
+
|
351
|
+
@writer.close
|
352
|
+
@result = @reader.gets
|
353
|
+
@reader.close
|
354
|
+
end
|
355
|
+
|
356
|
+
verify(nil) do
|
357
|
+
@result == 'true'
|
358
|
+
end
|
359
|
+
|
360
|
+
exercise('Confirm the profile ' \
|
361
|
+
'Dia::Profiles::NO_FILESYSTEM_WRITE_EXCEPT_TMP ' \
|
362
|
+
'is creating a working sandbox environment. ') do
|
363
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_FILESYSTEM_WRITE_EXCEPT_TMP) do
|
364
|
+
begin
|
365
|
+
@reader.close
|
366
|
+
out = Time.now.to_s
|
367
|
+
File.open('/tmp/%s.dia_test' % [ out ] , 'w') { |f| f.puts('success') }
|
368
|
+
File.open(File.join(ENV['HOME'], 'fail.txt')) { |f| f.puts('fail') }
|
369
|
+
@writer.write('false')
|
370
|
+
rescue SocketError, SystemCallError => e
|
371
|
+
if File.exists?('/tmp/%s.dia_test' % [ out ])
|
372
|
+
@writer.write('true')
|
373
|
+
else
|
374
|
+
@writer.write('false')
|
375
|
+
end
|
376
|
+
ensure
|
377
|
+
@writer.close
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
sandbox.run
|
382
|
+
|
383
|
+
@writer.close
|
384
|
+
@result = @reader.gets
|
385
|
+
@reader.close
|
386
|
+
end
|
387
|
+
|
388
|
+
verify(nil) do
|
389
|
+
@result == 'true'
|
390
|
+
end
|
391
|
+
|
392
|
+
exercise('Confirm the profile ' \
|
393
|
+
'Dia::Profiles::NO_NETWORKING ' \
|
394
|
+
'is creating a working sandbox environment') do
|
395
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_NETWORKING) do
|
396
|
+
begin
|
397
|
+
@reader.close
|
398
|
+
TCPSocket.open('http://www.youtube.com', 80)
|
399
|
+
@writer.write('false')
|
400
|
+
rescue SocketError => e
|
401
|
+
@writer.write('true')
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
sandbox.run
|
406
|
+
|
407
|
+
@writer.close
|
408
|
+
@result = @reader.gets
|
409
|
+
@reader.close
|
410
|
+
end
|
411
|
+
|
412
|
+
verify(nil) do
|
413
|
+
@result == 'true'
|
414
|
+
end
|
415
|
+
|
416
|
+
exercise('#run called. ') do
|
417
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_OS_SERVICES) { }
|
418
|
+
@result = sandbox.run
|
419
|
+
end
|
420
|
+
|
421
|
+
verify('returns the Process ID(PID) of spawned process as a Fixnum') do
|
422
|
+
@result.class == Fixnum
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
suite('#run_nonblock') do
|
428
|
+
|
429
|
+
setup do
|
430
|
+
@result = nil
|
431
|
+
@reader, @writer = IO.pipe
|
432
|
+
end
|
433
|
+
|
434
|
+
exercise('Confirm the profile ' \
|
435
|
+
'Dia::Profiles::NO_INTERNET ' \
|
436
|
+
'is creating a working sandbox environment.') do
|
437
|
+
|
438
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) do
|
439
|
+
begin
|
440
|
+
@reader.close
|
441
|
+
TCPSocket.open('http://www.google.com', 80)
|
442
|
+
@writer.write('false')
|
443
|
+
rescue SocketError, SystemCallError => e
|
444
|
+
@writer.write('true')
|
445
|
+
ensure
|
446
|
+
@writer.close
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
sandbox.run_nonblock
|
451
|
+
sleep(1)
|
452
|
+
|
453
|
+
@writer.close
|
454
|
+
@result = @reader.gets
|
455
|
+
@reader.close
|
456
|
+
end
|
457
|
+
|
458
|
+
verify(nil) do
|
459
|
+
@result == 'true'
|
460
|
+
end
|
461
|
+
|
462
|
+
exercise('Confirm the profile ' \
|
463
|
+
'Dia::Profiles::NO_FILESYSTEM_WRITE ' \
|
464
|
+
'is creating a working sandbox environment.') do
|
465
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_FILESYSTEM_WRITE) do
|
466
|
+
begin
|
467
|
+
@reader.close
|
468
|
+
File.open('/tmp/foo.txt', 'w') { |f| f.puts('fail') }
|
469
|
+
@writer.write('false')
|
470
|
+
rescue SocketError, SystemCallError => e
|
471
|
+
@writer.write('true')
|
472
|
+
ensure
|
473
|
+
@writer.close
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
|
478
|
+
sandbox.run_nonblock
|
479
|
+
sleep(1)
|
480
|
+
|
481
|
+
@writer.close
|
482
|
+
@result = @reader.gets
|
483
|
+
@reader.close
|
484
|
+
end
|
485
|
+
|
486
|
+
verify(nil) do
|
487
|
+
@result == 'true'
|
488
|
+
end
|
489
|
+
|
490
|
+
exercise('Confirm the profile ' \
|
491
|
+
'Dia::Profiles::NO_FILESYSTEM_WRITE_EXCEPT_TMP ' \
|
492
|
+
'is creating a working sandbox environment. ') do
|
493
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_FILESYSTEM_WRITE_EXCEPT_TMP) do
|
494
|
+
begin
|
495
|
+
@reader.close
|
496
|
+
out = Time.now.to_s
|
497
|
+
File.open('/tmp/%s.dia_test' % [ out ] , 'w') { |f| f.puts('success') }
|
498
|
+
File.open(File.join(ENV['HOME'], 'fail.txt')) { |f| f.puts('fail') }
|
499
|
+
@writer.write('false')
|
500
|
+
rescue SocketError, SystemCallError => e
|
501
|
+
if File.exists?('/tmp/%s.dia_test' % [ out ])
|
502
|
+
@writer.write('true')
|
503
|
+
else
|
504
|
+
@writer.write('false')
|
505
|
+
end
|
506
|
+
ensure
|
507
|
+
@writer.close
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
sandbox.run_nonblock
|
512
|
+
sleep(1)
|
513
|
+
|
514
|
+
@writer.close
|
515
|
+
@result = @reader.gets
|
516
|
+
@reader.close
|
517
|
+
end
|
518
|
+
|
519
|
+
verify(nil) do
|
520
|
+
@result == 'true'
|
521
|
+
end
|
522
|
+
|
523
|
+
exercise('Confirm the profile ' \
|
524
|
+
'Dia::Profiles::NO_NETWORKING ' \
|
525
|
+
'is creating a working sandbox environment') do
|
526
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_NETWORKING) do
|
527
|
+
begin
|
528
|
+
@reader.close
|
529
|
+
TCPSocket.open('http://www.youtube.com', 80)
|
530
|
+
@writer.write('false')
|
531
|
+
rescue SocketError => e
|
532
|
+
@writer.write('true')
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
sandbox.run_nonblock
|
537
|
+
sleep(1)
|
538
|
+
|
539
|
+
@writer.close
|
540
|
+
@result = @reader.gets
|
541
|
+
@reader.close
|
542
|
+
end
|
543
|
+
|
544
|
+
verify(nil) do
|
545
|
+
@result == 'true'
|
546
|
+
end
|
547
|
+
|
548
|
+
exercise('#run_nonblock called. ') do
|
549
|
+
|
550
|
+
sandbox = Dia::RubyBlock.new(Dia::Profiles::NO_INTERNET) { }
|
551
|
+
@result = sandbox.run_nonblock
|
552
|
+
end
|
553
|
+
|
554
|
+
verify('returns the Process ID(PID) of spawned process as a Fixnum') do
|
555
|
+
@result.class == Fixnum
|
556
|
+
end
|
557
|
+
|
558
|
+
end
|
559
|
+
|
560
|
+
end
|
561
|
+
|