diff options
Diffstat (limited to 'qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs')
-rw-r--r-- | qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs new file mode 100644 index 0000000000..4abc56905f --- /dev/null +++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs @@ -0,0 +1,149 @@ +/* + * + * 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 Apache.Qpid.Messaging; +using Apache.Qpid.Client.Qms; +using Apache.Qpid.Client; + +namespace Apache.Qpid.Integration.Tests.testcases +{ + /// <summary> + /// MandatoryMessageTest checks that messages sent with the 'mandatory' flag, must either be routed to a valid + /// queue or returned to the sender when no route is available. + /// + /// <p><table id="crc"><caption>CRC Card</caption> + /// <tr><th> Responsibilities <th> Collaborations + /// <tr><td> Check default exchange returns unroutable mandatory messages. + /// <tr><td> Check direct exchange returns unroutable mandatory messages. + /// <tr><td> Check headers exchange returns unroutable mandatory messages. + /// <tr><td> Check topic exchange returns unroutable mandatory messages. + /// </table> + /// </summary> + [TestFixture, Category("Integration")] + public class MandatoryMessageTest : BaseMessagingTestFixture + { + /// <summary>Used for debugging purposes.</summary> + private static ILog log = LogManager.GetLogger(typeof(MandatoryMessageTest)); + + /// <summary>Defines the maximum time in milliseconds, to wait for redelivery to occurr.</summary> + public const int TIMEOUT = 1000; + + /// <summary>Defines the name of the routing key to use with the tests.</summary> + public const string TEST_ROUTING_KEY = "unboundkey"; + + /// <summary>Condition used to coordinate receipt of redelivery exception to the sending thread.</summary> + private ManualResetEvent errorEvent; + + /// <summary>Holds the last received error condition, for examination by the tests sending thread.</summary> + private Exception lastErrorException; + + /// <summary> Holds the test connection. </summary> + protected IConnection _connection; + + /// <summary> Holds the test channel. </summary> + protected IChannel _channel; + + [SetUp] + public override void Init() + { + base.Init(); + + errorEvent = new ManualResetEvent(false); + lastErrorException = null; + } + + [TearDown] + public override void Shutdown() + { + base.Shutdown(); + } + + /// <summary> + /// Handles all exception conditions on the connection. The error event is notified and the exception recorded as the last seen. + /// </summary> + /// + /// <param name="e">The asynchronous exception on the connection.</param> + public void OnException(Exception e) + { + lastErrorException = e; + errorEvent.Set(); + } + + [Test] + public void SendUndeliverableMessageOnDirectExchange() + { + SendOne(ExchangeNameDefaults.DIRECT); + } + + [Test] + public void SendUndeliverableMessageOnTopicExchange() + { + SendOne(ExchangeNameDefaults.TOPIC); + } + + [Test] + public void SendUndeliverableMessageOnHeadersExchange() + { + SendOne(ExchangeNameDefaults.HEADERS); + } + + /// <summary> + /// Sends a single message to the specified exchange with the routing key 'unboundkey', marked as mandatory. + /// A check is performed to assert that a redelivery error is returned from the broker for the message. + /// </summary> + /// + /// <param name="exchangeName">The name of the exchange to send to.</param> + private void SendOne(string exchangeName) + { + log.Debug("private void SendOne(string exchangeName = " + exchangeName + "): called"); + + // Send a test message to a unbound key on the specified exchange. + SetUpEndPoint(0, false, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, exchangeName, + true, false, null); + testProducer[0] = testChannel[0].CreatePublisherBuilder() + .WithRoutingKey(TEST_ROUTING_KEY + testId) + .WithMandatory(true) + .WithExchangeName(exchangeName) + .Create(); + + // Set up the exception listener on the connection. + testConnection[0].ExceptionListener = new ExceptionListenerDelegate(OnException); + + // Send message that should fail. + testProducer[0].Send(testChannel[0].CreateTextMessage("Test Message")); + + // Wait for up to the timeout for a redelivery exception to be returned. + errorEvent.WaitOne(TIMEOUT, true); + + // Asserts that a redelivery exception was returned, and is of the correct type. + Type expectedException = typeof(AMQUndeliveredException); + Exception ex = lastErrorException; + + Assert.IsNotNull(ex, "No exception was thrown by the test. Expected " + expectedException); + Assert.IsInstanceOfType(expectedException, ex.InnerException); + + CloseEndPoint(0); + } + } +} |