aruba-jbb 0.2.6.8 → 0.2.6.9

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,10 +1,15 @@
1
+ == 0.2.6.9 jbb
2
+ * added timeout method and basic support step definitions
3
+ * somewhat improved api documentation
4
+
1
5
  == 0.2.6.8 jbb
2
6
  * added some api method documentation
3
7
 
4
8
  == 0.2.6.7 msassak
9
+ * Returned to using Background_Process
5
10
 
6
11
  === Bug fixes
7
- * Outputting large amounts of data causes BackgroundProcess#exitstatus to hang (#18 Mike Sassak)
12
+ * Outputting large amounts of data causes BackgroundProcess to hang
8
13
 
9
14
  == 0.2.6.6 jbb
10
15
  * reverted run api method to old implementation and removed background_process
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = Aruba
2
2
 
3
3
  Aruba-jbb is a fork of http://github.com/aslakhellesoy/aruba and is found
4
- at http://byrnejb/aruba.
4
+ at http://github.com/byrnejb/aruba.
5
5
 
6
6
  Aruba-jbb is a set of api methods and cucumber steps for driving out command
7
7
  line application behaviours. The command line application can be anything,
@@ -28,9 +28,13 @@ permits switching between the two in Bundler without having to alter env.rb
28
28
  as well. However, as of v-0.2.6.3 you have the option of requiring
29
29
  <tt>aruba_jbb</tt> instead.
30
30
 
31
- You now have a bunch of step definitions that you can use in your features.
32
- Look at aruba/cucumber_steps.rb to see all the step definitions. Look at
31
+ You now have sever api mehtods and a selection of step definitions that
32
+ you can use in features that test stand-alone processes. Look at
33
+ aruba/cucumber_steps.rb to see all the step definitions. Look at
33
34
  features/*.feature for examples (which are also testing Aruba itself).
35
+ A start has been made at documenting the api as well. Any suggestions
36
+ to improve what is already there, or to provide whatever is missing, are
37
+ most welcome.
34
38
 
35
39
  You should be aware that Aruba runs the application it tests and creates
36
40
  all local output in its own working directory (awd). The awd defaults to
@@ -70,14 +74,28 @@ Upstream addressed the more limited problem of locating <code>./bin</code>
70
74
  by adding a <code>@bin</code> tag which appends <code>./bin</code> to Cucumber's
71
75
  LOADPATH. This technique is supported by Aruba-jbb as well.
72
76
 
77
+ The aruba <tt>run</tt> api method is now (0.2.6.9) surrounded by a timeout call.
78
+ This means that after the default period of 2 seconds any process under test
79
+ is forceably terminated. However, be advised that the run api methods raises
80
+ no error is raised by default.Instead the process exit status is set to -1 and
81
+ stderr will contain <em>Aruba::Api::ProcessTimeout: execution expired</em>.
82
+ You are therefore advised to either override the When /run "([^\"])"/ do |cmd|
83
+ step definition or provide an alternative form.
73
84
 
74
- == Ruby/RVM love
85
+ The default timeout value of 2 may be overriden either by defining an environmental
86
+ variable called ARUBA_RUN_TIMEOUT to the approprate value (in seconds) or by
87
+ passing an optional third parameter to the run api method. Fractional values
88
+ are acepted but granularity of less than interger seconds is not guarenteed to
89
+ work.
75
90
 
76
- Aruba once had a couple of step definitions to make it easier to test your
77
- Ruby command line program with specific versions of Ruby (regardless of
78
- what Ruby version you were using to invoke Cucumber). These were removed in
79
- upstream's 0.2.2 version and are no longer present in this fork either.
80
- The last version of this fork having them was 0.2.6.
91
+ Timeout does not work for the run_interactive api method. This is experimaental
92
+ code merged from Mike Sassak's fork.
93
+
94
+ == Ruby/RVM
95
+
96
+ Aruba once had api methods to run rvm ruby from inside aruba. These
97
+ were removed in upstream's 0.2.2 version and are no longer present in this
98
+ fork either. The last version of this fork having them was 0.2.6.
81
99
 
82
100
  To test against specific versions of Ruby using RVM you are advised to use
83
101
  following idiom (note the comma between Ruby version numbers):
data/aruba-jbb.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{aruba-jbb}
5
- s.version = "0.2.6.8"
5
+ s.version = "0.2.6.9"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Aslak Hellesøy", "David Chelimsky", "James B. Byrne", "Mike Sassak"]
@@ -11,15 +11,15 @@ Feature: Flushing output
11
11
  Then the stdout should contain "rword"
12
12
 
13
13
 
14
- Scenario: Tons of output
14
+ Scenario: Stdout should equal output length plus \n
15
15
  When I run "ruby -e 'puts :a.to_s * 65536'"
16
16
  Then the output should contain "a"
17
- And the output should be 65537 bytes long
17
+ And the output should be exactly "65537" bytes long
18
18
 
19
-
20
- Scenario: Tons of interactive output
19
+
20
+ Scenario: Interactive Stdout should equal output length plus \n
21
21
  When I run "ruby -e 'len = gets.chomp; puts :a.to_s * len.to_i'" interactively
22
22
  And I type "65536"
23
23
  Then the output should contain "a"
24
- And the output should be 65537 bytes long
24
+ And the output should be at least "65536" bytes long
25
25
 
@@ -38,6 +38,7 @@ Feature: Output
38
38
  good-bye
39
39
  """
40
40
 
41
+ @announce
41
42
  Scenario: Detect exact one-line output
42
43
  When I run "ruby -e 'puts \"hello world\"'"
43
44
  Then the output should contain exactly "hello world\n"
@@ -0,0 +1,25 @@
1
+ Feature: process should timeout
2
+
3
+ In order to prevent test runs from suspending indefinitiely
4
+ As a developer using Cucumber Aruba
5
+ I want long processes to terminate after a fixed elapsed time
6
+
7
+
8
+ Scenario: process runner times out for long process
9
+ When I run "ruby -e 'sleep(12)'"
10
+ Then the exit status should not be 0
11
+ And stderr should contain "execution expired"
12
+
13
+
14
+ Scenario: process runner timeout can be set lower than default
15
+ Given the following step should fail with RuntimeError:
16
+ """
17
+ When I run "ruby -e 'sleep(2)'" with timeout of "1.5" seconds
18
+ """
19
+ Then the exit status should be -1
20
+
21
+
22
+ Scenario: process runner timeout can be set higher than default
23
+ When I run "ruby -e 'sleep(4)'" with timeout of "5.7" seconds
24
+ Then the exit status should be 0
25
+ And stderr should be empty
@@ -74,10 +74,19 @@ When /^aruba should fail with "([^\"]*)"$/ do |error_message|
74
74
  end
75
75
 
76
76
 
77
+ When /^the following step should fail with RuntimeError:$/ do |multiline_step|
78
+ proc {steps multiline_step}.should raise_error(RuntimeError)
79
+ end
80
+
81
+
77
82
  When /^the following step should fail with Spec::Expectations::ExpectationNotMetError:$/ do |multiline_step|
78
83
  proc {steps multiline_step}.should raise_error(RSpec::Expectations::ExpectationNotMetError)
79
84
  end
80
85
 
81
- Then /^the output should be (\d+) bytes long$/ do |length|
86
+ Then /^the output should be at least "(\d+)" bytes long$/ do |length|
87
+ combined_output.length.should >= length.to_i
88
+ end
89
+
90
+ Then /^the output should be exactly "(\d+)" bytes long$/ do |length|
82
91
  combined_output.length.should == length.to_i
83
92
  end
data/lib/aruba/api.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'timeout'
1
2
  require 'tempfile'
2
3
  require 'rbconfig'
3
4
  require 'background_process'
@@ -6,7 +7,7 @@ module Aruba
6
7
  module Api
7
8
 
8
9
  # announce_or_puts(msg) is an internal helper method for
9
- # reproduccing test process output in the Aruba run.
10
+ # reproducing test process output in the Aruba run.
10
11
  #
11
12
  def announce_or_puts(msg)
12
13
  if(@puts)
@@ -32,7 +33,7 @@ module Aruba
32
33
  end
33
34
  end
34
35
 
35
- # aruba_working_dir simple returns the value of the current
36
+ # aruba_working_dir simply returns the value of the current
36
37
  # directory that aruba is running its features in. This is
37
38
  # set using the aruba_working_dir_set method from within the
38
39
  # step definitions or through the environment variable
@@ -80,8 +81,8 @@ module Aruba
80
81
  end
81
82
  end
82
83
 
83
- # assert_exit_status_and_partial_output(pass_or_fail, output) is an
84
- # internal helper method not really should not be used in a step definition.
84
+ # assert_exit_status_and_partial_output is an internal helper
85
+ # method that really should not be used in a step definition.
85
86
  #
86
87
  def assert_exit_status_and_partial_output(expect_to_pass, partial_output)
87
88
  assert_partial_output(partial_output)
@@ -92,22 +93,45 @@ module Aruba
92
93
  end
93
94
  end
94
95
 
95
- # assert_failing_with(output) uses assert_exit_status_and_partial_output.
96
+ # assert_failing_with uses assert_exit_status_and_partial_output.
96
97
  # It passes the exit status expectation as false (fail) and the text
97
98
  # expected in the output to that method.
98
99
  #
100
+ # Usage:
101
+ # Then the program should fail with:
102
+ # """
103
+ # No such entry
104
+ # """
105
+ #
106
+ # Then /the program should fail with:$/ do |content|
107
+ # assert_failing_with(content)
108
+ #
99
109
  def assert_failing_with(partial_output)
100
110
  assert_exit_status_and_partial_output(false, partial_output)
101
111
  end
102
112
 
103
- # assert_partial_output(partial_output)
113
+ # assert_partial_output test if the provided string or rexexo occurs
114
+ # in either $stdout or $stderr.
115
+ #
116
+ # Usage:
117
+ # Then I should see "this text" in the output
118
+ #
119
+ # Then /I should see "([^\"]*)" in the output/ do |content\
120
+ # assert_partial_output(content)
121
+ #
104
122
  def assert_partial_output(partial_output)
105
123
  combined_output.should =~ regexp(partial_output)
106
124
  end
107
125
 
108
- # assert_passing_with(output) uses assert_exit_status_and_partial_output.
126
+ # assert_passing_with uses assert_exit_status_and_partial_output.
109
127
  # It passes the exit status expectation as true (pass) and the text
110
- # expected in the output to that method.
128
+ # expected in the output to that method. See assert_failing_with.
129
+ #
130
+ # Usage:
131
+ # Then the program should run successfully with ""
132
+ #
133
+ # Then /the program should run successfully with "([^\"]*)"/ do |output|
134
+ # assert_passing_with(output)
111
135
  #
112
136
  def assert_passing_with(partial_output)
113
137
  assert_exit_status_and_partial_output(true, partial_output)
@@ -116,7 +140,10 @@ module Aruba
116
140
  # cd(path) changes aruba's working directory (awd) to path.
117
141
  #
118
142
  # Usage:
119
- # When I cd to "foo/nonexistant" step"
143
+ # When I cd to "foo/nonexistant"
144
+ #
145
+ # When /I cd to "([^\"]*)"/ do |dir|
146
+ # cd(dir)
120
147
  #
121
148
  def cd(dir)
122
149
  dirs << dir
@@ -134,6 +161,14 @@ module Aruba
134
161
  # | foo/bar |
135
162
  # | foo/bla |
136
163
  #
164
+ # Then the following directories should not exist:
165
+ # | bar/foo |
166
+ # | bar/none |
167
+ #
168
+ # When /following directories should exist:$/ do |directories|
169
+ # check_directory_presence(directories.raw.map{
170
+ # |directory_row| directory_row[0]}, true)
171
+ #
137
172
  def check_directory_presence(paths, expect_presence)
138
173
  in_current_dir do
139
174
  paths.each do |path|
@@ -146,8 +181,8 @@ module Aruba
146
181
  end
147
182
  end
148
183
 
149
- # check_exact_file_content(file, exact_content) veries that
150
- # the specified file contains exactly the provided text.
184
+ # check_exact_file_content veries that the specified file contains
185
+ # exactly the provided text.
151
186
  #
152
187
  # Usage:
153
188
  # Then the file "foo" should contain exactly:
@@ -156,9 +191,12 @@ module Aruba
156
191
  # And this
157
192
  # """
158
193
  #
159
- def check_exact_file_content(file, exact_content)
194
+ # When /the file "([^\"]*)" should contain exactly:$/ do |file,contents|
195
+ # check_exact_file_content(exact_output)
196
+ #
197
+ def check_exact_file_content(file, contents)
160
198
  in_current_dir do
161
- IO.read(file).should == exact_content
199
+ IO.read(file).should == contents
162
200
  end
163
201
  end
164
202
 
@@ -166,7 +204,20 @@ module Aruba
166
204
  # the specified file contains at least the provided text.
167
205
  #
168
206
  # Usage:
169
- # Then I do have the file named "foo" with "blah"
207
+ # Then the file named "foo" should contain:
208
+ # """
209
+ # My file should have this.
210
+ # And this
211
+ # """
212
+ #
213
+ # Then the file "foo" should not contain:
214
+ # """
215
+ # My file should not have this.
216
+ # And this
217
+ # """
218
+ #
219
+ # When /the file named "foo" should contain:$/ do |file, content|
220
+ # check_file_content(file, content, true)
170
221
  #
171
222
  def check_file_content(file, partial_content, expect_match)
172
223
  regexp = regexp(partial_content)
@@ -180,10 +231,20 @@ module Aruba
180
231
  end
181
232
  end
182
233
 
183
- # check_file_presence(paths, expect_presence) operates on files in
184
- # a fashion similare to check_directory_presence. it enumerates
185
- # of a collection fo file names and passes or fails on the
186
- # existance of each according to the expect_presence setting.
234
+ # check_file_presence operates on files in a fashion similar
235
+ # to check_directory_presence. it enumerates on a collection
236
+ # of file names and passes or fails on the first presence or
237
+ # abscence in the filesystem according to the expect_presence setting.
238
+ #
239
+ # Usage:
240
+ # When the following files should exist:
241
+ # """
242
+ # blah/file.tst
243
+ # bare/file1.test
244
+ # foor/barnet.tst
245
+ # """
246
+ # When /following files? should exist:$/ do |files|
247
+ # check_file_presence(files.raw.map{|file_row| file_row[0]}, true)
187
248
  #
188
249
  def check_file_presence(paths, expect_presence)
189
250
  in_current_dir do
@@ -197,9 +258,9 @@ module Aruba
197
258
  end
198
259
  end
199
260
 
200
- # clean_up(dir = current_dir) is an internal helper method that empties
201
- # the current working directory of all content. It is used in the
202
- # Aruba before hook to clear out the awd at the start of each scenario.
261
+ # clean_up is an internal helper method that empties the current working
262
+ # directory of all content. It is used in the Aruba before hook to clear
263
+ # out the awd at the start of each scenario.
203
264
  #
204
265
  # It will not clear any directory that does not contain the directory
205
266
  # <tt>/tmp/</tt> somewhare in its path.
@@ -214,8 +275,8 @@ module Aruba
214
275
  end
215
276
  end
216
277
 
217
- # clean_up!(dir = current_dir). Internal helper method. Does not check
218
- # for tmp directory path.
278
+ # clean_up! is an Internal helper method that clears the awd without
279
+ # checking for tmp in the directory path. Do not use this.
219
280
  #
220
281
  def clean_up!(dir = current_dir)
221
282
  FileUtils.rm_rf(dir)
@@ -225,29 +286,65 @@ module Aruba
225
286
  # combined_output is an internal helper methiod that concatenates the
226
287
  # contents of $stdout with $stderr.
227
288
  #
289
+ # Usage:
290
+ # Then output should contain:
291
+ # """
292
+ # toto
293
+ # red shoes
294
+ # """
295
+ # Then output should contain "toto"
296
+ # Then output should contain exactly:
297
+ # """
298
+ # toto
299
+ # red shoes
300
+ # """
301
+ # Then output should contain exactly "toto"
302
+ # Then output should not contain:
303
+ # """
304
+ # toto
305
+ # red shoes
306
+ # """
307
+ # Then output should not contain "toto"
308
+ # Then output should not contain exactly:
309
+ # """
310
+ # toto
311
+ # red shoes
312
+ # """
313
+ # Then output should not contain exactly "toto"
314
+ #
315
+ # When /output should contain "([^\"]*)"$/ do |partial_output|
316
+ # combined_output.should =~ regexp(partial_output)
317
+ #
228
318
  def combined_output
229
319
  if @interactive
230
- interactive_output
320
+ interactive_output.to_s
231
321
  else
232
- @last_stdout.to_s + @last_stderr.to_s
322
+ if @last_stderr != nil and @last_stderr != ""
323
+ @last_stdout.to_s + @last_stderr.inspect.to_s
324
+ else
325
+ @last_stdout.to_s
326
+ end
233
327
  end
234
328
  end
235
329
 
236
- # create_dir(dir_name) creates the given directory name within the awd
330
+ # create_dir creates the given directory name within the awd
237
331
  # subject to normal filesystem restrictions.
238
332
  #
239
333
  # `Usage:
240
334
  # Given I do have a directory named "foobar"$
241
335
  #
336
+ # When /I do have a directory named "([^\"]*)"$/ do |dir_name|
337
+ # create_dir(dir_name)
338
+ #
242
339
  def create_dir(dir_name)
243
340
  in_current_dir do
244
341
  _mkdir(dir_name)
245
342
  end
246
343
  end
247
344
 
248
- # create_file(file_name, file_content, check_presence = false) creates
249
- # the given file name in the awd and fills it with the provided content,
250
- # optionally checking first to see if the file exists.
345
+ # create_file creates the given file name in the awd and fills it
346
+ # with the provided content, optionally checking first to see if
347
+ # the file exists.
251
348
  #
252
349
  # Usage:
253
350
  # When we do have a file named "foo" containing:
@@ -255,7 +352,15 @@ module Aruba
255
352
  # This is in my new file.
256
353
  # And so is this
257
354
  # """
258
- #
355
+ #
356
+ # When /do have a file named "([^\"]*)" containing:$/ do |file, content|
357
+ # create_file(file, content)
358
+ #
359
+ # When I do have an empty file named "empty"
360
+ #
361
+ # When /I do have an empty file named "([^\"]*)"$/ do |file_name|
362
+ # create_file(file_name, "")
363
+ #
259
364
  def create_file(file_name, file_content, check_presence = false)
260
365
  in_current_dir do
261
366
  raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
@@ -279,10 +384,10 @@ module Aruba
279
384
  RbConfig::CONFIG['ruby_install_name'])
280
385
  end
281
386
 
282
- # detect_ruby(cmd) is an internal helper method that checks to see
283
- # if the Aruba test cli command is ruby itself and returns the
284
- # value of current_ruby to the <tt>run</tt> method and the value
285
- # of cmd otherwise.
387
+ # detect_ruby is an internal helper method that checks to see
388
+ # if the Aruba test cli command is ruby itself. If so then it returns
389
+ # the value of current_ruby to the <tt>run</tt> method. If not then
390
+ # it returns the the value of cmd.
286
391
  #
287
392
  def detect_ruby(cmd)
288
393
  if cmd =~ /^ruby\s/
@@ -293,13 +398,13 @@ module Aruba
293
398
  end
294
399
 
295
400
  # This provides a regexp of commonly encountered Ruby scripts
296
- # for use in testing Aruba itself.
401
+ # for use in testing Aruba itself. Used by detect_ruby_script.
297
402
  #
298
403
  COMMON_RUBY_SCRIPTS = \
299
404
  /^(?:bundle|cucumber|gem|jeweler|rails|rake|rspec|spec)\s/
300
405
 
301
406
  # detect_ruby_script is an internal helper script used in testing
302
- # Aruba itself.
407
+ # Aruba itself. Uses COMMON_RUBY_SCRIPTS.
303
408
  #
304
409
  def detect_ruby_script(cmd)
305
410
  if cmd =~ COMMON_RUBY_SCRIPTS
@@ -325,14 +430,14 @@ module Aruba
325
430
  @dirs << aruba_working_dir
326
431
  end
327
432
 
328
- # ensure_newline(str) is an internal helper method used to test interactive
433
+ # ensure_newline is an internal helper method used to test interactive
329
434
  # CLI programs with Aruba.
330
435
  #
331
436
  def ensure_newline(str)
332
437
  str.chomp << "\n"
333
438
  end
334
439
 
335
- # in_current_dir(&block) is an internal helper method wherein all the magic
440
+ # in_current_dir is an internal helper method wherein all the magic
336
441
  # of Aruba takes place. It uses the value of current_dir to determine
337
442
  # what directory to change to before running Aruba steps.
338
443
  #
@@ -341,9 +446,10 @@ module Aruba
341
446
  Dir.chdir(current_dir, &block)
342
447
  end
343
448
 
344
- # install_gems(gemfile) internal helper method that uses Bundler to
345
- # install the gems specified int he given Gemfile name into the
346
- # current Ruby VM.
449
+ # install_gems internal helper method that uses up Bundler to
450
+ # install the gems specified in the given Gemfile name into the
451
+ # current Ruby VM. If Bundler is not present then this method will
452
+ # attempt to install it.
347
453
  #
348
454
  def install_gems(gemfile)
349
455
  create_file("Gemfile", gemfile)
@@ -353,8 +459,8 @@ module Aruba
353
459
  end
354
460
  end
355
461
 
356
- # interactive_output an internal helper method that provides the contents
357
- # of $stdout from interactive Aruba processes.
462
+ # interactive_output is an internal helper method that provides
463
+ # the contents of $stdout from interactive Aruba processes.
358
464
  #
359
465
  def interactive_output
360
466
  @_interactive ||= if @interactive
@@ -365,11 +471,14 @@ module Aruba
365
471
  end
366
472
  end
367
473
 
368
- # original_env is an internal helper method that returns a hash of the
369
- # original env variables and their values for restore_original_env
370
- #
371
- def original_env
372
- @original_env ||= {}
474
+ # Attribute.
475
+ def last_stderr
476
+ @last_stderr
477
+ end
478
+
479
+ # Attribute
480
+ def last_stdout
481
+ @last_stdout
373
482
  end
374
483
 
375
484
  # _mkdir(dir_name) is an internal helper name that does exactly as its
@@ -379,13 +488,23 @@ module Aruba
379
488
  FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
380
489
  end
381
490
 
382
- # rebase(dirs=nil) creates a symbolic link in the awd to each directory
383
- # contained in the passed array that are named relative to the user's
491
+ # original_env is an internal helper method that returns a hash of the
492
+ # original env variables and their values for use in restore_original_env
493
+ #
494
+ def original_env
495
+ @original_env ||= {}
496
+ end
497
+
498
+ # rebase creates a symbolic link in the awd to each directory
499
+ # contained in the passed array.Each entry is named relative to the user's
384
500
  # cwd. It first checkes that the awd path contains a directory named
385
501
  # <tt>/tmp/</tt> and fails if it does not.
386
502
  #
387
503
  # Usage:
388
- # When I rebase the directory "bar/foo"$
504
+ # When I rebase the directory named "bar/foo"$
505
+ #
506
+ # When /I rebase the directory named "([^\"]*)"$/ do |dir|
507
+ # rebase(dir)
389
508
  #
390
509
  def rebase(dirs=nil)
391
510
 
@@ -410,7 +529,7 @@ module Aruba
410
529
  @aruba_rebase_dirs
411
530
  end
412
531
 
413
- # rebase_dirs_add(dirs=nil) is an internal helper method that
532
+ # rebase_dirs_add is an internal helper method that
414
533
  # adds directory names to the rebase_dirs array.
415
534
  #
416
535
  def rebase_dirs_add(dirs=nil)
@@ -440,7 +559,10 @@ module Aruba
440
559
  # Then stdout should contain "this"
441
560
  # Then stderr should not contain "this"
442
561
  # Then stdout should not contain "this"
443
- #
562
+ #
563
+ # When /stderr should contain "([^\"]*)"$/ do |partial_output|
564
+ # last_stderr.should =~ regexp(partial_output)
565
+
444
566
  def regexp(string_or_regexp)
445
567
  Regexp === string_or_regexp ? string_or_regexp : Regexp.compile(Regexp.escape(string_or_regexp))
446
568
  end
@@ -453,9 +575,16 @@ module Aruba
453
575
  ENV[key] = value
454
576
  end
455
577
  end
578
+
579
+ class ProcessTimeout < Timeout::Error; end
580
+ # Set the default timeout in seconds for external process to finish
581
+ # May be overrriden by setting environment variable ARUBA_RUN_TIMEOUT
582
+ ARUBA_RUN_TIMEOUT_DEFAULT = 2
456
583
 
457
- # run(cmd, fail_on_error=true) is the internal helper method that actually
458
- # runs the test executable, optionally failing if the exit status != 0.
584
+ # run is the internal helper method that actually runs the external
585
+ # test process, optionally failing if the exit status != 0. Takes an
586
+ # optional thrid parameter to specific maximum time process should
587
+ # take befor exiting.
459
588
  #
460
589
  # Usage:
461
590
  # When I run "ruby -e 'puts "hello world"'
@@ -463,26 +592,57 @@ module Aruba
463
592
  # When I run "ruby -e 'fail' with errors
464
593
  # When I run "ruby -e 'exit' without errors
465
594
  #
466
- def run(cmd, fail_on_error=true)
595
+ # When /I run a long process without error/ do
596
+ # run(long_process, true, 15) # allow 15 seconds.
597
+ #
598
+ # When /run "(.*)" with timeout of "()" seconds$/ do |cmd, time|
599
+ # run(unescape(cmd), true, time.to_f)
600
+ # end
601
+ def run(cmd, fail_on_error=true, tlimit=nil)
602
+
603
+ @last_stderr = ""
604
+ @last_stdout = ""
467
605
  cmd = detect_ruby(cmd)
468
606
 
607
+ if tlimit == nil
608
+ if defined?(ENV[ARUBA_RUN_TIMEOUT])
609
+ tlimit = ENV[ARUBA_RUN_TIMEOUT]
610
+ else
611
+ tlimit = ARUBA_RUN_TIMEOUT_DEFAULT
612
+ end
613
+ else
614
+ tlimit = tlimit.to_f
615
+ end
469
616
 
470
617
  in_current_dir do
471
618
  announce_or_puts("$ cd #{Dir.pwd}") if @announce_dir
472
619
  announce_or_puts("$ #{cmd}") if @announce_cmd
473
- ps = BackgroundProcess.run(cmd)
474
- @last_stdout = ps.stdout.read
475
- announce_or_puts(@last_stdout) if @announce_stdout
476
- @last_stderr = ps.stderr.read
477
- announce_or_puts(@last_stderr) if @announce_stderr
478
- @last_exit_status = ps.exitstatus # Waits for process to finish
620
+ begin
621
+ Timeout::timeout(tlimit, ProcessTimeout) {
622
+ ps = BackgroundProcess.run(cmd)
623
+ @last_stdout = ps.stdout.read
624
+ announce_or_puts(@last_stdout) if @announce_stdout
625
+ @last_stderr = ps.stderr.read
626
+ announce_or_puts(@last_stderr) if @announce_stderr
627
+ # Waits for process to finish or timeout
628
+ @last_exit_status = ps.exitstatus
629
+ }
630
+ rescue ProcessTimeout => e
631
+ if @last_stderr
632
+ @last_stderr += e.inspect
633
+ else
634
+ @last_stderr = e.inspect
635
+ end
636
+ @last_exit_status = -1
637
+ announce_or_puts(@last_exit_status.to_i.to_s) if @announce_stderr
638
+ announce_or_puts(@last_stderr) if @announce_stderr
639
+ end
479
640
  end
480
641
 
481
642
  if(@last_exit_status != 0 && fail_on_error)
482
643
  fail("Exit status was #{@last_exit_status}. Output:\n#{combined_output}")
483
644
  end
484
645
 
485
- @last_stderr
486
646
  end
487
647
 
488
648
  # run_interactive(cmd) is an internal helper method that runs CLI
@@ -559,7 +719,7 @@ module Aruba
559
719
  # write_interactive(input) writes the provided string to $stdin of
560
720
  # the interactive process run by Aruba.
561
721
  # Usage
562
- # When i type "the answwer is 42"
722
+ # When I type "the answwer is 42"
563
723
  #
564
724
  def write_interactive(input)
565
725
  @interactive.stdin.write(input)
@@ -56,6 +56,16 @@ When /clean up the working directory/ do
56
56
  end
57
57
 
58
58
 
59
+ When /display stderr/ do
60
+ announce_or_puts(last_stderr)
61
+ end
62
+
63
+
64
+ When /display stdout/ do
65
+ announce_or_puts(last_stdout)
66
+ end
67
+
68
+
59
69
  When /do(?:es)? have (?:a|the) directory named "([^\"]*)"$/ do |dir_name|
60
70
  create_dir(dir_name)
61
71
  end
@@ -72,12 +82,13 @@ When /do(?:es)? have an empty file named "([^\"]*)"$/ do |file_name|
72
82
  end
73
83
 
74
84
 
75
- When /exit status should be (\d+)$/ do |exit_status|
85
+ When /exit status should be (-?\d+)$/ do |exit_status|
76
86
  @last_exit_status.should == exit_status.to_i
77
87
  end
78
88
 
79
89
 
80
- When /exit status should not be (\d+)$/ do |exit_status|
90
+ When /exit status should not be (-?\d+)$/ do |exit_status|
91
+ @last_exit_status.should_not == nil
81
92
  @last_exit_status.should_not == exit_status.to_i
82
93
  end
83
94
 
@@ -193,7 +204,7 @@ When /run "(.*)"$/ do |cmd|
193
204
  end
194
205
 
195
206
 
196
- When /run "([^\"]*)" interactively$/ do |cmd|
207
+ When /run "(.*)" interactively$/ do |cmd|
197
208
  run_interactive(unescape(cmd))
198
209
  end
199
210
 
@@ -203,6 +214,11 @@ When /run "(.*)" with errors?$/ do |cmd|
203
214
  end
204
215
 
205
216
 
217
+ When /run "(.*)" with timeout of "(\d+\.?\d*)" seconds$/ do |cmd, time|
218
+ run(unescape(cmd), true, time.to_f)
219
+ end
220
+
221
+
206
222
  When /run "(.*)" without errors?$/ do |cmd|
207
223
  run(unescape(cmd), true)
208
224
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aruba-jbb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 87
4
+ hash: 85
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
9
  - 6
10
- - 8
11
- version: 0.2.6.8
10
+ - 9
11
+ version: 0.2.6.9
12
12
  platform: ruby
13
13
  authors:
14
14
  - "Aslak Helles\xC3\xB8y"
@@ -97,6 +97,7 @@ files:
97
97
  - features/flushing.feature
98
98
  - features/interactive.feature
99
99
  - features/output.feature
100
+ - features/process_timeout.feature
100
101
  - features/step_definitions/aruba_dev_steps.rb
101
102
  - features/support/env.rb
102
103
  - lib/aruba.rb
@@ -145,5 +146,6 @@ test_files:
145
146
  - features/flushing.feature
146
147
  - features/interactive.feature
147
148
  - features/output.feature
149
+ - features/process_timeout.feature
148
150
  - features/step_definitions/aruba_dev_steps.rb
149
151
  - features/support/env.rb