|
7 | 7 | using FluentAssertions; |
8 | 8 | using IO.Ably.Realtime; |
9 | 9 | using IO.Ably.Realtime.Workflow; |
| 10 | +using IO.Ably.Tests.Infrastructure; |
10 | 11 | using IO.Ably.Types; |
11 | 12 | using Xunit; |
12 | 13 | using Xunit.Abstractions; |
@@ -342,6 +343,55 @@ public async Task WhenItMovesFromDisconnectedToSuspended_ShouldTryDefaultHostAga |
342 | 343 | realtimeHosts.Last().Should().Be("realtime.ably.io"); |
343 | 344 | } |
344 | 345 |
|
| 346 | + [Fact] |
| 347 | + [Trait("spec", "RTN17j")] |
| 348 | + [Trait("spec", "RTN17f")] |
| 349 | + public async Task WhenConnectionRetryNonRecoverableError_ShouldAlwaysTryDefaultHostFirst() |
| 350 | + { |
| 351 | + var client = await GetConnectedClient(opts => |
| 352 | + { |
| 353 | + opts.DisconnectedRetryTimeout = TimeSpan.FromSeconds(2); |
| 354 | + opts.SuspendedRetryTimeout = TimeSpan.FromSeconds(2); |
| 355 | + }); |
| 356 | + |
| 357 | + // Reduced connectionStateTTL for limited disconnected retries upto 20 seconds |
| 358 | + client.State.Connection.ConnectionStateTtl = TimeSpan.FromSeconds(20); |
| 359 | + |
| 360 | + var realtimeHosts = new List<string>(); |
| 361 | + FakeTransportFactory.InitialiseFakeTransport = p => realtimeHosts.Add(p.Parameters.Host); |
| 362 | + |
| 363 | + client.Connection.On(ConnectionEvent.Connecting, stateChange => |
| 364 | + { |
| 365 | + if (stateChange.Previous == ConnectionState.Disconnected) |
| 366 | + { |
| 367 | + ReceiveNonRecoverableDisconnectMessage(client); |
| 368 | + } |
| 369 | + }); |
| 370 | + |
| 371 | + // Receive first disconnect message on CONNECTED client, will call above callback after timeout |
| 372 | + ReceiveNonRecoverableDisconnectMessage(client); |
| 373 | + |
| 374 | + await new ConditionalAwaiter(() => client.Connection.State == ConnectionState.Suspended, null, 120); |
| 375 | + |
| 376 | + client.Connection.State.Should().Be(ConnectionState.Suspended); |
| 377 | + await client.WaitForState(ConnectionState.Connecting); |
| 378 | + |
| 379 | + ReceiveNonRecoverableDisconnectMessage(client); |
| 380 | + |
| 381 | + await client.WaitForState(ConnectionState.Suspended); |
| 382 | + await client.WaitForState(ConnectionState.Connecting); |
| 383 | + |
| 384 | + realtimeHosts.Should().AllBe("realtime.ably.io"); |
| 385 | + } |
| 386 | + |
| 387 | + private void ReceiveNonRecoverableDisconnectMessage(AblyRealtime client) |
| 388 | + { |
| 389 | + client.FakeProtocolMessageReceived(new ProtocolMessage(ProtocolMessage.MessageAction.Disconnected) |
| 390 | + { |
| 391 | + Error = new ErrorInfo { StatusCode = HttpStatusCode.Forbidden } |
| 392 | + }); |
| 393 | + } |
| 394 | + |
345 | 395 | public ConnectionFallbackSpecs(ITestOutputHelper output) |
346 | 396 | : base(output) |
347 | 397 | { |
|
0 commit comments