/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.protocol.mgmt;
import java.io.DataInput;
import java.io.IOException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.jboss.as.protocol.mgmt.support.RemoteChannelPairSetup;
import org.jboss.as.protocol.mgmt.support.RemotingChannelPairSetup;
import org.jboss.as.protocol.mgmt.support.SimpleHandlers;
import org.jboss.as.protocol.mgmt.support.SimpleHandlers.SimpleClient;
import org.jboss.threads.AsyncFuture;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.1 $
*/
public class RemoteChannelManagementTestCase {
private RemotingChannelPairSetup channels;
@Before
public void start() throws Exception {
channels = new RemoteChannelPairSetup();
channels.setupRemoting(new SimpleHandlers.OperationHandler());
channels.startChannels();
}
@After
public void stop() throws Exception {
channels.stopChannels();
channels.shutdownRemoting();
}
@Test
public void testSimpleRequest() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600);
Assert.assertEquals(Integer.valueOf(1200), client.executeForResult(request));
}
@Test
public void testTwoSimpleRequests() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600);
Assert.assertEquals(Integer.valueOf(1200), client.executeForResult(request));
request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 700);
Assert.assertEquals(Integer.valueOf(1400), client.executeForResult(request));
}
@Test
public void testSeveralConcurrentSimpleRequests() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request1 = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600);
SimpleHandlers.Request request2 = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 650);
SimpleHandlers.Request request3 = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 700);
Future<Integer> future1 = client.execute(request1);
Future<Integer> future2 = client.execute(request2);
Future<Integer> future3 = client.execute(request3);
Assert.assertEquals(Integer.valueOf(1400), future3.get());
Assert.assertEquals(Integer.valueOf(1300), future2.get());
Assert.assertEquals(Integer.valueOf(1200), future1.get());
}
@Test
public void testMissingOperationHandler() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
//Don't set the operation handler here
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.REQUEST_WITH_NO_HANDLER, 600);
try {
client.executeForResult(request);
Assert.fail("Should have failed");
} catch (ExecutionException expected) {
Assert.assertTrue(expected.getCause() instanceof IOException);
}
}
@Test
public void testMissingRequestHandler() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.REQUEST_WITH_NO_HANDLER, 600);
try {
client.executeForResult(request);
Assert.fail("Should have failed");
} catch (ExecutionException expected) {
Assert.assertTrue(expected.getCause() instanceof IOException);
}
}
@Test
public void testExceptionInRequestHandlerRead() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.REQUEST_WITH_BAD_READ, 600);
try {
client.executeForResult(request);
Assert.fail("Should have failed");
} catch (ExecutionException expected) {
Assert.assertTrue(expected.getCause() instanceof IOException);
}
}
@Test
public void testExceptionInRequestHandlerWrite() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.REQUEST_WITH_BAD_WRITE, 600);
try {
client.executeForResult(request);
Assert.fail("Should have failed");
} catch (ExecutionException expected) {
Assert.assertTrue(expected.getCause() instanceof IOException);
}
}
@Test
public void testExceptionInRequestWrite() throws Exception {
final SimpleClient client = SimpleClient.create(channels);
SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600) {
@Override
protected void sendRequest(ActiveOperation.ResultHandler<Integer> resultHandler, ManagementRequestContext<Void> context, FlushableDataOutput output) throws IOException {
throw new RuntimeException("Oh no!!!!");
}
};
try {
client.executeForResult(request);
Assert.fail("Should have failed");
} catch (ExecutionException expected) {
// TODO intermitted failures instanceof RuntimeException
// Assert.assertTrue(expected.getClass().toString(), expected.getCause() instanceof RuntimeException);
}
}
@Test
public void testNoResponse() throws Exception {
// Test request handler waiting for a response from the server, but never getting one...
// however once the channel gets closed the request should get cancelled
final SimpleClient client = SimpleClient.create(channels);
final SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.REQUEST_WITH_NO_RESPONSE, 600);
final AsyncFuture<Integer> future = client.execute(request);
try {
future.get(1, TimeUnit.SECONDS);
Assert.fail();
} catch(Exception expected) {
//
}
client.shutdownNow();
// channel close() would make it fail
// channels.getClientChannel().close();
try {
future.get();
Assert.fail();
} catch(CancellationException expected) {
//
}
Assert.assertEquals(future.getStatus(), AsyncFuture.Status.CANCELLED);
}
@Test
public void testCancelAsyncTask() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final SimpleClient client = SimpleClient.create(channels);
final SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600) {
@Override
public void handleRequest(final DataInput input, final ActiveOperation.ResultHandler<Integer> resultHandler, final ManagementRequestContext<Void> context) throws IOException {
final int i = input.readInt();
context.executeAsync(new ManagementRequestContext.AsyncTask<Void>() {
@Override
public void execute(ManagementRequestContext<Void> context) throws Exception {
try {
synchronized (this) {
wait();
}
resultHandler.done(i);
} catch(InterruptedException e) {
latch.countDown();
}
}
});
}
};
final AsyncFuture<Integer> future = client.execute(request);
final AsyncFuture.Status completed = future.await(1, TimeUnit.SECONDS);
Assert.assertEquals(completed, AsyncFuture.Status.WAITING);
future.cancel(false);
latch.await();
Assert.assertEquals(future.getStatus(), AsyncFuture.Status.CANCELLED);
}
@Test
public void testAwaitCompletion() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final SimpleClient client = SimpleClient.create(channels);
final SimpleHandlers.Request request = new SimpleHandlers.Request(SimpleHandlers.SIMPLE_REQUEST, 600) {
@Override
public void handleRequest(final DataInput input, final ActiveOperation.ResultHandler<Integer> resultHandler, final ManagementRequestContext<Void> context) throws IOException {
final int i = input.readInt();
context.executeAsync(new ManagementRequestContext.AsyncTask<Void>() {
@Override
public void execute(ManagementRequestContext<Void> voidManagementRequestContext) throws Exception {
latch.await();
resultHandler.done(i);
}
});
}
};
final AsyncFuture<Integer> future = client.execute(request);
final AsyncFuture.Status completed = future.await(1, TimeUnit.SECONDS);
Assert.assertEquals(completed, AsyncFuture.Status.WAITING);
client.shutdown();
boolean done = client.awaitCompletion(1, TimeUnit.SECONDS);
Assert.assertFalse(done);
latch.countDown();
done = client.awaitCompletion(2, TimeUnit.SECONDS);
Assert.assertTrue(done);
}
}