// Copyright (c) 2007-Present Pivotal Software, Inc. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2 // ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see // LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL, // please see LICENSE-APACHE2. // // This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, // either express or implied. See the LICENSE file for specific language governing // rights and limitations of this software. // // If you have any questions regarding licensing, please contact us at // info@rabbitmq.com. package com.rabbitmq.client.test; import com.rabbitmq.client.ChannelContinuationTimeoutException; import com.rabbitmq.client.Command; import com.rabbitmq.client.Method; import com.rabbitmq.client.impl.AMQChannel; import com.rabbitmq.client.impl.AMQCommand; import com.rabbitmq.client.impl.AMQConnection; import com.rabbitmq.client.impl.AMQImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class AMQChannelTest { ScheduledExecutorService scheduler; @Before public void init() { scheduler = Executors.newSingleThreadScheduledExecutor(); } @After public void tearDown() { scheduler.shutdownNow(); } @Test public void rpcTimesOutWhenResponseDoesNotCome() throws IOException { int rpcTimeout = 100; AMQConnection connection = mock(AMQConnection.class); when(connection.getChannelRpcTimeout()).thenReturn(rpcTimeout); DummyAmqChannel channel = new DummyAmqChannel(connection, 1); Method method = new AMQImpl.Queue.Declare.Builder() .queue("") .durable(false) .exclusive(true) .autoDelete(true) .arguments(null) .build(); try { channel.rpc(method); fail("Should time out and throw an exception"); } catch(ChannelContinuationTimeoutException e) { // OK assertThat((DummyAmqChannel) e.getChannel(), is(channel)); assertThat(e.getChannelNumber(), is(channel.getChannelNumber())); assertThat(e.getMethod(), is(method)); assertNull("outstanding RPC should have been cleaned", channel.nextOutstandingRpc()); } } @Test public void rpcReturnsResultWhenResponseHasCome() throws IOException { int rpcTimeout = 1000; AMQConnection connection = mock(AMQConnection.class); when(connection.getChannelRpcTimeout()).thenReturn(rpcTimeout); final DummyAmqChannel channel = new DummyAmqChannel(connection, 1); Method method = new AMQImpl.Queue.Declare.Builder() .queue("") .durable(false) .exclusive(true) .autoDelete(true) .arguments(null) .build(); final Method response = new AMQImpl.Queue.DeclareOk.Builder() .queue("whatever") .consumerCount(0) .messageCount(0).build(); scheduler.schedule(new Callable<Void>() { @Override public Void call() throws Exception { channel.handleCompleteInboundCommand(new AMQCommand(response)); return null; } }, (long) (rpcTimeout / 2.0), TimeUnit.MILLISECONDS); AMQCommand rpcResponse = channel.rpc(method); assertThat(rpcResponse.getMethod(), is(response)); } static class DummyAmqChannel extends AMQChannel { public DummyAmqChannel(AMQConnection connection, int channelNumber) { super(connection, channelNumber); } @Override public boolean processAsync(Command command) throws IOException { return false; } } }