Skip to content

Commit d31d992

Browse files
Add tests for controller restart behaviour.
Assisted-By: devx/904563b8-dbee-48b0-9726-f036df3ed96d
1 parent 4db57a0 commit d31d992

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

test/async/container/controller.rb

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,87 @@ def controller.setup(container)
8484
end
8585
end
8686

87+
with "#restart" do
88+
it "replaces the running container with a new one" do
89+
def controller.setup(container)
90+
container.spawn do |instance|
91+
instance.ready!
92+
sleep
93+
end
94+
end
95+
96+
controller.start
97+
first = controller.container
98+
99+
expect(first).not.to be_nil
100+
expect(controller).to be(:running?)
101+
102+
# A restart is a blue-green swap: a new container is created and the old one is stopped.
103+
controller.restart
104+
105+
expect(controller.container).not.to be_equal(first)
106+
expect(controller).to be(:running?)
107+
ensure
108+
controller.stop(false)
109+
end
110+
111+
it "starts a new container if not already running" do
112+
def controller.setup(container)
113+
container.spawn do |instance|
114+
instance.ready!
115+
sleep
116+
end
117+
end
118+
119+
expect(controller).not.to be(:running?)
120+
121+
controller.restart
122+
123+
expect(controller).to be(:running?)
124+
expect(controller.container).not.to be_nil
125+
ensure
126+
controller.stop(false)
127+
end
128+
129+
it "restarts when Restart is raised into the running controller thread" do
130+
def controller.setup(container)
131+
container.spawn do |instance|
132+
instance.ready!
133+
sleep
134+
end
135+
end
136+
137+
# Run the controller in a thread so we can deliver `Restart` via `Thread#raise`, which is the in-process (cross-thread) analog of sending `SIGHUP` to a process running a controller. `Child#restart!` uses exactly this mechanism.
138+
thread = Thread.new do
139+
Thread.current.report_on_exception = false
140+
controller.run
141+
end
142+
143+
# Wait until the controller is running:
144+
10.times do
145+
break if controller.running?
146+
sleep 0.1
147+
end
148+
expect(controller).to be(:running?)
149+
150+
first = controller.container
151+
152+
thread.raise(Async::Container::Restart)
153+
154+
# Wait until the container has been replaced by the restart:
155+
10.times do
156+
break if controller.container && !controller.container.equal?(first)
157+
sleep 0.1
158+
end
159+
160+
expect(controller.container).not.to be_equal(first)
161+
expect(controller).to be(:running?)
162+
ensure
163+
thread&.raise(Async::Container::Interrupt)
164+
thread&.join
165+
end
166+
end
167+
87168
with "notify" do
88169
before do
89170
@notify_server = Async::Container::Notify::Server.open

0 commit comments

Comments
 (0)