background_queue 0.2.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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.rvmrc +48 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +20 -0
- data/README.md +69 -0
- data/Rakefile +42 -0
- data/TODO +2 -0
- data/VERSION +1 -0
- data/background_queue.gemspec +158 -0
- data/bin/bg_queue +26 -0
- data/lib/background_queue.rb +8 -0
- data/lib/background_queue/client.rb +96 -0
- data/lib/background_queue/client_lib/command.rb +36 -0
- data/lib/background_queue/client_lib/config.rb +109 -0
- data/lib/background_queue/client_lib/connection.rb +105 -0
- data/lib/background_queue/client_lib/job_handle.rb +19 -0
- data/lib/background_queue/command.rb +49 -0
- data/lib/background_queue/config.rb +118 -0
- data/lib/background_queue/server_lib/balanced_queue.rb +108 -0
- data/lib/background_queue/server_lib/config.rb +339 -0
- data/lib/background_queue/server_lib/event_connection.rb +133 -0
- data/lib/background_queue/server_lib/event_server.rb +35 -0
- data/lib/background_queue/server_lib/job.rb +252 -0
- data/lib/background_queue/server_lib/job_registry.rb +30 -0
- data/lib/background_queue/server_lib/lru.rb +193 -0
- data/lib/background_queue/server_lib/owner.rb +54 -0
- data/lib/background_queue/server_lib/priority_queue.rb +156 -0
- data/lib/background_queue/server_lib/queue_registry.rb +123 -0
- data/lib/background_queue/server_lib/server.rb +314 -0
- data/lib/background_queue/server_lib/sorted_workers.rb +52 -0
- data/lib/background_queue/server_lib/task.rb +79 -0
- data/lib/background_queue/server_lib/task_registry.rb +51 -0
- data/lib/background_queue/server_lib/thread_manager.rb +121 -0
- data/lib/background_queue/server_lib/worker.rb +18 -0
- data/lib/background_queue/server_lib/worker_balancer.rb +97 -0
- data/lib/background_queue/server_lib/worker_client.rb +94 -0
- data/lib/background_queue/server_lib/worker_thread.rb +70 -0
- data/lib/background_queue/utils.rb +40 -0
- data/lib/background_queue/worker/base.rb +46 -0
- data/lib/background_queue/worker/calling.rb +59 -0
- data/lib/background_queue/worker/config.rb +35 -0
- data/lib/background_queue/worker/environment.rb +70 -0
- data/lib/background_queue/worker/worker_loader.rb +94 -0
- data/lib/background_queue_server.rb +21 -0
- data/lib/background_queue_worker.rb +5 -0
- data/spec/background_queue/client_lib/command_spec.rb +75 -0
- data/spec/background_queue/client_lib/config_spec.rb +156 -0
- data/spec/background_queue/client_lib/connection_spec.rb +170 -0
- data/spec/background_queue/client_spec.rb +95 -0
- data/spec/background_queue/command_spec.rb +34 -0
- data/spec/background_queue/config_spec.rb +134 -0
- data/spec/background_queue/server_lib/balanced_queue_spec.rb +122 -0
- data/spec/background_queue/server_lib/config_spec.rb +443 -0
- data/spec/background_queue/server_lib/event_connection_spec.rb +190 -0
- data/spec/background_queue/server_lib/event_server_spec.rb +48 -0
- data/spec/background_queue/server_lib/integration/full_test_spec.rb +247 -0
- data/spec/background_queue/server_lib/integration/queue_integration_spec.rb +98 -0
- data/spec/background_queue/server_lib/integration/serialize_spec.rb +127 -0
- data/spec/background_queue/server_lib/job_registry_spec.rb +65 -0
- data/spec/background_queue/server_lib/job_spec.rb +525 -0
- data/spec/background_queue/server_lib/owner_spec.rb +33 -0
- data/spec/background_queue/server_lib/priority_queue_spec.rb +182 -0
- data/spec/background_queue/server_lib/server_spec.rb +353 -0
- data/spec/background_queue/server_lib/sorted_workers_spec.rb +122 -0
- data/spec/background_queue/server_lib/task_registry_spec.rb +69 -0
- data/spec/background_queue/server_lib/task_spec.rb +20 -0
- data/spec/background_queue/server_lib/thread_manager_spec.rb +106 -0
- data/spec/background_queue/server_lib/worker_balancer_spec.rb +127 -0
- data/spec/background_queue/server_lib/worker_client_spec.rb +196 -0
- data/spec/background_queue/server_lib/worker_thread_spec.rb +125 -0
- data/spec/background_queue/utils_spec.rb +27 -0
- data/spec/background_queue/worker/base_spec.rb +35 -0
- data/spec/background_queue/worker/calling_spec.rb +103 -0
- data/spec/background_queue/worker/environment_spec.rb +67 -0
- data/spec/background_queue/worker/worker_loader_spec.rb +103 -0
- data/spec/background_queue_spec.rb +7 -0
- data/spec/resources/config-client.yml +7 -0
- data/spec/resources/config-serialize.yml +12 -0
- data/spec/resources/config.yml +12 -0
- data/spec/resources/example_worker.rb +4 -0
- data/spec/resources/example_worker_with_error.rb +4 -0
- data/spec/resources/test_worker.rb +8 -0
- data/spec/shared/queue_registry_shared.rb +216 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/default_task.rb +9 -0
- data/spec/support/private.rb +23 -0
- data/spec/support/simple_server.rb +28 -0
- data/spec/support/simple_task.rb +58 -0
- data/spec/support/test_worker_server.rb +205 -0
- 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
|