aws-flow 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/aws-flow.gemspec +4 -2
  2. data/lib/aws-flow.rb +1 -0
  3. data/lib/aws/decider/decider.rb +2 -2
  4. data/lib/aws/decider/workflow_client.rb +1 -0
  5. data/lib/aws/decider/workflow_clock.rb +3 -3
  6. metadata +3 -29
  7. data/aws-flow-core/Gemfile +0 -9
  8. data/aws-flow-core/LICENSE.TXT +0 -15
  9. data/aws-flow-core/NOTICE.TXT +0 -14
  10. data/aws-flow-core/Rakefile +0 -27
  11. data/aws-flow-core/aws-flow-core.gemspec +0 -12
  12. data/aws-flow-core/lib/aws/flow.rb +0 -26
  13. data/aws-flow-core/lib/aws/flow/async_backtrace.rb +0 -134
  14. data/aws-flow-core/lib/aws/flow/async_scope.rb +0 -195
  15. data/aws-flow-core/lib/aws/flow/begin_rescue_ensure.rb +0 -386
  16. data/aws-flow-core/lib/aws/flow/fiber.rb +0 -77
  17. data/aws-flow-core/lib/aws/flow/flow_utils.rb +0 -50
  18. data/aws-flow-core/lib/aws/flow/future.rb +0 -109
  19. data/aws-flow-core/lib/aws/flow/implementation.rb +0 -151
  20. data/aws-flow-core/lib/aws/flow/simple_dfa.rb +0 -85
  21. data/aws-flow-core/lib/aws/flow/tasks.rb +0 -405
  22. data/aws-flow-core/test/aws/async_backtrace_spec.rb +0 -41
  23. data/aws-flow-core/test/aws/async_scope_spec.rb +0 -118
  24. data/aws-flow-core/test/aws/begin_rescue_ensure_spec.rb +0 -665
  25. data/aws-flow-core/test/aws/external_task_spec.rb +0 -197
  26. data/aws-flow-core/test/aws/factories.rb +0 -52
  27. data/aws-flow-core/test/aws/fiber_condition_variable_spec.rb +0 -163
  28. data/aws-flow-core/test/aws/fiber_spec.rb +0 -78
  29. data/aws-flow-core/test/aws/flow_spec.rb +0 -255
  30. data/aws-flow-core/test/aws/future_spec.rb +0 -210
  31. data/aws-flow-core/test/aws/rubyflow.rb +0 -22
  32. data/aws-flow-core/test/aws/simple_dfa_spec.rb +0 -63
  33. data/aws-flow-core/test/aws/spec_helper.rb +0 -36
@@ -1,41 +0,0 @@
1
- ##
2
- # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License").
5
- # You may not use this file except in compliance with the License.
6
- # A copy of the License is located at
7
- #
8
- # http://aws.amazon.com/apache2.0
9
- #
10
- # or in the "license" file accompanying this file. This file is distributed
11
- # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12
- # express or implied. See the License for the specific language governing
13
- # permissions and limitations under the License.
14
- ##
15
-
16
- def validate_stacktrace_content(method_to_call_on_async_backtrace, thing_to_look_for, should_it_be_there)
17
- it "makes sure that any of #{thing_to_look_for.join", "} #{should_it_be_there} be printed when we call #{method_to_call_on_async_backtrace} on AsyncBacktrace" do
18
- AsyncBacktrace.enable
19
- AsyncBacktrace.send(method_to_call_on_async_backtrace)
20
- scope = AsyncScope.new do
21
- error_handler do |t|
22
- t.begin { raise StandardError.new }
23
- t.rescue(IOError) {}
24
- end
25
- end
26
- begin
27
- scope.eventLoop
28
- rescue Exception => e
29
- matching_lines = thing_to_look_for.select { |part| e.backtrace.to_s.include? part.to_s }
30
-
31
- matching_lines.send(should_it_be_there, be_empty)
32
- end
33
- end
34
- end
35
-
36
- describe AsyncBacktrace do
37
- validate_stacktrace_content(:enable, [:continuation], :should_not)
38
- validate_stacktrace_content(:disable, [:continuation], :should)
39
- validate_stacktrace_content(:enable_filtering, $RUBY_FLOW_FILES, :should)
40
- validate_stacktrace_content(:disable_filtering, $RUBY_FLOW_FILES, :should_not)
41
- end
@@ -1,118 +0,0 @@
1
- ##
2
- # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License").
5
- # You may not use this file except in compliance with the License.
6
- # A copy of the License is located at
7
- #
8
- # http://aws.amazon.com/apache2.0
9
- #
10
- # or in the "license" file accompanying this file. This file is distributed
11
- # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12
- # express or implied. See the License for the specific language governing
13
- # permissions and limitations under the License.
14
- ##
15
-
16
- describe AsyncScope do
17
-
18
- it "makes sure that basic AsyncScoping works" do
19
- trace = []
20
- this_scope = AsyncScope.new() do
21
- task { trace << :inside_task}
22
- end
23
- trace.should == []
24
- this_scope.eventLoop
25
- trace.should == [:inside_task]
26
- end
27
-
28
- context "empty AsyncScope" do
29
- let(:scope) { AsyncScope.new }
30
- let(:trace) { [] }
31
-
32
- it "adds tasks like a queue" do
33
- scope << Task.new(scope.root_context) { trace << :task }
34
- scope.eventLoop
35
- trace.should == [:task]
36
- end
37
-
38
- it "adds a task if given one on construction" do
39
- scope = AsyncScope.new { trace << :task }
40
- scope.eventLoop
41
- trace.should == [:task]
42
- end
43
-
44
-
45
- it "runs a task asynchronously" do
46
- scope << Task.new(scope.root_context) { trace << :inner }
47
- trace << :outer
48
- scope.eventLoop
49
- trace.should == [:outer, :inner]
50
- end
51
-
52
- it "runs multiple tasks in order" do
53
- scope << Task.new(scope.root_context) { trace << :first_task }
54
- scope << Task.new(scope.root_context) { trace << :second_task }
55
- scope.eventLoop
56
- trace.should == [:first_task, :second_task]
57
- end
58
-
59
- it "resumes tasks after a Future is ready" do
60
- f = Future.new
61
- scope = AsyncScope.new do
62
- task do
63
- trace << :first
64
- f.get
65
- trace << :fourth
66
- end
67
-
68
- task do
69
- trace << :second
70
- f.set(:foo)
71
- trace << :third
72
- end
73
- end
74
- scope.eventLoop
75
- trace.should == [:first, :second, :third, :fourth]
76
- end
77
-
78
- it "tests to make sure that scopes complete after an event loop" do
79
- scope = AsyncScope.new do
80
- error_handler do |t|
81
- t.begin do
82
- x = Future.new
83
- y = Future.new
84
- error_handler do |t|
85
- t.begin {}
86
- t.ensure { x.set }
87
- end
88
- x.get
89
- error_handler do |t|
90
- t.begin {}
91
- t.ensure { y.set }
92
- end
93
- y.get
94
- error_handler do |t|
95
- t.begin {}
96
- t.ensure {}
97
- end
98
- end
99
- end
100
- end
101
-
102
- completed = scope.eventLoop
103
- completed.should == true
104
- end
105
- it "ensures you can cancel an async scope " do
106
- condition = FiberConditionVariable.new
107
- @task = nil
108
- scope = AsyncScope.new do
109
- task do
110
- condition.wait
111
- end
112
- end
113
- scope.eventLoop
114
- scope.cancel(CancellationException.new)
115
- expect { scope.eventLoop }.to raise_error CancellationException
116
- end
117
- end
118
- end
@@ -1,665 +0,0 @@
1
- ##
2
- # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License").
5
- # You may not use this file except in compliance with the License.
6
- # A copy of the License is located at
7
- #
8
- # http://aws.amazon.com/apache2.0
9
- #
10
- # or in the "license" file accompanying this file. This file is distributed
11
- # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12
- # express or implied. See the License for the specific language governing
13
- # permissions and limitations under the License.
14
- ##
15
-
16
-
17
- def change_test(options = {})
18
- subject { this_bre }
19
- its(:heirs) { options[:heirs] ? (should_not be_empty) : (should be_empty) }
20
- its(:nonDaemonHeirsCount) { should == options[:nonDaemonHeirsCount] }
21
- end
22
-
23
- describe BeginRescueEnsure do
24
- let(:condition) { FiberConditionVariable.new }
25
- let(:flowfactory) { FlowFactory.new }
26
-
27
- def make_trying_BRE(begin_tasks = [])
28
- scope = AsyncScope.new do
29
- @error_handler = error_handler do |t|
30
- t.begin do
31
- begin_tasks.each { |task| task.call}
32
- condition.wait
33
- end
34
- t.rescue(IOError) {|x| condition.wait }
35
- t.rescue(CancellationException) { |x| x }
36
- end
37
- end
38
- scope.eventLoop
39
- @error_handler
40
- end
41
-
42
- def make_catching_BRE(begin_tasks = [])
43
- scope = AsyncScope.new do
44
- @error_handler = error_handler do |t|
45
- t.begin do
46
- raise IOError
47
- end
48
- t.rescue(IOError) do |x|
49
- begin_tasks.each { |task| task.call }
50
- condition.wait
51
- end
52
- end
53
- end
54
- scope.eventLoop
55
- @error_handler
56
- end
57
-
58
- let(:trying_BRE) do
59
- make_trying_BRE
60
- end
61
-
62
- let(:catching_BRE) do
63
- make_catching_BRE
64
- end
65
- context "BeginRescueEnsure in the :trying state" do
66
- subject { trying_BRE }
67
- its(:heirs) { should_not be_empty }
68
- its(:nonDaemonHeirsCount) { should == 1 }
69
-
70
- context "which adds a task," do
71
- let(:trying_BRE_with_one_task) do
72
- make_trying_BRE([lambda { task { condition.wait } }])
73
- end
74
- let(:first_task) { trying_BRE_with_one_task.heirs.first }
75
- subject { trying_BRE_with_one_task }
76
- its(:heirs) { should_not be_empty }
77
- its(:nonDaemonHeirsCount) { should == 2 }
78
-
79
- context "and then has the task status changed," do
80
- context "and cancel the BRE" do
81
- let(:this_bre) { trying_BRE_with_one_task.cancel(StandardError.new); trying_BRE_with_one_task }
82
- # As a note: we trigger the rescue task, so we have a task in the heirs
83
- change_test :heirs => true, :nonDaemonHeirsCount => 1
84
- end
85
-
86
- context "and fail the the task" do
87
- let(:this_bre) { expect { trying_BRE_with_one_task.fail(first_task, StandardError.new) }.to raise_error StandardError; trying_BRE_with_one_task }
88
- change_test :heirs => false, :nonDaemonHeirsCount => 0
89
- end
90
-
91
- context "and remove the task " do
92
- let(:this_bre) { trying_BRE_with_one_task.remove(first_task); trying_BRE_with_one_task }
93
- change_test :heirs => true, :nonDaemonHeirsCount => 1
94
- end
95
- end
96
- end
97
-
98
- context "which adds two tasks" do
99
- let(:trying_BRE_with_two_tasks) do
100
- make_trying_BRE([lambda { task { condition.wait }}, lambda { task { condition.wait }}])
101
- end
102
- let(:first_task) { trying_BRE_with_two_tasks.heirs.first }
103
- subject { trying_BRE_with_two_tasks }
104
- its(:heirs) { should_not be_empty }
105
- its(:nonDaemonHeirsCount) { should == 3 }
106
-
107
- context "And then we change the task status" do
108
- context "and cancel the BRE" do
109
- let(:this_bre) { trying_BRE_with_two_tasks.cancel(StandardError.new); trying_BRE_with_two_tasks }
110
- change_test :heirs => true, :nonDaemonHeirsCount => 1
111
- end
112
-
113
- context "and fail the the task" do
114
- let(:this_bre) { expect { trying_BRE_with_two_tasks.fail(first_task, StandardError.new) }.to raise_error StandardError; trying_BRE_with_two_tasks }
115
- change_test :heirs => false, :nonDaemonHeirsCount => 0
116
- end
117
-
118
- context "and remove the task " do
119
- let(:this_bre) { trying_BRE_with_two_tasks.remove(first_task); trying_BRE_with_two_tasks }
120
- change_test :heirs => true, :nonDaemonHeirsCount => 2
121
- end
122
- end
123
- end
124
- end
125
-
126
- context "BeginRescueEnsure in the :catching state" do
127
- subject { catching_BRE}
128
- its(:heirs) { should_not be_empty }
129
- its(:nonDaemonHeirsCount) { should == 1 }
130
-
131
- context "which adds a task," do
132
- let(:catching_BRE_with_one_task) do
133
- make_catching_BRE([lambda { task { condition.wait } }])
134
- end
135
- let(:first_task) { catching_BRE_with_one_task.heirs.first }
136
- subject { catching_BRE_with_one_task }
137
- its(:heirs) { should_not be_empty }
138
- its(:nonDaemonHeirsCount) { should == 2 }
139
-
140
- context "and then has the task status changed," do
141
- context "and cancel the BRE" do
142
- let(:this_bre) { catching_BRE_with_one_task.cancel(StandardError.new); catching_BRE_with_one_task }
143
- change_test :heirs => true, :nonDaemonHeirsCount => 2
144
- end
145
-
146
- context "and fail the the task" do
147
- let(:this_bre) { expect { catching_BRE_with_one_task.fail(first_task, StandardError.new) }.to raise_error StandardError; catching_BRE_with_one_task }
148
- change_test :heirs => false, :nonDaemonHeirsCount => 0
149
- end
150
-
151
- context "and remove the task " do
152
- let(:this_bre) { catching_BRE_with_one_task.remove(first_task); catching_BRE_with_one_task }
153
- change_test :heirs => true, :nonDaemonHeirsCount => 1
154
- end
155
- end
156
- end
157
-
158
- context "which adds two tasks" do
159
- let(:catching_BRE_with_two_tasks) do
160
- make_catching_BRE([lambda { task { condition.wait } },lambda { task { condition.wait } } ])
161
- end
162
- let(:first_task) { catching_BRE_with_two_tasks.heirs.first }
163
- subject { catching_BRE_with_two_tasks }
164
- its(:heirs) { should_not be_empty }
165
- its(:nonDaemonHeirsCount) { should == 3 }
166
-
167
- context "And then we change the task status" do
168
- context "and cancel the BRE" do
169
- let(:this_bre) { catching_BRE_with_two_tasks.cancel(StandardError.new); catching_BRE_with_two_tasks }
170
- change_test :heirs => true, :nonDaemonHeirsCount => 3
171
- end
172
-
173
- context "and fail the the task" do
174
- let(:this_bre) { expect { catching_BRE_with_two_tasks.fail(first_task, StandardError.new) }.to raise_error StandardError; catching_BRE_with_two_tasks }
175
- change_test :heirs => false, :nonDaemonHeirsCount => 0
176
- end
177
-
178
- context "and remove the task " do
179
- let(:this_bre) { catching_BRE_with_two_tasks.remove(first_task); catching_BRE_with_two_tasks }
180
- change_test :heirs => true, :nonDaemonHeirsCount => 2
181
- end
182
- end
183
-
184
- end
185
- end
186
-
187
- before(:each) { class RescueTestingError < StandardError; end }
188
- let(:trace) { [] }
189
- let(:flowfactory) { FlowFactory.new }
190
- let(:scope) { flowfactory.generate_scope }
191
-
192
- it "makes sure that error handling without resuming does nothing" do
193
-
194
- scope = AsyncScope.new do
195
- _error_handler do |t|
196
- t.begin { trace << :in_the_begin }
197
- end
198
- end
199
- trace.should == []
200
- end
201
-
202
- {:Task => lambda { |&x| task(&x) }, :DaemonTask => lambda { |&x| daemon_task(&x) }}.each_pair do |name, task_creation|
203
-
204
- # TODO: Reinstate this test, if it is easy enough
205
- #
206
- # it "makes sure that error handling with a #{name} free floating raises" do
207
- # scope = AsyncScope.new do
208
- # error_handler do |t|
209
- # t.begin { trace << :in_the_begin }
210
- # t.rescue(RescueTestingError) {}
211
- # task_creation.call { trace << :in_the_daemon }
212
- # end
213
- # end
214
- # expect { scope.eventLoop }.to raise_error NoContextException, /You have not scoped this task correctly!/
215
- # end
216
-
217
- it "make sure that #{name} in a BRE runs correctly, and that the BRE supports signal " do
218
- condition = FiberConditionVariable.new
219
- scope = AsyncScope.new do
220
- error_handler do |t|
221
- t.begin do
222
- trace << :in_the_begin
223
- task_creation.call { trace << :in_the_daemon; condition.signal }
224
- condition.wait
225
- end
226
- t.rescue(RescueTestingError) {}
227
- end
228
- end
229
- scope.eventLoop
230
- trace.should == [:in_the_begin, :in_the_daemon]
231
- end
232
- end
233
-
234
- it "makes sure that a BRE can finish with a daemon task still alive" do
235
- condition = FiberConditionVariable.new
236
- scope = AsyncScope.new do
237
- error_handler do |t|
238
- t.begin do
239
- trace << :in_the_begin
240
- @daemon_task = daemon_task { condition.wait; :should_never_be_hit }
241
- end
242
- t.rescue(RescueTestingError) {}
243
- end
244
- end
245
- scope.eventLoop
246
- trace.should == [:in_the_begin]
247
- end
248
-
249
- # TODO Reinstate this test, after fixing it so it doesn't add to BRE directly
250
- # it "makes sure that a daemon task can cancel a BRE" do
251
- # flowfactory = FlowFactory.new
252
- # condition = FiberConditionVariable.new
253
- # scope = flowfactory.generate_scope
254
- # bre = flowfactory.generate_BRE(:begin => lambda { condition.wait })
255
- # daemon_task = DaemonTask.new(bre) { condition.wait }
256
- # task = Task.new(bre) { condition.wait }
257
- # bre << task
258
- # bre << daemon_task
259
- # scope.eventLoop
260
- # bre.remove(task)
261
- # scope.eventLoop
262
- # trace.should == []
263
- # end
264
-
265
-
266
- # TODO Reinstate this test, after fixing it so it doesn't add to BRE directly
267
- # it "makes sure that a daemon task cancelling does not override other fails" do
268
- # flowfactory = FlowFactory.new
269
- # condition = FiberConditionVariable.new
270
- # scope = flowfactory.generate_scope
271
- # bre = flowfactory.generate_BRE(:begin => lambda { condition.wait })
272
- # daemon_task = DaemonTask.new(bre) { condition.wait }
273
- # task = Task.new(bre) { condition.wait }
274
- # bre << daemon_task
275
- # bre << task
276
- # scope.eventLoop
277
- # daemon_task.cancel(StandardError)
278
- # bre.fail(task, RescueTestingError)
279
- # expect { debugger; scope.eventLoop }.to raise_error RescueTestingError
280
- # trace.should == []
281
- # end
282
-
283
- # TODO Fix these up with the FlowFactory
284
- it "makes sure that creating a task in the rescue block will run it" do
285
- scope = AsyncScope.new do
286
- error_handler do |t|
287
- t.begin { raise RescueTestingError}
288
-
289
- t.rescue(RescueTestingError) do
290
- trace << :in_the_rescue
291
- task { trace << :in_the_task }
292
- end
293
- end
294
- scope.eventLoop
295
- trace.should == [:in_the_beginning, :in_the_task]
296
- end
297
- end
298
-
299
- it "makes sure that creating a task inside a BRE block will run it" do
300
- scope = AsyncScope.new do
301
- error_handler do |t|
302
- t.begin do
303
- trace << :in_the_beginning
304
- task { trace << :in_the_task }
305
- end
306
- t.rescue(StandardError) {|x| }
307
- end
308
- end
309
- scope.eventLoop
310
- trace.should == [:in_the_beginning, :in_the_task]
311
- end
312
-
313
- it "ensures you can have error handling without ensure" do
314
- scope = AsyncScope.new do
315
- error_handler do |t|
316
- t.begin { trace << :in_the_begin }
317
- t.rescue(StandardError) { trace << :in_the_rescue }
318
- end
319
- end
320
- scope.eventLoop
321
- trace.should == [:in_the_begin]
322
- end
323
-
324
- it "ensures that rescue picks the first matching rescue block" do
325
- scope = AsyncScope.new do
326
- @error_handler = _error_handler do |t|
327
- t.begin do
328
- trace << :in_the_begin
329
- raise RescueTestingError
330
- end
331
- t.rescue(RescueTestingError) { trace << :in_the_rescue }
332
- t.rescue(StandardError) { trace << :in_the_bad_rescue }
333
- end
334
- end
335
- scope.eventLoop
336
- trace.should == [:in_the_begin, :in_the_rescue]
337
- end
338
-
339
- it "ensures that rescue blocks trickle to the first applicable block" do
340
- scope = AsyncScope.new do
341
- error_handler do |t|
342
- t.begin do
343
- trace << :in_the_begin
344
- raise RescueTestingError
345
- end
346
- t.rescue(IOError) { trace << :bad_rescue }
347
- t.rescue(RescueTestingError) { trace << :in_the_rescue }
348
- end
349
- end
350
- scope.eventLoop
351
- trace.should == [:in_the_begin, :in_the_rescue]
352
- end
353
-
354
- it "ensures that the same rescue exception twice causes an exception" do
355
- scope = AsyncScope.new do
356
- error_handler do |t|
357
- t.begin {}
358
- t.rescue(RescueTestingError) {}
359
- t.rescue(RescueTestingError) {}
360
- end
361
- end
362
- # TODO Make rescue give a specific error in this case
363
-
364
- expect { scope.eventLoop }.to raise_error /You have already registered RescueTestingError/
365
- end
366
-
367
- it "ensures that stack traces work properly" do
368
- scope = AsyncScope.new do
369
- error_handler do |t|
370
- t.begin { raise "simulated" }
371
- t.rescue(Exception) do |e|
372
- e.backtrace.should include "------ continuation ------"
373
- e.message.should == "simulated"
374
- end
375
- end
376
- end
377
- scope.eventLoop
378
- end
379
-
380
- it "makes sure an error is raised if none of the rescue blocks apply to it" do
381
- scope = AsyncScope.new do
382
- error_handler do |t|
383
- t.begin { raise RescueTestingError }
384
- t.rescue(IOError) { p "nothing doing here" }
385
- end
386
- end
387
- expect { scope.eventLoop }.to raise_error RescueTestingError
388
- end
389
-
390
- it "ensures that the ensure block is called with a rescue path" do
391
- scope = AsyncScope.new do
392
- error_handler do |t|
393
- t.begin do
394
- trace << :in_the_begin
395
- raise RescueTestingError
396
- end
397
- t.rescue(RescueTestingError) { trace << :in_the_rescue }
398
- t.ensure { trace << :in_the_ensure }
399
- end
400
- end
401
- scope.eventLoop
402
- trace.should == [:in_the_begin, :in_the_rescue, :in_the_ensure]
403
- end
404
-
405
- it "calls ensure after subtask ensure" do
406
- scope = AsyncScope.new do
407
- error_handler do |t|
408
- t.begin do
409
- trace << :in_the_top_begin
410
- error_handler do |h|
411
- h.begin { trace << :in_the_inner_begin }
412
- h.rescue(StandardError) { }
413
- h.ensure { trace << :in_the_inner_ensure }
414
- end
415
- t.rescue(StandardError) { }
416
- t.ensure { trace << :in_the_outer_ensure}
417
- end
418
- end
419
- scope.eventLoop
420
- trace.should == [:in_the_top_begin, :in_the_inner_begin, :in_the_inner_ensure, :in_the_outer_ensure]
421
- end
422
- end
423
-
424
- it "ensures that an ensure block will be called when an exception is raised" do
425
- scope = AsyncScope.new do
426
- error_handler do |t|
427
- t.begin do
428
- trace << :in_the_begin
429
- raise StandardError
430
- end
431
- t.rescue(RescueTestingError) { trace << :this_is_not_okay }
432
- t.ensure { trace << :in_the_ensure }
433
- end
434
- end
435
- expect { scope.eventLoop }.to raise_error StandardError
436
- trace.should == [:in_the_begin, :in_the_ensure]
437
- end
438
-
439
- it "ensures that the ensure block is called without an applicable rescue case
440
- passes the error up" do
441
- scope = AsyncScope.new do
442
- error_handler do |t|
443
- t.begin do
444
- trace << :in_the_begin
445
- raise RescueTestingError
446
- end
447
- t.rescue(IOError) { trace << :in_the_rescue }
448
- t.ensure { trace << :in_the_ensure }
449
- expect { scope.eventLoop }.to raise_error RescueTestingError
450
- trace.should == [:in_the_begin, :in_the_ensure]
451
- end
452
- end
453
- end
454
-
455
- it "ensures that two begins raise an error" do
456
- scope = AsyncScope.new do
457
- error_handler do |t|
458
- t.begin { trace << :yay }
459
- t.begin { trace << :oh_no }
460
- t.rescue(StandardError) { trace << :should_never_be_hit }
461
- end
462
- end
463
- expect { scope.eventLoop }.to raise_error RuntimeError, /Duplicated begin/
464
- end
465
-
466
- it "ensures that two ensure statements raise an error" do
467
- scope = AsyncScope.new do
468
- error_handler do |t|
469
- t.begin { trace << :yay }
470
- t.rescue(StandardError) { trace << :should_never_be_hit }
471
- t.ensure { trace << :this_is_okay }
472
- t.ensure { trace << :but_this_is_not }
473
- end
474
- end
475
- expect { scope.eventLoop }.to raise_error /Duplicated ensure/
476
- end
477
- # TODO: Reinstate this test
478
- # it "ensures that you can't call resume inside the error handler" do
479
- # scope = AsyncScope.new do
480
- # error_handler do |t|
481
- # t.begin { trace << :in_the_begin }
482
- # t.rescue(StandardError) { trace << :in_the_rescue }
483
- # t.ensure { trace << :in_the_ensure }
484
- # t.resume
485
- # end
486
- # end
487
- # expect { scope.eventLoop }.to raise_error NoMethodError
488
- # end
489
-
490
- it "ensures that you can't access the private variables of a BeginRescueEnsure block" do
491
- scope = AsyncScope.new do
492
- error_handler do |t|
493
- t.begin { "This is the begin" }
494
- t.rescue(StandardError) { "This is the rescue" }
495
- t.ensure { trace << t.begin_task }
496
- end
497
- end
498
- expect { scope.eventLoop }.to raise_error
499
- trace.should == []
500
- end
501
-
502
- describe "BRE's closed behavior" do
503
- before (:each) do
504
- @scope = AsyncScope.new do
505
- @error_handler = error_handler do |t|
506
- t.begin do
507
- "this is the beginning"
508
- end
509
- t.rescue StandardError do
510
- "this is the rescue"
511
- end
512
- end
513
- end
514
- end
515
-
516
- it "ensures that BRE's end at closed" do
517
- @scope.eventLoop
518
- @error_handler.current_state.should == :closed
519
- end
520
-
521
- end
522
- context "Cancelling a BRE in the created state" do
523
- scope = AsyncScope.new
524
- condition = FiberConditionVariable.new
525
- error_handler = BeginRescueEnsure.new(:parent => scope.root_context)
526
- scope << error_handler
527
- error_handler.begin lambda { raise StandardError; condition.wait }
528
- error_handler.rescue(IOError, lambda { "this is the rescue" })
529
- error_handler.cancel(StandardError)
530
- subject { error_handler }
531
- its(:current_state) { should == :closed }
532
- end
533
-
534
- it "makes sure that get_heirs works" do
535
- flowfactory = FlowFactory.new
536
- condition = FiberConditionVariable.new
537
- scope = flowfactory.generate_scope
538
- bre = flowfactory.generate_BRE(:begin => lambda { task { condition.wait; trace << :yay} })
539
- scope.eventLoop
540
- bre.get_heirs.length.should > 1
541
- trace.should == []
542
- end
543
- #TODO this test shouldn't be needed, but it's a good comparison for flowfactory being borked
544
- it "makes sure that get_heirs works" do
545
- condition = FiberConditionVariable.new
546
- scope = AsyncScope.new do
547
- error_handler do |t|
548
- t.begin { task { condition.wait; trace << :yay }}
549
- t.rescue(StandardError) {}
550
- end
551
- end
552
- scope.eventLoop
553
- trace.should == []
554
- end
555
-
556
- it "makes sure that you can have a schedule in the middle of a BRE" do
557
- future = Future.new
558
- scope = AsyncScope.new do
559
- error_handler do |t|
560
- t.begin { task { future.get }}
561
- end
562
- end
563
- scope.eventLoop
564
- future.set(nil)
565
- completed = scope.eventLoop
566
- completed.should == true
567
- end
568
- # it "makes sure that failing a begin task will cause the other tasks to not get run" do
569
- # trace = []
570
- # scope = AsyncScope.new do
571
- # error_handler do |t|
572
- # t.begin do
573
- # condition = FiberConditionVariable.new
574
- # error_handler do |first_t|
575
- # first_t.begin do
576
- # task do
577
- # trace << "in the error"
578
- # condition.signal
579
- # raise "simulated error"
580
- # end
581
- # debugger
582
- # condition.wait
583
- # other_future = task do
584
- # trace << "This should not be"
585
- # end
586
- # end
587
- # first_t.rescue(StandardError) do |error|
588
- # raise error
589
- # end
590
- # first_t.ensure {condition.signal}
591
- # end
592
-
593
- # error_handler do |second_t|
594
- # second_t.begin do
595
- # other_future = task do
596
- # trace << "This should not be"
597
- # end
598
- # end
599
- # second_t.rescue(StandardError) do |error|
600
- # raise error
601
- # end
602
- # second_t.ensure {}
603
- # end
604
- # t.rescue(StandardError) {|error| raise error}
605
- # t.ensure {}
606
- # end
607
- # end
608
- # end
609
- # debugger
610
- # expect { scope.eventLoop }.to raise_error StandardError
611
- # trace.should == []
612
- # end
613
-
614
-
615
- end
616
-
617
- describe "BRE#alive?" do
618
- context "checking different types of BREs" do
619
- let(:flowfactory) { FlowFactory.new }
620
- let(:scope) { flowfactory.generate_scope }
621
- before(:each) do
622
- @regular_bre = flowfactory.generate_BRE
623
- @rescue_bre = flowfactory.generate_BRE(:begin => lambda { raise StandardError })
624
- end
625
- context "regular bre" do
626
- subject { @regular_bre }
627
- it { should be_alive }
628
- context "and then we run the scope" do
629
- let(:run_bre) { scope.eventLoop; @regular_bre }
630
- subject { run_bre }
631
- it { should_not be_alive }
632
- end
633
- end
634
- context "rescue bre" do
635
- subject { @rescue_bre }
636
- it { should be_alive }
637
- context "and then we run the scope" do
638
- let(:run_bre) { scope.eventLoop; @rescue_bre }
639
- subject { run_bre }
640
- it { should_not be_alive }
641
- end
642
- end
643
- end
644
- end
645
- describe "Misc" do
646
- it "makes sure that the return value of a BRE is the begin" do
647
- scope = AsyncScope.new do
648
- @x = _error_handler do |t|
649
- t.begin { 5 }
650
- end
651
- end
652
- scope.eventLoop
653
- @x.get.should == 5
654
- end
655
- it "meakes sure that if there is a failure, the result is the rescue value" do
656
- scope = AsyncScope.new do
657
- @x = _error_handler do |t|
658
- t.begin { raise StandardError }
659
- t.rescue(StandardError) { 6 }
660
- end
661
- end
662
- scope.eventLoop
663
- @x.get.should == 6
664
- end
665
- end