activemessaging 0.6.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -48,18 +48,13 @@ module ActiveMessaging #:nodoc:
48
48
 
49
49
  end
50
50
 
51
- class TestMessage
52
- attr_reader :headers
53
- attr_accessor :body
51
+ class TestMessage < ActiveMessaging::BaseMessage
54
52
 
55
- def initialize(destination, headers = {}, body = "")
56
- @headers, @body = headers, body
53
+ def initialize(body="", headers={}, destination="")
54
+ super(body, nil, headers, destination)
57
55
  @headers['destination'] = destination
58
56
  end
59
-
60
- def command
61
- "MESSAGE"
62
- end
57
+
63
58
  end
64
59
 
65
60
  module TestHelper
data/poller.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # Make sure stdout and stderr write out without delay for using with daemon like scripts
3
+ STDOUT.sync = true; STDOUT.flush
4
+ STDERR.sync = true; STDERR.flush
5
+
6
+ # Load Rails
7
+ RAILS_ROOT=File.expand_path(File.join(File.dirname(__FILE__), '..','..','..'))
8
+ load File.join(RAILS_ROOT, 'config', 'environment.rb')
9
+
10
+ # Load ActiveMessaging processors
11
+ #ActiveMessaging::load_processors
12
+
13
+ # Start it up!
14
+ ActiveMessaging::start
data/test/all_tests.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+
3
+ require 'test/unit'
4
+
5
+ # tests
6
+ require 'config_test'
7
+ require 'filter_test'
8
+ require 'tracer_test'
9
+ require 'jms_test'
10
+ require 'asqs_test'
@@ -0,0 +1,4 @@
1
+ # Yaml config file for testing ActiveMessaging
2
+ test:
3
+ adapter: test
4
+ reliable: false
data/test/asqs_test.rb ADDED
@@ -0,0 +1,102 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'activemessaging/adapters/asqs'
3
+
4
+ class AsqsTest < Test::Unit::TestCase
5
+
6
+ class FakeHTTPResponse
7
+ attr_accessor :headers, :body
8
+
9
+ def to_hash
10
+ @headers
11
+ end
12
+
13
+ def kind_of? kind
14
+ true
15
+ end
16
+ end
17
+
18
+ ::ActiveMessaging::Adapters::AmazonSqs::Connection.class_eval do
19
+ attr_accessor :test_response, :test_headers
20
+
21
+ DEFAULT_RESPONSE = <<EOM
22
+ <ListQueuesResponse xmlns='http://queue.amazonaws.com/doc/2007-05-01/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:type='ListQueuesResponse'>
23
+ <Queues>
24
+ <QueueUrl>http://queue.amazonaws.com/thisisatestid1/test1</QueueUrl>
25
+ <QueueUrl>http://queue.amazonaws.com/thisisatestid12/test2</QueueUrl>
26
+ </Queues>
27
+ <ResponseStatus><StatusCode>Success</StatusCode><RequestId>cb919c0a-9bce-4afe-9b48-9bdf2412bb67</RequestId></ResponseStatus>
28
+ </ListQueuesResponse>
29
+ EOM
30
+
31
+ def http_request h, p, r
32
+ raise test_response if test_response.is_a?(Exception)
33
+
34
+ resp = FakeHTTPResponse.new
35
+ resp.body = @test_response || DEFAULT_RESPONSE
36
+ resp.headers = @test_headers || {}
37
+ return resp
38
+ end
39
+ end
40
+
41
+
42
+ def setup
43
+ @connection = ActiveMessaging::Adapters::AmazonSqs::Connection.new(:reliable=>false, :access_key_id=>'access_key_id', :secret_access_key=>'secret_access_key', :reconnectDelay=>1)
44
+ @d = "asqs"
45
+ @message = "mary had a little lamb"
46
+ end
47
+
48
+ def teardown
49
+ @connection.disconnect unless @connection.nil?
50
+ end
51
+
52
+ def test_allow_underscore_and_dash
53
+ assert_nothing_raised do
54
+ @connection.subscribe 'name-name_dash'
55
+ end
56
+ assert_raise(RuntimeError) do
57
+ @connection.subscribe '!@#$%^&'
58
+ end
59
+ end
60
+
61
+
62
+ def test_send_and_receive
63
+ @connection.subscribe @d, :visibility_timeout=>100
64
+ @connection.send @d, @message
65
+
66
+ @connection.test_headers = {:destination=>@d}
67
+ @connection.test_response = <<EOM
68
+ <ReceiveMessageResponse>
69
+ <Message>
70
+ <MessageId>11YEJMCHE2DM483NGN40|3H4AA8J7EJKM0DQZR7E1|PT6DRTB278S4MNY77NJ0</MessageId>
71
+ <ReceiptHandle>some handle value</ReceiptHandle>
72
+ <Body>#{@message}</Body>
73
+ <MD5OfBody>not really the md5</MD5OfBody>
74
+ </Message>
75
+ <ResponseStatus>
76
+ <StatusCode>Success</StatusCode>
77
+ <RequestId>b5bf2332-e983-4d3e-941a-f64c0d21f00f</RequestId>
78
+ </ResponseStatus>
79
+ </ReceiveMessageResponse>
80
+ EOM
81
+
82
+ message = @connection.receive
83
+ assert_equal @message, message.body
84
+ end
85
+
86
+ def test_receive_timeout
87
+ @connection.subscribe @d
88
+ @connection.send @d, @message
89
+
90
+ @connection.test_headers = {:destination=>@d}
91
+ @connection.test_response = TimeoutError.new('test timeout error')
92
+ @connection.reliable = true
93
+ begin
94
+ Timeout.timeout 2 do
95
+ @connection.receive
96
+ end
97
+ rescue Timeout::Error=>toe
98
+ assert_not_equal toe.message, 'test timeout error'
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TestProcessor < ActiveMessaging::Processor
4
+ end
5
+
6
+ class ConfigTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ ActiveMessaging::Gateway.define do |s|
10
+ s.destination :hello_world, '/queue/helloWorld'
11
+ end
12
+ end
13
+
14
+ def teardown
15
+ ActiveMessaging::Gateway.reset
16
+ end
17
+
18
+ def test_can_subscribe_to_named_queue
19
+ TestProcessor.subscribes_to :hello_world
20
+ sub = ActiveMessaging::Gateway.subscriptions.values.last
21
+ assert_equal :hello_world, sub.destination.name
22
+ assert_equal TestProcessor, sub.processor_class
23
+ end
24
+
25
+ def test_can_publish_to_named_queue
26
+ TestProcessor.publishes_to :hello_world
27
+ #no exception - publish just checks to see if the queue exists
28
+ end
29
+
30
+ def test_should_raise_error_if_subscribe_to_queue_that_does_not_exist
31
+ assert_raises(RuntimeError) do
32
+ TestProcessor.subscribes_to :queue_that_does_not_exist
33
+ end
34
+ end
35
+
36
+ def test_should_raise_error_if_publishes_to_queue_that_does_not_exist
37
+ assert_raises(RuntimeError) do
38
+ TestProcessor.publishes_to :queue_that_does_not_exist
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'activemessaging/filter'
3
+
4
+ module ActiveMessaging #:nodoc:
5
+ def self.reload_activemessaging
6
+ end
7
+ end
8
+
9
+ class FilterTest < Test::Unit::TestCase
10
+
11
+ class MockFilter < ActiveMessaging::Filter
12
+
13
+ @@called = {}
14
+ cattr_reader :called
15
+
16
+ attr_reader :options
17
+
18
+ def initialize(options)
19
+ @options = options
20
+ end
21
+
22
+ def process(message, details={})
23
+ @@called[options[:name]] = {:message=>message, :details=>details}
24
+ end
25
+
26
+ class << self
27
+ include Test::Unit::Assertions
28
+
29
+ def reset
30
+ @@called = {}
31
+ end
32
+
33
+ def assert_was_called(name=nil)
34
+ assert @@called.has_key?(name)
35
+ end
36
+
37
+ def assert_was_not_called(name=nil)
38
+ assert !@@called.has_key?(name)
39
+ end
40
+
41
+ def assert_routing(name, routing)
42
+ assert_equal routing, @@called[name][:details]
43
+ end
44
+ end
45
+ end
46
+
47
+ class TestProcessor < ActiveMessaging::Processor
48
+ include ActiveMessaging::MessageSender
49
+ #subscribes_to :testqueue
50
+
51
+ @@was_called = false
52
+ class<<self
53
+ include Test::Unit::Assertions
54
+
55
+ def assert_was_called
56
+ assert @@was_called
57
+ @@was_called = false
58
+ end
59
+ end
60
+
61
+ def on_message(message)
62
+ @@was_called = true
63
+ end
64
+ end
65
+
66
+ include ActiveMessaging::TestHelper
67
+
68
+ def setup
69
+ ActiveMessaging::Gateway.define do |d|
70
+ d.destination :testqueue, '/queue/test.queue'
71
+ d.filter 'filter_test/mock_filter', :direction=>:bidirectional, :name=>:bidirectional
72
+ d.filter 'filter_test/mock_filter', :direction=>:incoming, :name=>:incoming
73
+ d.filter 'filter_test/mock_filter', :direction=>:outgoing, :name=>:outgoing
74
+
75
+ d.filter 'filter_test/mock_filter', :direction=>:incoming, :name=>:exclude_only, :only=>:foo
76
+ d.filter 'filter_test/mock_filter', :direction=>:incoming, :name=>:include_only, :only=>:testqueue
77
+ d.filter 'filter_test/mock_filter', :direction=>:incoming, :name=>:exclude_except, :except=>:testqueue
78
+ d.filter 'filter_test/mock_filter', :direction=>:incoming, :name=>:include_except, :except=>:foo
79
+ end
80
+
81
+ TestProcessor.subscribes_to :testqueue
82
+ MockFilter.reset
83
+ end
84
+
85
+ def teardown
86
+ ActiveMessaging::Gateway.reset
87
+ end
88
+
89
+ def test_filters_use_include
90
+ ActiveMessaging::Gateway.dispatch ActiveMessaging::TestMessage.new('body', {}, '/queue/test.queue')
91
+ MockFilter.assert_was_called(:include_only)
92
+ MockFilter.assert_was_not_called(:exclude_only)
93
+ end
94
+
95
+ def test_filters_use_exclude
96
+ ActiveMessaging::Gateway.dispatch ActiveMessaging::TestMessage.new('body', {}, '/queue/test.queue')
97
+ MockFilter.assert_was_called(:include_except)
98
+ MockFilter.assert_was_not_called(:exclude_except)
99
+ end
100
+
101
+ def test_filters_and_processor_gets_called_on_receive
102
+ ActiveMessaging::Gateway.dispatch ActiveMessaging::TestMessage.new('body', {}, '/queue/test.queue')
103
+ MockFilter.assert_was_called(:bidirectional)
104
+ MockFilter.assert_was_called(:incoming)
105
+ MockFilter.assert_was_not_called(:outgoing)
106
+ TestProcessor.assert_was_called
107
+ end
108
+
109
+ def test_filters_gets_called_on_publish
110
+ ActiveMessaging::Gateway.publish :testqueue, "blah blah"
111
+ MockFilter.assert_was_called(:bidirectional)
112
+ MockFilter.assert_was_not_called(:incoming)
113
+ MockFilter.assert_was_called(:outgoing)
114
+ end
115
+
116
+ def test_sets_routing_details_on_send
117
+ sender = TestProcessor.new
118
+ sender.publish :testqueue, "Hi there!"
119
+
120
+ MockFilter.assert_was_called(:outgoing)
121
+ MockFilter.assert_routing(:outgoing, {:destination=>ActiveMessaging::Gateway.find_queue(:testqueue), :publisher=>FilterTest::TestProcessor, :direction=>:outgoing})
122
+ end
123
+
124
+ def test_sets_routing_details_on_receive
125
+ ActiveMessaging::Gateway.dispatch ActiveMessaging::TestMessage.new('body', {}, '/queue/test.queue')
126
+
127
+ MockFilter.assert_was_called(:incoming)
128
+ MockFilter.assert_routing(:incoming, {:destination=>ActiveMessaging::Gateway.find_queue(:testqueue), :receiver=>FilterTest::TestProcessor, :direction=>:incoming})
129
+ end
130
+
131
+ end
@@ -0,0 +1,195 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class InitializeFilter
4
+
5
+ attr_accessor :options
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def process(message, details={})
12
+ puts "ObjectFilter process called!"
13
+ end
14
+ end
15
+
16
+ class GatewayTest < Test::Unit::TestCase
17
+
18
+
19
+ class ClassFilter
20
+
21
+ def initialize
22
+ raise "Don't try and construct one of these please"
23
+ end
24
+
25
+ class << self
26
+ def process(message, details={})
27
+ puts "ClassFilter process called!"
28
+ end
29
+ end
30
+ end
31
+
32
+ class ObjectFilter
33
+ def process(message, details={})
34
+ puts "ObjectFilter process called!"
35
+ end
36
+ end
37
+
38
+ class TestProcessor < ActiveMessaging::Processor
39
+ include ActiveMessaging::MessageSender
40
+ #subscribes_to :testqueue
41
+ def on_message(message)
42
+ @test_message = true
43
+ end
44
+ end
45
+
46
+ class TestRetryProcessor < ActiveMessaging::Processor
47
+ include ActiveMessaging::MessageSender
48
+ #subscribes_to :testqueue
49
+ def on_message(message)
50
+ #puts "TestRetryProcessor - about to raise exception"
51
+ raise ActiveMessaging::AbortMessageException.new("Cause a retry!")
52
+ end
53
+ end
54
+
55
+ class TestAdapter
56
+ end
57
+
58
+ def setup
59
+ end
60
+
61
+ def teardown
62
+ ActiveMessaging::Gateway.reset
63
+ end
64
+
65
+
66
+ def test_create_filter
67
+ filter_obj = ActiveMessaging::Gateway.create_filter('gateway_test/object_filter', {:direction=>:incoming, :name=>'test1'})
68
+ assert filter_obj
69
+ assert filter_obj.is_a?(GatewayTest::ObjectFilter)
70
+
71
+ filter_obj = ActiveMessaging::Gateway.create_filter('initialize_filter', {:direction=>:incoming, :name=>'test2'})
72
+ assert filter_obj
73
+ assert filter_obj.is_a?(InitializeFilter)
74
+ assert_equal filter_obj.options, {:direction=>:incoming, :name=>'test2'}
75
+
76
+ filter_obj = ActiveMessaging::Gateway.create_filter(:initialize_filter, {:direction=>:incoming, :name=>'test2'})
77
+ assert filter_obj
78
+ assert filter_obj.is_a?(InitializeFilter)
79
+ assert_equal filter_obj.options, {:direction=>:incoming, :name=>'test2'}
80
+
81
+ filter_obj = ActiveMessaging::Gateway.create_filter(:'gateway_test/class_filter', {:direction=>:incoming, :name=>'test2'})
82
+ assert filter_obj
83
+ assert filter_obj.is_a?(Class)
84
+ assert_equal filter_obj.name, "GatewayTest::ClassFilter"
85
+ end
86
+
87
+ def test_register_adapter
88
+ ActiveMessaging::Gateway.register_adapter :test_register_adapter, TestAdapter
89
+ assert_equal TestAdapter, ActiveMessaging::Gateway.adapters[:test_register_adapter]
90
+ end
91
+
92
+ def test_destination
93
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
94
+ dest = ActiveMessaging::Gateway.named_destinations[:hello_world]
95
+ assert_equal :hello_world, dest.name
96
+ end
97
+
98
+ def test_destination_duplicates
99
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
100
+ dest = ActiveMessaging::Gateway.named_destinations[:hello_world]
101
+ assert_equal :hello_world, dest.name
102
+
103
+ # make sure a dupe name causes an error
104
+ assert_raises RuntimeError do
105
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld2'
106
+ end
107
+ end
108
+
109
+ def test_connection
110
+ conn = ActiveMessaging::Gateway.connection
111
+ assert_equal conn.class, ActiveMessaging::Adapters::Test::Connection
112
+ end
113
+
114
+ def test_subscribe_and_unsubscribe
115
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
116
+ ActiveMessaging::Gateway.subscribe_to :hello_world, TestProcessor, headers={}
117
+ sub = ActiveMessaging::Gateway.subscriptions.values.last
118
+ assert_equal :hello_world, sub.destination.name
119
+ assert_equal TestProcessor, sub.processor_class
120
+
121
+ ActiveMessaging::Gateway.subscribe
122
+ assert_not_nil ActiveMessaging::Gateway.connection.find_subscription(sub.destination.value)
123
+
124
+ ActiveMessaging::Gateway.unsubscribe
125
+ assert_nil ActiveMessaging::Gateway.connection.find_subscription(sub.destination.value)
126
+ end
127
+
128
+ def test_disconnect
129
+ assert_equal 0, ActiveMessaging::Gateway.connections.keys.size
130
+
131
+ conn = ActiveMessaging::Gateway.connection
132
+ assert_equal 1, ActiveMessaging::Gateway.connections.keys.size
133
+ assert_equal true, conn.connected
134
+
135
+ ActiveMessaging::Gateway.disconnect
136
+
137
+ assert_equal 0, ActiveMessaging::Gateway.connections.keys.size
138
+ assert_equal false, conn.connected
139
+ end
140
+
141
+ def test_publish
142
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
143
+ ActiveMessaging::Gateway.publish :hello_world, "test_publish body", self.class, headers={}, timeout=10
144
+ assert_not_nil ActiveMessaging::Gateway.connection.find_message('/queue/helloWorld', "test_publish body")
145
+
146
+ assert_raise(RuntimeError) do
147
+ ActiveMessaging::Gateway.publish :hello_world, nil, self.class, headers={}, timeout=10
148
+ end
149
+ assert_raise(RuntimeError) do
150
+ ActiveMessaging::Gateway.publish :hello_world, '', self.class, headers={}, timeout=10
151
+ end
152
+ end
153
+
154
+ def test_acknowledge_message
155
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
156
+ ActiveMessaging::Gateway.subscribe_to :hello_world, TestProcessor, headers={}
157
+ sub = ActiveMessaging::Gateway.subscriptions.values.last
158
+ dest = ActiveMessaging::Adapters::Test::Destination.new '/queue/helloWorld'
159
+ msg = ActiveMessaging::Adapters::Test::Message.new("message_body", nil, {}, dest.name)
160
+ ActiveMessaging::Gateway.acknowledge_message sub, msg
161
+ assert_equal msg, ActiveMessaging::Gateway.connection.received_messages.first
162
+ end
163
+
164
+ def test_abort_message
165
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
166
+ ActiveMessaging::Gateway.subscribe_to :hello_world, TestRetryProcessor, headers={}
167
+ sub = ActiveMessaging::Gateway.subscriptions.values.last
168
+ dest = ActiveMessaging::Adapters::Test::Destination.new '/queue/helloWorld'
169
+ msg = ActiveMessaging::Adapters::Test::Message.new("message_body", nil, {}, dest.name)
170
+ ActiveMessaging::Gateway.dispatch(msg)
171
+ assert_equal msg, ActiveMessaging::Gateway.connection.unreceived_messages.first
172
+ end
173
+
174
+ def test_receive
175
+ ActiveMessaging::Gateway.destination :hello_world, '/queue/helloWorld'
176
+ ActiveMessaging::Gateway.publish :hello_world, "test_publish body", self.class, headers={}, timeout=10
177
+ msg = ActiveMessaging::Gateway.receive :hello_world, self.class, headers={}, timeout=10
178
+ assert_not_nil ActiveMessaging::Gateway.connection.find_message('/queue/helloWorld', "test_publish body")
179
+ end
180
+
181
+ # def test_reload
182
+ # ActiveMessaging.reload_activemessaging
183
+ # size = ActiveMessaging::Gateway.named_destinations.size
184
+ # ActiveMessaging.reload_activemessaging
185
+ # assert_equal size, ActiveMessaging::Gateway.named_destinations.size
186
+ # end
187
+
188
+ ## figure out how to test these better - start in a thread perhaps?
189
+ # def test_start
190
+ # end
191
+ #
192
+ # def test_stop
193
+ # end
194
+
195
+ end