qwirk 0.0.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.
Files changed (154) hide show
  1. data/History.md +7 -0
  2. data/LICENSE.txt +201 -0
  3. data/README.md +180 -0
  4. data/Rakefile +34 -0
  5. data/examples/README +1 -0
  6. data/examples/activemq.xml +84 -0
  7. data/examples/advanced_requestor/README.md +15 -0
  8. data/examples/advanced_requestor/base_request_worker.rb +18 -0
  9. data/examples/advanced_requestor/char_count_worker.rb +16 -0
  10. data/examples/advanced_requestor/config.ru +24 -0
  11. data/examples/advanced_requestor/exception_raiser_worker.rb +17 -0
  12. data/examples/advanced_requestor/length_worker.rb +14 -0
  13. data/examples/advanced_requestor/print_worker.rb +14 -0
  14. data/examples/advanced_requestor/publisher.rb +49 -0
  15. data/examples/advanced_requestor/qwirk.yml +16 -0
  16. data/examples/advanced_requestor/reverse_worker.rb +14 -0
  17. data/examples/advanced_requestor/triple_worker.rb +14 -0
  18. data/examples/batch/my_batch_worker.rb +30 -0
  19. data/examples/batch/my_line_worker.rb +8 -0
  20. data/examples/qwirk.yml +20 -0
  21. data/examples/requestor/README.md +13 -0
  22. data/examples/requestor/config.ru +13 -0
  23. data/examples/requestor/qwirk_persist.yml +5 -0
  24. data/examples/requestor/requestor.rb +68 -0
  25. data/examples/requestor/reverse_echo_worker.rb +15 -0
  26. data/examples/setup.rb +13 -0
  27. data/examples/shared/README.md +24 -0
  28. data/examples/shared/config.ru +13 -0
  29. data/examples/shared/publisher.rb +49 -0
  30. data/examples/shared/qwirk_persist.yml +5 -0
  31. data/examples/shared/shared_worker.rb +16 -0
  32. data/examples/simple/README +53 -0
  33. data/examples/simple/bar_worker.rb +10 -0
  34. data/examples/simple/baz_worker.rb +10 -0
  35. data/examples/simple/config.ru +14 -0
  36. data/examples/simple/publisher.rb +49 -0
  37. data/examples/simple/qwirk_persist.yml +4 -0
  38. data/examples/simple/tmp/kahadb/db-1.log +0 -0
  39. data/examples/simple/tmp/kahadb/db.data +0 -0
  40. data/examples/simple/tmp/kahadb/db.redo +0 -0
  41. data/examples/task/README +47 -0
  42. data/examples/task/config.ru +14 -0
  43. data/examples/task/foo_worker.rb +10 -0
  44. data/examples/task/messages.out +1000 -0
  45. data/examples/task/publisher.rb +25 -0
  46. data/examples/task/qwirk_persist.yml +5 -0
  47. data/examples/task/task.rb +36 -0
  48. data/lib/qwirk.rb +63 -0
  49. data/lib/qwirk/adapter.rb +45 -0
  50. data/lib/qwirk/base_worker.rb +96 -0
  51. data/lib/qwirk/batch.rb +4 -0
  52. data/lib/qwirk/batch/acquire_file_strategy.rb +47 -0
  53. data/lib/qwirk/batch/active_record.rb +3 -0
  54. data/lib/qwirk/batch/active_record/batch_job.rb +111 -0
  55. data/lib/qwirk/batch/active_record/failed_record.rb +5 -0
  56. data/lib/qwirk/batch/active_record/outstanding_record.rb +6 -0
  57. data/lib/qwirk/batch/file_status_strategy.rb +86 -0
  58. data/lib/qwirk/batch/file_worker.rb +228 -0
  59. data/lib/qwirk/batch/job_status.rb +29 -0
  60. data/lib/qwirk/batch/parse_file_strategy.rb +48 -0
  61. data/lib/qwirk/engine.rb +9 -0
  62. data/lib/qwirk/loggable.rb +23 -0
  63. data/lib/qwirk/manager.rb +140 -0
  64. data/lib/qwirk/marshal_strategy.rb +74 -0
  65. data/lib/qwirk/marshal_strategy/bson.rb +37 -0
  66. data/lib/qwirk/marshal_strategy/json.rb +37 -0
  67. data/lib/qwirk/marshal_strategy/none.rb +26 -0
  68. data/lib/qwirk/marshal_strategy/ruby.rb +26 -0
  69. data/lib/qwirk/marshal_strategy/string.rb +25 -0
  70. data/lib/qwirk/marshal_strategy/yaml.rb +25 -0
  71. data/lib/qwirk/publish_handle.rb +170 -0
  72. data/lib/qwirk/publisher.rb +67 -0
  73. data/lib/qwirk/queue_adapter.rb +3 -0
  74. data/lib/qwirk/queue_adapter/active_mq.rb +13 -0
  75. data/lib/qwirk/queue_adapter/active_mq/publisher.rb +12 -0
  76. data/lib/qwirk/queue_adapter/active_mq/worker_config.rb +16 -0
  77. data/lib/qwirk/queue_adapter/in_mem.rb +7 -0
  78. data/lib/qwirk/queue_adapter/in_mem/factory.rb +45 -0
  79. data/lib/qwirk/queue_adapter/in_mem/publisher.rb +98 -0
  80. data/lib/qwirk/queue_adapter/in_mem/queue.rb +88 -0
  81. data/lib/qwirk/queue_adapter/in_mem/reply_queue.rb +56 -0
  82. data/lib/qwirk/queue_adapter/in_mem/topic.rb +48 -0
  83. data/lib/qwirk/queue_adapter/in_mem/worker.rb +63 -0
  84. data/lib/qwirk/queue_adapter/in_mem/worker_config.rb +59 -0
  85. data/lib/qwirk/queue_adapter/jms.rb +50 -0
  86. data/lib/qwirk/queue_adapter/jms/connection.rb +42 -0
  87. data/lib/qwirk/queue_adapter/jms/consumer.rb +37 -0
  88. data/lib/qwirk/queue_adapter/jms/publisher.rb +126 -0
  89. data/lib/qwirk/queue_adapter/jms/worker.rb +89 -0
  90. data/lib/qwirk/queue_adapter/jms/worker_config.rb +38 -0
  91. data/lib/qwirk/remote_exception.rb +42 -0
  92. data/lib/qwirk/request_worker.rb +62 -0
  93. data/lib/qwirk/task.rb +177 -0
  94. data/lib/qwirk/task.rb.sav +194 -0
  95. data/lib/qwirk/version.rb +3 -0
  96. data/lib/qwirk/worker.rb +222 -0
  97. data/lib/qwirk/worker_config.rb +187 -0
  98. data/lib/rails/generators/qwirk/qwirk_generator.rb +82 -0
  99. data/lib/rails/generators/qwirk/templates/initializer.rb +6 -0
  100. data/lib/rails/generators/qwirk/templates/migration.rb +9 -0
  101. data/lib/rails/generators/qwirk/templates/schema.rb +28 -0
  102. data/lib/rails/railties/tasks.rake +8 -0
  103. data/lib/tasks/qwirk_tasks.rake +4 -0
  104. data/test/base_test.rb +248 -0
  105. data/test/database.yml +14 -0
  106. data/test/dummy/Rakefile +7 -0
  107. data/test/dummy/app/controllers/application_controller.rb +3 -0
  108. data/test/dummy/app/helpers/application_helper.rb +2 -0
  109. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  110. data/test/dummy/config.ru +4 -0
  111. data/test/dummy/config/application.rb +45 -0
  112. data/test/dummy/config/boot.rb +10 -0
  113. data/test/dummy/config/database.yml +22 -0
  114. data/test/dummy/config/environment.rb +5 -0
  115. data/test/dummy/config/environments/development.rb +26 -0
  116. data/test/dummy/config/environments/production.rb +49 -0
  117. data/test/dummy/config/environments/test.rb +35 -0
  118. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  119. data/test/dummy/config/initializers/inflections.rb +10 -0
  120. data/test/dummy/config/initializers/mime_types.rb +5 -0
  121. data/test/dummy/config/initializers/secret_token.rb +7 -0
  122. data/test/dummy/config/initializers/session_store.rb +8 -0
  123. data/test/dummy/config/locales/en.yml +5 -0
  124. data/test/dummy/config/routes.rb +58 -0
  125. data/test/dummy/log/development.log +0 -0
  126. data/test/dummy/log/production.log +0 -0
  127. data/test/dummy/log/server.log +0 -0
  128. data/test/dummy/log/test.log +0 -0
  129. data/test/dummy/public/404.html +26 -0
  130. data/test/dummy/public/422.html +26 -0
  131. data/test/dummy/public/500.html +26 -0
  132. data/test/dummy/public/favicon.ico +0 -0
  133. data/test/dummy/public/javascripts/application.js +2 -0
  134. data/test/dummy/public/javascripts/controls.js +965 -0
  135. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  136. data/test/dummy/public/javascripts/effects.js +1123 -0
  137. data/test/dummy/public/javascripts/prototype.js +6001 -0
  138. data/test/dummy/public/javascripts/rails.js +191 -0
  139. data/test/dummy/script/rails +6 -0
  140. data/test/integration/navigation_test.rb +7 -0
  141. data/test/jms.yml +9 -0
  142. data/test/jms_fail_test.rb +149 -0
  143. data/test/jms_requestor_block_test.rb +278 -0
  144. data/test/jms_requestor_test.rb +238 -0
  145. data/test/jms_test.rb +287 -0
  146. data/test/marshal_strategy_test.rb +62 -0
  147. data/test/support/integration_case.rb +5 -0
  148. data/test/test_helper.rb +7 -0
  149. data/test/test_helper.rbold +22 -0
  150. data/test/test_helper_active_record.rb +61 -0
  151. data/test/unit/qwirk/batch/acquire_file_strategy_test.rb +101 -0
  152. data/test/unit/qwirk/batch/active_record/batch_job_test.rb +35 -0
  153. data/test/unit/qwirk/batch/parse_file_strategy_test.rb +49 -0
  154. metadata +366 -0
@@ -0,0 +1,238 @@
1
+ require 'qwirk'
2
+ require 'shoulda'
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ require 'erb'
6
+
7
+ # NOTE: This test requires a running ActiveMQ server
8
+
9
+ module HashTest
10
+ def self.create_obj(i)
11
+ {
12
+ 'foo' => 1,
13
+ 'bar' => {
14
+ 'message' => i,
15
+ 'dummy' => "Message #{i}"
16
+ },
17
+ # Only YAML will maintain symbols
18
+ :zulu => :rugger
19
+ }
20
+ end
21
+
22
+ def self.parse_obj(obj)
23
+ obj['answer']
24
+ end
25
+
26
+ def self.request(obj)
27
+ {
28
+ 'answer' => obj['bar']['message']
29
+ }
30
+ end
31
+ end
32
+
33
+ module RubyTest
34
+
35
+ class MyClass
36
+ attr_reader :i
37
+ def initialize(i)
38
+ @i = i
39
+ end
40
+ end
41
+
42
+ def self.create_obj(i)
43
+ MyClass.new(i)
44
+ end
45
+
46
+ def self.parse_obj(obj)
47
+ obj.i-10
48
+ end
49
+
50
+ def self.request(obj)
51
+ return MyClass.new(obj.i+10)
52
+ end
53
+ end
54
+
55
+ module StringTest
56
+ def self.create_obj(i)
57
+ "Message #{i}"
58
+ end
59
+
60
+ def self.parse_obj(obj)
61
+ if obj =~ /^Returning (\d+)$/
62
+ $1.to_i
63
+ else
64
+ raise "Unknown message: #{obj}"
65
+ end
66
+ end
67
+
68
+ def self.request(str)
69
+ if str =~ /^Message (\d+)$/
70
+ "Returning #{$1}"
71
+ else
72
+ raise "Unknown message: #{str}"
73
+ end
74
+ end
75
+ end
76
+
77
+ class DefaultWorker
78
+ include Qwirk::QueueAdapter::JMS::RequestWorker
79
+ response :marshal => :yaml
80
+
81
+ def request(obj)
82
+ options[:tester].request(obj)
83
+ end
84
+ end
85
+
86
+ class SleepWorker
87
+ include Qwirk::QueueAdapter::JMS::RequestWorker
88
+ response :marshal => :string
89
+
90
+ def request(i)
91
+ sleep i.to_i
92
+ return i
93
+ end
94
+ end
95
+
96
+ class JMSRequestorTest < Test::Unit::TestCase
97
+
98
+ @@server = JMX.simple_server
99
+ @@client = JMX.connect
100
+
101
+ context 'jms request' do
102
+ setup do
103
+ config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), 'jms.yml'))).result(binding))
104
+ Qwirk::QueueAdapter::JMS::Connection.init(config)
105
+ end
106
+
107
+ teardown do
108
+ end
109
+
110
+ {
111
+ :bson => HashTest,
112
+ :json => HashTest,
113
+ :ruby => RubyTest,
114
+ :string => StringTest,
115
+ :yaml => HashTest
116
+ }.each do |marshal, tester|
117
+
118
+ context "marshaling with #{marshal}" do
119
+ setup do
120
+ @domain = "Uniquize_#{marshal}"
121
+ @manager = Qwirk::Manager.new(:domain => @domain)
122
+ end
123
+
124
+ teardown do
125
+ if @manager
126
+ @manager.stop
127
+ @manager.join
128
+ end
129
+ end
130
+
131
+ should "reply correctly with multiple threads" do
132
+ DefaultWorker.response(:marshal => marshal, :time_to_live => 10000)
133
+ @manager.add(DefaultWorker, 10, :tester => tester)
134
+
135
+ sleep 1
136
+
137
+ publisher = Qwirk::QueueAdapter::JMS::Publisher.new(:queue_name => 'Default', :marshal => marshal, :response_time_to_live => 10000)
138
+ threads = []
139
+ start = Time.now
140
+ (0..9).each do |i|
141
+ threads << Thread.new(i) do |i|
142
+ start = i*10
143
+ range = start..(start+9)
144
+ range.each do |x|
145
+ obj = tester.create_obj(x)
146
+ handle = publisher.publish(obj)
147
+ reply_obj = handle.read_response(2)
148
+ val = tester.parse_obj(reply_obj)
149
+ assert x == val, "#{x} does not equal #{val}"
150
+ end
151
+ end
152
+ end
153
+ threads.each {|t| t.join}
154
+ end
155
+ end
156
+ end
157
+
158
+ context 'timed requesting' do
159
+ setup do
160
+ @domain = "TimedQwirk"
161
+ @manager = Qwirk::Manager.new(:domain => @domain)
162
+ @manager.add(SleepWorker, 10)
163
+ sleep 1
164
+ @producer = Qwirk::QueueAdapter::JMS::Publisher.new(:queue_name => 'Sleep', :marshal => :string, :response_time_to_live => 10000)
165
+ end
166
+
167
+ teardown do
168
+ if @manager
169
+ @manager.stop
170
+ @manager.join
171
+ end
172
+ end
173
+
174
+ should "work correctly if request is complete before the timeout" do
175
+ [[1,0,2,0.8,1.2], [2,1,3,1.8,2.2], [1,2,3,0.8,1.2], [3,1,2,2.8,3.2]].each do |info|
176
+ work_sleep_time, publish_sleep_time, timeout_time, min_time, max_time = info
177
+ threads = []
178
+ start_time = Time.now
179
+ (0..9).each do |i|
180
+ threads << Thread.new(i) do |i|
181
+ handle = @producer.publish(work_sleep_time)
182
+ sleep publish_sleep_time
183
+ if work_sleep_time < timeout_time
184
+ response = handle.read_response(timeout_time).to_i
185
+ assert work_sleep_time == response, "#{work_sleep_time} does not equal #{response}"
186
+ else
187
+ assert handle.read_response(timeout_time).nil?
188
+ actual_time = Time.now - start_time
189
+ assert timeout_time-0.1 < actual_time, "Bad timeout #{actual_time}"
190
+ assert timeout_time+0.3 > actual_time, "Bad timeout #{actual_time}"
191
+
192
+ # Give the requests time to complete
193
+ sleep work_sleep_time - timeout_time + 1
194
+ end
195
+ end
196
+ end
197
+ threads.each {|t| t.join}
198
+ total_time = Time.now - start_time
199
+ bean = @@client[Qwirk.supervisor_mbean_object_name(@domain, 'Sleep')]
200
+ bean_avg = bean.average_response_time
201
+ bean_min = bean.min_response_time
202
+ bean_max = bean.max_response_time
203
+ puts "total=#{total_time} avg=#{bean_avg} min=#{bean_min} max=#{bean_max}"
204
+ all_times = [bean_avg, bean_min, bean_max]
205
+ all_times << total_time if work_sleep_time > publish_sleep_time && work_sleep_time < timeout_time
206
+ all_times.each do |time_val|
207
+ assert min_time < time_val, "#{time_val} is not between #{min_time} and #{max_time}"
208
+ assert max_time > time_val, "#{time_val} is not between #{min_time} and #{max_time}"
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ context 'dummy requesting' do
215
+ setup do
216
+ @tester = RubyTest
217
+ workers = [
218
+ DefaultWorker.new(:tester => @tester)
219
+ ]
220
+ Qwirk::QueueAdapter::JMS::Publisher.setup_dummy_publishing(workers)
221
+ end
222
+
223
+ teardown do
224
+ Qwirk::QueueAdapter::JMS::Publisher.clear_dummy_publishing
225
+ end
226
+
227
+ should "directly call applicable workers" do
228
+ x=9999
229
+ obj = @tester.create_obj(x)
230
+ publisher = Qwirk::QueueAdapter::JMS::Publisher.new(:queue_name => 'Default', :marshal => :ruby, :response => true)
231
+ handle = publisher.publish(obj)
232
+ reply_obj = handle.read_response(2)
233
+ val = @tester.parse_obj(reply_obj)
234
+ assert x == val, "#{x} does not equal #{val}"
235
+ end
236
+ end
237
+ end
238
+ end
data/test/jms_test.rb ADDED
@@ -0,0 +1,287 @@
1
+ require 'qwirk'
2
+ require 'shoulda'
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ require 'erb'
6
+
7
+ # NOTE: This test requires a running ActiveMQ server
8
+
9
+ module WorkerHelper
10
+ @@workers = {}
11
+ @@mutex = Mutex.new
12
+ def initialize(opts={})
13
+ super
14
+ @tester = opts[:tester]
15
+ @@mutex.synchronize do
16
+ @@workers[self.name] ||= []
17
+ @@workers[self.name] << self
18
+ end
19
+ @hash = Hash.new(0)
20
+ end
21
+
22
+ def perform(obj)
23
+ add_message(@tester.translate(obj))
24
+ end
25
+
26
+ def self.workers(names)
27
+ workers = []
28
+ names.each {|name| workers += @@workers[name]}
29
+ workers
30
+ end
31
+
32
+ def self.reset_workers
33
+ @@workers = {}
34
+ end
35
+
36
+ def add_message(i)
37
+ @hash[i] += 1
38
+ end
39
+
40
+ def call_count
41
+ puts "hash=#{@hash.inspect}"
42
+ @hash.values.reduce(:+)
43
+ end
44
+
45
+ def messages
46
+ @hash.keys
47
+ end
48
+ end
49
+
50
+ module HashTest
51
+ def self.create_obj(i)
52
+ {
53
+ 'foo' => 1,
54
+ 'bar' => {
55
+ 'message' => i,
56
+ 'dummy' => "Message #{i}"
57
+ },
58
+ # Only YAML will maintain symbols
59
+ :zulu => :rugger
60
+ }
61
+ end
62
+
63
+ def self.translate(obj)
64
+ obj['bar']['message']
65
+ end
66
+ end
67
+
68
+ module RubyTest
69
+ class MyClass
70
+ attr_reader :i
71
+ def initialize(i)
72
+ @i = i
73
+ end
74
+ end
75
+
76
+ def self.create_obj(i)
77
+ MyClass.new(i)
78
+ end
79
+
80
+ def self.translate(obj)
81
+ obj.i
82
+ end
83
+ end
84
+
85
+ module StringTest
86
+ def self.create_obj(i)
87
+ "Message #{i}"
88
+ end
89
+
90
+ def self.translate(str)
91
+ if str =~ /^Message (\d+)$/
92
+ $1.to_i
93
+ else
94
+ raise "Unknown message: #{str}"
95
+ end
96
+ end
97
+ end
98
+
99
+ class DefaultWorker
100
+ include Qwirk::QueueAdapter::JMS::Worker
101
+ include WorkerHelper
102
+ end
103
+
104
+ module Dummy
105
+ class DefaultWorker
106
+ include Qwirk::QueueAdapter::JMS::Worker
107
+ include WorkerHelper
108
+ end
109
+ end
110
+
111
+ class SpecifiedQueueWorker
112
+ include Qwirk::QueueAdapter::JMS::Worker
113
+ queue 'MyQueueName'
114
+ include WorkerHelper
115
+ end
116
+
117
+ class SpecifiedQueue2Worker
118
+ include Qwirk::QueueAdapter::JMS::Worker
119
+ queue 'MyQueueName'
120
+ include WorkerHelper
121
+ end
122
+
123
+ class SpecifiedTopicWorker
124
+ include Qwirk::QueueAdapter::JMS::Worker
125
+ virtual_topic 'MyTopicName'
126
+ include WorkerHelper
127
+ end
128
+
129
+ class SpecifiedTopic2Worker
130
+ include Qwirk::QueueAdapter::JMS::Worker
131
+ virtual_topic 'MyTopicName'
132
+ include WorkerHelper
133
+ end
134
+
135
+ class JMSTest < Test::Unit::TestCase
136
+
137
+ @@server = JMX.simple_server
138
+ @@client = JMX.connect
139
+
140
+ def publish(marshal, tester, range, options)
141
+ publisher = Qwirk::QueueAdapter::JMS::Publisher.new(options.merge(:marshal => marshal))
142
+ puts "Publishing #{range} to #{publisher} via #{marshal}"
143
+ range.each do |i|
144
+ obj = tester.create_obj(i)
145
+ publisher.publish(obj)
146
+ end
147
+ end
148
+
149
+ def assert_worker(domain, names, worker_count, range, min, max, instance_count)
150
+ puts "Checking #{names.inspect}"
151
+ names = [names] unless names.kind_of?(Array)
152
+ workers = WorkerHelper.workers(names)
153
+
154
+ assert_equal worker_count, workers.size
155
+ all_messages = []
156
+ workers.each do |worker|
157
+ msg_count = worker.call_count
158
+ assert msg_count
159
+ assert msg_count >= min, "#{msg_count} is not between #{min} and #{max}"
160
+ assert msg_count <= max, "#{msg_count} is not between #{min} and #{max}"
161
+ # Make sure no duplicate messages
162
+ assert msg_count == worker.messages.size, "#{msg_count} is not == #{worker.messages.size}"
163
+ all_messages.concat(worker.messages)
164
+ end
165
+ all_messages.sort!
166
+ assert_equal all_messages, (range.to_a*instance_count).sort
167
+
168
+ if domain
169
+ total_count = 0
170
+ names.each do |name|
171
+ bean = @@client[Qwirk.supervisor_mbean_object_name(domain, name)]
172
+ bean.message_counts.each do |msg_count|
173
+ total_count += msg_count
174
+ assert msg_count >= min, "#{msg_count} is not between #{min} and #{max}"
175
+ assert msg_count <= max, "#{msg_count} is not between #{min} and #{max}"
176
+ end
177
+ end
178
+ assert_equal all_messages.size, total_count
179
+ end
180
+ end
181
+
182
+ context 'jms' do
183
+ setup do
184
+ config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), 'jms.yml'))).result(binding))
185
+ Qwirk::QueueAdapter::JMS::Connection.init(config)
186
+ end
187
+
188
+ teardown do
189
+ end
190
+
191
+ {
192
+ :bson => HashTest,
193
+ :json => HashTest,
194
+ :ruby => RubyTest,
195
+ :string => StringTest,
196
+ :yaml => HashTest
197
+ }.each do |marshal, tester|
198
+
199
+ context "marshaling with #{marshal}" do
200
+ setup do
201
+ @domain = "Uniquize_#{marshal}"
202
+ @manager = Qwirk::Manager.new(:domain => @domain)
203
+ end
204
+
205
+ teardown do
206
+ if @manager
207
+ @manager.stop
208
+ @manager.join
209
+ end
210
+ end
211
+
212
+ should "operate on queues and topics" do
213
+ WorkerHelper.reset_workers
214
+ @manager.add(DefaultWorker, 3, :tester => tester)
215
+ @manager.add(DefaultWorker, 2, :name => 'DefaultClone', :tester => tester)
216
+ @manager.add(Dummy::DefaultWorker, 4, :tester => tester)
217
+ @manager.add(SpecifiedQueueWorker, 3, :tester => tester)
218
+ @manager.add(SpecifiedQueueWorker, 2, :name => 'SpecifiedQueueClone', :tester => tester)
219
+ @manager.add(SpecifiedQueue2Worker, 2, :tester => tester)
220
+ @manager.add(SpecifiedTopicWorker, 3, :tester => tester)
221
+ @manager.add(SpecifiedTopicWorker, 2, :name => 'SpecifiedTopicClone', :tester => tester)
222
+ @manager.add(SpecifiedTopic2Worker, 2, :tester => tester)
223
+
224
+ sleep 1
225
+
226
+ publish(marshal, tester, 100..199, :queue_name => 'Default')
227
+ publish(marshal, tester, 200..299, :queue_name => 'DefaultClone')
228
+ publish(marshal, tester, 300..399, :queue_name => 'Dummy_Default')
229
+ publish(marshal, tester, 400..599, :queue_name => 'MyQueueName')
230
+ publish(marshal, tester, 600..699, :virtual_topic_name => 'MyTopicName')
231
+
232
+ # Let the workers do their thing
233
+ sleep 5
234
+
235
+ # DefaultWorker should have 5 instances running with each worker handling between 10-30 messages in the range 100.199
236
+ assert_worker(@domain, 'Default', 3, 100..199, 30, 36, 1)
237
+ assert_worker(@domain, 'DefaultClone', 2, 200..299, 45, 55, 1)
238
+ assert_worker(@domain, 'Dummy_Default', 4, 300..399, 20, 30, 1)
239
+ assert_worker(@domain, ['SpecifiedQueue', 'SpecifiedQueueClone', 'SpecifiedQueue2'], 7, 400..599, 20, 40, 1)
240
+ assert_worker(@domain, ['SpecifiedTopic', 'SpecifiedTopicClone'], 5, 600..699, 30, 60, 2)
241
+ assert_worker(@domain, 'SpecifiedTopic2', 2, 600..699, 35, 65, 1)
242
+ end
243
+ end
244
+ end
245
+
246
+ context 'dummy publishing' do
247
+ setup do
248
+ WorkerHelper.reset_workers
249
+ workers = [
250
+ DefaultWorker.new(:tester => RubyTest),
251
+ DefaultWorker.new(:tester => RubyTest, :name => 'DefaultClone'),
252
+ Dummy::DefaultWorker.new(:tester => RubyTest),
253
+ SpecifiedQueueWorker.new(:tester => RubyTest),
254
+ SpecifiedQueueWorker.new(:tester => RubyTest, :name => 'SpecifiedQueueClone'),
255
+ SpecifiedQueue2Worker.new(:tester => RubyTest),
256
+ SpecifiedTopicWorker.new(:tester => RubyTest),
257
+ SpecifiedTopicWorker.new(:tester => RubyTest, :name => 'SpecifiedTopicClone'),
258
+ SpecifiedTopic2Worker.new(:tester => RubyTest),
259
+ ]
260
+ Qwirk::QueueAdapter::JMS::Publisher.setup_dummy_publishing(workers)
261
+ end
262
+
263
+ teardown do
264
+ Qwirk::QueueAdapter::JMS::Publisher.clear_dummy_publishing
265
+ end
266
+
267
+ should "directly call applicable workers" do
268
+ publish(:ruby, RubyTest, 100..199, :queue_name => 'Default')
269
+ publish(:ruby, RubyTest, 200..299, :queue_name => 'DefaultClone')
270
+ publish(:ruby, RubyTest, 300..399, :queue_name => 'Dummy_Default')
271
+ publish(:ruby, RubyTest, 400..599, :queue_name => 'MyQueueName')
272
+ publish(:ruby, RubyTest, 600..699, :virtual_topic_name => 'MyTopicName')
273
+
274
+ # The single instance of each class will be called so everyone will have all messages.
275
+ assert_worker(nil, 'Default', 1, 100..199, 100, 100, 1)
276
+ assert_worker(nil, 'DefaultClone', 1, 200..299, 100, 100, 1)
277
+ assert_worker(nil, 'Dummy_Default', 1, 300..399, 100, 100, 1)
278
+ assert_worker(nil, 'SpecifiedQueue', 1, 400..599, 200, 200, 1)
279
+ assert_worker(nil, 'SpecifiedQueueClone', 1, 400..599, 200, 200, 1)
280
+ assert_worker(nil, 'SpecifiedQueue2', 1, 400..599, 200, 200, 1)
281
+ assert_worker(nil, 'SpecifiedTopic', 1, 600..699, 100, 100, 1)
282
+ assert_worker(nil, 'SpecifiedTopicClone', 1, 600..699, 100, 100, 1)
283
+ assert_worker(nil, 'SpecifiedTopic2', 1, 600..699, 100, 100, 1)
284
+ end
285
+ end
286
+ end
287
+ end