amqp-spec 0.0.4 → 0.1.7
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/HISTORY +32 -0
- data/README.rdoc +8 -9
- data/VERSION +1 -1
- data/lib/amqp-spec.rb +0 -3
- data/lib/amqp-spec/rspec.rb +63 -52
- data/spec/problematic_rspec_spec.rb +5 -0
- data/spec/rspec_amqp_spec.rb +43 -214
- data/spec/rspec_em_spec.rb +22 -28
- data/spec/shared_examples.rb +147 -0
- data/spec/spec_helper.rb +3 -1
- metadata +9 -5
data/HISTORY
CHANGED
@@ -17,3 +17,35 @@
|
|
17
17
|
== 0.0.4 / 2010-10-14
|
18
18
|
|
19
19
|
* Problems with default_options resolved
|
20
|
+
|
21
|
+
== 0.1.0 / 2010-10-15
|
22
|
+
|
23
|
+
* Monkeypatched start/stop_connection into AMQP
|
24
|
+
|
25
|
+
== 0.1.1 / 2010-10-15
|
26
|
+
|
27
|
+
* Cleanup in AMQP.cleanup
|
28
|
+
|
29
|
+
== 0.1.2 / 2010-10-15
|
30
|
+
|
31
|
+
* Cleanup in AMQP.cleanup
|
32
|
+
|
33
|
+
== 0.1.3 / 2010-10-15
|
34
|
+
|
35
|
+
* Make sure Thread.current[:mq] state is cleaned after each example
|
36
|
+
|
37
|
+
== 0.1.4 / 2010-10-15
|
38
|
+
|
39
|
+
* Problematic tests fixed
|
40
|
+
|
41
|
+
== 0.1.5 / 2010-10-15
|
42
|
+
|
43
|
+
* Clean up debugging output
|
44
|
+
|
45
|
+
== 0.1.6 / 2010-10-15
|
46
|
+
|
47
|
+
* README tweaked
|
48
|
+
|
49
|
+
== 0.1.7 / 2010-10-15
|
50
|
+
|
51
|
+
* em interface improved for timeout arg
|
data/README.rdoc
CHANGED
@@ -32,13 +32,19 @@ There are several ways to use amqp-spec. To use it as a helper, include AMQP::Sp
|
|
32
32
|
You then use either 'amqp' or 'em' methods to wrap your evented test code. Inside the amqp/em block, you must call
|
33
33
|
#done after your expectations. Everything works normally otherwise. You can use default_timeout and default_options
|
34
34
|
macros to avoid manually setting AMQP options in each example. However, if you DO manually set options inside
|
35
|
-
the example, they override the defaults. Only
|
36
|
-
it is
|
35
|
+
the example, they override the defaults. Only default options and default timeout are global across groups,
|
36
|
+
it is currently impossible to have separate defaults for separate groups.
|
37
37
|
|
38
38
|
require "amqp-spec/rspec"
|
39
39
|
describe AMQP do
|
40
40
|
include AMQP::SpecHelper
|
41
41
|
|
42
|
+
default_options :host => 'my.amqp.broker.org', :port => '21118'
|
43
|
+
# Can be used to set default options for all your amqp{} event loops
|
44
|
+
|
45
|
+
default_timeout 1
|
46
|
+
# Can be used to set default :spec_timeout for all your amqp-based specs
|
47
|
+
|
42
48
|
before(:each) do
|
43
49
|
puts EM.reactor_running?
|
44
50
|
end
|
@@ -71,7 +77,6 @@ it is not possible to have separate defaults for separate groups.
|
|
71
77
|
}.should raise_error SpecTimeoutExceededError
|
72
78
|
end
|
73
79
|
|
74
|
-
default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
|
75
80
|
end
|
76
81
|
|
77
82
|
Another option is to include AMQP::Spec in your describe block. This will patch Rspec so that all of your
|
@@ -91,9 +96,6 @@ inside the EM loop but before/after AMQP loop (these hooks are currently not imp
|
|
91
96
|
done
|
92
97
|
end
|
93
98
|
|
94
|
-
default_options :host => 'my.amqp.broker.org', :port => '21118'
|
95
|
-
# Can be used to set default options for all your (implied) amqp{} event loops
|
96
|
-
|
97
99
|
it "requires a call to #done in every example" do
|
98
100
|
1.should == 1
|
99
101
|
done
|
@@ -139,9 +141,6 @@ when including AMQP::Spec, and same caution about using them applies.
|
|
139
141
|
done
|
140
142
|
}
|
141
143
|
end
|
142
|
-
|
143
|
-
default_timeout 1
|
144
|
-
# Default spec timeouts can be used same as with AMQP::Spec, default_options (if defined) are not used
|
145
144
|
end
|
146
145
|
|
147
146
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.7
|
data/lib/amqp-spec.rb
CHANGED
@@ -3,9 +3,6 @@ require 'version'
|
|
3
3
|
module AMQP
|
4
4
|
module Spec
|
5
5
|
|
6
|
-
# require "bundler"
|
7
|
-
# Bundler.setup
|
8
|
-
|
9
6
|
# Requires ruby source file(s). Accepts either single filename/glob or Array of filenames/globs.
|
10
7
|
# Accepts following options:
|
11
8
|
# :*file*:: Lib(s) required relative to this file - defaults to __FILE__
|
data/lib/amqp-spec/rspec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'mq'
|
2
1
|
require 'fiber' unless Fiber.respond_to?(:current)
|
2
|
+
require 'mq'
|
3
3
|
|
4
4
|
# You can include one of the following modules into your example groups:
|
5
5
|
# AMQP::SpecHelper
|
@@ -19,9 +19,37 @@ require 'fiber' unless Fiber.respond_to?(:current)
|
|
19
19
|
# For example, if you are using subscribe block that tests expectations on messages, 'done' should be
|
20
20
|
# probably called at the end of this block.
|
21
21
|
#
|
22
|
-
# TODO: Define 'async' method wrapping async requests and returning results... 'async_loop' too for subscribe?
|
22
|
+
# TODO: Define 'async' method wrapping async requests and returning results... 'async_loop' too for subscribe block?
|
23
23
|
# TODO: 'evented_before', 'evented_after' that will be run inside EM before the example
|
24
24
|
module AMQP
|
25
|
+
|
26
|
+
# Initializes new AMQP client/connection without starting another EM loop
|
27
|
+
def self.start_connection opts={}, &block
|
28
|
+
# puts "!!!!!!!!! Existing connection: #{@conn}" if @conn
|
29
|
+
@conn = connect opts
|
30
|
+
@conn.callback(&block) if block
|
31
|
+
end
|
32
|
+
|
33
|
+
# Closes AMQP connection and raises optional exception AFTER the AMQP connection is 100% closed
|
34
|
+
def self.stop_connection
|
35
|
+
if AMQP.conn and not AMQP.closing
|
36
|
+
# MQ.reset ?
|
37
|
+
@closing = true
|
38
|
+
@conn.close {
|
39
|
+
yield if block_given?
|
40
|
+
cleanup_state
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.cleanup_state
|
46
|
+
# MQ.reset ?
|
47
|
+
Thread.current[:mq] = nil
|
48
|
+
Thread.current[:mq_id] = nil
|
49
|
+
@conn = nil
|
50
|
+
@closing = false
|
51
|
+
end
|
52
|
+
|
25
53
|
module SpecHelper
|
26
54
|
|
27
55
|
SpecTimeoutExceededError = Class.new(RuntimeError)
|
@@ -40,6 +68,7 @@ module AMQP
|
|
40
68
|
@@_em_default_timeout
|
41
69
|
end
|
42
70
|
end
|
71
|
+
|
43
72
|
alias default_timeout default_spec_timeout
|
44
73
|
|
45
74
|
def self.default_options(opts=nil)
|
@@ -66,31 +95,37 @@ module AMQP
|
|
66
95
|
|
67
96
|
def amqp opts={}, &block
|
68
97
|
opts = @@_em_default_options.merge opts
|
69
|
-
|
98
|
+
begin
|
99
|
+
EM.run do
|
70
100
|
# begin ?
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
101
|
+
@_em_spec_with_amqp = true
|
102
|
+
@_em_spec_exception = nil
|
103
|
+
spec_timeout = opts.delete(:spec_timeout) || @@_em_default_timeout
|
104
|
+
timeout(spec_timeout) if spec_timeout
|
105
|
+
@_em_spec_fiber = Fiber.new do
|
106
|
+
begin
|
107
|
+
AMQP.start_connection opts, &block
|
108
|
+
rescue Exception => @_em_spec_exception
|
109
|
+
# p "inner", @_em_spec_exception
|
110
|
+
done
|
111
|
+
end
|
112
|
+
Fiber.yield
|
81
113
|
end
|
82
|
-
Fiber.yield
|
83
|
-
end
|
84
114
|
|
85
|
-
|
86
|
-
|
115
|
+
@_em_spec_fiber.resume
|
116
|
+
end
|
117
|
+
rescue Exception => outer_spec_exception
|
118
|
+
# p "outer", outer_spec_exception unless outer_spec_exception.is_a? SpecTimeoutExceededError
|
119
|
+
# Makes sure AMQP state is cleaned even after Rspec failures
|
120
|
+
AMQP.cleanup_state
|
121
|
+
raise outer_spec_exception
|
87
122
|
end
|
88
123
|
end
|
89
124
|
|
90
125
|
# Yields to block inside EM loop, :spec_timeout option (in seconds) is used to force spec to timeout
|
91
126
|
# if something goes wrong and EM/AMQP loop hangs for some reason. SpecTimeoutExceededError is raised.
|
92
|
-
# TODO: accept :spec_timeout =>1 as a Hash for compatibility with amqp interface
|
93
127
|
def em(spec_timeout = @@_em_default_timeout, &block)
|
128
|
+
spec_timeout = spec_timeout[:spec_timeout] || @@_em_default_timeout if spec_timeout.is_a?(Hash)
|
94
129
|
EM.run do
|
95
130
|
@_em_spec_with_amqp = false
|
96
131
|
@_em_spec_exception = nil
|
@@ -117,53 +152,31 @@ module AMQP
|
|
117
152
|
end
|
118
153
|
end
|
119
154
|
|
120
|
-
# Stops AMQP and
|
155
|
+
# Stops EM event loop, for amqp specs stops AMQP and cleans up its state
|
121
156
|
def done
|
122
157
|
EM.next_tick do
|
123
158
|
if @_em_spec_with_amqp
|
124
|
-
|
125
|
-
|
159
|
+
if AMQP.conn and not AMQP.closing
|
160
|
+
AMQP.stop_connection do
|
161
|
+
finish_em_spec_fiber { AMQP.cleanup_state }
|
162
|
+
end
|
163
|
+
else
|
164
|
+
finish_em_spec_fiber { AMQP.cleanup_state }
|
126
165
|
end
|
127
166
|
else
|
128
167
|
finish_em_spec_fiber
|
129
|
-
raise @_em_spec_exception if @_em_spec_exception
|
130
168
|
end
|
131
169
|
end
|
132
170
|
end
|
133
171
|
|
134
172
|
private
|
135
173
|
|
174
|
+
# Stops EM loop, executes optional block, finishes off fiber and raises exception if any
|
136
175
|
def finish_em_spec_fiber
|
137
176
|
EM.stop_event_loop if EM.reactor_running?
|
138
|
-
|
177
|
+
yield if block_given?
|
139
178
|
@_em_spec_fiber.resume if @_em_spec_fiber.alive?
|
140
|
-
|
141
|
-
|
142
|
-
# Private method that initializes AMQP client/connection without starting another EM loop
|
143
|
-
def amqp_start opts={}, &block
|
144
|
-
AMQP.instance_exec do
|
145
|
-
# p Thread.current, Thread.current[:mq]
|
146
|
-
puts "!!!!!!!!! Existing connection: #{@conn}" if @conn
|
147
|
-
@conn = connect opts
|
148
|
-
# @conn ||= connect opts
|
149
|
-
@conn.callback(&block) if block
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# Private method that closes AMQP connection and raises optional
|
154
|
-
# exception AFTER the AMQP connection is 100% closed
|
155
|
-
def amqp_stop exception
|
156
|
-
if AMQP.conn and not AMQP.closing
|
157
|
-
AMQP.instance_exec do #(@_em_spec_exception) do |exception|
|
158
|
-
@closing = true
|
159
|
-
@conn.close {
|
160
|
-
yield if block_given?
|
161
|
-
@conn = nil
|
162
|
-
@closing = false
|
163
|
-
raise exception if exception
|
164
|
-
}
|
165
|
-
end
|
166
|
-
end
|
179
|
+
raise @_em_spec_exception if @_em_spec_exception
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
@@ -191,5 +204,3 @@ module AMQP
|
|
191
204
|
end
|
192
205
|
end
|
193
206
|
end
|
194
|
-
|
195
|
-
|
data/spec/rspec_amqp_spec.rb
CHANGED
@@ -6,185 +6,71 @@ describe 'Rspec' do
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
def publish_and_consume_once(queue_name="test_sink", data="data")
|
10
|
+
amqp do
|
11
|
+
q = MQ.queue(queue_name)
|
12
|
+
q.subscribe do |hdr, msg|
|
13
|
+
hdr.should be_an MQ::Header
|
14
|
+
msg.should == data
|
15
|
+
EM.next_tick {
|
16
|
+
q.unsubscribe; q.delete
|
17
|
+
done
|
18
|
+
}
|
19
|
+
end
|
20
|
+
EM.add_timer(0.2) do
|
21
|
+
MQ.queue(queue_name).publish data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
9
26
|
context 'Evented AMQP specs' do
|
10
27
|
describe AMQP, " when testing with AMQP::SpecHelper" do
|
11
28
|
include AMQP::SpecHelper
|
12
|
-
after(:each) do
|
13
|
-
EM.reactor_running?.should == false
|
14
|
-
AMQP.conn.should be_nil
|
15
|
-
end
|
16
29
|
|
17
30
|
default_options AMQP_OPTS if defined? AMQP_OPTS
|
18
31
|
default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
|
19
32
|
|
20
|
-
|
21
|
-
|
22
|
-
it "should not require a call to done when #em/#amqp is not used" do
|
23
|
-
1.should == 1
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should properly work" do
|
27
|
-
amqp do
|
28
|
-
done
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should have timers" do
|
33
|
-
amqp do
|
34
|
-
start = Time.now
|
35
|
-
|
36
|
-
EM.add_timer(0.5) {
|
37
|
-
(Time.now-start).should be_close(0.5, 0.1)
|
38
|
-
done
|
39
|
-
}
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should run AMQP.start loop with options given to #amqp" do
|
44
|
-
amqp(:vhost => '/', :user => 'guest') do
|
45
|
-
AMQP.conn.should be_connected
|
46
|
-
done
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should properly close AMQP connection if block completes normally" do
|
51
|
-
amqp do
|
52
|
-
AMQP.conn.should be_connected
|
53
|
-
done
|
54
|
-
end
|
55
|
-
AMQP.conn.should be_nil
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should have deferrables' do
|
59
|
-
amqp do
|
60
|
-
defr = EM::DefaultDeferrable.new
|
61
|
-
defr.timeout(0.5)
|
62
|
-
defr.errback {
|
63
|
-
done
|
64
|
-
}
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'on exceptions/failures' do
|
69
|
-
# default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
|
33
|
+
puts "Default timeout: #{default_timeout.inspect}, Default options:"
|
34
|
+
p default_options
|
70
35
|
|
36
|
+
it_should_behave_like 'SpecHelper examples'
|
37
|
+
it_should_behave_like 'timeout examples'
|
71
38
|
|
39
|
+
context 'inside embedded context / example group' do
|
40
|
+
it_should_behave_like 'SpecHelper examples'
|
41
|
+
it_should_behave_like 'timeout examples'
|
72
42
|
end
|
73
43
|
end
|
74
44
|
|
75
45
|
describe AMQP, " when testing with AMQP::Spec" do
|
76
46
|
include AMQP::Spec
|
77
|
-
|
78
|
-
EM.reactor_running?.should == true
|
79
|
-
done
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should work' do
|
83
|
-
done
|
84
|
-
end
|
47
|
+
it_should_behave_like 'Spec examples'
|
85
48
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
EM.add_timer(0.5) {
|
90
|
-
(Time.now-start).should be_close(0.5, 0.1)
|
91
|
-
done
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'should have periodic timers' do
|
96
|
-
num = 0
|
97
|
-
start = Time.now
|
98
|
-
|
99
|
-
timer = EM.add_periodic_timer(0.25) {
|
100
|
-
if (num += 1) == 2
|
101
|
-
(Time.now-start).should be_close(0.5, 0.1)
|
102
|
-
EM.cancel_timer timer
|
103
|
-
done
|
104
|
-
end
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'should have deferrables' do
|
109
|
-
defr = EM::DefaultDeferrable.new
|
110
|
-
defr.timeout(0.5)
|
111
|
-
defr.errback {
|
112
|
-
done
|
113
|
-
}
|
49
|
+
context 'inside embedded context / example group' do
|
50
|
+
it_should_behave_like 'Spec examples'
|
114
51
|
end
|
115
52
|
end
|
116
53
|
|
117
|
-
|
54
|
+
describe AMQP, " tested with AMQP::SpecHelper when Rspec failures occur" do
|
118
55
|
include AMQP::SpecHelper
|
119
|
-
before(:each) { @start = Time.now }
|
120
56
|
|
121
|
-
it
|
57
|
+
it "bubbles failing expectations up to Rspec" do
|
122
58
|
proc {
|
123
59
|
amqp do
|
124
|
-
|
125
|
-
end
|
126
|
-
}.should raise_error SpecTimeoutExceededError
|
127
|
-
(Time.now-@start).should be_close(1.0, 0.1)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'should timeout before reaching done because of explicit in-loop timeout' do
|
131
|
-
proc {
|
132
|
-
amqp do
|
133
|
-
timeout(0.2)
|
134
|
-
EM.add_timer(0.5) { done }
|
60
|
+
:this.should == :fail
|
135
61
|
end
|
136
|
-
}.should raise_error
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
specify "spec timeout given in amqp options has higher priority than default" do
|
141
|
-
proc {
|
142
|
-
amqp(:spec_timeout => 0.2) {}
|
143
|
-
}.should raise_error SpecTimeoutExceededError
|
144
|
-
(Time.now-@start).should be_close(0.2, 0.1)
|
62
|
+
}.should raise_error Spec::Expectations::ExpectationNotMetError
|
63
|
+
AMQP.conn.should == nil
|
145
64
|
end
|
146
65
|
|
147
|
-
|
66
|
+
it "should NOT ignore failing expectations after 'done'" do
|
148
67
|
proc {
|
149
|
-
amqp(:spec_timeout => 0.5) { timeout(0.2) }
|
150
|
-
}.should raise_error SpecTimeoutExceededError
|
151
|
-
(Time.now-@start).should be_close(0.2, 0.1)
|
152
|
-
end
|
153
|
-
|
154
|
-
specify "AMQP connection should not leak between examples" do
|
155
|
-
AMQP.conn.should be_nil
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe AMQP, " when testing with AMQP::SpecHelper with spec timeouts" do
|
160
|
-
it_should_behave_like 'timeout examples'
|
161
|
-
|
162
|
-
context 'inside embedded context / example group' do
|
163
|
-
it_should_behave_like 'timeout examples'
|
164
|
-
# it "should properly timeout " do
|
165
|
-
# amqp do
|
166
|
-
# timeout(0.2)
|
167
|
-
# end
|
168
|
-
# end
|
169
|
-
# it "should properly timeout inside embedded context/describe blocks" do
|
170
|
-
# amqp do
|
171
|
-
# end
|
172
|
-
# end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# PROBLEMATIC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
177
|
-
describe AMQP, " when testing with AMQP::SpecHelper with spec timeouts" do
|
178
|
-
include AMQP::SpecHelper
|
179
|
-
|
180
|
-
it "should fail to provide context to next spec" do
|
181
|
-
begin
|
182
68
|
amqp do
|
69
|
+
done
|
183
70
|
:this.should == :fail
|
184
71
|
end
|
185
|
-
|
186
|
-
|
187
|
-
end
|
72
|
+
}.should raise_error Spec::Expectations::ExpectationNotMetError
|
73
|
+
AMQP.conn.should == nil
|
188
74
|
end
|
189
75
|
|
190
76
|
it "should properly close AMQP connection after Rspec failures" do
|
@@ -192,80 +78,23 @@ context 'Evented AMQP specs' do
|
|
192
78
|
end
|
193
79
|
end
|
194
80
|
|
195
|
-
|
196
|
-
# include AMQP::SpecHelper
|
197
|
-
#
|
198
|
-
# default_timeout 1
|
199
|
-
#
|
200
|
-
# it 'sends data to queue' do
|
201
|
-
# amqp do
|
202
|
-
# q = MQ.new.queue("test_sink")
|
203
|
-
# q.subscribe do |hdr, data|
|
204
|
-
# p hdr, data
|
205
|
-
# EM.next_tick {
|
206
|
-
# q.unsubscribe; q.delete
|
207
|
-
# AMQP.stop { EM.stop_event_loop }
|
208
|
-
# }
|
209
|
-
# end
|
210
|
-
# EM.add_timer(0.2) do
|
211
|
-
# p Thread.current, Thread.current[:mq]
|
212
|
-
# MQ.queue('test_sink').publish 'data' # MQ.new. !!!!!!!!!!!
|
213
|
-
# end
|
214
|
-
# end
|
215
|
-
# end
|
216
|
-
#
|
217
|
-
# it 'sends data to queue' do
|
218
|
-
# amqp do
|
219
|
-
# q = MQ.new.queue("test_sink")
|
220
|
-
# q.subscribe do |hdr, data|
|
221
|
-
# p hdr, data
|
222
|
-
# EM.next_tick {
|
223
|
-
# q.unsubscribe; q.delete
|
224
|
-
# AMQP.stop { EM.stop_event_loop }
|
225
|
-
# }
|
226
|
-
# end
|
227
|
-
# EM.add_timer(0.2) do
|
228
|
-
# p Thread.current, Thread.current[:mq]
|
229
|
-
# MQ.queue('test_sink').publish 'data' # MQ.new. !!!!!!!!!!!
|
230
|
-
# end
|
231
|
-
# end
|
232
|
-
# end
|
233
|
-
#
|
234
|
-
# end
|
235
|
-
end
|
236
|
-
|
237
|
-
context '!!!!!!!!!!! LEAKING !!!!!!!!!!!!!!!!!!' do
|
238
|
-
describe EventMachine, " when running failing examples" do
|
81
|
+
describe 'MQ', " when MQ.queue/fanout/topic tries to access Thread.current[:mq] across examples" do
|
239
82
|
include AMQP::SpecHelper
|
240
83
|
|
241
|
-
it
|
242
|
-
|
243
|
-
EM.add_timer(0.1) do
|
244
|
-
:should_not_bubble.should == :failures
|
245
|
-
done
|
246
|
-
end
|
247
|
-
end
|
248
|
-
AMQP.conn.should == nil
|
84
|
+
it 'sends data to queue' do
|
85
|
+
publish_and_consume_once
|
249
86
|
end
|
250
87
|
|
251
|
-
it
|
252
|
-
|
88
|
+
it 'sends data to queue, again' do
|
89
|
+
publish_and_consume_once
|
253
90
|
end
|
254
|
-
end
|
255
|
-
|
256
|
-
describe EventMachine, " when testing with AMQP::Spec with a maximum execution time per test" do
|
257
91
|
|
258
|
-
|
259
|
-
|
260
|
-
it 'should timeout before reaching done' do
|
261
|
-
EM.add_timer(2) {
|
262
|
-
done
|
263
|
-
}
|
92
|
+
it 'cleans Thread.current[:mq] after pubsub examples' do
|
93
|
+
Thread.current[:mq].should be_nil
|
264
94
|
end
|
265
95
|
end
|
266
96
|
end
|
267
97
|
|
268
|
-
|
269
98
|
describe "Rspec", " when running an example group after another group that uses AMQP-Spec " do
|
270
99
|
it "should work normally" do
|
271
100
|
:does_not_hang.should_not be_false
|
data/spec/rspec_em_spec.rb
CHANGED
@@ -18,44 +18,38 @@ context 'Plain EM, no AMQP' do
|
|
18
18
|
}
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe EventMachine, " when testing with AMQP::Spec" do
|
24
|
-
include AMQP::EMSpec
|
25
21
|
|
26
|
-
it
|
27
|
-
done
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should have timers' do
|
22
|
+
it "should be possible to set spec timeouts as a number of secounds" do
|
31
23
|
start = Time.now
|
24
|
+
proc {
|
25
|
+
em(0.5) do
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
27
|
+
EM.add_timer(1) {
|
28
|
+
done
|
29
|
+
}
|
30
|
+
end
|
31
|
+
}.should raise_error SpecTimeoutExceededError
|
32
|
+
(Time.now-start).should be_close(0.5, 0.1)
|
37
33
|
end
|
38
34
|
|
39
|
-
it
|
40
|
-
num = 0
|
35
|
+
it "should be possible to set spec timeout as an option (amqp interface compatibility)" do
|
41
36
|
start = Time.now
|
37
|
+
proc {
|
38
|
+
em(0.5) do
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
EM.__send__ :cancel_timer, timer
|
47
|
-
done
|
40
|
+
EM.add_timer(1) {
|
41
|
+
done
|
42
|
+
}
|
48
43
|
end
|
49
|
-
}
|
44
|
+
}.should raise_error SpecTimeoutExceededError
|
45
|
+
(Time.now-start).should be_close(0.5, 0.1)
|
50
46
|
end
|
47
|
+
end
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
done
|
57
|
-
}
|
58
|
-
end
|
49
|
+
describe EventMachine, " when testing with AMQP::Spec" do
|
50
|
+
include AMQP::EMSpec
|
51
|
+
|
52
|
+
it_should_behave_like 'Spec examples'
|
59
53
|
|
60
54
|
end
|
61
55
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
shared_examples_for 'SpecHelper examples' do
|
2
|
+
after(:each) do
|
3
|
+
EM.reactor_running?.should == false
|
4
|
+
AMQP.conn.should be_nil
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should not require a call to done when #em/#amqp is not used" do
|
8
|
+
1.should == 1
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should properly work" do
|
12
|
+
amqp do
|
13
|
+
done
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have timers" do
|
18
|
+
amqp do
|
19
|
+
start = Time.now
|
20
|
+
|
21
|
+
EM.add_timer(0.5) {
|
22
|
+
(Time.now-start).should be_close(0.5, 0.1)
|
23
|
+
done
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have deferrables' do
|
29
|
+
amqp do
|
30
|
+
defr = EM::DefaultDeferrable.new
|
31
|
+
defr.timeout(0.5)
|
32
|
+
defr.errback {
|
33
|
+
done
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should run AMQP.start loop with options given to #amqp" do
|
39
|
+
amqp(:vhost => '/', :user => 'guest') do
|
40
|
+
AMQP.conn.should be_connected
|
41
|
+
done
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should properly close AMQP connection if block completes normally" do
|
46
|
+
amqp do
|
47
|
+
AMQP.conn.should be_connected
|
48
|
+
done
|
49
|
+
end
|
50
|
+
AMQP.conn.should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should gracefully exit if no AMQP connection was made" do
|
54
|
+
proc {
|
55
|
+
amqp(:host => 'Impossible') do
|
56
|
+
AMQP.conn.should be_nil
|
57
|
+
done
|
58
|
+
end
|
59
|
+
}.should raise_error EventMachine::ConnectionError
|
60
|
+
AMQP.conn.should be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
shared_examples_for 'Spec examples' do
|
65
|
+
after(:each) do
|
66
|
+
EM.reactor_running?.should == true
|
67
|
+
# AMQP.conn.should be_nil # You're inside running amqp block, stupid!
|
68
|
+
done
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should work' do
|
72
|
+
done
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should have timers' do
|
76
|
+
start = Time.now
|
77
|
+
|
78
|
+
EM.add_timer(0.5) {
|
79
|
+
(Time.now-start).should be_close(0.5, 0.1)
|
80
|
+
done
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should have periodic timers' do
|
85
|
+
num = 0
|
86
|
+
start = Time.now
|
87
|
+
|
88
|
+
timer = EM.add_periodic_timer(0.25) {
|
89
|
+
if (num += 1) == 2
|
90
|
+
(Time.now-start).should be_close(0.5, 0.1)
|
91
|
+
EM.cancel_timer timer
|
92
|
+
done
|
93
|
+
end
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should have deferrables' do
|
98
|
+
defr = EM::DefaultDeferrable.new
|
99
|
+
defr.timeout(0.5)
|
100
|
+
defr.errback {
|
101
|
+
done
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
shared_examples_for 'timeout examples' do
|
107
|
+
before(:each) { @start = Time.now }
|
108
|
+
|
109
|
+
it 'should timeout before reaching done because of default spec timeout' do
|
110
|
+
proc {
|
111
|
+
amqp do
|
112
|
+
EM.add_timer(2) { done }
|
113
|
+
end
|
114
|
+
}.should raise_error SpecTimeoutExceededError
|
115
|
+
(Time.now-@start).should be_close(1.0, 0.1)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should timeout before reaching done because of explicit in-loop timeout' do
|
119
|
+
proc {
|
120
|
+
amqp do
|
121
|
+
timeout(0.2)
|
122
|
+
EM.add_timer(0.5) { done }
|
123
|
+
end
|
124
|
+
}.should raise_error SpecTimeoutExceededError
|
125
|
+
(Time.now-@start).should be_close(0.2, 0.1)
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "spec timeout given in amqp options has higher priority than default" do
|
129
|
+
proc {
|
130
|
+
amqp(:spec_timeout => 0.2) {}
|
131
|
+
}.should raise_error SpecTimeoutExceededError
|
132
|
+
(Time.now-@start).should be_close(0.2, 0.1)
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "but timeout call inside amqp loop has even higher priority" do
|
136
|
+
proc {
|
137
|
+
amqp(:spec_timeout => 0.5) { timeout(0.2) }
|
138
|
+
}.should raise_error SpecTimeoutExceededError
|
139
|
+
(Time.now-@start).should be_close(0.2, 0.1)
|
140
|
+
end
|
141
|
+
|
142
|
+
specify "AMQP connection should not leak between examples" do
|
143
|
+
AMQP.conn.should be_nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,9 @@ $LOAD_PATH << "." unless $LOAD_PATH.include? "." # moronic 1.9.2 breaks things b
|
|
5
5
|
require 'spec'
|
6
6
|
require 'yaml'
|
7
7
|
|
8
|
-
require
|
8
|
+
require 'amqp-spec/rspec'
|
9
|
+
require 'shared_examples'
|
10
|
+
#require File.join(File.dirname(__FILE__), '..', 'lib', 'amqp-spec', 'rspec.rb')
|
9
11
|
|
10
12
|
amqp_config = File.dirname(__FILE__) + '/amqp.yml'
|
11
13
|
if File.exists? amqp_config
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amqp-spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 1
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Arvicco
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-15 00:00:00 +04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,8 +50,10 @@ files:
|
|
50
50
|
- lib/version.rb
|
51
51
|
- spec/amqp.yml
|
52
52
|
- spec/failing_rspec_spec.rb
|
53
|
+
- spec/problematic_rspec_spec.rb
|
53
54
|
- spec/rspec_amqp_spec.rb
|
54
55
|
- spec/rspec_em_spec.rb
|
56
|
+
- spec/shared_examples.rb
|
55
57
|
- spec/spec.opts
|
56
58
|
- spec/spec_helper.rb
|
57
59
|
- tasks/common.rake
|
@@ -108,7 +110,9 @@ summary: Simple API for writing (asynchronous) AMQP specs
|
|
108
110
|
test_files:
|
109
111
|
- spec/amqp.yml
|
110
112
|
- spec/failing_rspec_spec.rb
|
113
|
+
- spec/problematic_rspec_spec.rb
|
111
114
|
- spec/rspec_amqp_spec.rb
|
112
115
|
- spec/rspec_em_spec.rb
|
116
|
+
- spec/shared_examples.rb
|
113
117
|
- spec/spec.opts
|
114
118
|
- spec/spec_helper.rb
|