@@ -126,6 +126,101 @@ async def test_timeout(self):
126126 await ably .request ('GET' , '/time' , version = Defaults .protocol_version )
127127 await ably .close ()
128128
129+ # RSC15l3
130+ @dont_vary_protocol
131+ async def test_503_status_fallback (self ):
132+ default_endpoint = 'https://sandbox-rest.ably.io/time'
133+ fallback_host = 'sandbox-a-fallback.ably-realtime.com'
134+ fallback_endpoint = f'https://{ fallback_host } /time'
135+ ably = await TestApp .get_ably_rest (fallback_hosts = [fallback_host ])
136+ with respx .mock :
137+ default_route = respx .get (default_endpoint )
138+ fallback_route = respx .get (fallback_endpoint )
139+ headers = {
140+ "Content-Type" : "application/json"
141+ }
142+ default_route .return_value = httpx .Response (503 , headers = headers )
143+ fallback_route .return_value = httpx .Response (200 , headers = headers , text = '[123]' )
144+ result = await ably .request ('GET' , '/time' , version = Defaults .protocol_version )
145+ assert default_route .called
146+ assert result .status_code == 200
147+ assert result .items [0 ] == 123
148+ await ably .close ()
149+
150+ # RSC15l2
151+ @dont_vary_protocol
152+ async def test_httpx_timeout_fallback (self ):
153+ default_endpoint = 'https://sandbox-rest.ably.io/time'
154+ fallback_host = 'sandbox-a-fallback.ably-realtime.com'
155+ fallback_endpoint = f'https://{ fallback_host } /time'
156+ ably = await TestApp .get_ably_rest (fallback_hosts = [fallback_host ])
157+ with respx .mock :
158+ default_route = respx .get (default_endpoint )
159+ fallback_route = respx .get (fallback_endpoint )
160+ headers = {
161+ "Content-Type" : "application/json"
162+ }
163+ default_route .side_effect = httpx .ReadTimeout
164+ fallback_route .return_value = httpx .Response (200 , headers = headers , text = '[123]' )
165+ result = await ably .request ('GET' , '/time' , version = Defaults .protocol_version )
166+ assert default_route .called
167+ assert result .status_code == 200
168+ assert result .items [0 ] == 123
169+ await ably .close ()
170+
171+ # RSC15l3
172+ @dont_vary_protocol
173+ async def test_503_status_fallback_on_publish (self ):
174+ default_endpoint = 'https://sandbox-rest.ably.io/channels/test/messages'
175+ fallback_host = 'sandbox-a-fallback.ably-realtime.com'
176+ fallback_endpoint = f'https://{ fallback_host } /channels/test/messages'
177+
178+ fallback_response_text = (
179+ '{"id": "unique_id:0", "channel": "test", "name": "test", "data": "data", '
180+ '"clientId": null, "connectionId": "connection_id", "timestamp": 1696944145000, '
181+ '"encoding": null}'
182+ )
183+
184+ ably = await TestApp .get_ably_rest (fallback_hosts = [fallback_host ])
185+ with respx .mock :
186+ default_route = respx .post (default_endpoint )
187+ fallback_route = respx .post (fallback_endpoint )
188+ headers = {
189+ "Content-Type" : "application/json"
190+ }
191+ default_route .return_value = httpx .Response (503 , headers = headers )
192+ fallback_route .return_value = httpx .Response (
193+ 200 ,
194+ headers = headers ,
195+ text = fallback_response_text ,
196+ )
197+ message_response = await ably .channels ['test' ].publish ('test' , 'data' )
198+ assert default_route .called
199+ assert message_response .to_native ()['data' ] == 'data'
200+ await ably .close ()
201+
202+ # RSC15l4
203+ @dont_vary_protocol
204+ async def test_400_cloudfront_fallback (self ):
205+ default_endpoint = 'https://sandbox-rest.ably.io/time'
206+ fallback_host = 'sandbox-a-fallback.ably-realtime.com'
207+ fallback_endpoint = f'https://{ fallback_host } /time'
208+ ably = await TestApp .get_ably_rest (fallback_hosts = [fallback_host ])
209+ with respx .mock :
210+ default_route = respx .get (default_endpoint )
211+ fallback_route = respx .get (fallback_endpoint )
212+ headers = {
213+ "Server" : "CloudFront" ,
214+ "Content-Type" : "application/json" ,
215+ }
216+ default_route .return_value = httpx .Response (400 , headers = headers , text = '[456]' )
217+ fallback_route .return_value = httpx .Response (200 , headers = headers , text = '[123]' )
218+ result = await ably .request ('GET' , '/time' , version = Defaults .protocol_version )
219+ assert default_route .called
220+ assert result .status_code == 200
221+ assert result .items [0 ] == 123
222+ await ably .close ()
223+
129224 async def test_version (self ):
130225 version = "150" # chosen arbitrarily
131226 result = await self .ably .request ('GET' , '/time' , "150" )
0 commit comments