44# Copyright, 2025, by Samuel Williams.
55
66require "async/container/supervisor/a_server"
7- require "sus/fixtures/console/null_logger "
7+ require "sus/fixtures/console/captured_logger "
88
99describe Async ::Container ::Supervisor ::Server do
10- include Sus ::Fixtures ::Console ::NullLogger
1110 include Async ::Container ::Supervisor ::AServer
11+ include Sus ::Fixtures ::Console ::CapturedLogger
1212
1313 it "can handle unexpected failures" do
1414 # First, send invalid JSON to trigger the error:
3636 )
3737
3838 stream . close
39+
40+ # Verify error was logged about the parsing failure
41+ error_logs = console_capture . select { |log | log [ :severity ] == :warn }
42+ expect ( error_logs ) . not . to be ( :empty? )
3943 end
4044
4145 with "failing monitor" do
@@ -45,9 +49,11 @@ def run
4549 end
4650
4751 def register ( connection )
52+ raise "Monitor failed to register!"
4853 end
4954
5055 def remove ( connection )
56+ raise "Monitor failed to remove!"
5157 end
5258
5359 def status ( call )
@@ -58,6 +64,30 @@ def status(call)
5864
5965 let ( :monitors ) { [ failing_monitor ] }
6066
67+ it "can handle monitor registration failures" do
68+ # Send a register message:
69+ stream = endpoint . connect
70+
71+ message = { id : 1 , do : :register , state : { process_id : ::Process . pid } }
72+ stream . puts ( JSON . dump ( message ) )
73+ stream . flush
74+
75+ # Read the response:
76+ response = JSON . parse ( stream . gets , symbolize_names : true )
77+
78+ # The server should still finish despite the monitor error:
79+ expect ( response ) . to have_keys (
80+ id : be == 1 ,
81+ finished : be == true
82+ )
83+
84+ # Verify error was logged about the monitor failure:
85+ error_log = console_capture . find { |log | log [ :severity ] == :error && log [ :message ] =~ /Error while registering process/ }
86+ expect ( error_log ) . to be_truthy
87+
88+ stream . close
89+ end
90+
6191 it "can handle monitor status failures" do
6292 # Send a status request:
6393 stream = endpoint . connect
@@ -71,14 +101,41 @@ def status(call)
71101
72102 # The server should still respond with a finished message despite the monitor error:
73103 expect ( response ) . to have_keys (
74- id : be == 1 ,
75- finished : be == true ,
76- error : have_keys (
77- class : be == "RuntimeError" ,
78- message : be == "Monitor failed to get status!" ,
79- backtrace : be_a ( Array )
80- )
104+ id : be == 1 ,
105+ finished : be == true ,
106+ error : have_keys (
107+ class : be == "RuntimeError" ,
108+ message : be == "Monitor failed to get status!" ,
109+ backtrace : be_a ( Array )
81110 )
111+ )
112+
113+ stream . close
114+ end
115+
116+ it "can handle monitor removal failures" do
117+ # Connect then disconnect to trigger removal:
118+ stream = endpoint . connect
119+ stream . close
120+
121+ # Give time for removal to process
122+ reactor . sleep ( 0.01 )
123+
124+ # Verify error was logged about the monitor removal failure:
125+ error_log = console_capture . find { |log | log [ :severity ] == :error && log [ :message ] =~ /Error while removing process/ }
126+ expect ( error_log ) . to be_truthy
127+
128+ # Verify server is still working by sending a new request:
129+ stream = endpoint . connect
130+ message = { id : 1 , do : :status }
131+ stream . puts ( JSON . dump ( message ) )
132+ stream . flush
133+
134+ response = JSON . parse ( stream . gets , symbolize_names : true )
135+ expect ( response ) . to have_keys (
136+ id : be == 1 ,
137+ finished : be == true
138+ )
82139
83140 stream . close
84141 end
@@ -98,6 +155,13 @@ def status(call)
98155 stream . puts ( JSON . dump ( message ) )
99156 stream . flush
100157
158+ # Wait for the message to be processed
159+ reactor . sleep ( 0.01 )
160+
161+ # Verify a debug warning was logged about ignoring the message:
162+ debug_log = console_capture . find { |log | log [ :severity ] == :debug && log [ :message ] =~ /Ignoring message/ }
163+ expect ( debug_log ) . to be_truthy
164+
101165 # Send a valid message to confirm the server is still working:
102166 valid_message = { id : 3 , do : :register , state : { process_id : ::Process . pid } }
103167 stream . puts ( JSON . dump ( valid_message ) )
@@ -145,4 +209,4 @@ def status(call)
145209
146210 stream . close
147211 end
148- end
212+ end
0 commit comments