concurrent-ruby 0.6.0.pre.2 → 0.6.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -8
  3. data/lib/concurrent.rb +2 -0
  4. data/lib/concurrent/actor/actor.rb +3 -3
  5. data/lib/concurrent/actor/postable.rb +1 -1
  6. data/lib/concurrent/actors.rb +0 -3
  7. data/lib/concurrent/actress.rb +75 -0
  8. data/lib/concurrent/actress/ad_hoc.rb +14 -0
  9. data/lib/concurrent/actress/context.rb +96 -0
  10. data/lib/concurrent/actress/core.rb +204 -0
  11. data/lib/concurrent/actress/core_delegations.rb +37 -0
  12. data/lib/concurrent/actress/doc.md +53 -0
  13. data/lib/concurrent/actress/envelope.rb +25 -0
  14. data/lib/concurrent/actress/errors.rb +14 -0
  15. data/lib/concurrent/actress/reference.rb +64 -0
  16. data/lib/concurrent/actress/type_check.rb +48 -0
  17. data/lib/concurrent/agent.rb +20 -11
  18. data/lib/concurrent/async.rb +54 -25
  19. data/lib/concurrent/atomic/atomic.rb +48 -0
  20. data/lib/concurrent/atomic/atomic_boolean.rb +13 -13
  21. data/lib/concurrent/atomic/atomic_fixnum.rb +9 -17
  22. data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +7 -4
  23. data/lib/concurrent/atomic/copy_on_write_observer_set.rb +16 -14
  24. data/lib/concurrent/atomic/event.rb +11 -16
  25. data/lib/concurrent/atomics.rb +1 -0
  26. data/lib/concurrent/channel/channel.rb +4 -2
  27. data/lib/concurrent/collection/blocking_ring_buffer.rb +1 -1
  28. data/lib/concurrent/configuration.rb +59 -47
  29. data/lib/concurrent/delay.rb +28 -12
  30. data/lib/concurrent/dereferenceable.rb +6 -6
  31. data/lib/concurrent/errors.rb +30 -0
  32. data/lib/concurrent/executor/executor.rb +11 -4
  33. data/lib/concurrent/executor/immediate_executor.rb +1 -0
  34. data/lib/concurrent/executor/java_thread_pool_executor.rb +4 -0
  35. data/lib/concurrent/executor/one_by_one.rb +24 -12
  36. data/lib/concurrent/executor/per_thread_executor.rb +1 -0
  37. data/lib/concurrent/executor/ruby_single_thread_executor.rb +2 -1
  38. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +7 -2
  39. data/lib/concurrent/executor/ruby_thread_pool_worker.rb +3 -0
  40. data/lib/concurrent/executor/timer_set.rb +1 -1
  41. data/lib/concurrent/future.rb +0 -2
  42. data/lib/concurrent/ivar.rb +31 -6
  43. data/lib/concurrent/logging.rb +17 -0
  44. data/lib/concurrent/mvar.rb +45 -0
  45. data/lib/concurrent/obligation.rb +61 -20
  46. data/lib/concurrent/observable.rb +7 -0
  47. data/lib/concurrent/promise.rb +1 -0
  48. data/lib/concurrent/runnable.rb +2 -2
  49. data/lib/concurrent/supervisor.rb +1 -2
  50. data/lib/concurrent/timer_task.rb +17 -13
  51. data/lib/concurrent/tvar.rb +113 -73
  52. data/lib/concurrent/utility/processor_count.rb +141 -116
  53. data/lib/concurrent/utility/timeout.rb +4 -5
  54. data/lib/concurrent/version.rb +1 -1
  55. data/spec/concurrent/actor/postable_shared.rb +1 -1
  56. data/spec/concurrent/actress_spec.rb +191 -0
  57. data/spec/concurrent/async_spec.rb +35 -3
  58. data/spec/concurrent/atomic/atomic_boolean_spec.rb +1 -1
  59. data/spec/concurrent/atomic/atomic_fixnum_spec.rb +1 -1
  60. data/spec/concurrent/atomic/atomic_spec.rb +133 -0
  61. data/spec/concurrent/atomic/count_down_latch_spec.rb +1 -1
  62. data/spec/concurrent/collection/priority_queue_spec.rb +1 -1
  63. data/spec/concurrent/configuration_spec.rb +5 -2
  64. data/spec/concurrent/delay_spec.rb +14 -0
  65. data/spec/concurrent/exchanger_spec.rb +4 -9
  66. data/spec/concurrent/executor/java_cached_thread_pool_spec.rb +1 -1
  67. data/spec/concurrent/executor/java_fixed_thread_pool_spec.rb +1 -1
  68. data/spec/concurrent/executor/java_single_thread_executor_spec.rb +1 -1
  69. data/spec/concurrent/executor/java_thread_pool_executor_spec.rb +1 -1
  70. data/spec/concurrent/executor/ruby_thread_pool_executor_spec.rb +4 -4
  71. data/spec/concurrent/ivar_spec.rb +2 -2
  72. data/spec/concurrent/obligation_spec.rb +113 -24
  73. data/spec/concurrent/observable_shared.rb +4 -0
  74. data/spec/concurrent/observable_spec.rb +8 -3
  75. data/spec/concurrent/runnable_spec.rb +2 -2
  76. data/spec/concurrent/scheduled_task_spec.rb +1 -0
  77. data/spec/concurrent/supervisor_spec.rb +26 -11
  78. data/spec/concurrent/timer_task_spec.rb +36 -35
  79. data/spec/concurrent/tvar_spec.rb +1 -1
  80. data/spec/concurrent/utility/timer_spec.rb +8 -8
  81. data/spec/spec_helper.rb +8 -18
  82. data/spec/support/example_group_extensions.rb +48 -0
  83. metadata +23 -16
  84. data/lib/concurrent/actor/actor_context.rb +0 -77
  85. data/lib/concurrent/actor/actor_ref.rb +0 -67
  86. data/lib/concurrent/actor/simple_actor_ref.rb +0 -94
  87. data/lib/concurrent_ruby_ext.bundle +0 -0
  88. data/spec/concurrent/actor/actor_context_spec.rb +0 -29
  89. data/spec/concurrent/actor/actor_ref_shared.rb +0 -263
  90. data/spec/concurrent/actor/simple_actor_ref_spec.rb +0 -135
  91. data/spec/support/functions.rb +0 -25
@@ -135,6 +135,7 @@ share_examples_for :observable do
135
135
  subject.add_observer(obs, observer_func)
136
136
  end
137
137
  trigger_observable(subject)
138
+ latch.wait(1)
138
139
  latch.count.should eq 0
139
140
  end
140
141
 
@@ -144,6 +145,7 @@ share_examples_for :observable do
144
145
  subject.add_observer{ latch.count_down }
145
146
  end
146
147
  trigger_observable(subject)
148
+ latch.wait(1)
147
149
  latch.count.should eq 0
148
150
  end
149
151
 
@@ -155,6 +157,7 @@ share_examples_for :observable do
155
157
  subject.delete_observer(obs)
156
158
 
157
159
  trigger_observable(subject)
160
+ latch.wait(1)
158
161
  latch.count.should eq 5
159
162
  end
160
163
 
@@ -167,6 +170,7 @@ share_examples_for :observable do
167
170
  subject.delete_observers
168
171
 
169
172
  trigger_observable(subject)
173
+ latch.wait(1)
170
174
  latch.count.should eq 5
171
175
  end
172
176
  end
@@ -23,14 +23,19 @@ module Concurrent
23
23
  end
24
24
 
25
25
  it 'uses the given observer set' do
26
- expected = CopyOnWriteObserverSet.new
26
+ expected = CopyOnWriteObserverSet.new
27
27
  subject.observers = expected
28
28
  subject.observers.should eql expected
29
29
  end
30
30
 
31
31
  it 'delegates #add_observer' do
32
- observer_set.should_receive(:add_observer).with(:observer)
33
- subject.add_observer(:observer)
32
+ observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
33
+ subject.add_observer(:observer).should eq :observer
34
+ end
35
+
36
+ it 'delegates #with_observer' do
37
+ observer_set.should_receive(:add_observer).with(:observer).and_return { |v| v }
38
+ subject.with_observer(:observer).should eq subject
34
39
  end
35
40
 
36
41
  it 'delegates #delete_observer' do
@@ -70,7 +70,7 @@ module Concurrent
70
70
  runner = Class.new { include Runnable }.new
71
71
  expect {
72
72
  runner.run
73
- }.to raise_error(Runnable::LifecycleError)
73
+ }.to raise_error(Concurrent::LifecycleError)
74
74
  end
75
75
 
76
76
  it 'returns false when the task loop raises an exception' do
@@ -150,7 +150,7 @@ module Concurrent
150
150
  @thread.join(0.1)
151
151
  expect {
152
152
  @thread = subject.run!
153
- }.to raise_exception(Concurrent::Runnable::LifecycleError)
153
+ }.to raise_exception(Concurrent::LifecycleError)
154
154
  sleep(0.1)
155
155
  end
156
156
 
@@ -7,6 +7,7 @@ require_relative 'observable_shared'
7
7
  module Concurrent
8
8
 
9
9
  describe ScheduledTask do
10
+ with_full_reset
10
11
 
11
12
  context 'behavior' do
12
13
 
@@ -23,8 +23,16 @@ module Concurrent
23
23
 
24
24
  let(:stopper_class) do
25
25
  Class.new(worker_class) {
26
- def initialize(sleep_time = 0.2) @sleep_time = sleep_time; end;
27
- def run() super(); sleep(@sleep_time); end
26
+ attr_reader :latch
27
+ def initialize(sleep_time = 0.2)
28
+ @sleep_time = sleep_time
29
+ @latch = Concurrent::CountDownLatch.new(1)
30
+ end
31
+ def run
32
+ super
33
+ sleep(@sleep_time)
34
+ @latch.count_down
35
+ end
28
36
  }
29
37
  end
30
38
 
@@ -326,13 +334,18 @@ module Concurrent
326
334
 
327
335
  context '#count' do
328
336
 
337
+ let(:stoppers){ Array.new }
338
+
329
339
  let(:busy_supervisor) do
330
340
  supervisor = Supervisor.new(monitor_interval: 60)
331
341
  3.times do
332
342
  supervisor.add_worker(sleeper_class.new)
333
- supervisor.add_worker(stopper_class.new)
334
343
  supervisor.add_worker(error_class.new)
335
344
  supervisor.add_worker(runner_class.new)
345
+
346
+ stopper = stopper_class.new
347
+ stoppers << stopper
348
+ supervisor.add_worker(stopper)
336
349
  end
337
350
  supervisor
338
351
  end
@@ -426,7 +439,8 @@ module Concurrent
426
439
  it 'returns the count of all stopped workers as #stopped' do
427
440
  busy_supervisor.count.stopped.should eq total_count
428
441
  busy_supervisor.run!
429
- sleep(0.5)
442
+ stoppers.each{|stopper| stopper.latch.wait(1) }
443
+ sleep(0.1)
430
444
 
431
445
  busy_supervisor.count.stopped.should eq stopped_count
432
446
  end
@@ -434,7 +448,8 @@ module Concurrent
434
448
  it 'returns the count of all workers terminated by exception as #abend' do
435
449
  busy_supervisor.count.abend.should eq 0
436
450
  busy_supervisor.run!
437
- sleep(0.5)
451
+ stoppers.each{|stopper| stopper.latch.wait(1) }
452
+ sleep(0.1)
438
453
 
439
454
  busy_supervisor.count.abend.should eq abend_count
440
455
  end
@@ -832,8 +847,8 @@ module Concurrent
832
847
  monitor_interval: 0.1)
833
848
  supervisor.add_worker(error_class.new)
834
849
  supervisor.should_receive(:exceeded_max_restart_frequency?).once.and_return(true)
835
- supervisor.run!
836
- sleep(0.2)
850
+ future = Concurrent::Future.execute{ supervisor.run }
851
+ future.value(1)
837
852
  supervisor.should_not be_running
838
853
  end
839
854
 
@@ -842,8 +857,8 @@ module Concurrent
842
857
  monitor_interval: 0.1)
843
858
  supervisor.add_worker(error_class.new)
844
859
  supervisor.should_receive(:exceeded_max_restart_frequency?).once.and_return(true)
845
- supervisor.run!
846
- sleep(0.2)
860
+ future = Concurrent::Future.execute{ supervisor.run }
861
+ future.value(1)
847
862
  supervisor.should_not be_running
848
863
  end
849
864
 
@@ -852,8 +867,8 @@ module Concurrent
852
867
  monitor_interval: 0.1)
853
868
  supervisor.add_worker(error_class.new)
854
869
  supervisor.should_receive(:exceeded_max_restart_frequency?).once.and_return(true)
855
- supervisor.run!
856
- sleep(0.2)
870
+ future = Concurrent::Future.execute{ supervisor.run }
871
+ future.value(1)
857
872
  supervisor.should_not be_running
858
873
  end
859
874
  end
@@ -5,6 +5,7 @@ require_relative 'observable_shared'
5
5
  module Concurrent
6
6
 
7
7
  describe TimerTask do
8
+ with_full_reset
8
9
 
9
10
  before(:each) do
10
11
  # suppress deprecation warnings.
@@ -23,13 +24,13 @@ module Concurrent
23
24
  end
24
25
 
25
26
  def dereferenceable_subject(value, opts = {})
26
- opts = opts.merge(execution_interval: 0.1, run_now: true)
27
- @subject = TimerTask.new(opts){ value }.execute.tap{ sleep(0.1) }
27
+ opts = opts.merge(execution_interval: 0.1, run_now: true)
28
+ @subject = TimerTask.new(opts) { value }.execute.tap { sleep(0.1) }
28
29
  end
29
30
 
30
31
  def dereferenceable_observable(opts = {})
31
- opts = opts.merge(execution_interval: 0.1, run_now: true)
32
- @subject = TimerTask.new(opts){ 'value' }
32
+ opts = opts.merge(execution_interval: 0.1, run_now: true)
33
+ @subject = TimerTask.new(opts) { 'value' }
33
34
  end
34
35
 
35
36
  def execute_dereferenceable(subject)
@@ -42,9 +43,9 @@ module Concurrent
42
43
 
43
44
  context :observable do
44
45
 
45
- subject{ TimerTask.new(execution_interval: 0.1){ nil } }
46
+ subject { TimerTask.new(execution_interval: 0.1) { nil } }
46
47
 
47
- after(:each){ subject.kill }
48
+ after(:each) { subject.kill }
48
49
 
49
50
  def trigger_observable(observable)
50
51
  observable.execute
@@ -66,45 +67,45 @@ module Concurrent
66
67
 
67
68
  it 'raises an exception if :execution_interval is not greater than zero' do
68
69
  lambda {
69
- Concurrent::TimerTask.new(execution_interval: 0){ nil }
70
+ Concurrent::TimerTask.new(execution_interval: 0) { nil }
70
71
  }.should raise_error(ArgumentError)
71
72
  end
72
73
 
73
74
  it 'raises an exception if :execution_interval is not an integer' do
74
75
  lambda {
75
- Concurrent::TimerTask.new(execution_interval: 'one'){ nil }
76
+ Concurrent::TimerTask.new(execution_interval: 'one') { nil }
76
77
  }.should raise_error(ArgumentError)
77
78
  end
78
79
 
79
80
  it 'raises an exception if :timeout_interval is not greater than zero' do
80
81
  lambda {
81
- Concurrent::TimerTask.new(timeout_interval: 0){ nil }
82
+ Concurrent::TimerTask.new(timeout_interval: 0) { nil }
82
83
  }.should raise_error(ArgumentError)
83
84
  end
84
85
 
85
86
  it 'raises an exception if :timeout_interval is not an integer' do
86
87
  lambda {
87
- Concurrent::TimerTask.new(timeout_interval: 'one'){ nil }
88
+ Concurrent::TimerTask.new(timeout_interval: 'one') { nil }
88
89
  }.should raise_error(ArgumentError)
89
90
  end
90
91
 
91
92
  it 'uses the default execution interval when no interval is given' do
92
- subject = TimerTask.new{ nil }
93
+ subject = TimerTask.new { nil }
93
94
  subject.execution_interval.should eq TimerTask::EXECUTION_INTERVAL
94
95
  end
95
96
 
96
97
  it 'uses the default timeout interval when no interval is given' do
97
- subject = TimerTask.new{ nil }
98
+ subject = TimerTask.new { nil }
98
99
  subject.timeout_interval.should eq TimerTask::TIMEOUT_INTERVAL
99
100
  end
100
101
 
101
102
  it 'uses the given execution interval' do
102
- subject = TimerTask.new(execution_interval: 5){ nil }
103
+ subject = TimerTask.new(execution_interval: 5) { nil }
103
104
  subject.execution_interval.should eq 5
104
105
  end
105
106
 
106
107
  it 'uses the given timeout interval' do
107
- subject = TimerTask.new(timeout_interval: 5){ nil }
108
+ subject = TimerTask.new(timeout_interval: 5) { nil }
108
109
  subject.timeout_interval.should eq 5
109
110
  end
110
111
  end
@@ -112,7 +113,7 @@ module Concurrent
112
113
  context '#kill' do
113
114
 
114
115
  it 'returns true on success' do
115
- task = TimerTask.execute(run_now: false){ nil }
116
+ task = TimerTask.execute(run_now: false) { nil }
116
117
  sleep(0.1)
117
118
  task.kill.should be_true
118
119
  end
@@ -129,7 +130,7 @@ module Concurrent
129
130
 
130
131
  specify '#execution_interval is writeable' do
131
132
 
132
- latch = CountDownLatch.new(1)
133
+ latch = CountDownLatch.new(1)
133
134
  subject = TimerTask.new(execution_interval: 1) do |task|
134
135
  task.execution_interval = 3
135
136
  latch.count_down
@@ -148,7 +149,7 @@ module Concurrent
148
149
 
149
150
  specify '#execution_interval is writeable' do
150
151
 
151
- latch = CountDownLatch.new(1)
152
+ latch = CountDownLatch.new(1)
152
153
  subject = TimerTask.new(timeout_interval: 1, execution_interval: 0.1) do |task|
153
154
  task.timeout_interval = 3
154
155
  latch.count_down
@@ -169,37 +170,37 @@ module Concurrent
169
170
  context 'execution' do
170
171
 
171
172
  it 'runs the block immediately when the :run_now option is true' do
172
- latch = CountDownLatch.new(1)
173
- subject = TimerTask.execute(execution: 500, now: true){ latch.count_down }
174
- latch.wait(0.1).should be_true
173
+ latch = CountDownLatch.new(1)
174
+ subject = TimerTask.execute(execution: 500, now: true) { latch.count_down }
175
+ latch.wait(1).should be_true
175
176
  subject.kill
176
177
  end
177
178
 
178
179
  it 'waits for :execution_interval seconds when the :run_now option is false' do
179
- latch = CountDownLatch.new(1)
180
- subject = TimerTask.execute(execution: 0.1, now: false){ latch.count_down }
180
+ latch = CountDownLatch.new(1)
181
+ subject = TimerTask.execute(execution: 0.1, now: false) { latch.count_down }
181
182
  latch.count.should eq 1
182
- latch.wait(0.2).should be_true
183
+ latch.wait(1).should be_true
183
184
  subject.kill
184
185
  end
185
186
 
186
187
  it 'waits for :execution_interval seconds when the :run_now option is not given' do
187
- latch = CountDownLatch.new(1)
188
- subject = TimerTask.execute(execution: 0.1, now: false){ latch.count_down }
188
+ latch = CountDownLatch.new(1)
189
+ subject = TimerTask.execute(execution: 0.1, now: false) { latch.count_down }
189
190
  latch.count.should eq 1
190
- latch.wait(0.2).should be_true
191
+ latch.wait(1).should be_true
191
192
  subject.kill
192
193
  end
193
194
 
194
195
  it 'passes a "self" reference to the block as the sole argument' do
195
196
  expected = nil
196
- latch = CountDownLatch.new(1)
197
- subject = TimerTask.new(execution_interval: 1, run_now: true) do |task|
197
+ latch = CountDownLatch.new(1)
198
+ subject = TimerTask.new(execution_interval: 1, run_now: true) do |task|
198
199
  expected = task
199
200
  latch.sount_down
200
201
  end
201
202
  subject.execute
202
- latch.wait(0.2)
203
+ latch.wait(1)
203
204
  expected.should eq subject
204
205
  subject.kill
205
206
  end
@@ -213,18 +214,18 @@ module Concurrent
213
214
  attr_reader :value
214
215
  attr_reader :ex
215
216
  attr_reader :latch
216
- define_method(:initialize){ @latch = CountDownLatch.new(1) }
217
+ define_method(:initialize) { @latch = CountDownLatch.new(1) }
217
218
  define_method(:update) do |time, value, ex|
218
- @time = time
219
+ @time = time
219
220
  @value = value
220
- @ex = ex
221
+ @ex = ex
221
222
  @latch.count_down
222
223
  end
223
224
  end.new
224
225
  end
225
226
 
226
227
  it 'notifies all observers on success' do
227
- subject = TimerTask.new(execution: 0.1){ 42 }
228
+ subject = TimerTask.new(execution: 0.1) { 42 }
228
229
  subject.add_observer(observer)
229
230
  subject.execute
230
231
  observer.latch.wait(1)
@@ -234,7 +235,7 @@ module Concurrent
234
235
  end
235
236
 
236
237
  it 'notifies all observers on timeout' do
237
- subject = TimerTask.new(execution: 0.1, timeout: 0.1){ sleep }
238
+ subject = TimerTask.new(execution: 0.1, timeout: 0.1) { sleep }
238
239
  subject.add_observer(observer)
239
240
  subject.execute
240
241
  observer.latch.wait(1)
@@ -244,7 +245,7 @@ module Concurrent
244
245
  end
245
246
 
246
247
  it 'notifies all observers on error' do
247
- subject = TimerTask.new(execution: 0.1){ raise ArgumentError }
248
+ subject = TimerTask.new(execution: 0.1) { raise ArgumentError }
248
249
  subject.add_observer(observer)
249
250
  subject.execute
250
251
  observer.latch.wait(1)
@@ -129,7 +129,7 @@ module Concurrent
129
129
  describe '#abort_transaction' do
130
130
 
131
131
  it 'raises an exception outside an #atomically block' do
132
- expect { Concurrent::abort_transaction }.to raise_error(Concurrent::AbortError)
132
+ expect { Concurrent::abort_transaction }.to raise_error(Concurrent::Transaction::AbortError)
133
133
  end
134
134
 
135
135
  end
@@ -17,14 +17,14 @@ module Concurrent
17
17
  end
18
18
 
19
19
  it 'executes the block after the given number of seconds' do
20
- start = Time.now
21
- expected = Concurrent::AtomicFixnum.new(0)
22
- Concurrent::timer(0.5){ expected.increment }
23
- expected.value.should eq 0
24
- sleep(0.1)
25
- expected.value.should eq 0
26
- sleep(0.8)
27
- expected.value.should eq 1
20
+ start = Time.now.to_f
21
+ latch = CountDownLatch.new(1)
22
+ Concurrent::timer(0.5){ latch.count_down }
23
+ latch.count.should eq 1
24
+ latch.wait(0.1)
25
+ latch.count.should eq 1
26
+ latch.wait(1)
27
+ latch.count.should eq 0
28
28
  end
29
29
 
30
30
  it 'suppresses exceptions thrown by the block' do
data/spec/spec_helper.rb CHANGED
@@ -2,8 +2,8 @@ require 'simplecov'
2
2
  require 'coveralls'
3
3
 
4
4
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
- SimpleCov::Formatter::HTMLFormatter,
6
- Coveralls::SimpleCov::Formatter
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
7
  ]
8
8
 
9
9
  SimpleCov.start do
@@ -17,25 +17,15 @@ end
17
17
 
18
18
  require 'concurrent'
19
19
 
20
+ logger = Logger.new($stderr)
21
+ logger.level = Logger::INFO
22
+ Concurrent.configuration.logger = lambda do |level, progname, message = nil, &block|
23
+ logger.add level, message, progname, &block
24
+ end
25
+
20
26
  # import all the support files
21
27
  Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
22
28
 
23
29
  RSpec.configure do |config|
24
30
  config.order = 'random'
25
-
26
- config.before(:suite) do
27
- end
28
-
29
- config.before(:each) do
30
- reset_gem_configuration
31
- end
32
-
33
- config.after(:each) do
34
- Thread.list.each do |thread|
35
- thread.kill unless thread == Thread.current
36
- end
37
- end
38
-
39
- config.after(:suite) do
40
- end
41
31
  end