qs 0.3.0 → 0.4.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 (63) hide show
  1. data/bench/config.qs +4 -27
  2. data/bench/dispatcher.qs +24 -0
  3. data/bench/report.rb +80 -10
  4. data/bench/report.txt +10 -3
  5. data/bench/setup.rb +55 -0
  6. data/lib/qs.rb +75 -15
  7. data/lib/qs/client.rb +73 -22
  8. data/lib/qs/daemon.rb +21 -21
  9. data/lib/qs/daemon_data.rb +4 -4
  10. data/lib/qs/dispatch_job.rb +36 -0
  11. data/lib/qs/dispatch_job_handler.rb +79 -0
  12. data/lib/qs/dispatcher_queue.rb +19 -0
  13. data/lib/qs/error_handler.rb +12 -12
  14. data/lib/qs/event.rb +82 -0
  15. data/lib/qs/event_handler.rb +34 -0
  16. data/lib/qs/event_handler_test_helpers.rb +17 -0
  17. data/lib/qs/job.rb +19 -31
  18. data/lib/qs/job_handler.rb +6 -63
  19. data/lib/qs/{test_helpers.rb → job_handler_test_helpers.rb} +2 -2
  20. data/lib/qs/message.rb +29 -0
  21. data/lib/qs/message_handler.rb +84 -0
  22. data/lib/qs/payload.rb +98 -0
  23. data/lib/qs/payload_handler.rb +106 -54
  24. data/lib/qs/queue.rb +39 -6
  25. data/lib/qs/queue_item.rb +33 -0
  26. data/lib/qs/route.rb +7 -7
  27. data/lib/qs/runner.rb +6 -5
  28. data/lib/qs/test_runner.rb +41 -13
  29. data/lib/qs/version.rb +1 -1
  30. data/qs.gemspec +1 -1
  31. data/test/helper.rb +1 -1
  32. data/test/support/app_daemon.rb +77 -11
  33. data/test/support/factory.rb +34 -0
  34. data/test/system/daemon_tests.rb +146 -77
  35. data/test/system/queue_tests.rb +87 -0
  36. data/test/unit/client_tests.rb +184 -45
  37. data/test/unit/daemon_data_tests.rb +4 -4
  38. data/test/unit/daemon_tests.rb +32 -32
  39. data/test/unit/dispatch_job_handler_tests.rb +163 -0
  40. data/test/unit/dispatch_job_tests.rb +75 -0
  41. data/test/unit/dispatcher_queue_tests.rb +42 -0
  42. data/test/unit/error_handler_tests.rb +9 -9
  43. data/test/unit/event_handler_test_helpers_tests.rb +55 -0
  44. data/test/unit/event_handler_tests.rb +63 -0
  45. data/test/unit/event_tests.rb +162 -0
  46. data/test/unit/{test_helper_tests.rb → job_handler_test_helper_tests.rb} +13 -19
  47. data/test/unit/job_handler_tests.rb +17 -210
  48. data/test/unit/job_tests.rb +49 -79
  49. data/test/unit/message_handler_tests.rb +235 -0
  50. data/test/unit/message_tests.rb +64 -0
  51. data/test/unit/payload_handler_tests.rb +285 -86
  52. data/test/unit/payload_tests.rb +139 -0
  53. data/test/unit/qs_runner_tests.rb +6 -6
  54. data/test/unit/qs_tests.rb +167 -28
  55. data/test/unit/queue_item_tests.rb +51 -0
  56. data/test/unit/queue_tests.rb +126 -18
  57. data/test/unit/route_tests.rb +12 -13
  58. data/test/unit/runner_tests.rb +10 -10
  59. data/test/unit/test_runner_tests.rb +117 -24
  60. metadata +51 -21
  61. data/bench/queue.rb +0 -8
  62. data/lib/qs/redis_item.rb +0 -33
  63. data/test/unit/redis_item_tests.rb +0 -49
@@ -1,6 +1,8 @@
1
1
  require 'assert'
2
2
  require 'qs/job'
3
3
 
4
+ require 'qs/message'
5
+
4
6
  class Qs::Job
5
7
 
6
8
  class UnitTests < Assert::Context
@@ -14,19 +16,12 @@ class Qs::Job
14
16
  end
15
17
  subject{ @job_class }
16
18
 
17
- should have_imeths :parse
18
-
19
- should "parse a job from a payload hash" do
20
- payload = {
21
- 'name' => @name,
22
- 'params' => @params,
23
- 'created_at' => @created_at.to_i
24
- }
25
- job = subject.parse(payload)
26
- assert_instance_of subject, job
27
- assert_equal payload['name'], job.name
28
- assert_equal payload['params'], job.params
29
- assert_equal Time.at(payload['created_at']), job.created_at
19
+ should "know its payload type" do
20
+ assert_equal 'job', PAYLOAD_TYPE
21
+ end
22
+
23
+ should "be a message" do
24
+ assert subject < Qs::Message
30
25
  end
31
26
 
32
27
  end
@@ -37,94 +32,69 @@ class Qs::Job
37
32
  @current_time = Factory.time
38
33
  Assert.stub(Time, :now).with{ @current_time }
39
34
 
40
- @job = @job_class.new(@name, @params, @created_at)
35
+ @job = @job_class.new(@name, {
36
+ :params => @params,
37
+ :created_at => @created_at
38
+ })
41
39
  end
42
40
  subject{ @job }
43
41
 
44
- should have_readers :name, :params, :created_at
45
- should have_imeths :to_payload
42
+ should have_readers :name, :created_at
43
+ should have_imeths :route_name
46
44
 
47
- should "know its name, params and created at" do
48
- assert_equal @name, subject.name
49
- assert_equal @params, subject.params
50
- assert_equal @created_at, subject.created_at
45
+ should "know its attributes" do
46
+ assert_equal PAYLOAD_TYPE, subject.payload_type
47
+ assert_equal @name, subject.name
48
+ assert_equal @params, subject.params
49
+ assert_equal @created_at, subject.created_at
51
50
  end
52
51
 
53
- should "default its created at" do
54
- job = @job_class.new(@name, @params)
52
+ should "default its params and created at to the current time" do
53
+ job = @job_class.new(@name)
54
+ assert_equal({}, job.params)
55
55
  assert_equal @current_time, job.created_at
56
56
  end
57
57
 
58
- should "return a payload hash using `to_payload`" do
59
- payload_hash = subject.to_payload
60
- expected = {
61
- 'name' => @name,
62
- 'params' => @params,
63
- 'created_at' => @created_at.to_i
64
- }
65
- assert_equal expected, payload_hash
66
- end
67
-
68
- should "convert job names to strings using `to_payload`" do
69
- job = @job_class.new(@name.to_sym, @params)
70
- assert_equal @name, job.to_payload['name']
71
- end
72
-
73
- should "convert stringify its params using `to_payload`" do
74
- params = { Factory.string.to_sym => Factory.string }
75
- job = @job_class.new(@name, params)
76
- exp = StringifyParams.new(params)
77
- assert_equal exp, job.to_payload['params']
78
- end
79
-
80
- should "raise an error when given an invalid name or params" do
81
- assert_raises(Qs::BadJobError){ @job_class.new(nil, @params) }
82
- assert_raises(Qs::BadJobError){ @job_class.new(@name, nil) }
83
- assert_raises(Qs::BadJobError){ @job_class.new(@name, Factory.string) }
58
+ should "know its route name" do
59
+ assert_same subject.name, subject.route_name
84
60
  end
85
61
 
86
62
  should "have a custom inspect" do
87
63
  reference = '0x0%x' % (subject.object_id << 1)
88
- expected = "#<Qs::Job:#{reference} " \
89
- "@name=#{subject.name.inspect} " \
90
- "@params=#{subject.params.inspect} " \
91
- "@created_at=#{subject.created_at.inspect}>"
92
- assert_equal expected, subject.inspect
64
+ exp = "#<Qs::Job:#{reference} " \
65
+ "@name=#{subject.name.inspect} " \
66
+ "@params=#{subject.params.inspect} " \
67
+ "@created_at=#{subject.created_at.inspect}>"
68
+ assert_equal exp, subject.inspect
93
69
  end
94
70
 
95
71
  should "be comparable" do
96
- matching = @job_class.new(@name, @params, @created_at)
72
+ matching = @job_class.new(@name, {
73
+ :params => @params,
74
+ :created_at => @created_at
75
+ })
97
76
  assert_equal matching, subject
98
- non_matching = @job_class.new(Factory.string, @params, @created_at)
77
+
78
+ non_matching = @job_class.new(Factory.string, {
79
+ :params => @params,
80
+ :created_at => @created_at
81
+ })
99
82
  assert_not_equal non_matching, subject
100
- params = { Factory.string => Factory.string }
101
- non_matching = @job_class.new(@name, params, @created_at)
83
+ non_matching = @job_class.new(@name, {
84
+ :params => { Factory.string => Factory.string },
85
+ :created_at => @created_at
86
+ })
102
87
  assert_not_equal non_matching, subject
103
- non_matching = @job_class.new(@name, @params, Factory.time)
88
+ non_matching = @job_class.new(@name, {
89
+ :params => @params,
90
+ :created_at => Factory.time
91
+ })
104
92
  assert_not_equal non_matching, subject
105
93
  end
106
94
 
107
- end
108
-
109
- class StringifyParamsTests < UnitTests
110
- desc "StringifyParams"
111
- subject{ StringifyParams }
112
-
113
- should have_imeths :new
114
-
115
- should "convert all hash keys to strings" do
116
- key, value = Factory.string.to_sym, Factory.string
117
- result = subject.new({
118
- key => value,
119
- :hash => { key => [value] },
120
- :array => [{ key => value }]
121
- })
122
- exp = {
123
- key.to_s => value,
124
- 'hash' => { key.to_s => [value] },
125
- 'array' => [{ key.to_s => value }]
126
- }
127
- assert_equal exp, result
95
+ should "raise an error when given invalid attributes" do
96
+ assert_raises(InvalidError){ @job_class.new(nil) }
97
+ assert_raises(InvalidError){ @job_class.new(@name, :params => Factory.string) }
128
98
  end
129
99
 
130
100
  end
@@ -0,0 +1,235 @@
1
+ require 'assert'
2
+ require 'qs/message_handler'
3
+
4
+ module Qs::MessageHandler
5
+
6
+ class UnitTests < Assert::Context
7
+ desc "Qs::MessageHandler"
8
+ setup do
9
+ @handler_class = Class.new{ include Qs::MessageHandler }
10
+ end
11
+ subject{ @handler_class }
12
+
13
+ should have_imeths :timeout
14
+ should have_imeths :before_callbacks, :after_callbacks
15
+ should have_imeths :before_init_callbacks, :after_init_callbacks
16
+ should have_imeths :before_run_callbacks, :after_run_callbacks
17
+ should have_imeths :before, :after
18
+ should have_imeths :before_init, :after_init
19
+ should have_imeths :before_run, :after_run
20
+ should have_imeths :prepend_before, :prepend_after
21
+ should have_imeths :prepend_before_init, :prepend_after_init
22
+ should have_imeths :prepend_before_run, :prepend_after_run
23
+
24
+ should "allow reading/writing its timeout" do
25
+ assert_nil subject.timeout
26
+ value = Factory.integer
27
+ subject.timeout(value)
28
+ assert_equal value, subject.timeout
29
+ end
30
+
31
+ should "convert timeout values to floats" do
32
+ value = Factory.float.to_s
33
+ subject.timeout(value)
34
+ assert_equal value.to_f, subject.timeout
35
+ end
36
+
37
+ should "return an empty array by default using `before_callbacks`" do
38
+ assert_equal [], subject.before_callbacks
39
+ end
40
+
41
+ should "return an empty array by default using `after_callbacks`" do
42
+ assert_equal [], subject.after_callbacks
43
+ end
44
+
45
+ should "return an empty array by default using `before_init_callbacks`" do
46
+ assert_equal [], subject.before_init_callbacks
47
+ end
48
+
49
+ should "return an empty array by default using `after_init_callbacks`" do
50
+ assert_equal [], subject.after_init_callbacks
51
+ end
52
+
53
+ should "return an empty array by default using `before_run_callbacks`" do
54
+ assert_equal [], subject.before_run_callbacks
55
+ end
56
+
57
+ should "return an empty array by default using `after_run_callbacks`" do
58
+ assert_equal [], subject.after_run_callbacks
59
+ end
60
+
61
+ should "append a block to the before callbacks using `before`" do
62
+ subject.before_callbacks << proc{ Factory.string }
63
+ block = Proc.new{ Factory.string }
64
+ subject.before(&block)
65
+ assert_equal block, subject.before_callbacks.last
66
+ end
67
+
68
+ should "append a block to the after callbacks using `after`" do
69
+ subject.after_callbacks << proc{ Factory.string }
70
+ block = Proc.new{ Factory.string }
71
+ subject.after(&block)
72
+ assert_equal block, subject.after_callbacks.last
73
+ end
74
+
75
+ should "append a block to the before init callbacks using `before_init`" do
76
+ subject.before_init_callbacks << proc{ Factory.string }
77
+ block = Proc.new{ Factory.string }
78
+ subject.before_init(&block)
79
+ assert_equal block, subject.before_init_callbacks.last
80
+ end
81
+
82
+ should "append a block to the after init callbacks using `after_init`" do
83
+ subject.after_init_callbacks << proc{ Factory.string }
84
+ block = Proc.new{ Factory.string }
85
+ subject.after_init(&block)
86
+ assert_equal block, subject.after_init_callbacks.last
87
+ end
88
+
89
+ should "append a block to the before run callbacks using `before_run`" do
90
+ subject.before_run_callbacks << proc{ Factory.string }
91
+ block = Proc.new{ Factory.string }
92
+ subject.before_run(&block)
93
+ assert_equal block, subject.before_run_callbacks.last
94
+ end
95
+
96
+ should "append a block to the after run callbacks using `after_run`" do
97
+ subject.after_run_callbacks << proc{ Factory.string }
98
+ block = Proc.new{ Factory.string }
99
+ subject.after_run(&block)
100
+ assert_equal block, subject.after_run_callbacks.last
101
+ end
102
+
103
+ should "prepend a block to the before callbacks using `prepend_before`" do
104
+ subject.before_callbacks << proc{ Factory.string }
105
+ block = Proc.new{ Factory.string }
106
+ subject.prepend_before(&block)
107
+ assert_equal block, subject.before_callbacks.first
108
+ end
109
+
110
+ should "prepend a block to the after callbacks using `prepend_after`" do
111
+ subject.after_callbacks << proc{ Factory.string }
112
+ block = Proc.new{ Factory.string }
113
+ subject.prepend_after(&block)
114
+ assert_equal block, subject.after_callbacks.first
115
+ end
116
+
117
+ should "prepend a block to the before init callbacks using `prepend_before_init`" do
118
+ subject.before_init_callbacks << proc{ Factory.string }
119
+ block = Proc.new{ Factory.string }
120
+ subject.prepend_before_init(&block)
121
+ assert_equal block, subject.before_init_callbacks.first
122
+ end
123
+
124
+ should "prepend a block to the after init callbacks using `prepend_after_init`" do
125
+ subject.after_init_callbacks << proc{ Factory.string }
126
+ block = Proc.new{ Factory.string }
127
+ subject.prepend_after_init(&block)
128
+ assert_equal block, subject.after_init_callbacks.first
129
+ end
130
+
131
+ should "prepend a block to the before run callbacks using `prepend_before_run`" do
132
+ subject.before_run_callbacks << proc{ Factory.string }
133
+ block = Proc.new{ Factory.string }
134
+ subject.prepend_before_run(&block)
135
+ assert_equal block, subject.before_run_callbacks.first
136
+ end
137
+
138
+ should "prepend a block to the after run callbacks using `prepend_after_run`" do
139
+ subject.after_run_callbacks << proc{ Factory.string }
140
+ block = Proc.new{ Factory.string }
141
+ subject.prepend_after_run(&block)
142
+ assert_equal block, subject.after_run_callbacks.first
143
+ end
144
+
145
+ end
146
+
147
+ class InitTests < UnitTests
148
+ desc "when init"
149
+ setup do
150
+ @runner = FakeRunner.new
151
+ @handler = TestMessageHandler.new(@runner)
152
+ end
153
+ subject{ @handler }
154
+
155
+ should have_imeths :init, :init!, :run, :run!
156
+
157
+ should "know its params and logger" do
158
+ assert_equal @runner.params, subject.public_params
159
+ assert_equal @runner.logger, subject.public_logger
160
+ end
161
+
162
+ should "call `init!` and its before/after init callbacks using `init`" do
163
+ subject.init
164
+ assert_equal 1, subject.first_before_init_call_order
165
+ assert_equal 2, subject.second_before_init_call_order
166
+ assert_equal 3, subject.init_call_order
167
+ assert_equal 4, subject.first_after_init_call_order
168
+ assert_equal 5, subject.second_after_init_call_order
169
+ end
170
+
171
+ should "call `run!` and its before/after run callbacks using `run`" do
172
+ subject.run
173
+ assert_equal 1, subject.first_before_run_call_order
174
+ assert_equal 2, subject.second_before_run_call_order
175
+ assert_equal 3, subject.run_call_order
176
+ assert_equal 4, subject.first_after_run_call_order
177
+ assert_equal 5, subject.second_after_run_call_order
178
+ end
179
+
180
+ should "raise a not implemented error when `run!` by default" do
181
+ assert_raises(NotImplementedError){ @handler_class.new(@runner).run! }
182
+ end
183
+
184
+ end
185
+
186
+ class TestMessageHandler
187
+ include Qs::MessageHandler
188
+
189
+ attr_reader :first_before_init_call_order, :second_before_init_call_order
190
+ attr_reader :first_after_init_call_order, :second_after_init_call_order
191
+ attr_reader :first_before_run_call_order, :second_before_run_call_order
192
+ attr_reader :first_after_run_call_order, :second_after_run_call_order
193
+ attr_reader :init_call_order, :run_call_order
194
+
195
+ before_init{ @first_before_init_call_order = next_call_order }
196
+ before_init{ @second_before_init_call_order = next_call_order }
197
+
198
+ after_init{ @first_after_init_call_order = next_call_order }
199
+ after_init{ @second_after_init_call_order = next_call_order }
200
+
201
+ before_run{ @first_before_run_call_order = next_call_order }
202
+ before_run{ @second_before_run_call_order = next_call_order }
203
+
204
+ after_run{ @first_after_run_call_order = next_call_order }
205
+ after_run{ @second_after_run_call_order = next_call_order }
206
+
207
+ def init!
208
+ @init_call_order = next_call_order
209
+ end
210
+
211
+ def run!
212
+ @run_call_order = next_call_order
213
+ end
214
+
215
+ def public_params; params; end
216
+ def public_logger; logger; end
217
+
218
+ private
219
+
220
+ def next_call_order
221
+ @order ||= 0
222
+ @order += 1
223
+ end
224
+ end
225
+
226
+ class FakeRunner
227
+ attr_accessor :params, :logger
228
+
229
+ def initialize
230
+ @params = Factory.string
231
+ @logger = Factory.string
232
+ end
233
+ end
234
+
235
+ end
@@ -0,0 +1,64 @@
1
+ require 'assert'
2
+ require 'qs/message'
3
+
4
+ class Qs::Message
5
+
6
+ class UnitTests < Assert::Context
7
+ desc "Qs::Message"
8
+ setup do
9
+ @payload_type = Factory.string
10
+ @params = { Factory.string => Factory.string }
11
+ @message_class = Qs::Message
12
+ end
13
+ subject{ @message_class }
14
+
15
+ end
16
+
17
+ class InitTests < UnitTests
18
+ desc "when init"
19
+ setup do
20
+ @message = @message_class.new(@payload_type, :params => @params)
21
+ end
22
+ subject{ @message }
23
+
24
+ should have_readers :payload_type, :params
25
+ should have_imeths :route_id, :route_name
26
+
27
+ should "know its payload type and params" do
28
+ assert_equal @payload_type, subject.payload_type
29
+ assert_equal @params, subject.params
30
+ end
31
+
32
+ should "default its params" do
33
+ message = @message_class.new(@payload_type)
34
+ assert_equal({}, message.params)
35
+ end
36
+
37
+ should "know its route id" do
38
+ route_name = Factory.string
39
+ Assert.stub(subject, :route_name){ route_name }
40
+
41
+ exp = RouteId.new(@payload_type, route_name)
42
+ assert_equal exp, subject.route_id
43
+ end
44
+
45
+ should "raise a not implement error for its route name" do
46
+ assert_raises(NotImplementedError){ subject.route_name }
47
+ end
48
+
49
+ end
50
+
51
+ class RouteIdTests < UnitTests
52
+ desc "RouteId"
53
+ subject{ RouteId }
54
+
55
+ should have_imeths :new
56
+
57
+ should "build a route id given a payload type and a route name" do
58
+ exp = "#{@payload_type}|#{@name}"
59
+ assert_equal exp, subject.new(@payload_type, @name)
60
+ end
61
+
62
+ end
63
+
64
+ end