Skip to content

Commit 68bab2a

Browse files
committed
WIP: specs should be done
1 parent a68f05f commit 68bab2a

File tree

8 files changed

+248
-11
lines changed

8 files changed

+248
-11
lines changed

lib/docker_manager/pitchfork_adapter.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,5 @@ def launcher_pid
1313
def master_pid
1414
`pgrep -f "pitchfork monitor"`.strip.to_i
1515
end
16-
17-
def workers
18-
`pgrep -f -P #{master_pid} worker`.split("\n").map(&:to_i)
19-
end
2016
end
2117
end

lib/docker_manager/unicorn_adapter.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,5 @@ def launcher_pid
1313
def master_pid
1414
`pgrep -f "unicorn master -E"`.strip.to_i
1515
end
16-
17-
def workers
18-
`pgrep -f -P #{master_pid} worker`.split("\n").map(&:to_i)
19-
end
2016
end
2117
end

lib/docker_manager/web_server_adapter.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ def initialize(upgrader)
1212
@upgrader = upgrader
1313
end
1414

15+
def workers
16+
`pgrep -f -P #{master_pid} worker`.split("\n").map(&:to_i)
17+
end
18+
1519
def local_web_url
1620
"http://127.0.0.1:#{ENV["UNICORN_PORT"] || 3000}/srv/status"
1721
end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# frozen_string_literal: true
2+
3+
require "docker_manager/upgrader"
4+
5+
RSpec.describe DockerManager::PitchforkAdapter do
6+
subject(:adapter) { described_class.new(upgrader) }
7+
8+
let(:upgrader) { instance_double(DockerManager::Upgrader, log: nil) }
9+
10+
before { allow_any_instance_of(Kernel).to receive(:`) }
11+
12+
it_behaves_like "a web server adapter"
13+
14+
describe "#server_name" do
15+
it "returns 'Pitchfork'" do
16+
expect(adapter.server_name).to eq("Pitchfork")
17+
end
18+
end
19+
20+
describe "#launcher_pid" do
21+
before do
22+
allow_any_instance_of(Kernel).to receive(:`).with("pgrep -f unicorn_launcher").and_return(
23+
"1234\n",
24+
)
25+
end
26+
27+
it "returns the pid of the 'unicorn_launcher' process" do
28+
expect(adapter.launcher_pid).to eq(1234)
29+
end
30+
end
31+
32+
describe "#master_pid" do
33+
before do
34+
allow_any_instance_of(Kernel).to receive(:`).with('pgrep -f "pitchfork monitor"').and_return(
35+
"5678\n",
36+
)
37+
end
38+
39+
it "returns the pid of the Pitchfork monitor process" do
40+
expect(adapter.master_pid).to eq(5678)
41+
end
42+
end
43+
end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# frozen_string_literal: true
2+
3+
require "docker_manager/upgrader"
4+
5+
RSpec.describe DockerManager::UnicornAdapter do
6+
subject(:adapter) { described_class.new(upgrader) }
7+
8+
let(:upgrader) { instance_double(DockerManager::Upgrader, log: nil) }
9+
10+
before { allow_any_instance_of(Kernel).to receive(:`) }
11+
12+
it_behaves_like "a web server adapter"
13+
14+
describe "#server_name" do
15+
it "returns 'Unicorn'" do
16+
expect(adapter.server_name).to eq("Unicorn")
17+
end
18+
end
19+
20+
describe "#launcher_pid" do
21+
before do
22+
allow_any_instance_of(Kernel).to receive(:`).with("pgrep -f unicorn_launcher").and_return(
23+
"1234\n",
24+
)
25+
end
26+
27+
it "returns the pid of the 'unicorn_launcher' process" do
28+
expect(adapter.launcher_pid).to eq(1234)
29+
end
30+
end
31+
32+
describe "#master_pid" do
33+
before do
34+
allow_any_instance_of(Kernel).to receive(:`).with('pgrep -f "unicorn master -E"').and_return(
35+
"5678\n",
36+
)
37+
end
38+
39+
it "returns the pid of the Unicorn master process" do
40+
expect(adapter.master_pid).to eq(5678)
41+
end
42+
end
43+
end

spec/lib/docker_manager/upgrader_spec.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,9 @@
154154
end
155155

156156
it "logs the version upgrade" do
157-
expect(upgrader).to receive(:log_version_upgrade)
158-
upgrader.upgrade
157+
expect { upgrader.upgrade }.to change {
158+
UserHistory.where(custom_type: "discourse_update").count
159+
}.by(1)
159160
end
160161

161162
it "sets status to complete when done" do
@@ -249,7 +250,7 @@
249250
expect(upgrader.last_status).to eq("failed")
250251
end
251252

252-
it "stops upgrading for all repos in ensure block" do
253+
it "stops upgrading for all repos" do
253254
expect { upgrader.upgrade }.to raise_error(RuntimeError)
254255
expect(repo).to have_received(:stop_upgrading)
255256
end

spec/plugin_helper.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# frozen_string_literal: true
2+
3+
Pathname.new(__dir__).glob("support/**/*.rb").each { |f| require f }
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.shared_examples "a web server adapter" do
4+
subject(:adapter) { described_class.new(upgrader) }
5+
6+
let(:upgrader) { instance_double(DockerManager::Upgrader, log: nil) }
7+
8+
describe "#workers" do
9+
before do
10+
allow(adapter).to receive(:master_pid).and_return(1001)
11+
allow_any_instance_of(Kernel).to receive(:`).with("pgrep -f -P 1001 worker").and_return(
12+
"2001\n2002\n2003\n",
13+
)
14+
end
15+
16+
it "returns array of worker PIDs" do
17+
expect(adapter.workers).to contain_exactly(2001, 2002, 2003)
18+
end
19+
end
20+
21+
describe "#min_workers" do
22+
it "returns at least 1" do
23+
expect(adapter.min_workers).to be >= 1
24+
end
25+
end
26+
27+
describe "#local_web_url" do
28+
context "when UNICORN_PORT is set" do
29+
before { allow(ENV).to receive(:[]).with("UNICORN_PORT").and_return("8080") }
30+
31+
it "uses the configured port" do
32+
expect(adapter.local_web_url).to eq("http://127.0.0.1:8080/srv/status")
33+
end
34+
end
35+
36+
context "when UNICORN_PORT is not set" do
37+
it "defaults to port 3000" do
38+
expect(adapter.local_web_url).to eq("http://127.0.0.1:3000/srv/status")
39+
end
40+
end
41+
end
42+
43+
describe "#scale_down_workers" do
44+
let(:master_pid) { 1234 }
45+
46+
before do
47+
allow(adapter).to receive(:master_pid).and_return(master_pid)
48+
allow(Process).to receive(:kill)
49+
end
50+
51+
it "sends TTOU signal to master for each worker to scale down" do
52+
adapter.scale_down_workers(3)
53+
expect(Process).to have_received(:kill).with("TTOU", master_pid).thrice
54+
end
55+
end
56+
57+
describe "#scale_up_workers" do
58+
let(:master_pid) { 1234 }
59+
60+
before do
61+
allow(adapter).to receive(:master_pid).and_return(master_pid)
62+
allow(Process).to receive(:kill)
63+
end
64+
65+
it "sends TTIN signal to master for each worker to scale up" do
66+
adapter.scale_up_workers(2)
67+
expect(Process).to have_received(:kill).with("TTIN", master_pid).twice
68+
end
69+
end
70+
71+
describe "#set_restart_flag" do
72+
it "sets the server restart flag through redis" do
73+
expect { adapter.set_restart_flag }.to change {
74+
Discourse.redis.get(DockerManager::WebServerAdapter::RESTART_FLAG_KEY)
75+
}.to("1")
76+
end
77+
end
78+
79+
describe "#clear_restart_flag" do
80+
before { adapter.set_restart_flag }
81+
82+
it "deletes the server restart flag in redis" do
83+
expect { adapter.clear_restart_flag }.to change {
84+
Discourse.redis.get(DockerManager::WebServerAdapter::RESTART_FLAG_KEY)
85+
}.to be_nil
86+
end
87+
end
88+
89+
describe "#reload" do
90+
let(:launcher_pid) { 1000 }
91+
let(:master_pid) { 1001 }
92+
let(:server_name) { adapter.server_name }
93+
94+
before do
95+
allow(adapter).to receive_messages(
96+
launcher_pid:,
97+
master_pid:,
98+
set_restart_flag: "OK",
99+
clear_restart_flag: nil,
100+
)
101+
allow(adapter).to receive(:sleep)
102+
allow(adapter).to receive(:`).and_return("ok")
103+
allow(Process).to receive(:kill)
104+
allow(Process).to receive(:getpgid).and_raise(Errno::ESRCH)
105+
end
106+
107+
it "sets the restart flag before reloading" do
108+
adapter.reload
109+
expect(adapter).to have_received(:set_restart_flag).ordered
110+
expect(Process).to have_received(:kill).with("USR2", launcher_pid).ordered
111+
end
112+
113+
it "logs the restart action" do
114+
adapter.reload
115+
expect(upgrader).to have_received(:log).with("Restarting #{server_name} pid: #{launcher_pid}")
116+
end
117+
118+
it "sends USR2 signal to launcher" do
119+
adapter.reload
120+
expect(Process).to have_received(:kill).with("USR2", launcher_pid)
121+
end
122+
123+
it "waits for original master to exit" do
124+
call_count = 0
125+
allow(Process).to receive(:getpgid).with(master_pid) do
126+
call_count += 1
127+
raise Errno::ESRCH if call_count > 2
128+
true
129+
end
130+
131+
adapter.reload
132+
expect(adapter).to have_received(:sleep).with(2).twice
133+
end
134+
135+
it "waits for workers to respond to health check" do
136+
call_count = 0
137+
allow(adapter).to receive(:`).with(/curl/) do
138+
call_count += 1
139+
call_count > 3 ? "ok" : "not ready"
140+
end
141+
142+
adapter.reload
143+
expect(adapter).to have_received(:sleep).with(2).thrice
144+
end
145+
146+
it "clears the restart flag after successful reload" do
147+
adapter.reload
148+
expect(adapter).to have_received(:clear_restart_flag)
149+
end
150+
end
151+
end

0 commit comments

Comments
 (0)