qs 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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