activemessaging 0.6.1 → 0.7.1

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.
@@ -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