File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -85,6 +85,7 @@ def run(
8585 stdin = None ,
8686 env = None ,
8787 port = None ,
88+ admin_port = None ,
8889 host = None ,
8990 wait_for_readiness = True ,
9091 wait_max_seconds = 1 ,
@@ -113,7 +114,7 @@ def run(
113114 env ["PGRST_SERVER_UNIX_SOCKET" ] = str (socketfile )
114115 baseurl = "http+unix://" + urllib .parse .quote_plus (str (socketfile ))
115116
116- adminport = freeport (used_ports = [port ])
117+ adminport = freeport (used_ports = [port ]) if admin_port is None else admin_port
117118 env ["PGRST_ADMIN_SERVER_PORT" ] = str (adminport )
118119 adminhost = f"[{ host } ]" if host and is_ipv6 (host ) else localhost
119120 adminurl = f"http://{ adminhost } :{ adminport } "
Original file line number Diff line number Diff line change @@ -133,6 +133,61 @@ def test_random_port_bound(defaultenv):
133133 assert True # liveness check is done by run(), so we just need to check that it doesn't fail
134134
135135
136+ @pytest .mark .xfail (reason = "SO_REUSEPORT handover is currently failing" )
137+ def test_so_reuseport_zero_downtime_handover (defaultenv ):
138+ "A second PostgREST instance should take over on the same main/admin ports without request failures."
139+
140+ port = freeport ()
141+ admin_port = freeport (used_ports = [port ])
142+ failures = []
143+ keep_running = {"value" : True }
144+
145+ with run (
146+ env = {** defaultenv },
147+ port = port ,
148+ admin_port = admin_port ,
149+ wait_max_seconds = 3 ,
150+ ) as first :
151+
152+ def continuously_request ():
153+ while keep_running ["value" ]:
154+ try :
155+ response = first .session .get ("/projects" , timeout = 1 )
156+ assert response .status_code == 200
157+ except Exception as exc :
158+ failures .append (exc )
159+ break
160+ time .sleep (0.05 )
161+
162+ requester = Thread (target = continuously_request )
163+ requester .start ()
164+
165+ try :
166+ time .sleep (1 )
167+ with run (
168+ env = {** defaultenv },
169+ port = port ,
170+ admin_port = admin_port ,
171+ wait_max_seconds = 3 ,
172+ ):
173+ response = first .admin .get ("/live" )
174+ assert response .status_code == 200
175+
176+ time .sleep (1 )
177+ first .process .terminate ()
178+ wait_until_exit (first )
179+
180+ response = first .admin .get ("/live" )
181+ assert response .status_code == 200
182+
183+ time .sleep (1 )
184+ finally :
185+ keep_running ["value" ] = False
186+ requester .join ()
187+
188+ assert failures == []
189+
190+
136191def test_app_settings_reload (tmp_path , defaultenv ):
137192 "App settings should be reloaded from file when PostgREST is sent SIGUSR2."
138193 config = (CONFIGSDIR / "sigusr2-settings.config" ).read_text ()
You can’t perform that action at this time.
0 commit comments