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)));
        }
Exemplo n.º 2
0
        /// <summary>Initializes a new instance of the <see cref="S101LogReader"/> class.</summary>
        /// <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 events from. The format needs to match the
        /// one written by <see cref="S101Logger"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="types"/> and/or <paramref name="logReader"/> equal
        /// <c>null</c>.</exception>
        public S101LogReader(EmberTypeBag types, XmlReader logReader)
        {
            if (logReader == null)
            {
                throw new ArgumentNullException(nameof(logReader));
            }

            this.converter = new EmberConverter(types);
            this.logReader = logReader;
            logReader.ReadStartElement(LogNames.Root);
        }
Exemplo n.º 3
0
        /// <summary>Initializes a new instance of the <see cref="S101LogReader"/> class.</summary>
        /// <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 events from. The format needs to match the
        /// one written by <see cref="S101Logger"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="types"/> and/or <paramref name="logReader"/> equal
        /// <c>null</c>.</exception>
        public S101LogReader(EmberTypeBag types, XmlReader logReader)
        {
            if (logReader == null)
            {
                throw new ArgumentNullException(nameof(logReader));
            }

            this.converter = new EmberConverter(types);
            this.logReader = logReader;
            logReader.ReadStartElement(LogNames.Root);
        }
Exemplo n.º 4
0
        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();
        }
Exemplo n.º 5
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();
            }
        }
Exemplo n.º 6
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();
            }
        }
Exemplo n.º 7
0
        private S101Robot(S101Client client, EmberTypeBag types, XmlReader logReader, bool sendFirstMessage)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            this.client = 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();
        }
Exemplo n.º 8
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class.</summary>
 /// <param name="types">The types to pass to the internal <see cref="EmberConverter"/>, which is used to convert
 /// the payload to XML.</param>
 /// <param name="xmlLogWriter">The <see cref="XmlWriter"/> to write log messages to.</param>
 /// <exception cref="ArgumentNullException"><paramref name="types"/> and/or <paramref name="xmlLogWriter"/>
 /// equal <c>null</c>.</exception>
 public S101Logger(EmberTypeBag types, XmlWriter xmlLogWriter)
     : this(new EmberConverter(types), xmlLogWriter)
 {
 }
Exemplo n.º 9
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class.</summary>
 /// <param name="types">The types to pass to the internal <see cref="EmberConverter"/>, which is used to convert
 /// the payload to XML.</param>
 /// <param name="logWriter">The <see cref="TextWriter"/> to write log messages to, will be passed to
 /// <see cref="XmlWriter.Create(TextWriter, XmlWriterSettings)"/>.</param>
 /// <param name="settings">The settings to create the internal <see cref="XmlWriter"/> with, will be passed to
 /// <see cref="XmlWriter.Create(TextWriter, XmlWriterSettings)"/>.</param>
 /// <exception cref="ArgumentNullException"><paramref name="types"/>, <paramref name="logWriter"/> and/or
 /// <paramref name="settings"/> equal <c>null</c>.</exception>
 public S101Logger(EmberTypeBag types, TextWriter logWriter, XmlWriterSettings settings)
     : this(types, XmlWriter.Create(ValidateLogWriter(logWriter), settings))
 {
 }
Exemplo n.º 10
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class by calling
 /// <see cref="S101Logger(EmberTypeBag, TextWriter, XmlWriterSettings)">S101Logger(
 /// <paramref name="types"/>, <paramref name="logWriter"/>, new XmlWriterSettings { Indent = true })</see>.
 /// </summary>
 public S101Logger(EmberTypeBag types, TextWriter logWriter)
     : this(types, logWriter, new XmlWriterSettings { Indent = true })
 {
 }
Exemplo n.º 11
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class.</summary>
 /// <param name="types">The types to pass to the internal <see cref="EmberConverter"/>, which is used to convert
 /// the payload to XML.</param>
 /// <param name="xmlLogWriter">The <see cref="XmlWriter"/> to write log messages to.</param>
 /// <exception cref="ArgumentNullException"><paramref name="types"/> and/or <paramref name="xmlLogWriter"/>
 /// equal <c>null</c>.</exception>
 public S101Logger(EmberTypeBag types, XmlWriter xmlLogWriter)
     : this(new EmberConverter(types), xmlLogWriter)
 {
 }
Exemplo n.º 12
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class.</summary>
 /// <param name="types">The types to pass to the internal <see cref="EmberConverter"/>, which is used to convert
 /// the payload to XML.</param>
 /// <param name="logWriter">The <see cref="TextWriter"/> to write log messages to, will be passed to
 /// <see cref="XmlWriter.Create(TextWriter, XmlWriterSettings)"/>.</param>
 /// <param name="settings">The settings to create the internal <see cref="XmlWriter"/> with, will be passed to
 /// <see cref="XmlWriter.Create(TextWriter, XmlWriterSettings)"/>.</param>
 /// <exception cref="ArgumentNullException"><paramref name="types"/>, <paramref name="logWriter"/> and/or
 /// <paramref name="settings"/> equal <c>null</c>.</exception>
 public S101Logger(EmberTypeBag types, TextWriter logWriter, XmlWriterSettings settings)
     : this(types, XmlWriter.Create(ValidateLogWriter(logWriter), settings))
 {
 }
Exemplo n.º 13
0
 /// <summary>Initializes a new instance of the <see cref="S101Logger"/> class by calling
 /// <see cref="S101Logger(EmberTypeBag, TextWriter, XmlWriterSettings)">S101Logger(
 /// <paramref name="types"/>, <paramref name="logWriter"/>, new XmlWriterSettings { Indent = true })</see>.
 /// </summary>
 public S101Logger(EmberTypeBag types, TextWriter logWriter)
     : this(types, logWriter, new XmlWriterSettings {
     Indent = true
 })
 {
 }
 /// <summary>Initializes a new instance of the <see cref="GlowLogInterpreter"/> class.</summary>
 /// <param name="types">The types to pass to the internal <see cref="S101LogReader"/>.</param>
 /// <param name="logReader">The <see cref="XmlReader"/> to read the messages from. The format needs to match the
 /// one written by <see cref="S101Logger"/>.</param>
 /// <exception cref="ArgumentNullException"><paramref name="types"/> and/or <paramref name="logReader"/> equal
 /// <c>null</c>.</exception>
 public GlowLogInterpreter(EmberTypeBag types, XmlReader logReader)
 {
     this.reader = new S101LogReader(types, logReader);
 }