qs 0.6.1 → 0.7.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.
@@ -1,7 +1,7 @@
1
1
  require 'assert'
2
2
  require 'qs'
3
3
 
4
- require 'test/support/app_daemon'
4
+ require 'test/support/app_queue'
5
5
 
6
6
  class Qs::Queue
7
7
 
@@ -123,8 +123,8 @@ class Qs::CLI
123
123
  end
124
124
 
125
125
  should "output the error with the help" do
126
- expected = "#{@command.inspect} is not a valid command"
127
- assert_includes expected, @kernel_spy.output
126
+ exp = "#{@command.inspect} is not a valid command"
127
+ assert_includes exp, @kernel_spy.output
128
128
  assert_includes "Usage: qs", @kernel_spy.output
129
129
  end
130
130
 
@@ -15,7 +15,7 @@ module Qs::Client
15
15
  ENV['QS_TEST_MODE'] = 'yes'
16
16
  Qs.init
17
17
 
18
- @redis_config = Qs.redis_config
18
+ @redis_connect_hash = Qs.redis_connect_hash
19
19
  @queue = Qs::Queue.new{ name Factory.string }
20
20
  @job_name = Factory.string
21
21
  @job_params = { Factory.string => Factory.string }
@@ -30,12 +30,12 @@ module Qs::Client
30
30
 
31
31
  should "return a qs client using `new`" do
32
32
  ENV.delete('QS_TEST_MODE')
33
- client = subject.new(@redis_config)
33
+ client = subject.new(@redis_connect_hash)
34
34
  assert_instance_of Qs::QsClient, client
35
35
  end
36
36
 
37
37
  should "return a test client using `new` in test mode" do
38
- client = subject.new(@redis_config)
38
+ client = subject.new(@redis_connect_hash)
39
39
  assert_instance_of Qs::TestClient, client
40
40
  end
41
41
 
@@ -43,11 +43,11 @@ module Qs::Client
43
43
 
44
44
  class MixinTests < UnitTests
45
45
  setup do
46
- @client = FakeClient.new(@redis_config)
46
+ @client = FakeClient.new(@redis_connect_hash)
47
47
  end
48
48
  subject{ @client }
49
49
 
50
- should have_readers :redis_config, :redis
50
+ should have_readers :redis_connect_hash, :redis
51
51
  should have_imeths :enqueue, :publish, :publish_as, :push
52
52
  should have_imeths :block_dequeue
53
53
  should have_imeths :append, :prepend
@@ -56,7 +56,7 @@ module Qs::Client
56
56
  should have_imeths :event_subscribers
57
57
 
58
58
  should "know its redis config" do
59
- assert_equal @redis_config, subject.redis_config
59
+ assert_equal @redis_connect_hash, subject.redis_connect_hash
60
60
  end
61
61
 
62
62
  should "not have a redis connection" do
@@ -122,7 +122,7 @@ module Qs::Client
122
122
 
123
123
  class RedisCallTests < MixinTests
124
124
  setup do
125
- @connection_spy = HellaRedis::ConnectionSpy.new(@client.redis_config)
125
+ @connection_spy = HellaRedis::ConnectionSpy.new(@client.redis_connect_hash)
126
126
  Assert.stub(@client, :redis){ @connection_spy }
127
127
 
128
128
  @queue_redis_key = Factory.string
@@ -284,13 +284,13 @@ module Qs::Client
284
284
  @connection_spy = HellaRedis::ConnectionSpy.new(*args)
285
285
  end
286
286
 
287
- @client = @client_class.new(@redis_config)
287
+ @client = @client_class.new(@redis_connect_hash)
288
288
  end
289
289
  subject{ @client }
290
290
 
291
291
  should "build a redis connection" do
292
292
  assert_not_nil @connection_spy
293
- assert_equal @connection_spy.config, subject.redis_config
293
+ assert_equal @connection_spy.config, subject.redis_connect_hash
294
294
  assert_equal @connection_spy, subject.redis
295
295
  end
296
296
 
@@ -338,7 +338,7 @@ module Qs::Client
338
338
  @serialized_job = nil
339
339
  Assert.stub(Qs::Payload, :serialize){ |job| @serialized_job = job }
340
340
 
341
- @client = @client_class.new(@redis_config)
341
+ @client = @client_class.new(@redis_connect_hash)
342
342
  end
343
343
  subject{ @client }
344
344
 
@@ -347,7 +347,7 @@ module Qs::Client
347
347
 
348
348
  should "build a redis connection spy" do
349
349
  assert_instance_of HellaRedis::ConnectionSpy, subject.redis
350
- assert_equal @redis_config, subject.redis.config
350
+ assert_equal @redis_connect_hash, subject.redis.config
351
351
  end
352
352
 
353
353
  should "default its pushed items" do
@@ -15,7 +15,7 @@ class Qs::ConfigFile
15
15
  should have_imeths :run
16
16
 
17
17
  should "know its daemon" do
18
- assert_instance_of AppDaemon, subject.daemon
18
+ assert_instance_of ConfigFileTestDaemon, subject.daemon
19
19
  end
20
20
 
21
21
  should "define constants in the file at the top-level binding" do
@@ -35,7 +35,7 @@ class Qs::ConfigFile
35
35
  assert_nothing_raised do
36
36
  config_file = Qs::ConfigFile.new(file_path)
37
37
  end
38
- assert_instance_of AppDaemon, config_file.daemon
38
+ assert_instance_of ConfigFileTestDaemon, config_file.daemon
39
39
  end
40
40
 
41
41
  should "raise no config file error when the file doesn't exist" do
@@ -13,23 +13,27 @@ class Qs::DaemonData
13
13
  ENV['QS_PROCESS_LABEL'] = Factory.string
14
14
 
15
15
  @current_env_debug = ENV['QS_DEBUG']
16
- ENV['QS_DEBUG'] = Factory.string
16
+ ENV.delete('QS_DEBUG')
17
+
18
+ @queues = Factory.integer(3).times.map do
19
+ Qs::Queue.new{ name Factory.string }
20
+ end
17
21
 
18
- @routes = (0..Factory.integer(3)).map do
22
+ @routes = Factory.integer(3).times.map do
19
23
  Qs::Route.new(Factory.string, TestHandler.to_s).tap(&:validate!)
20
24
  end
21
25
 
22
26
  @config_hash = {
23
27
  :name => Factory.string,
24
28
  :pid_file => Factory.file_path,
29
+ :shutdown_timeout => Factory.integer,
25
30
  :worker_class => Class.new,
26
31
  :worker_params => { Factory.string => Factory.string },
27
32
  :num_workers => Factory.integer,
33
+ :error_procs => Factory.integer(3).times.map{ proc{} },
28
34
  :logger => Factory.string,
35
+ :queues => @queues,
29
36
  :verbose_logging => Factory.boolean,
30
- :shutdown_timeout => Factory.integer,
31
- :error_procs => [ proc{ Factory.string } ],
32
- :queue_redis_keys => Factory.integer(3).times.map{ Factory.string },
33
37
  :routes => @routes
34
38
  }
35
39
  @daemon_data = Qs::DaemonData.new(@config_hash)
@@ -40,31 +44,40 @@ class Qs::DaemonData
40
44
  end
41
45
  subject{ @daemon_data }
42
46
 
43
- should have_readers :name, :process_label, :pid_file
47
+ should have_readers :name, :pid_file, :shutdown_timeout
44
48
  should have_readers :worker_class, :worker_params, :num_workers
45
- should have_readers :debug, :logger, :dwp_logger, :verbose_logging
46
- should have_readers :shutdown_timeout
47
- should have_readers :error_procs, :queue_redis_keys, :routes
49
+ should have_readers :error_procs, :logger, :queue_redis_keys
50
+ should have_readers :verbose_logging
51
+ should have_readers :debug, :dwp_logger, :routes, :process_label
48
52
  should have_imeths :route_for
49
53
 
50
- should "know its attributes" do
54
+ should "know its attrs" do
51
55
  h = @config_hash
52
- assert_equal h[:name], subject.name
53
- assert_equal h[:pid_file], subject.pid_file
54
- assert_equal h[:worker_class], subject.worker_class
55
- assert_equal h[:worker_params], subject.worker_params
56
- assert_equal h[:num_workers], subject.num_workers
57
- assert_equal h[:logger], subject.logger
58
- assert_equal h[:verbose_logging], subject.verbose_logging
56
+ assert_equal h[:name], subject.name
57
+ assert_equal h[:pid_file], subject.pid_file
58
+
59
59
  assert_equal h[:shutdown_timeout], subject.shutdown_timeout
60
- assert_equal h[:error_procs], subject.error_procs
61
- assert_equal h[:queue_redis_keys], subject.queue_redis_keys
60
+
61
+ assert_equal h[:worker_class], subject.worker_class
62
+ assert_equal h[:worker_params], subject.worker_params
63
+ assert_equal h[:num_workers], subject.num_workers
64
+ assert_equal h[:error_procs], subject.error_procs
65
+ assert_equal h[:logger], subject.logger
66
+
67
+ exp = @queues.map(&:redis_key)
68
+ assert_equal exp, subject.queue_redis_keys
69
+
70
+ assert_equal h[:verbose_logging], subject.verbose_logging
71
+
72
+ assert_false subject.debug
73
+ assert_nil subject.dwp_logger
74
+
75
+ exp = @routes.inject({}){ |h, r| h.merge(r.id => r) }
76
+ assert_equal exp, subject.routes
62
77
  end
63
78
 
64
- should "use process label env var if set" do
65
- ENV['QS_PROCESS_LABEL'] = Factory.string
66
- daemon_data = Qs::DaemonData.new(@config_hash)
67
- assert_equal ENV['QS_PROCESS_LABEL'], daemon_data.process_label
79
+ should "know its process label" do
80
+ assert_equal ENV['QS_PROCESS_LABEL'], subject.process_label
68
81
 
69
82
  ENV['QS_PROCESS_LABEL'] = ""
70
83
  daemon_data = Qs::DaemonData.new(@config_hash)
@@ -75,32 +88,16 @@ class Qs::DaemonData
75
88
  assert_equal @config_hash[:name], daemon_data.process_label
76
89
  end
77
90
 
78
- should "use debug env var if set" do
91
+ should "use the debug env var if set" do
79
92
  ENV['QS_DEBUG'] = Factory.string
80
93
  daemon_data = Qs::DaemonData.new(@config_hash)
81
94
  assert_true daemon_data.debug
82
- assert_equal @config_hash[:logger], daemon_data.dwp_logger
83
-
84
- ENV['QS_DEBUG'] = ""
85
- daemon_data = Qs::DaemonData.new(@config_hash)
86
- assert_false daemon_data.debug
87
- assert_nil daemon_data.dwp_logger
88
-
89
- ENV.delete('QS_DEBUG')
90
- daemon_data = Qs::DaemonData.new(@config_hash)
91
- assert_false daemon_data.debug
92
- assert_nil daemon_data.dwp_logger
95
+ assert_equal daemon_data.logger, daemon_data.dwp_logger
93
96
  end
94
97
 
95
- should "build a routes lookup hash" do
96
- expected = @routes.inject({}){ |h, r| h.merge(r.id => r) }
97
- assert_equal expected, subject.routes
98
- end
99
-
100
- should "allow looking up a route using `route_for`" do
101
- exp_route = @routes.choice
102
- route = subject.route_for(exp_route.id)
103
- assert_equal exp_route, route
98
+ should "look up a route using `route_for`" do
99
+ exp_route = @routes.sample
100
+ assert_equal exp_route, subject.route_for(exp_route.id)
104
101
  end
105
102
 
106
103
  should "raise a not found error using `route_for` with an invalid name" do
@@ -109,18 +106,26 @@ class Qs::DaemonData
109
106
  end
110
107
  end
111
108
 
112
- should "default its attributes when they aren't provided" do
109
+ should "default its attrs when they aren't provided" do
113
110
  daemon_data = Qs::DaemonData.new
114
111
  assert_nil daemon_data.name
115
112
  assert_nil daemon_data.pid_file
113
+ assert_nil daemon_data.shutdown_timeout
114
+
116
115
  assert_nil daemon_data.worker_class
117
116
  assert_equal({}, daemon_data.worker_params)
118
117
  assert_nil daemon_data.num_workers
119
- assert_nil daemon_data.logger
120
- assert_false daemon_data.verbose_logging
121
- assert_nil daemon_data.shutdown_timeout
118
+
122
119
  assert_equal [], daemon_data.error_procs
120
+
121
+ assert_nil daemon_data.logger
123
122
  assert_equal [], daemon_data.queue_redis_keys
123
+
124
+ assert_false daemon_data.verbose_logging
125
+
126
+ assert_false daemon_data.debug
127
+ assert_nil daemon_data.dwp_logger
128
+
124
129
  assert_equal({}, daemon_data.routes)
125
130
  end
126
131
 
@@ -3,9 +3,9 @@ require 'qs/daemon'
3
3
 
4
4
  require 'dat-worker-pool/worker_pool_spy'
5
5
  require 'much-plugin'
6
- require 'ns-options/assert_macros'
7
6
  require 'thread'
8
7
  require 'qs/client'
8
+ require 'qs/logger'
9
9
  require 'qs/queue'
10
10
  require 'qs/queue_item'
11
11
  require 'test/support/client_spy'
@@ -19,110 +19,80 @@ module Qs::Daemon
19
19
  end
20
20
  subject{ @daemon_class }
21
21
 
22
- should have_imeths :configuration
23
- should have_imeths :name, :pid_file
24
- should have_imeths :worker_class, :worker_params
25
- should have_imeths :num_workers, :workers
26
- should have_imeths :verbose_logging, :logger
27
- should have_imeths :shutdown_timeout
28
- should have_imeths :init, :error, :queue, :queues
22
+ should have_imeths :config
23
+ should have_imeths :name, :pid_file, :shutdown_timeout
24
+ should have_imeths :worker_class, :worker_params, :num_workers, :workers
25
+ should have_imeths :init, :init_procs, :error, :error_procs
26
+ should have_imeths :logger, :queue, :queues
27
+ should have_imeths :verbose_logging
29
28
 
30
29
  should "use much-plugin" do
31
30
  assert_includes MuchPlugin, Qs::Daemon
32
31
  end
33
32
 
34
- should "know its configuration" do
35
- config = subject.configuration
36
- assert_instance_of Configuration, config
37
- assert_same config, subject.configuration
38
- end
33
+ should "allow setting its config values" do
34
+ config = subject.config
39
35
 
40
- should "allow reading/writing its configuration name" do
41
- new_name = Factory.string
42
- subject.name(new_name)
43
- assert_equal new_name, subject.configuration.name
44
- assert_equal new_name, subject.name
45
- end
36
+ exp = Factory.string
37
+ subject.name exp
38
+ assert_equal exp, config.name
46
39
 
47
- should "allow reading/writing its configuration pid file" do
48
- new_pid_file = Factory.string
49
- subject.pid_file(new_pid_file)
50
- expected = Pathname.new(new_pid_file)
51
- assert_equal expected, subject.configuration.pid_file
52
- assert_equal expected, subject.pid_file
53
- end
40
+ exp = Factory.file_path
41
+ subject.pid_file exp
42
+ assert_equal exp, config.pid_file
54
43
 
55
- should "allow reading/writing its configuration worker class" do
56
- new_worker_class = Class.new
57
- subject.worker_class(new_worker_class)
58
- assert_equal new_worker_class, subject.configuration.worker_class
59
- assert_equal new_worker_class, subject.worker_class
60
- end
44
+ exp = Factory.integer
45
+ subject.shutdown_timeout exp
46
+ assert_equal exp, config.shutdown_timeout
61
47
 
62
- should "allow reading/writing its configuration worker params" do
63
- new_worker_params = { Factory.string => Factory.string }
64
- subject.worker_params(new_worker_params)
65
- assert_equal new_worker_params, subject.configuration.worker_params
66
- assert_equal new_worker_params, subject.worker_params
67
- end
48
+ exp = Class.new
49
+ subject.worker_class exp
50
+ assert_equal exp, subject.config.worker_class
68
51
 
69
- should "allow reading/writing its configuration num workers" do
70
- new_num_workers = Factory.integer
71
- subject.num_workers(new_num_workers)
72
- assert_equal new_num_workers, subject.configuration.num_workers
73
- assert_equal new_num_workers, subject.num_workers
74
- end
52
+ exp = { Factory.string => Factory.string }
53
+ subject.worker_params exp
54
+ assert_equal exp, subject.config.worker_params
75
55
 
76
- should "alias workers as num workers" do
77
- new_workers = Factory.integer
78
- subject.workers(new_workers)
79
- assert_equal new_workers, subject.configuration.num_workers
80
- assert_equal new_workers, subject.workers
81
- end
56
+ exp = Factory.integer
57
+ subject.num_workers(exp)
58
+ assert_equal exp, subject.config.num_workers
59
+ assert_equal exp, subject.workers
82
60
 
83
- should "allow reading/writing its configuration verbose logging" do
84
- new_verbose = Factory.boolean
85
- subject.verbose_logging(new_verbose)
86
- assert_equal new_verbose, subject.configuration.verbose_logging
87
- assert_equal new_verbose, subject.verbose_logging
88
- end
61
+ exp = proc{ Factory.string }
62
+ assert_equal 0, config.init_procs.size
63
+ subject.init(&exp)
64
+ assert_equal 1, config.init_procs.size
65
+ assert_equal exp, config.init_procs.first
89
66
 
90
- should "allow reading/writing its configuration logger" do
91
- new_logger = Factory.string
92
- subject.logger(new_logger)
93
- assert_equal new_logger, subject.configuration.logger
94
- assert_equal new_logger, subject.logger
95
- end
67
+ exp = proc{ Factory.string }
68
+ assert_equal 0, config.error_procs.size
69
+ subject.error(&exp)
70
+ assert_equal 1, config.error_procs.size
71
+ assert_equal exp, config.error_procs.first
96
72
 
97
- should "allow reading/writing its configuration shutdown timeout" do
98
- new_shutdown_timeout = Factory.integer
99
- subject.shutdown_timeout(new_shutdown_timeout)
100
- assert_equal new_shutdown_timeout, subject.configuration.shutdown_timeout
101
- assert_equal new_shutdown_timeout, subject.shutdown_timeout
102
- end
73
+ exp = Logger.new(STDOUT)
74
+ subject.logger exp
75
+ assert_equal exp, config.logger
103
76
 
104
- should "allow adding init procs to its configuration" do
105
- new_init_proc = proc{ Factory.string }
106
- subject.init(&new_init_proc)
107
- assert_includes new_init_proc, subject.configuration.init_procs
108
- end
77
+ exp = Factory.string
78
+ subject.queue(exp)
79
+ assert_equal [exp], subject.config.queues
109
80
 
110
- should "allow adding error procs to its configuration" do
111
- new_error_proc = proc{ Factory.string }
112
- subject.error(&new_error_proc)
113
- assert_includes new_error_proc, subject.configuration.error_procs
81
+ exp = Factory.boolean
82
+ subject.verbose_logging exp
83
+ assert_equal exp, config.verbose_logging
114
84
  end
115
85
 
116
- should "allow adding queues to its configuration" do
117
- new_queue = Factory.string
118
- subject.queue(new_queue)
119
- assert_includes new_queue, subject.configuration.queues
86
+ should "demeter its config values that aren't directly set" do
87
+ assert_equal subject.config.init_procs, subject.init_procs
88
+ assert_equal subject.config.error_procs, subject.error_procs
120
89
  end
121
90
 
122
- should "allow reading its configuration queues" do
123
- new_queue = Factory.string
124
- subject.queue(new_queue)
125
- assert_equal [new_queue], subject.queues
91
+ should "know its queues" do
92
+ assert_equal [], subject.queues
93
+ exp = Factory.string
94
+ subject.queue(exp)
95
+ assert_equal [exp], subject.queues
126
96
  end
127
97
 
128
98
  end
@@ -134,10 +104,10 @@ module Qs::Daemon
134
104
 
135
105
  @daemon_class.name Factory.string
136
106
  @daemon_class.pid_file Factory.file_path
107
+ @daemon_class.shutdown_timeout Factory.integer
137
108
  @daemon_class.worker_params(Factory.string => Factory.string)
138
- @daemon_class.workers Factory.integer
109
+ @daemon_class.num_workers Factory.integer
139
110
  @daemon_class.verbose_logging Factory.boolean
140
- @daemon_class.shutdown_timeout Factory.integer
141
111
  @daemon_class.error{ Factory.string }
142
112
 
143
113
  @queue = Qs::Queue.new do
@@ -175,71 +145,65 @@ module Qs::Daemon
175
145
  end
176
146
  subject{ @daemon }
177
147
 
178
- should have_readers :daemon_data, :logger
179
- should have_readers :signals_redis_key, :queue_redis_keys
148
+ should have_readers :daemon_data, :signals_redis_key
180
149
  should have_imeths :name, :process_label, :pid_file
150
+ should have_imeths :logger, :queue_redis_keys
181
151
  should have_imeths :running?
182
152
  should have_imeths :start, :stop, :halt
183
153
 
184
- should "validate its configuration" do
185
- assert_true @daemon_class.configuration.valid?
154
+ should "have validated its config" do
155
+ assert_true @daemon_class.config.valid?
186
156
  end
187
157
 
188
- should "init Qs" do
158
+ should "have initialized Qs" do
189
159
  assert_true @qs_init_called
190
160
  end
191
161
 
192
162
  should "know its daemon data" do
193
- configuration = @daemon_class.configuration
194
- data = subject.daemon_data
163
+ config = @daemon_class.config
164
+ data = subject.daemon_data
195
165
 
196
166
  assert_instance_of Qs::DaemonData, data
197
- assert_equal configuration.name, data.name
198
- assert_equal configuration.pid_file, data.pid_file
199
- assert_equal configuration.worker_class, data.worker_class
200
- assert_equal configuration.worker_params, data.worker_params
201
- assert_equal configuration.num_workers, data.num_workers
202
167
 
203
- assert_equal configuration.verbose_logging, data.verbose_logging
204
- assert_equal configuration.shutdown_timeout, data.shutdown_timeout
205
- assert_equal configuration.error_procs, data.error_procs
168
+ assert_equal config.name, data.name
169
+ assert_equal config.pid_file, data.pid_file
170
+ assert_equal config.shutdown_timeout, data.shutdown_timeout
171
+ assert_equal config.worker_class, data.worker_class
172
+ assert_equal config.worker_params, data.worker_params
173
+ assert_equal config.num_workers, data.num_workers
174
+ assert_equal config.error_procs, data.error_procs
206
175
 
207
- assert_equal [@queue.redis_key], data.queue_redis_keys
208
- assert_equal configuration.routes, data.routes.values
176
+ assert_instance_of config.logger.class, data.logger
209
177
 
210
- assert_instance_of configuration.logger.class, data.logger
211
- end
178
+ assert_equal config.queues.size, data.queue_redis_keys.size
179
+ assert_equal config.verbose_logging, data.verbose_logging
212
180
 
213
- should "know its signal and queues redis keys" do
214
- data = subject.daemon_data
215
- expected = "signals:#{data.name}-#{Socket.gethostname}-#{::Process.pid}"
216
- assert_equal expected, subject.signals_redis_key
217
- assert_equal data.queue_redis_keys, subject.queue_redis_keys
181
+ assert_equal config.routes, data.routes.values
218
182
  end
219
183
 
220
- should "know its name, process label and pid file" do
184
+ should "know its signals redis keys" do
221
185
  data = subject.daemon_data
222
- assert_equal data.name, subject.name
223
- assert_equal data.process_label, subject.process_label
224
- assert_equal data.pid_file, subject.pid_file
186
+ exp = "signals:#{data.name}-#{Socket.gethostname}-#{::Process.pid}"
187
+ assert_equal exp, subject.signals_redis_key
225
188
  end
226
189
 
227
190
  should "build a client" do
228
191
  assert_not_nil @client_spy
229
- exp = Qs.redis_config.merge({
192
+ exp = Qs.redis_connect_hash.merge({
230
193
  :timeout => 1,
231
194
  :size => subject.daemon_data.num_workers + 1
232
195
  })
233
- assert_equal exp, @client_spy.redis_config
196
+ assert_equal exp, @client_spy.redis_connect_hash
234
197
  end
235
198
 
236
- should "build a worker pool" do
199
+ should "build a dat-worker-pool worker pool" do
237
200
  data = subject.daemon_data
238
201
 
239
202
  assert_not_nil @wp_spy
240
203
  assert_equal data.worker_class, @wp_spy.worker_class
241
204
  assert_equal data.dwp_logger, @wp_spy.logger
242
205
  assert_equal data.num_workers, @wp_spy.num_workers
206
+
243
207
  exp = data.worker_params.merge({
244
208
  :qs_daemon_data => data,
245
209
  :qs_client => @client_spy,
@@ -250,6 +214,16 @@ module Qs::Daemon
250
214
  assert_false @wp_spy.start_called
251
215
  end
252
216
 
217
+ should "demeter its daemon data" do
218
+ data = subject.daemon_data
219
+
220
+ assert_equal data.name, subject.name
221
+ assert_equal data.process_label, subject.process_label
222
+ assert_equal data.pid_file, subject.pid_file
223
+ assert_equal data.logger, subject.logger
224
+ assert_equal data.queue_redis_keys, subject.queue_redis_keys
225
+ end
226
+
253
227
  should "not be running by default" do
254
228
  assert_false subject.running?
255
229
  end
@@ -260,7 +234,7 @@ module Qs::Daemon
260
234
  desc "and started"
261
235
  setup do
262
236
  @thread = @daemon.start
263
- @thread.join 0.1
237
+ @thread.join(JOIN_SECONDS)
264
238
  end
265
239
 
266
240
  should "ping redis" do
@@ -296,14 +270,14 @@ module Qs::Daemon
296
270
 
297
271
  @daemon = @daemon_class.new
298
272
  @thread = @daemon.start
273
+ @thread.join(JOIN_SECONDS)
299
274
  end
300
275
  subject{ @daemon }
301
276
 
302
277
  should "sleep its thread and not add work to its worker pool" do
303
- @thread.join(0.1)
304
278
  assert_equal 'sleep', @thread.status
305
279
  @client_spy.append(@queue.redis_key, Factory.string)
306
- @thread.join(0.1)
280
+ @thread.join(JOIN_SECONDS)
307
281
  assert_empty @wp_spy.work_items
308
282
  end
309
283
 
@@ -314,17 +288,21 @@ module Qs::Daemon
314
288
  setup do
315
289
  @daemon = @daemon_class.new
316
290
  @thread = @daemon.start
291
+ @thread.join(JOIN_SECONDS)
317
292
 
318
293
  @encoded_payload = Factory.string
319
294
  @client_spy.append(@queue.redis_key, @encoded_payload)
295
+ @thread.join(JOIN_SECONDS)
320
296
  end
321
297
  subject{ @daemon }
322
298
 
323
299
  should "call dequeue on its client and add work to the worker pool" do
324
300
  call = @client_spy.calls.last
325
301
  assert_equal :block_dequeue, call.command
302
+
326
303
  exp = [subject.signals_redis_key, subject.queue_redis_keys, 0].flatten
327
304
  assert_equal exp, call.args
305
+
328
306
  exp = Qs::QueueItem.new(@queue.redis_key, @encoded_payload)
329
307
  assert_equal exp, @wp_spy.work_items.first
330
308
  end
@@ -334,25 +312,35 @@ module Qs::Daemon
334
312
  class RunningWithErrorWhileDequeuingTests < InitSetupTests
335
313
  desc "running with an error while dequeueing"
336
314
  setup do
337
- @daemon = @daemon_class.new
338
- @thread = @daemon.start
315
+ @mutex = Mutex.new
316
+ @cond_var = ConditionVariable.new
317
+ @daemon = @daemon_class.new
339
318
 
340
319
  @block_dequeue_calls = 0
341
320
  Assert.stub(@client_spy, :block_dequeue) do
342
321
  @block_dequeue_calls += 1
322
+ @mutex.synchronize{ @cond_var.wait(@mutex) }
343
323
  raise RuntimeError
344
324
  end
345
- # cause the daemon to loop, its sleeping on the original block_dequeue
346
- # call that happened before the stub
347
- @client_spy.append(@queue.redis_key, Factory.string)
348
- @thread.join(0.1)
325
+
326
+ @thread = @daemon.start
327
+ @thread.join(JOIN_SECONDS)
328
+ end
329
+ teardown do
330
+ Assert.unstub(@client_spy, :block_dequeue)
331
+ @mutex.synchronize{ @cond_var.broadcast }
349
332
  end
350
333
  subject{ @daemon }
351
334
 
352
335
  should "not cause the thread to exit" do
353
336
  assert_true @thread.alive?
354
337
  assert_equal 1, @block_dequeue_calls
355
- @thread.join(1)
338
+
339
+ # the daemon is sleeping on the original block_dequeue, cause it to
340
+ # dequeue (and error)
341
+ @mutex.synchronize{ @cond_var.broadcast }
342
+ @thread.join(Qs::Daemon::FETCH_ERR_SLEEP_TIME + JOIN_SECONDS)
343
+
356
344
  assert_true @thread.alive?
357
345
  assert_equal 2, @block_dequeue_calls
358
346
  end
@@ -370,6 +358,7 @@ module Qs::Daemon
370
358
  Assert.stub(@daemon.queue_redis_keys, :shuffle){ @shuffled_keys }
371
359
 
372
360
  @thread = @daemon.start
361
+ @thread.join(JOIN_SECONDS)
373
362
  end
374
363
  subject{ @daemon }
375
364
 
@@ -419,6 +408,7 @@ module Qs::Daemon
419
408
  @wp_worker_available = false
420
409
  @daemon = @daemon_class.new
421
410
  @thread = @daemon.start
411
+ @thread.join(JOIN_SECONDS)
422
412
  @daemon.stop(true)
423
413
  end
424
414
  subject{ @daemon }
@@ -466,6 +456,7 @@ module Qs::Daemon
466
456
  @wp_worker_available = false
467
457
  @daemon = @daemon_class.new
468
458
  @thread = @daemon.start
459
+ @thread.join(JOIN_SECONDS)
469
460
  @daemon.halt(true)
470
461
  end
471
462
  subject{ @daemon }
@@ -486,7 +477,7 @@ module Qs::Daemon
486
477
  # call that happened before the stub
487
478
  @queue_item = Qs::QueueItem.new(@queue.redis_key, Factory.string)
488
479
  @client_spy.append(@queue_item.queue_redis_key, @queue_item.encoded_payload)
489
- @thread.join
480
+ @thread.join(JOIN_SECONDS)
490
481
  end
491
482
 
492
483
  should "shutdown the worker pool" do
@@ -511,10 +502,8 @@ module Qs::Daemon
511
502
 
512
503
  end
513
504
 
514
- class ConfigurationTests < UnitTests
515
- include NsOptions::AssertMacros
516
-
517
- desc "Configuration"
505
+ class ConfigTests < UnitTests
506
+ desc "Config"
518
507
  setup do
519
508
  @queue = Qs::Queue.new do
520
509
  name Factory.string
@@ -522,85 +511,106 @@ module Qs::Daemon
522
511
  job 'test', 'TestHandler'
523
512
  end
524
513
 
525
- @configuration = Configuration.new.tap do |c|
526
- c.name Factory.string
527
- c.queues << @queue
528
- end
514
+ @config_class = Config
515
+ @config = Config.new
529
516
  end
530
- subject{ @configuration }
531
-
532
- should have_options :name, :pid_file
533
- should have_options :num_workers
534
- should have_options :verbose_logging, :logger
535
- should have_options :shutdown_timeout
536
- should have_accessors :init_procs, :error_procs
537
- should have_accessors :worker_class, :worker_params
538
- should have_accessors :queues
539
- should have_imeths :routes
540
- should have_imeths :to_hash
541
- should have_imeths :valid?, :validate!
542
-
543
- should "be an ns-options proxy" do
544
- assert_includes NsOptions::Proxy, subject.class
545
- end
546
-
547
- should "default its options and attrs" do
548
- config = Configuration.new
549
- assert_nil config.name
550
- assert_nil config.pid_file
551
- assert_equal 4, config.num_workers
552
- assert_true config.verbose_logging
553
- assert_instance_of Qs::NullLogger, config.logger
554
- assert_nil subject.shutdown_timeout
517
+ subject{ @config }
555
518
 
556
- assert_equal [], config.init_procs
557
- assert_equal [], config.error_procs
558
- assert_equal DefaultWorker, config.worker_class
559
- assert_nil config.worker_params
560
- assert_equal [], config.queues
561
- assert_equal [], config.routes
519
+ should have_accessors :name, :pid_file, :shutdown_timeout
520
+ should have_accessors :worker_class, :worker_params, :num_workers
521
+ should have_accessors :init_procs, :error_procs, :logger, :queues
522
+ should have_accessors :verbose_logging
523
+ should have_imeths :routes, :valid?, :validate!
524
+
525
+ should "know its default attr values" do
526
+ assert_equal 4, @config_class::DEFAULT_NUM_WORKERS
562
527
  end
563
528
 
564
- should "not be valid by default" do
565
- assert_false subject.valid?
529
+ should "default its attrs" do
530
+ assert_nil subject.name
531
+ assert_nil subject.pid_file
532
+ assert_nil subject.shutdown_timeout
533
+
534
+ assert_equal DefaultWorker, subject.worker_class
535
+
536
+ assert_nil subject.worker_params
537
+
538
+ exp = @config_class::DEFAULT_NUM_WORKERS
539
+ assert_equal exp, subject.num_workers
540
+
541
+ assert_equal [], subject.init_procs
542
+ assert_equal [], subject.error_procs
543
+
544
+ assert_instance_of Qs::NullLogger, subject.logger
545
+
546
+ assert_equal [], subject.queues
547
+ assert_equal true, subject.verbose_logging
566
548
  end
567
549
 
568
550
  should "know its routes" do
569
- assert_equal subject.queues.map(&:routes).flatten, subject.routes
551
+ exp = subject.queues.map(&:routes).flatten
552
+ assert_equal exp, subject.routes
570
553
  end
571
554
 
572
- should "include some attrs (not just the options) in its hash" do
573
- config_hash = subject.to_hash
574
-
575
- assert_equal subject.error_procs, config_hash[:error_procs]
576
- assert_equal subject.worker_class, config_hash[:worker_class]
577
- assert_equal subject.worker_params, config_hash[:worker_params]
578
- assert_equal subject.routes, config_hash[:routes]
555
+ should "not be valid until validate! has been run" do
556
+ assert_false subject.valid?
579
557
 
580
- exp = subject.queues.map(&:redis_key)
581
- assert_equal exp, config_hash[:queue_redis_keys]
582
- end
558
+ subject.name = Factory.string
559
+ subject.queues << @queue
583
560
 
584
- should "call its init procs when validated" do
585
- called = false
586
- subject.init_procs << proc{ called = true }
587
561
  subject.validate!
588
- assert_true called
562
+ assert_true subject.valid?
589
563
  end
590
564
 
591
- should "ensure its required options have been set when validated" do
565
+ should "complain if validating and its name is nil or it has no queues" do
592
566
  subject.name = nil
567
+ subject.queues << @queue
593
568
  assert_raises(InvalidError){ subject.validate! }
594
- subject.name = Factory.string
595
569
 
596
- subject.queues = []
570
+ subject.name = Factory.string
571
+ subject.queues.clear
597
572
  assert_raises(InvalidError){ subject.validate! }
573
+ end
574
+
575
+ should "complain if validating and its worker class isn't a Worker" do
576
+ subject.name = Factory.string
598
577
  subject.queues << @queue
599
578
 
600
- assert_nothing_raised{ subject.validate! }
579
+ subject.worker_class = Module.new
580
+ assert_raises(InvalidError){ subject.validate! }
581
+
582
+ subject.worker_class = Class.new
583
+ assert_raises(InvalidError){ subject.validate! }
584
+ end
585
+
586
+ end
587
+
588
+ class ValidationTests < ConfigTests
589
+ desc "when successfully validated"
590
+ setup do
591
+ @config = Config.new.tap do |c|
592
+ c.name = Factory.string
593
+ c.queues << @queue
594
+ end
595
+
596
+ @initialized = false
597
+ @config.init_procs << proc{ @initialized = true }
598
+
599
+ @other_initialized = false
600
+ @config.init_procs << proc{ @other_initialized = true }
601
+ end
602
+
603
+ should "call its init procs" do
604
+ assert_equal false, @initialized
605
+ assert_equal false, @other_initialized
606
+
607
+ subject.validate!
608
+
609
+ assert_equal true, @initialized
610
+ assert_equal true, @other_initialized
601
611
  end
602
612
 
603
- should "validate its routes when validated" do
613
+ should "validate its routes" do
604
614
  subject.routes.each{ |route| assert_nil route.handler_class }
605
615
  subject.validate!
606
616
  subject.routes.each{ |route| assert_not_nil route.handler_class }
@@ -614,12 +624,6 @@ module Qs::Daemon
614
624
  assert_raises(InvalidError){ subject.validate! }
615
625
  end
616
626
 
617
- should "be valid after being validated" do
618
- assert_false subject.valid?
619
- subject.validate!
620
- assert_true subject.valid?
621
- end
622
-
623
627
  should "only be able to be validated once" do
624
628
  called = 0
625
629
  subject.init_procs << proc{ called += 1 }
@@ -631,6 +635,27 @@ module Qs::Daemon
631
635
 
632
636
  end
633
637
 
638
+ class WorkerAvailableTests < UnitTests
639
+ desc "WorkerAvailable"
640
+ setup do
641
+ @worker_available = WorkerAvailable.new
642
+ end
643
+ subject{ @worker_available }
644
+
645
+ should have_imeths :wait, :signal
646
+
647
+ should "allow waiting and signalling" do
648
+ thread = Thread.new{ subject.wait }
649
+ thread.join(JOIN_SECONDS)
650
+ assert_equal 'sleep', thread.status
651
+
652
+ subject.signal
653
+ thread.join(JOIN_SECONDS)
654
+ assert_equal false, thread.status # dead, done running
655
+ end
656
+
657
+ end
658
+
634
659
  class StateTests < UnitTests
635
660
  desc "State"
636
661
  setup do
@@ -664,24 +689,6 @@ module Qs::Daemon
664
689
 
665
690
  end
666
691
 
667
- class WorkerAvailableTests < UnitTests
668
- desc "WorkerAvailable"
669
- setup do
670
- @worker_available = WorkerAvailable.new
671
- end
672
- subject{ @worker_available }
673
-
674
- should have_imeths :wait, :signal
675
-
676
- should "allow waiting and signalling" do
677
- thread = Thread.new{ subject.wait }
678
- assert_equal 'sleep', thread.status
679
- subject.signal
680
- assert_equal false, thread.status # dead, done running
681
- end
682
-
683
- end
684
-
685
692
  TestHandler = Class.new
686
693
 
687
694
  end