public void ConnectionLostTest() { AsyncPump.Run( async() => { var readResult = new TaskCompletionSource <int>(); using (var client = new S101Client( new MemoryStream(), (b, o, c, t) => readResult.Task, (b, o, c, t) => Task.FromResult(false), new S101Logger(GlowTypes.Instance, Console.Out))) { var exception = new IOException(); var connectionLost = new TaskCompletionSource <bool>(); client.ConnectionLost += (s, e) => { Assert.AreEqual(exception, e.Exception); connectionLost.SetResult(true); }; readResult.SetException(exception); await connectionLost.Task; await AssertThrowAsync <ObjectDisposedException>( () => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest()))); } }); }
private S101Robot(S101Client client, EmberTypeBag types, XmlReader logReader, bool sendFirstMessage) { this.client = client ?? throw new ArgumentNullException(nameof(client)); this.logReader = new S101LogReader(types, logReader); this.sendFirstMessage = sendFirstMessage; this.client.OutOfFrameByteReceived += this.OnOutOfFrameByteReceived; this.client.EmberDataReceived += this.OnClientEmberDataReceived; this.client.ConnectionLost += this.OnClientConnectionLost; this.SendMessages(); }
/// <summary>Asynchronously simulates S101 communication.</summary> /// <param name="client">The <see cref="S101Client"/> to use.</param> /// <param name="types">The types to pass to the internal <see cref="EmberConverter"/>, which is used to convert /// between XML payload and EmBER payload.</param> /// <param name="logReader">The <see cref="XmlReader"/> to read the messages from. The messages that are /// expected to be received from the remote party as well as the ones that will be sent are read with this /// reader. The format needs to match the one written by <see cref="S101Logger"/>.</param> /// <param name="sendFirstMessage"><c>true</c> to send the first <see cref="EmberData"/> message read with /// <paramref name="logReader"/>; <c>false</c> to wait for the first message from the remote party and match it /// to the first <see cref="EmberData"/> message read with <paramref name="logReader"/>.</param> /// <returns>A <see cref="Task"/> object representing the communication. This task completes when one of the /// following events occurs: /// <list type="bullet"> /// <item>The last message in the log has been sent/received.</item> /// <item>The <see cref="S101Client.ConnectionLost"/> event occurred on the client passed to /// <see cref="RunAsync"/>.</item> /// </list></returns> /// <exception cref="ArgumentNullException"><paramref name="client"/>, <paramref name="types"/> and/or /// <paramref name="logReader"/> equal <c>null</c>.</exception> /// <exception cref="S101Exception"><list type="bullet"> /// <item>There was a mismatch between an incoming message and one read from the log.</item> /// <item>The <see cref="S101Client.ConnectionLost"/> event occurred on the client passed to /// <see cref="RunAsync"/>.</item> /// </list></exception> /// <exception cref="XmlException">The XML read with <paramref name="logReader"/> is invalid, see /// <see cref="Exception.Message"/> for details.</exception> /// <remarks> /// <para>Reads messages with <paramref name="logReader"/> and depending on the direction either sends them to /// the remote party or matches them to messages received from the remote party. If a message received from the /// remote party does not match the one in the log then an appropriate exception is thrown.</para> /// <para>Subsequent messages read with <paramref name="logReader"/> that match the direction of the first /// message read with <paramref name="logReader"/> are sent if <paramref name="sendFirstMessage"/> equals /// <c>true</c>; otherwise such messages are matched to the ones received from the remote party. The opposite /// happens with log messages of opposite direction.</para> /// </remarks> public static async Task RunAsync( S101Client client, EmberTypeBag types, XmlReader logReader, bool sendFirstMessage) { var robot = new S101Robot(client, types, logReader, sendFirstMessage); try { await robot.WaitAsync(); } finally { robot.Dispose(); } }
public void ExceptionTest() { AsyncPump.Run( async() => { using (var client = new S101Client(Stream.Null, Stream.Null.ReadAsync, Stream.Null.WriteAsync)) { await AssertThrowAsync <ArgumentNullException>( () => S101Robot.RunAsync(null, Types, XmlReader.Create(Stream.Null), false), () => S101Robot.RunAsync(client, null, XmlReader.Create(Stream.Null), false), () => S101Robot.RunAsync(client, Types, null, false)); } await AssertThrowAsync <XmlException>(() => TestWithRobot <S101Payloads>( client => Task.FromResult(false), null, null, Types, true, "MissingPayloadLog.xml")); }); }
public void ExceptionTest() { using (var dummy = new MemoryStream()) { ReadAsyncCallback fakeRead = (b, o, c, t) => Task.FromResult(0); WriteAsyncCallback fakeWrite = (b, o, c, t) => Task.FromResult(false); AssertThrow <NotSupportedException>(() => new S101Client(dummy, fakeRead, fakeWrite).Dispose()); AsyncPump.Run( async() => { using (var connection = new CompleteOnDispose()) using (var client = new S101Client(connection, (b, o, c, t) => connection.Task, fakeWrite)) { await AssertThrowAsync <InvalidOperationException>( () => Task.Run(() => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest())))); } AssertThrow <ArgumentNullException>( () => new S101Client(null, fakeRead, fakeWrite).Dispose(), () => new S101Client(dummy, null, fakeWrite).Dispose(), () => new S101Client(dummy, fakeRead, null).Dispose()); AssertThrow <ArgumentOutOfRangeException>( () => new S101Client(dummy, fakeRead, fakeWrite, null, 3000, 0).Dispose(), () => new S101Client(dummy, fakeRead, fakeWrite, null, -2, 1).Dispose()); using (var connection = new CompleteOnDispose()) using (var client = new S101Client( connection, (b, o, c, t) => connection.Task, fakeWrite, null, 3000, 1)) { await AssertThrowAsync <ArgumentNullException>( () => client.SendMessageAsync(null)); await AssertThrowAsync <ArgumentException>(() => client.SendMessageAsync(EmberDataMessage)); await AssertThrowAsync <ArgumentException>(() => client.SendOutOfFrameByteAsync(0xFE)); client.Dispose(); await AssertThrowAsync <ObjectDisposedException>( () => client.SendMessageAsync(new S101Message(0x00, new KeepAliveRequest()))); } }); } }
public void KeepAliveExceptionTest() { AsyncPump.Run( async() => { var providerTask = WaitForConnectionAsync(); int timeout = this.Random.Next(4000, 8000); Console.WriteLine("Timeout: {0}", timeout); using (var consumer = new TcpClient("localhost", 8099)) using (var stream = consumer.GetStream()) using (var logger = new S101Logger(GlowTypes.Instance, Console.Out)) using (var consumerClient = new S101Client(consumer, stream.ReadAsync, stream.WriteAsync, logger, timeout, 8192)) { (await providerTask).Ignore(); consumerClient.KeepAliveRequestSlot = (byte)this.Random.Next(byte.MaxValue + 1); var source = new TaskCompletionSource <bool>(); consumerClient.ConnectionLost += (s, e) => OnConnectionLost(source, e); var task = await Task.WhenAny(source.Task, Task.Delay(timeout + (timeout / 4))); await AssertThrowAsync <S101Exception>(() => task); } }); }