background_queue 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +48 -0
  4. data/Gemfile +19 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +69 -0
  7. data/Rakefile +42 -0
  8. data/TODO +2 -0
  9. data/VERSION +1 -0
  10. data/background_queue.gemspec +158 -0
  11. data/bin/bg_queue +26 -0
  12. data/lib/background_queue.rb +8 -0
  13. data/lib/background_queue/client.rb +96 -0
  14. data/lib/background_queue/client_lib/command.rb +36 -0
  15. data/lib/background_queue/client_lib/config.rb +109 -0
  16. data/lib/background_queue/client_lib/connection.rb +105 -0
  17. data/lib/background_queue/client_lib/job_handle.rb +19 -0
  18. data/lib/background_queue/command.rb +49 -0
  19. data/lib/background_queue/config.rb +118 -0
  20. data/lib/background_queue/server_lib/balanced_queue.rb +108 -0
  21. data/lib/background_queue/server_lib/config.rb +339 -0
  22. data/lib/background_queue/server_lib/event_connection.rb +133 -0
  23. data/lib/background_queue/server_lib/event_server.rb +35 -0
  24. data/lib/background_queue/server_lib/job.rb +252 -0
  25. data/lib/background_queue/server_lib/job_registry.rb +30 -0
  26. data/lib/background_queue/server_lib/lru.rb +193 -0
  27. data/lib/background_queue/server_lib/owner.rb +54 -0
  28. data/lib/background_queue/server_lib/priority_queue.rb +156 -0
  29. data/lib/background_queue/server_lib/queue_registry.rb +123 -0
  30. data/lib/background_queue/server_lib/server.rb +314 -0
  31. data/lib/background_queue/server_lib/sorted_workers.rb +52 -0
  32. data/lib/background_queue/server_lib/task.rb +79 -0
  33. data/lib/background_queue/server_lib/task_registry.rb +51 -0
  34. data/lib/background_queue/server_lib/thread_manager.rb +121 -0
  35. data/lib/background_queue/server_lib/worker.rb +18 -0
  36. data/lib/background_queue/server_lib/worker_balancer.rb +97 -0
  37. data/lib/background_queue/server_lib/worker_client.rb +94 -0
  38. data/lib/background_queue/server_lib/worker_thread.rb +70 -0
  39. data/lib/background_queue/utils.rb +40 -0
  40. data/lib/background_queue/worker/base.rb +46 -0
  41. data/lib/background_queue/worker/calling.rb +59 -0
  42. data/lib/background_queue/worker/config.rb +35 -0
  43. data/lib/background_queue/worker/environment.rb +70 -0
  44. data/lib/background_queue/worker/worker_loader.rb +94 -0
  45. data/lib/background_queue_server.rb +21 -0
  46. data/lib/background_queue_worker.rb +5 -0
  47. data/spec/background_queue/client_lib/command_spec.rb +75 -0
  48. data/spec/background_queue/client_lib/config_spec.rb +156 -0
  49. data/spec/background_queue/client_lib/connection_spec.rb +170 -0
  50. data/spec/background_queue/client_spec.rb +95 -0
  51. data/spec/background_queue/command_spec.rb +34 -0
  52. data/spec/background_queue/config_spec.rb +134 -0
  53. data/spec/background_queue/server_lib/balanced_queue_spec.rb +122 -0
  54. data/spec/background_queue/server_lib/config_spec.rb +443 -0
  55. data/spec/background_queue/server_lib/event_connection_spec.rb +190 -0
  56. data/spec/background_queue/server_lib/event_server_spec.rb +48 -0
  57. data/spec/background_queue/server_lib/integration/full_test_spec.rb +247 -0
  58. data/spec/background_queue/server_lib/integration/queue_integration_spec.rb +98 -0
  59. data/spec/background_queue/server_lib/integration/serialize_spec.rb +127 -0
  60. data/spec/background_queue/server_lib/job_registry_spec.rb +65 -0
  61. data/spec/background_queue/server_lib/job_spec.rb +525 -0
  62. data/spec/background_queue/server_lib/owner_spec.rb +33 -0
  63. data/spec/background_queue/server_lib/priority_queue_spec.rb +182 -0
  64. data/spec/background_queue/server_lib/server_spec.rb +353 -0
  65. data/spec/background_queue/server_lib/sorted_workers_spec.rb +122 -0
  66. data/spec/background_queue/server_lib/task_registry_spec.rb +69 -0
  67. data/spec/background_queue/server_lib/task_spec.rb +20 -0
  68. data/spec/background_queue/server_lib/thread_manager_spec.rb +106 -0
  69. data/spec/background_queue/server_lib/worker_balancer_spec.rb +127 -0
  70. data/spec/background_queue/server_lib/worker_client_spec.rb +196 -0
  71. data/spec/background_queue/server_lib/worker_thread_spec.rb +125 -0
  72. data/spec/background_queue/utils_spec.rb +27 -0
  73. data/spec/background_queue/worker/base_spec.rb +35 -0
  74. data/spec/background_queue/worker/calling_spec.rb +103 -0
  75. data/spec/background_queue/worker/environment_spec.rb +67 -0
  76. data/spec/background_queue/worker/worker_loader_spec.rb +103 -0
  77. data/spec/background_queue_spec.rb +7 -0
  78. data/spec/resources/config-client.yml +7 -0
  79. data/spec/resources/config-serialize.yml +12 -0
  80. data/spec/resources/config.yml +12 -0
  81. data/spec/resources/example_worker.rb +4 -0
  82. data/spec/resources/example_worker_with_error.rb +4 -0
  83. data/spec/resources/test_worker.rb +8 -0
  84. data/spec/shared/queue_registry_shared.rb +216 -0
  85. data/spec/spec_helper.rb +15 -0
  86. data/spec/support/default_task.rb +9 -0
  87. data/spec/support/private.rb +23 -0
  88. data/spec/support/simple_server.rb +28 -0
  89. data/spec/support/simple_task.rb +58 -0
  90. data/spec/support/test_worker_server.rb +205 -0
  91. metadata +254 -0
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'background_queue_server'
3
+
4
+
5
+ describe BackgroundQueue::ServerLib::Owner do
6
+ let(:balancer_manager) {
7
+ p = double("bm")
8
+ p.stub(:register_job)
9
+ p
10
+ }
11
+ it_behaves_like "a queue registry" do
12
+
13
+ let(:new_instance) { BackgroundQueue::ServerLib::Owner.new(1, balancer_manager) }
14
+ end
15
+
16
+ context "callbacks" do
17
+
18
+ subject { BackgroundQueue::ServerLib::Owner.new(1, balancer_manager) }
19
+
20
+ it "gets the job_id from tasks" do
21
+ subject.__prv__get_queue_id_from_item(SimpleTask.new(:owner_id, :job_id, :task_id, 3)).should eq(:job_id)
22
+ end
23
+
24
+ it "calls add_item to add items to jobs" do
25
+ BackgroundQueue::ServerLib::Job.any_instance.should_receive(:add_item).with(:item)
26
+ subject.__prv__add_item_to_queue(BackgroundQueue::ServerLib::Job.new(1, balancer_manager), :item)
27
+ end
28
+
29
+ it "specifies the job class as its queue class" do
30
+ subject.class.queue_class.should eq(BackgroundQueue::ServerLib::Job)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,182 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'background_queue_server'
3
+
4
+
5
+ class SimpleItem
6
+ attr_accessor :id
7
+ attr_accessor :priority
8
+
9
+ def initialize(id, priority)
10
+ @id = id
11
+ @priority = priority
12
+ end
13
+ end
14
+
15
+
16
+ describe "Priority Queue" do
17
+
18
+ context "internal array of queues" do
19
+
20
+ subject { BackgroundQueue::ServerLib::PriorityQueue.new }
21
+
22
+ it "can insert queue entries" do
23
+
24
+ q1 = subject.__prv__insert_queue_at_index(1, 0)
25
+ q3 = subject.__prv__insert_queue_at_index(3, 1)
26
+ q2 = subject.__prv__insert_queue_at_index(2, 1)
27
+
28
+ subject.__prv__get_queues.should eq([q1, q2, q3])
29
+
30
+ end
31
+
32
+
33
+ it "can add a queue to the correct priority index" do
34
+ q3 = subject.__prv__get_queue_for_priority(3, true)
35
+
36
+ subject.__prv__get_queues.should eq([q3])
37
+
38
+ q2 = subject.__prv__get_queue_for_priority(2, true)
39
+ subject.__prv__get_queues.should eq([q2, q3])
40
+
41
+ q5 = subject.__prv__get_queue_for_priority(5, true)
42
+ subject.__prv__get_queues.should eq([q2, q3, q5])
43
+
44
+ q4 = subject.__prv__get_queue_for_priority(4, true)
45
+ subject.__prv__get_queues.should eq([q2, q3, q4, q5])
46
+ end
47
+
48
+ it "can get the next priority entry" do
49
+ subject.__prv__get_queue_for_priority(3, true)
50
+ q2 = subject.__prv__get_queue_for_priority(2, true)
51
+ subject.__prv__get_queue_for_priority(4, true)
52
+
53
+ subject.__prv__get_next_queue.should eq(q2)
54
+ end
55
+
56
+ it "can remove the queue entry" do
57
+
58
+ q3 = subject.__prv__get_queue_for_priority(3, true)
59
+ q2 = subject.__prv__get_queue_for_priority(2, true)
60
+ q5 = subject.__prv__get_queue_for_priority(5, true)
61
+ q4 = subject.__prv__get_queue_for_priority(4, true)
62
+
63
+ subject.__prv__get_queues.should eq([q2, q3, q4, q5])
64
+
65
+ subject.__prv__remove_queue(q3)
66
+ subject.__prv__get_queues.should eq([q2, q4, q5])
67
+
68
+ subject.__prv__remove_queue(q2)
69
+ subject.__prv__get_queues.should eq([q4, q5])
70
+
71
+ subject.__prv__remove_queue(q5)
72
+ subject.__prv__get_queues.should eq([q4])
73
+
74
+
75
+ subject.__prv__remove_queue(q4)
76
+ subject.__prv__get_queues.should eq([])
77
+ end
78
+
79
+
80
+ end
81
+
82
+ context "single priority" do
83
+
84
+ subject { BackgroundQueue::ServerLib::PriorityQueue.new }
85
+
86
+ it "adds a single entry" do
87
+ subject.push(SimpleItem.new(2, 1))
88
+ subject.__prv__get_queues.length.should eq(1)
89
+ subject.__prv__get_queues.first.priority.should eq(1)
90
+ subject.__prv__get_queues.first.first.id.should eq(2)
91
+
92
+ end
93
+
94
+ it "returns a single entry" do
95
+ subject.push(SimpleItem.new(2, 1))
96
+ popped = subject.pop
97
+ popped.id.should eq(2)
98
+ subject.__prv__get_queues.length.should eq(0)
99
+ end
100
+
101
+ it "returns nil if empty" do
102
+ subject.pop.should eq(nil)
103
+ end
104
+
105
+ it "returns entries in same order added" do
106
+ subject.push(SimpleItem.new(2, 1))
107
+ subject.push(SimpleItem.new(3, 1))
108
+ subject.pop.id.should eq(2)
109
+ subject.pop.id.should eq(3)
110
+ subject.__prv__get_queues.length.should eq(0)
111
+ end
112
+
113
+ end
114
+
115
+ context "multiple priorities" do
116
+ subject { BackgroundQueue::ServerLib::PriorityQueue.new }
117
+
118
+ it "can add multiple entries" do
119
+ subject.push(SimpleItem.new(2, 2))
120
+ subject.push(SimpleItem.new(3, 1))
121
+ subject.__prv__get_queues.length.should eq(2)
122
+ subject.__prv__get_queues.first.priority.should eq(1)
123
+ subject.__prv__get_queues.last.priority.should eq(2)
124
+ end
125
+
126
+ it "returns entries in correct priority" do
127
+ subject.push(SimpleItem.new(2, 2))
128
+ subject.push(SimpleItem.new(3, 1))
129
+
130
+ subject.pop.id.should eq(3)
131
+ subject.pop.id.should eq(2)
132
+ subject.__prv__get_queues.length.should eq(0)
133
+ end
134
+
135
+ it "returns entries in correct priority and added order" do
136
+ subject.push(SimpleItem.new(2, 2))
137
+ subject.push(SimpleItem.new(3, 3))
138
+ subject.push(SimpleItem.new(4, 2))
139
+
140
+ subject.pop.id.should eq(2)
141
+ subject.pop.id.should eq(4)
142
+ subject.pop.id.should eq(3)
143
+ subject.__prv__get_queues.length.should eq(0)
144
+ end
145
+
146
+ it "knows the highest priority" do
147
+ subject.push(SimpleItem.new(2, 2))
148
+ subject.priority.should eq(2)
149
+ subject.push(SimpleItem.new(3, 3))
150
+ subject.priority.should eq(2)
151
+ subject.pop.id.should eq(2)
152
+ subject.priority.should eq(3)
153
+ subject.pop.id.should eq(3)
154
+ subject.priority.should eq(nil)
155
+ end
156
+
157
+ it "can remove existing item" do
158
+ subject.push(SimpleItem.new(2, 2))
159
+ subject.push(SimpleItem.new(3, 3))
160
+ subject.remove(SimpleItem.new(2, 2))
161
+ subject.__prv__get_queues.length.should eq(1)
162
+ subject.__prv__get_queues.first.priority.should eq(3)
163
+ end
164
+
165
+ end
166
+
167
+ context "#each_item" do
168
+
169
+ subject { BackgroundQueue::ServerLib::PriorityQueue.new }
170
+
171
+ it "will iterate accross the items" do
172
+ subject.push(SimpleItem.new(2, 2))
173
+ subject.push(SimpleItem.new(3, 3))
174
+ subject.push(SimpleItem.new(4, 2))
175
+
176
+ found = []
177
+ subject.each_item { |item| found << item.id }
178
+
179
+ found.should eq([2,4,3])
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,353 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'background_queue_server'
3
+
4
+
5
+ describe BackgroundQueue::ServerLib::Server do
6
+
7
+ context "#process_args" do
8
+ it "knows the start command" do
9
+ options = subject.process_args(["start", "-c", "the_path"])
10
+ options[:command].should eq(:start)
11
+ end
12
+
13
+ it "knows short version of config file path" do
14
+ options = subject.process_args(["start", "-c", "the_path"])
15
+ options[:config].should eq("the_path")
16
+ end
17
+
18
+ it "knows long version of config file path" do
19
+ options = subject.process_args(["start", "--config", "the_path"])
20
+ options[:config].should eq("the_path")
21
+ end
22
+
23
+ it "raises an error if no config file is specified when starting" do
24
+ expect { subject.process_args(["start"]) }.to raise_exception
25
+ end
26
+
27
+
28
+ it "knows the stop command" do
29
+ options = subject.process_args(["stop"])
30
+ options[:command].should eq(:stop)
31
+ end
32
+
33
+ it "knows the test command" do
34
+ options = subject.process_args(["test", "-c", "the_path"])
35
+ options[:command].should eq(:test)
36
+ end
37
+
38
+ it "raises an error if no config file is specified when testing" do
39
+ expect { subject.process_args(["test"]) }.to raise_exception
40
+ end
41
+
42
+ it "raises an error if the command is not recognised" do
43
+ expect { subject.process_args(["blah"]) }.to raise_exception
44
+ end
45
+
46
+ it "knows the short logging path flag" do
47
+ options = subject.process_args(["stop", "-l", "the_path"])
48
+ options[:log_file].should eq("the_path")
49
+ end
50
+
51
+ it "knows the long logging path flag" do
52
+ options = subject.process_args(["stop", "--logfile", "the_path"])
53
+ options[:log_file].should eq("the_path")
54
+ end
55
+
56
+ it "knows the short logging level flag" do
57
+ options = subject.process_args(["stop", "-v", "debug"])
58
+ options[:log_level].should eq("debug")
59
+ end
60
+
61
+ it "knows the long logging level flag" do
62
+ options = subject.process_args(["stop", "--loglevel", "debug"])
63
+ options[:log_level].should eq("debug")
64
+ end
65
+
66
+ it "knows the short pid path flag" do
67
+ options = subject.process_args(["stop", "-p", "the_path"])
68
+ options[:pid_file].should eq("the_path")
69
+ end
70
+
71
+ it "knows the long pid path flag" do
72
+ options = subject.process_args(["stop", "--pidfile", "the_path"])
73
+ options[:pid_file].should eq("the_path")
74
+ end
75
+ end
76
+
77
+ context "#load_configuration" do
78
+ it "will continue if successful" do
79
+ BackgroundQueue::Config.should_receive(:load_file).with(:path).and_return(true)
80
+ subject.load_configuration(:path).should be_true
81
+ end
82
+
83
+ it "will raise an error if configuration does not load" do
84
+ BackgroundQueue::Config.should_receive(:load_file).with(:path).and_raise("nooo!")
85
+ expect { subject.load_configuration(:path) }.to raise_exception("nooo!")
86
+ end
87
+ end
88
+
89
+ context "#resolve_logging_path" do
90
+ it "will handle an absolute path" do
91
+ subject.resolve_logging_path("/path").should eq("/path")
92
+ end
93
+
94
+ it "will use current working directory when given a relative path" do
95
+ Dir.chdir("/tmp")
96
+ subject.resolve_logging_path("path").should eq("/tmp/path")
97
+ end
98
+ end
99
+
100
+ context "#set_logging_level" do
101
+ it "will set level debug" do
102
+ log = Logger.new(STDOUT)
103
+ subject.set_logging_level(log, "debug")
104
+ log.level.should eq(Logger::DEBUG)
105
+ subject.set_logging_level(log, "DEBUG")
106
+ log.level.should eq(Logger::DEBUG)
107
+ end
108
+
109
+ it "will set level info" do
110
+ log = Logger.new(STDOUT)
111
+ subject.set_logging_level(log, "info")
112
+ log.level.should eq(Logger::INFO)
113
+ end
114
+
115
+ it "will set level warning" do
116
+ log = Logger.new(STDOUT)
117
+ subject.set_logging_level(log, "warn")
118
+ log.level.should eq(Logger::WARN)
119
+ end
120
+
121
+ it "will set level error" do
122
+ log = Logger.new(STDOUT)
123
+ subject.set_logging_level(log, "error")
124
+ log.level.should eq(Logger::ERROR)
125
+ end
126
+
127
+ it "will set level fatal" do
128
+ log = Logger.new(STDOUT)
129
+ subject.set_logging_level(log, "fatal")
130
+ log.level.should eq(Logger::FATAL)
131
+ end
132
+
133
+ it "will default to warning" do
134
+ log = Logger.new(STDOUT)
135
+ subject.set_logging_level(log, nil)
136
+ log.level.should eq(Logger::WARN)
137
+ subject.set_logging_level(log, '')
138
+ log.level.should eq(Logger::WARN)
139
+ end
140
+
141
+ it "will error when the level is not recognised" do
142
+ log = Logger.new(STDOUT)
143
+ expect { subject.set_logging_level(log, "argh") }.to raise_exception
144
+ end
145
+ end
146
+
147
+ context "#init_logging" do
148
+ it "will initialize when everything works" do
149
+ Logger.should_receive(:new).with(:resolved_path, 'daily').and_return(:logger)
150
+ subject.should_receive(:resolve_logging_path).with(:path).and_return(:resolved_path)
151
+ subject.should_receive(:set_logging_level).with(:logger, "debug").and_return(nil)
152
+ subject.init_logging(:path, "debug")
153
+ end
154
+
155
+ it "will skip logging if the log path is nil" do
156
+ subject.init_logging(nil, "debug")
157
+ subject.init_logging(' ', "debug")
158
+ end
159
+
160
+
161
+ it "will error when the logfile cannot be opened" do
162
+ subject.should_receive(:resolve_logging_path).with(:path).and_return(:resolved_path)
163
+ Logger.should_receive(:new).with(:resolved_path, 'daily').and_raise("cannot open")
164
+ expect { subject.init_logging(:path, "debug") }.to raise_exception("Error initializing log file resolved_path: cannot open")
165
+ end
166
+ end
167
+
168
+ context "#get_pid_path" do
169
+ it "will use /var/run if pid i not specified on command line" do
170
+ subject.get_pid_path({:pid_file=>:pid}).should eq(:pid)
171
+ end
172
+
173
+ it "will use the command line path if passed" do
174
+ subject.get_pid_path({}).should eq("/var/run/background_queue.pid")
175
+ end
176
+ end
177
+
178
+ context "#get_pid" do
179
+ it "will return the pid if in the pid file and the process is running" do
180
+ f = double("file", :read=>"123")
181
+ File.should_receive(:open).with(:pid_path).and_yield(f)
182
+ Process.should_receive(:kill).with(0, 123).and_return(nil)
183
+ subject.get_pid({:pid_file=>:pid_path}).should eq(123)
184
+ end
185
+
186
+ it "will return nil if the pid file does not exist" do
187
+ File.should_receive(:open).with(:pid_path).and_raise("file not found")
188
+ subject.get_pid({:pid_file=>:pid_path}).should be_nil
189
+ end
190
+
191
+ it "will return nil if the process is not running" do
192
+ f = double("file", :read=>"123")
193
+ File.should_receive(:open).with(:pid_path).and_yield(f)
194
+ Process.should_receive(:kill).with(0, 123).and_raise("not running")
195
+ subject.get_pid({:pid_file=>:pid_path}).should be_nil
196
+ end
197
+
198
+ it "will return nil if the pid is 0" do
199
+ f = double("file", :read=>"")
200
+ File.should_receive(:open).with(:pid_path).and_yield(f)
201
+ subject.get_pid({:pid_file=>:pid_path}).should be_nil
202
+ end
203
+ end
204
+
205
+ context "#check_not_running" do
206
+ it "will return if the pid is nil" do
207
+ subject.should_receive(:get_pid).and_return(nil)
208
+ subject.check_not_running({})
209
+ end
210
+
211
+ it "will raise an error if the pid is not nil" do
212
+ subject.should_receive(:get_pid).and_return(123)
213
+ expect { subject.check_not_running({}) }.to raise_exception("Process 123 already running")
214
+ end
215
+ end
216
+
217
+ context "#kill_pid" do
218
+ it "will do nothing if the pid is nil" do
219
+ subject.should_receive(:get_pid).and_return(nil)
220
+ subject.kill_pid({})
221
+ end
222
+
223
+ it "will kill the pid if it exists" do
224
+ subject.should_receive(:get_pid).and_return(123)
225
+ Process.should_receive(:kill).with(9, 123).and_return(nil)
226
+ subject.kill_pid({})
227
+ end
228
+ end
229
+
230
+ context "#write_pid" do
231
+ before do
232
+ Process.should_receive(:pid).and_return(123)
233
+ end
234
+ it "will write the pid file with the current process id" do
235
+ f = double("file")
236
+ f.should_receive("write").with("123")
237
+ File.should_receive(:open).with(:pid, "w").and_yield(f)
238
+ subject.write_pid({:pid_file=>:pid})
239
+ end
240
+
241
+ it "will error if the pid file cannot be opened" do
242
+ File.should_receive(:open).with(:pid, "w").and_raise("permission denied")
243
+ expect { subject.write_pid({:pid_file=>:pid}) }.to raise_exception("Unable to write to pid file pid: permission denied")
244
+ end
245
+ end
246
+
247
+ context "#remove_pid" do
248
+ it "will remove the file if it exists" do
249
+ File.should_receive(:delete).with(:pid)
250
+ subject.remove_pid({:pid_file=>:pid})
251
+ end
252
+
253
+ it "will do nothing if the pid file does not exist" do
254
+ File.should_receive(:delete).with(:pid).and_raise("aaarrrgggghhh")
255
+ subject.remove_pid({:pid_file=>:pid})
256
+ end
257
+ end
258
+
259
+ context "#load_tasks" do
260
+ it "will do nothing if the task_file is nil" do
261
+ File.should_not_receive(:exist?)
262
+ subject.load_tasks(nil)
263
+ end
264
+
265
+ it "will not load the tasks if the path does not exist" do
266
+ File.should_receive(:exist?).with('path').and_return(false)
267
+ File.should_not_receive(:open)
268
+ subject.load_tasks('path')
269
+ end
270
+
271
+ it "will load the tasks from the path" do
272
+ File.should_receive(:exist?).with('path').and_return(true)
273
+ File.should_receive(:open).with('path', 'r').and_yield(:io)
274
+ task_queue = double("tq")
275
+ task_queue.should_receive(:load_from_file).with(:io)
276
+ subject.stub(:task_queue) { task_queue }
277
+ subject.load_tasks('path')
278
+ end
279
+
280
+ it "will log errors when loading the file" do
281
+ File.should_receive(:exist?).with('path').and_return(true)
282
+ File.should_receive(:open).with('path', 'r').and_yield(:io)
283
+ task_queue = double("tq")
284
+ task_queue.should_receive(:load_from_file).with(:io).and_raise("ERROR")
285
+ subject.stub(:task_queue) { task_queue }
286
+
287
+ logger = double("logger")
288
+ logger.should_receive(:error)
289
+ logger.should_receive(:debug)
290
+ subject.stub(:logger) { logger }
291
+ subject.load_tasks('path')
292
+
293
+ end
294
+
295
+ end
296
+
297
+ context "#save_tasks" do
298
+ it "will do nothing if the task_file is nil" do
299
+ File.should_not_receive(:exist?)
300
+ subject.save_tasks(nil)
301
+ end
302
+
303
+ it "will save the tasks to the path" do
304
+ File.should_receive(:open).with('path', 'w').and_yield(:io)
305
+ task_queue = double("tq")
306
+ task_queue.should_receive(:save_to_file).with(:io)
307
+ subject.stub(:task_queue) { task_queue }
308
+ subject.save_tasks('path')
309
+ end
310
+
311
+ it "will log errors when saving to file" do
312
+ File.should_receive(:open).with('path', 'w').and_yield(:io)
313
+ task_queue = double("tq")
314
+ task_queue.should_receive(:save_to_file).with(:io).and_raise("ERROR")
315
+ subject.stub(:task_queue) { task_queue }
316
+
317
+ logger = double("logger")
318
+ logger.should_receive(:error)
319
+ logger.should_receive(:debug)
320
+ subject.stub(:logger) { logger }
321
+ subject.save_tasks('path')
322
+
323
+ end
324
+
325
+ end
326
+
327
+ context "#start" do
328
+ it "will load configuration, init logging then deamonise" do
329
+ subject.should_receive(:load_configuration).and_return(nil)
330
+ subject.should_receive(:init_logging).and_return(nil)
331
+ subject.should_receive(:check_not_running).and_return(nil)
332
+ subject.should_receive(:write_pid).and_return(nil)
333
+ subject.should_receive(:daemonize).and_return(nil)
334
+ subject.start({:command=>:start})
335
+ end
336
+
337
+ it "will load configuration, init logging then run directly" do
338
+ subject.should_receive(:load_configuration).and_return(nil)
339
+ subject.should_receive(:init_logging).and_return(nil)
340
+ subject.should_receive(:check_not_running).and_return(nil)
341
+ subject.should_receive(:write_pid).and_return(nil)
342
+ subject.should_receive(:run).and_return(nil)
343
+ subject.should_not_receive(:daemonize)
344
+ subject.start({:command=>:run})
345
+ end
346
+
347
+ it "will display any error and exit" do
348
+ subject.should_receive(:load_configuration).and_raise(BackgroundQueue::ServerLib::InitError.new("some_error"))
349
+ STDERR.should_receive(:puts).with("some_error")
350
+ subject.start({:command=>:run})
351
+ end
352
+ end
353
+ end