Simulates S101 communication.
        protected static Task TestWithRobot <TResourceNamespace>(
            Func <S101Client, Task> testCallback,
            IS101Logger consumerLogger,
            IS101Logger providerLogger,
            EmberTypeBag types,
            bool sendFirstMessage,
            string logXmlName,
            params object[] args)
        {
            var xml = string.Format(CultureInfo.InvariantCulture, GetContent <TResourceNamespace>(logXmlName), args);

            return(TestNoExceptionsAsync(
                       async(consumerClientTask, providerClient) =>
            {
                using (var reader = new StringReader(xml))
                    using (var xmlReader = XmlReader.Create(reader))
                    {
                        var robotTask = S101Robot.RunAsync(providerClient, types, xmlReader, sendFirstMessage);

                        using (var consumerClient = await consumerClientTask)
                        {
                            var testTask = testCallback(consumerClient);

                            // The following lines ensure that exceptions thrown from either testTask or robotTask are
                            // immediately propagated up the call chain to fail the test. It also makes sure that
                            // both tasks complete when the first completed task did not throw an exception.
                            await await Task.WhenAny(testTask, robotTask);
                            await Task.WhenAll(testTask, robotTask);
                        }
                    }
            },
                       () => ConnectAsync(-1, consumerLogger),
                       () => WaitForConnectionAsync(providerLogger)));
        }
Esempio n. 2
0
        /// <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();
            }
        }
Esempio n. 3
0
        /// <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"));
            });
        }