示例#1
0
            public async Task WithNackMessageReceived_CallbackIsCalledWithError()
            {
                // Arrange
                var client = await GetConnectedClient();

                var callbacks = new List <ValueTuple <bool, ErrorInfo> >();
                var message   = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");

                void Callback(bool ack, ErrorInfo err)
                {
                    callbacks.Add((ack, err));
                }

                // Act
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 0, Count = 1
                }));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 1, Count = 1
                }));

                await client.ProcessCommands();

                // Assert
                callbacks.Count.Should().Be(2);
                Assert.True(callbacks.TrueForAll(c => c.Item1 == false)); // Nack
                Assert.True(callbacks.TrueForAll(c => c.Item2 != null));  // Error
            }
示例#2
0
            public async Task WhenNackReceivedForMultipleMessage_AllCallbacksAreCalledAndErrorMessagePassed()
            {
                // Arrange
                var client = await GetConnectedClient();

                var callbacks = new List <ValueTuple <bool, ErrorInfo> >();

                var message = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");

                void Callback(bool ack, ErrorInfo err)
                {
                    callbacks.Add((ack, err));
                }

                // Act
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));

                var error = new ErrorInfo("reason", 123);

                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 0, Count = 3, Error = error
                }));

                await client.ProcessCommands();

                // Assert
                callbacks.Count.Should().Be(3);
                Assert.True(callbacks.TrueForAll(c => !c.Item1));                        // Nack
                Assert.True(callbacks.TrueForAll(c => ReferenceEquals(c.Item2, error))); // Error
            }
示例#3
0
        public async Task WithBase64Message_ShouldKeepBase64DecodedPayload()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);

            const string testString = "Testing, testing, testing";
            var          successfulProtocolMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[] { new Message {
                                       Data = testString.ToBase64(), Encoding = "base64"
                                   }, },
            };

            realtime.ExecuteCommand(ProcessMessageCommand.Create(successfulProtocolMessage));

            await realtime.ProcessCommands();

            var previousPayload = channel.MessageDecodingContext.PreviousPayload;

            previousPayload.StringData.Should().BeNull();
            previousPayload.Encoding.Should().BeEmpty();
            previousPayload.ByteData.Should().Equal(testString.GetBytes());
        }
示例#4
0
        WhenMessageReceived_WithNotMatchingDeltaFromProperty_ShouldStartDecodeRecoveryAndMoveToAttachingWithError()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);
            var awaiter = new TaskCompletionAwaiter();
            ChannelStateChange stateChange = null;

            channel.On(ChannelEvent.Attaching, change =>
            {
                stateChange = change;
                channel.DecodeRecovery.Should().BeTrue();
                awaiter.Done();
            });

            realtime.ExecuteCommand(ProcessMessageCommand.Create(
                                        new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[]
                {
                    new Message {
                        Extras = CreateExtrasWithDelta(new DeltaExtras("1", string.Empty))
                    },
                },
            }));

            await awaiter.Task;

            stateChange.Current.Should().Be(ChannelState.Attaching);
            stateChange.Error.Code.Should().Be(ErrorCodes.VcDiffDecodeError);
        }
示例#5
0
        public async Task WithBinaryMessage_ShouldKeepItPreviousPayloadInBinaryForm()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);

            var binaryData = new byte[] { 112, 100, 111 };
            var successfulProtocolMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[] { new Message {
                                       Data = binaryData
                                   }, },
            };

            realtime.ExecuteCommand(ProcessMessageCommand.Create(successfulProtocolMessage));
            await realtime.ProcessCommands();

            var previousPayload = channel.MessageDecodingContext.PreviousPayload;

            previousPayload.StringData.Should().BeNull();
            previousPayload.ByteData.Should().Equal(binaryData);
        }
示例#6
0
        public async Task WithStringMessage_ShouldKeepItWithoutProcessing()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);

            var successfulProtocolMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[] { new Message {
                                       Data = "test", Encoding = "custom"
                                   }, },
            };

            realtime.ExecuteCommand(ProcessMessageCommand.Create(successfulProtocolMessage));
            await realtime.ProcessCommands();

            var previousPayload = channel.MessageDecodingContext.PreviousPayload;

            previousPayload.Encoding.Should().Be("custom");
            previousPayload.StringData.Should().Be("test");
            previousPayload.ByteData.Should().BeNull();
        }
示例#7
0
            public async Task WhenSendingMessage_AckCallbackCalled_ForMultipleMessages()
            {
                // Arrange
                var client = await GetConnectedClient();

                var callbacks = new List <ValueTuple <bool, ErrorInfo> >();

                var message1 = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");
                var message2 = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");
                var message3 = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");

                var awaiter = new TaskCompletionAwaiter();

                Action <bool, ErrorInfo> GetCallback(int forCount) =>
                (ack, err) =>
                {
                    if (callbacks.Count == forCount)
                    {
                        callbacks.Add((ack, err));
                    }

                    if (callbacks.Count == 3)
                    {
                        awaiter.SetCompleted();
                    }
                };

                var ackMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Ack)
                {
                    MsgSerial = 0, Count = 3
                };

                // Act
                client.Workflow.QueueAck(message1, GetCallback(0));
                client.Workflow.QueueAck(message2, GetCallback(1));
                client.Workflow.QueueAck(message3, GetCallback(2));
                client.ExecuteCommand(ProcessMessageCommand.Create(ackMessage));

                await client.ProcessCommands();

                await awaiter.Task;

                // Assert
                callbacks.Count.Should().Be(3);
                Assert.True(callbacks.TrueForAll(c => c.Item1));         // Ack
                Assert.True(callbacks.TrueForAll(c => c.Item2 == null)); // No error
            }
示例#8
0
        WhenMessageReceivedAndFailsVcdiffDecoding_ShouldSendAttachProtocolMessageWithLastSuccessfulChannelSerial()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);

            var successfulProtocolMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel       = channel.Name,
                ChannelSerial = "testSerial",
                Messages      = new[] { new Message {
                                            Data = "test", Encoding = string.Empty
                                        }, },
            };

            realtime.ExecuteCommand(ProcessMessageCommand.Create(successfulProtocolMessage));

            var awaiter = new TaskCompletionAwaiter();

            channel.On(ChannelEvent.Attaching, change => { awaiter.Tick(); });

            realtime.ExecuteCommand(ProcessMessageCommand.Create(
                                        new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[]
                {
                    new Message {
                        Extras = CreateExtrasWithDelta(new DeltaExtras("1", string.Empty))
                    },
                },
            }));

            await awaiter.Task;
            await realtime.ProcessCommands();

            var fakeTransport   = FakeTransportFactory.LastCreatedTransport;
            var lastMessageSend = fakeTransport.LastMessageSend;

            lastMessageSend.Should().NotBeNull();
            lastMessageSend.Action.Should().Be(ProtocolMessage.MessageAction.Attach);
            lastMessageSend.ChannelSerial.Should().Be("testSerial");
        }
示例#9
0
            public async Task WithInboundErrorMessage_WhenNotTokenErrorAndChannelsEmpty_GoesToFailed()
            {
                var client = GetRealtimeClient(opts => opts.RealtimeHost = "non-default.ably.io"); // Force no fallback

                await client.WaitForState(ConnectionState.Connecting);

                // Arrange
                ErrorInfo targetError = new ErrorInfo("test", 123);

                // Act
                client.Workflow.ProcessCommand(ProcessMessageCommand.Create(new ProtocolMessage(ProtocolMessage.MessageAction.Error)
                {
                    Error = targetError
                }));

                // Assert
                await client.WaitForState(ConnectionState.Failed);
            }
示例#10
0
            public async Task WithInboundDisconnectedMessage_ShouldTransitionToDisconnectedState()
            {
                // Arrange
                var client = GetRealtimeClient();

                client.Connect();

                await client.WaitForState(ConnectionState.Connecting);

                var disconnectedMessage = new ProtocolMessage(ProtocolMessage.MessageAction.Disconnected)
                {
                    Error = ErrorInfo.ReasonDisconnected
                };

                // Act
                client.ExecuteCommand(ProcessMessageCommand.Create(disconnectedMessage));

                await client.WaitForState(ConnectionState.Disconnected, TimeSpan.FromSeconds(5));
            }
示例#11
0
        public async Task WhenMessageReceived_WithDeltaError_ShouldNotPassMessageToChannelSubscriber()
        {
            var(realtime, c) = await GetClientAndChannel();

            RealtimeChannel channel = (RealtimeChannel)c;

            channel.SetChannelState(ChannelState.Attached);
            List <Message> receivedMessages = new List <Message>();

            channel.Subscribe(receivedMessages.Add);

            realtime.ExecuteCommand(ProcessMessageCommand.Create(
                                        new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[] { new Message {
                                       Id = "goodMessage", Data = "test"
                                   }, },
            }));

            realtime.ExecuteCommand(ProcessMessageCommand.Create(
                                        new ProtocolMessage(ProtocolMessage.MessageAction.Message)
            {
                Channel  = channel.Name,
                Messages = new[]
                {
                    new Message {
                        Extras = CreateExtrasWithDelta(new DeltaExtras("1", string.Empty))
                    },
                },
            }));

            await Task.Delay(2000); // wait for 2 seconds

            // We want to ensure just the good message was received
            receivedMessages.Should().HaveCount(1);
            receivedMessages.Should().Contain(x => x.Id == "goodMessage");
        }
示例#12
0
 internal static async Task ProcessMessage(this IRealtimeClient client, ProtocolMessage message)
 {
     ((AblyRealtime)client).Workflow.QueueCommand(ProcessMessageCommand.Create(message));
     await client.ProcessCommands();
 }
示例#13
0
        public async Task WhenDeltaDecodeFail_ShouldSetStateToAttachingLogTheErrorAndDiscardTheMessage(Protocol protocol)
        {
            string channelName          = "delta-channel".AddRandomSuffix();
            var    testSink             = new TestLoggerSink();
            var    taskAwaiter          = new TaskCompletionAwaiter(5000);
            var    firstMessageReceived = new TaskCompletionAwaiter();

            using (((IInternalLogger)Logger).CreateDisposableLoggingContext(testSink))
            {
                var realtime = await GetRealtimeClient(protocol);

                var channel = realtime.Channels.Get(channelName, new ChannelOptions(channelParams: new ChannelParams {
                    { "delta", "vcdiff" }
                }));

                var received = new List <Message>();
                channel.Subscribe(message =>
                {
                    received.Add(message);
                    if (received.Count == 1)
                    {
                        firstMessageReceived.Done();
                    }

                    if (received.Count == 2)
                    {
                        taskAwaiter.Done();
                    }
                });

                await channel.AttachAsync();

                // We wait for the first message to be acknowledged. Any consequent messages will be deltas
                await channel.PublishAsync("firstMessage", new TestData("bar", 1, "active"));

                (await firstMessageReceived).Should().BeTrue("First message should be received before continuing with broken message");

                channel.Publish("second", "second message"); // We don't want to wait for the acknowledgement
                realtime.ExecuteCommand(ProcessMessageCommand.Create(new ProtocolMessage(ProtocolMessage.MessageAction.Message)
                {
                    Channel  = channelName,
                    Messages = new[]
                    {
                        new Message
                        {
                            Id = "badMessage", Encoding = "vcdiff", Data = Array.Empty <byte>()
                        },
                    },
                }));

                await channel.WaitForState(ChannelState.Attaching);

                await channel.WaitForAttachedState();

                var result = await taskAwaiter;

                result.Should().BeTrue("TaskAwaiter Done() Should be called.");

                received.Should().HaveCount(2);
                received[1].Data.Should().Be("second message");

                // RTL17 - we make sure the message is not emitted to subscribers
                received.Should().NotContain(x => x.Id == "badMessage");

                bool hasVcdiffErrorMessage = testSink.Messages.Any(x => x.StartsWith(LogLevel.Error.ToString()) &&
                                                                   x.Contains(ErrorCodes.VcDiffDecodeError
                                                                              .ToString()));

                hasVcdiffErrorMessage.Should().BeTrue();
            }
        }
示例#14
0
        void ITransportListener.OnTransportDataReceived(RealtimeTransportData data)
        {
            var message = Handler.ParseRealtimeData(data);

            ExecuteCommand(ProcessMessageCommand.Create(message).TriggeredBy("ConnectionManager.OnTransportDataReceived()"));
        }
示例#15
0
 public static void FakeProtocolMessageReceived(this AblyRealtime client, ProtocolMessage message)
 {
     client.Workflow.QueueCommand(ProcessMessageCommand.Create(message));
 }