summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2007-01-10 13:02:45 +0000
committerRobert Greig <rgreig@apache.org>2007-01-10 13:02:45 +0000
commit13089aec5735eed904988130a8c1d7733ea66828 (patch)
tree66491c64da697e2dbb29b93c5ce79899b72d4b44
parent6512467ba70eaf3e2f4b09dc31ee9712d534542a (diff)
downloadqpid-python-13089aec5735eed904988130a8c1d7733ea66828.tar.gz
Qpid-257 patch applied.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@494803 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs25
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersExchangeTest.cs270
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs105
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs113
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj2
5 files changed, 293 insertions, 222 deletions
diff --git a/qpid/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs b/qpid/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs
index e27174909c..fae610eb85 100644
--- a/qpid/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs
+++ b/qpid/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs
@@ -26,19 +26,32 @@ using Qpid.Client.qms;
namespace Qpid.Client.Tests
{
+ /// <summary>
+ /// Provides a basis for writing Unit tests that communicate with an AMQ protocol broker. By default it creates a connection
+ /// to a message broker running on localhost on the standard AMQ port, 5672, using guest:guest login credentials, on the default exchange,
+ /// 'test' queue.
+ /// </summary>
public class BaseMessagingTestFixture
{
private static ILog _logger = LogManager.GetLogger(typeof(BaseMessagingTestFixture));
+ /// <summary> The default AMQ connection URL to use for tests. </summary>
const string connectionUri = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+ /// <summary> Holds the test connection. </summary>
protected IConnection _connection;
+ /// <summary> Holds the test channel. </summary>
protected IChannel _channel;
+ /// <summary>
+ /// Creates the test connection and channel.
+ /// </summary>
[SetUp]
public virtual void Init()
{
+ _logger.Info("public virtual void Init(): called");
+
try
{
ConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
@@ -52,14 +65,20 @@ namespace Qpid.Client.Tests
}
}
+ /// <summary>
+ /// Disposes the test connection. This is called manually because the connection is a field so dispose will not be automatically
+ /// called on it.
+ /// </summary>
[TearDown]
- public void Shutdown()
+ public virtual void Shutdown()
{
- Console.WriteLine("Shutdown");
+ _logger.Info("public virtual void Shutdown(): called");
+
if (_connection != null)
{
- Console.WriteLine("Disposing connection");
+ _logger.Info("Disposing connection.");
_connection.Dispose();
+ _logger.Info("Connection disposed.");
}
}
}
diff --git a/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersExchangeTest.cs b/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersExchangeTest.cs
new file mode 100644
index 0000000000..fe44bc8639
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersExchangeTest.cs
@@ -0,0 +1,270 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Qpid.Framing;
+using Qpid.Messaging;
+
+namespace Qpid.Client.Tests
+{
+ /// <summary>
+ /// Sets up a producer/consumer pair to send test messages through a header exchange. The header exchange matching pattern is tested to
+ /// verify that it correctly matches or filters out messages based on their headers.
+ ///
+ /// Check that a message matching all fields of a headers exchange is passed by the exchange.
+ /// Check that a message containing values for empty fields of a headers exchange is passed by the exchange.
+ /// Check that a message matching only some fields of a headers exhcnage is not passed by the exchange.
+ /// Check that a message with additional fields to the correct matching fields of a headers exchange is passed by the exchange.
+ /// </summary>
+ ///
+ /// <todo>Remove the HeadersMatchingProducer class and rename this to HeaderExchangeTest. The producer and consumer are implemented
+ /// in a single test class to make running this as part of an automated test suite possible.</todo>
+ ///
+ /// <todo>Consider not using a delegate to callback the OnMessage method. Easier to just call receive on the consumer but using the
+ /// callback does demonstrate how to do so.</todo>
+ [TestFixture]
+ public class HeadersExchangeTest : BaseMessagingTestFixture
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(HeadersExchangeTest));
+
+ /// <summary> Holds the default test timeout for broker communications before tests give up. </summary>
+ private static readonly int TIMEOUT = 1000;
+
+ /// <summary> Holds the name of the headers exchange to create to send test messages on. </summary>
+ private string _exchangeName = "ServiceQ1";
+
+ /// <summary> Used to preserve the most recent exception in case test cases need to examine it. </summary>
+ private Exception _lastException = null;
+
+ /// <summary> Used to preserve the most recent message from the test consumer. </summary>
+ private IMessage _lastMessage = null;
+
+ /// <summary> The test consumer to get messages from the broker with. </summary>
+ private IMessageConsumer _consumer;
+
+ private IMessagePublisher _publisher;
+
+ private AutoResetEvent _evt = new AutoResetEvent(false);
+
+ private MessageReceivedDelegate _msgRecDelegate;
+ private ExceptionListenerDelegate _exceptionDelegate;
+
+ [SetUp]
+ public override void Init()
+ {
+ // Ensure that the base init method is called. It establishes a connection with the broker.
+ base.Init();
+
+ _logger.Info("Starting...");
+ _logger.Info("Exchange name is '" + _exchangeName + "'...");
+
+ // Register this to listen for exceptions on the test connection.
+ _exceptionDelegate = new ExceptionListenerDelegate(OnException);
+ _connection.ExceptionListener += _exceptionDelegate;
+
+ // Declare a new headers exchange with the name of the test service.
+ _channel.DeclareExchange(_exchangeName, ExchangeClassConstants.HEADERS);
+
+ // Create a non-durable, temporary (aka auto-delete), exclusive queue.
+ string queueName = _channel.GenerateUniqueName();
+ _channel.DeclareQueue(queueName, false, true, true);
+
+ // Bind the queue to the new headers exchange, setting up some header patterns for the exchange to match.
+ _channel.Bind(queueName, _exchangeName, null, CreatePatternAsFieldTable());
+
+ // Create a test consumer to consume messages from the test exchange.
+ _consumer = _channel.CreateConsumerBuilder(queueName)
+ .WithPrefetchLow(100)
+ .WithPrefetchHigh(500)
+ .WithNoLocal(true)
+ .Create();
+
+ // Register this to listen for messages on the consumer.
+ _msgRecDelegate = new MessageReceivedDelegate(OnMessage);
+ _consumer.OnMessage += _msgRecDelegate;
+
+ // Clear the most recent message and exception.
+ _lastException = null;
+ _lastMessage = null;
+
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(_exchangeName)
+ .WithMandatory(true)
+ .Create();
+
+ _publisher.DeliveryMode = DeliveryMode.NonPersistent;
+
+ // Start all channel
+ _connection.Start();
+ }
+
+ /// <summary>
+ /// Deregisters the on message delegate before closing the connection.
+ /// </summary>
+ [TearDown]
+ public override void Shutdown()
+ {
+ _logger.Info("public void Shutdown(): called");
+
+ //_consumer.OnMessage -= _msgRecDelegate;
+ //_connection.ExceptionListener -= _exceptionDelegate;
+
+ _connection.Stop();
+
+ base.Shutdown();
+ }
+
+ /// <summary>
+ /// Callback method that is passed any messages received on the test channel.
+ /// </summary>
+ ///
+ /// <param name="message">The received message.</param>
+ public void OnMessage(IMessage message)
+ {
+ _logger.Debug(string.Format("message.Type = {0}", message.GetType()));
+ _logger.Debug("Got message '" + message + "'");
+
+ // Preserve the most recent exception so that test cases can examine it.
+ _lastMessage = message;
+
+ // Notify any waiting threads that a message has been received.
+ _evt.Set();
+ }
+
+ /// <summary>Callback method to handle any exceptions raised by the test connection.</summary>
+ ///
+ /// <param name="e">The connection exception.</param>
+ public void OnException(Exception e)
+ {
+ // Preserve the most recent exception in case test cases need to examine it.
+ _lastException = e;
+
+ // Notify any waiting threads that an exception event has occurred.
+ _evt.Set();
+ }
+
+ /// <summary>Check that a message matching all fields of a headers exchange is passed by the exchange.</summary>
+ [Test]
+ public void TestMatchAll()
+ {
+ IMessage msg = _channel.CreateTextMessage("matches match2=''");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>Check that a message containing values for empty fields of a headers exchange is passed by the exchange.</summary>
+ [Test]
+ public void TestMatchEmptyMatchesAnything()
+ {
+ // Send a test message that matches the headers exchange.
+ IMessage msg = _channel.CreateTextMessage("matches match1='foo' and match2='bar'");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "bar";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>Check that a message matching only some fields of a headers exhcnage is not passed by the exchange.</summary>
+ [Test]
+ public void TestMatchOneFails()
+ {
+ IMessage msg = _channel.CreateTextMessage("not match - only match1");
+ msg.Headers["match1"] = "foo";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and not received.
+ SendTestMessage(msg, false);
+ }
+
+ /// <summary>
+ /// Check that a message with additional fields to the correct matching fields of a headers exchange is passed by
+ /// the exchange.
+ /// </summary>
+ [Test]
+ public void TestMatchExtraFields()
+ {
+ IMessage msg = _channel.CreateTextMessage("matches - extra headers");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "bar";
+ msg.Headers["match3"] = "not required";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>
+ /// Sends the specified message to the test publisher, and confirms that it was received by the test consumer or not
+ /// depending on whether or not the message should be received by the consumer.
+ ///
+ /// Any exceptions raised by the connection will cause an Assert failure exception to be raised.
+ /// </summary>
+ ///
+ /// <param name="msgSend">The message to send.</param>
+ /// <param name="shouldPass">A flag to indicate whether or not the message should be received by the consumer.</param>
+ private void SendTestMessage(IMessage msgSend, bool shouldPass)
+ {
+ _publisher.Send(msgSend);
+ _evt.WaitOne(TIMEOUT, true);
+
+ // Check that an exception other than not routable was raised in which case re-raise it as a test error.
+ if (_lastException != null && !(_lastException.InnerException is AMQUndeliveredException))
+ {
+ Assert.Fail("Exception {0} was raised by the broker connection.", _lastException);
+ }
+ // Check that a message was returned if the test is expecting the message to pass.
+ else if (shouldPass)
+ {
+ Assert.IsNotNull(_lastMessage, "Did not get a matching message from the headers exchange.");
+ }
+ // Check that a not routable exception was raised if the test is expecting the message to fail.
+ else if (_lastException != null && _lastException.InnerException is AMQUndeliveredException)
+ {
+ Assert.IsNull(_lastMessage, "Message could not be routed so consumer should not have received it.");
+ }
+ // The broker did not respond within the test timeout so fail the test.
+ else
+ {
+ Assert.Fail("The test timed out without a response from the broker.");
+ }
+ }
+
+ /// <summary>
+ /// Returns a field table containing patterns to match the test header exchange against.
+ /// </summary>
+ ///
+ /// <returns>A field table containing test patterns.</returns>
+ private FieldTable CreatePatternAsFieldTable()
+ {
+ FieldTable matchTable = new FieldTable();
+
+ // Currently all String matching must be prefixed by an "S" ("S" for string because of a failing of the FieldType definition).
+ matchTable["Smatch1"] = "foo";
+ matchTable["Smatch2"] = "";
+
+ return matchTable;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs b/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs
deleted file mode 100644
index 1b27f920b8..0000000000
--- a/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using System;
-using System.Threading;
-using log4net;
-using NUnit.Framework;
-using Qpid.Framing;
-using Qpid.Messaging;
-
-namespace Qpid.Client.Tests
-{
- [TestFixture]
- public class HeadersMatchingConsumer : BaseMessagingTestFixture
- {
- private static ILog _logger = LogManager.GetLogger(typeof(HeadersMatchingConsumer));
-
- private string _serviceName = "ServiceQ1";
-
- private AutoResetEvent _evt = new AutoResetEvent(false);
-
- [SetUp]
- public override void Init()
- {
- base.Init();
-
- _logger.Info("Starting...");
-
- _logger.Info("Service (queue) name is '" + _serviceName + "'...");
-
- _connection.ExceptionListener = new ExceptionListenerDelegate(OnException);
-
- // Declare a new HeadersExchange with the name of the service.
- _channel.DeclareExchange(_serviceName, ExchangeClassConstants.HEADERS);
-
- // Create non-durable, temporary (aka auto-delete), exclusive queue.
- string queueName = _channel.GenerateUniqueName();
- _channel.DeclareQueue(queueName, false, true, true);
-
- // Bind our queue to the new HeadersExchange.
- _channel.Bind(queueName, _serviceName, null, CreatePatternAsFieldTable());
-
- IMessageConsumer consumer = _channel.CreateConsumerBuilder(queueName)
- .WithPrefetchLow(100)
- .WithPrefetchHigh(500)
- .WithNoLocal(true)
- .Create();
-
- consumer.OnMessage = new MessageReceivedDelegate(OnMessage);
- }
-
- [Test]
- public void Test()
- {
- _connection.Start();
- _logger.Info("Waiting...");
- _evt.WaitOne();
- }
-
- public void OnMessage(IMessage message)
- {
- _logger.Info(string.Format("message.Type = {0}", message.GetType()));
- _logger.Info("Got message '" + message + "'");
- }
-
- private FieldTable CreatePatternAsFieldTable()
- {
- FieldTable matchTable = new FieldTable();
- // Currently all String matching must be prefixed by an "S" ("S" for string because of a failing of the FieldType definition).
- matchTable["Smatch1"] = "foo";
- matchTable["Smatch2"] = "";
- return matchTable;
- }
-
- public void OnException(Exception e)
- {
- if (e is QpidException && e.InnerException is AMQDisconnectedException)
- {
- _logger.Error("Broker closed connection");
- }
- else
- {
- _logger.Error("Connection exception occurred: " + e);
- }
- _evt.Set();
- }
- }
-}
diff --git a/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs b/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs
deleted file mode 100644
index c748ef8840..0000000000
--- a/qpid/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using log4net;
-using NUnit.Framework;
-using Qpid.Messaging;
-
-namespace Qpid.Client.Tests
-{
- [TestFixture]
- public class HeadersMatchingProducer : BaseMessagingTestFixture
- {
- private static ILog _logger = LogManager.GetLogger(typeof(HeadersMatchingProducer));
-
- private string _commandExchangeName = "ServiceQ1";
-
- private int _messageCount = 12;
-
- private IMessagePublisher _publisher;
-
- [SetUp]
- public override void Init()
- {
- base.Init();
-
- try
- {
- _publisher = _channel.CreatePublisherBuilder()
- .WithExchangeName(_commandExchangeName)
- .WithMandatory(true)
- .Create();
-
- // Disabling timestamps - a performance optimisation where timestamps and TTL/expiration
- // are not required.
- _publisher.DisableMessageTimestamp = true;
-
- _publisher.DeliveryMode = DeliveryMode.NonPersistent;
- }
- catch (QpidException e)
- {
- _logger.Error("Error: " + e, e);
- }
- }
-
- [Test]
- public void SendMessages()
- {
- _connection.Start();
- for (int i = 0; i < _messageCount; i++)
- {
- int rem = i % 6;
- IMessage msg = null;
- switch (rem)
- {
- case 0:
- msg = _channel.CreateTextMessage("matches match2='bar'");
- msg.Headers["match1"] = "foo";
- msg.Headers["match2"] = "bar";
- break;
-
- case 1:
- msg = _channel.CreateTextMessage("not match - only match1");
- msg.Headers["match1"] = "foo";
- break;
-
- case 2:
- msg = _channel.CreateTextMessage("not match - only match2");
- msg.Headers["match2"] = "bar";
- break;
-
- case 3:
- msg = _channel.CreateTextMessage("matches match2=''");
- msg.Headers["match1"] = "foo";
- msg.Headers["match2"] = "";
- break;
-
- case 4:
- msg = _channel.CreateTextMessage("matches - extra headers");
- msg.Headers["match1"] = "foo";
- msg.Headers["match2"] = "bar";
- msg.Headers["match3"] = "not required";
- break;
-
- case 5:
- msg = _channel.CreateTextMessage("5: no match");
- msg.Headers["match1"] = "foo1";
- msg.Headers["match2"] = "bar";
- msg.Headers["match3"] = "not required";
- break;
- }
- _publisher.Send(msg);
- }
- _logger.Info("Finished sending " + _messageCount + " messages");
- }
- }
-}
diff --git a/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj b/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj
index a7b6e49879..401bbce75d 100644
--- a/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj
+++ b/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj
@@ -47,7 +47,7 @@
<Compile Include="connection\ConnectionTest.cs" />
<Compile Include="failover\FailoverTest.cs" />
<Compile Include="failover\FailoverTxTest.cs" />
- <Compile Include="HeadersExchange\HeadersMatchingConsumer.cs" />
+ <Compile Include="HeadersExchange\HeadersExchangeTest.cs" />
<Compile Include="HeadersExchange\HeadersMatchingProducer.cs" />
<Compile Include="MultiConsumer\ProducerMultiConsumer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />