/* * (C) 2007-2012 Alibaba Group Holding Limited. * * Licensed 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. */ package com.taobao.gecko.service.impl; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.taobao.gecko.core.command.ResponseCommand; import com.taobao.gecko.core.command.ResponseStatus; import com.taobao.gecko.service.Connection; import com.taobao.gecko.service.SingleRequestCallBackListener; import com.taobao.gecko.service.callback.SingleRequestCallBack; import com.taobao.gecko.service.config.ClientConfig; import com.taobao.gecko.service.exception.NotifyRemotingException; import com.taobao.gecko.service.mock.MockSession; import com.taobao.gecko.service.notify.NotifyCommandFactory; import com.taobao.gecko.service.notify.request.NotifyDummyRequestCommand; import com.taobao.gecko.service.notify.response.NotifyBooleanAckCommand; import com.taobao.gecko.service.notify.response.NotifyDummyAckCommand; /** * * * * @author boyan * * @since 1.0, 2009-12-21 ����02:25:29 */ public class DefaultConnectionUnitTest { private DefaultConnection connection; private MockSession mockSession; private DefaultRemotingContext remotingContext; @Before public void setUp() { this.mockSession = new MockSession(); this.remotingContext = new DefaultRemotingContext(new ClientConfig(), new NotifyCommandFactory()); this.connection = new DefaultConnection(this.mockSession, this.remotingContext); } @After public void tearDown() throws Exception { this.connection.close(false); this.remotingContext.dispose(); } @Test public void testSendMessage() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("hello"); this.connection.send(requestCommand); Assert.assertTrue(this.mockSession.getMessageList().contains(requestCommand)); Assert.assertNull(this.connection.getRequestCallBack(requestCommand.getOpaque())); } @Test public void testSendMessageWithListener() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("hello"); final NotifyDummyAckCommand response = new NotifyDummyAckCommand(requestCommand, "hello"); final AtomicBoolean invoked = new AtomicBoolean(false); this.connection.send(requestCommand, new SingleRequestCallBackListener() { public void onException(final Exception e) { e.printStackTrace(); } public ThreadPoolExecutor getExecutor() { return null; } public void onResponse(final ResponseCommand responseCommand, final Connection conn) { Assert.assertSame(responseCommand, response); Assert.assertSame(DefaultConnectionUnitTest.this.connection, conn); synchronized (DefaultConnectionUnitTest.this.connection) { invoked.set(true); DefaultConnectionUnitTest.this.connection.notifyAll(); } } }, 5000, TimeUnit.MILLISECONDS); final RequestCallBack requestCallBack = this.connection.getRequestCallBack(requestCommand.getOpaque()); Assert.assertNotNull(requestCallBack); requestCallBack.onResponse("test", response, this.connection); synchronized (this.connection) { while (!invoked.get()) { this.connection.wait(); } } Assert.assertTrue(invoked.get()); } @Test public void testSendMessageWithListenerTimeout() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("hello"); final NotifyDummyAckCommand response = new NotifyDummyAckCommand(requestCommand, "hello"); final AtomicBoolean invoked = new AtomicBoolean(false); this.connection.send(requestCommand, new SingleRequestCallBackListener() { public void onException(final Exception e) { e.printStackTrace(); } public ThreadPoolExecutor getExecutor() { return null; } public void onResponse(final ResponseCommand responseCommand, final Connection conn) { Assert.assertNotSame(response, responseCommand); Assert.assertEquals("�ȴ���Ӧ��ʱ", ((NotifyBooleanAckCommand) responseCommand).getErrorMsg()); Assert.assertEquals(ResponseStatus.TIMEOUT, responseCommand.getResponseStatus()); Assert.assertSame(DefaultConnectionUnitTest.this.connection, conn); synchronized (DefaultConnectionUnitTest.this.connection) { invoked.set(true); DefaultConnectionUnitTest.this.connection.notifyAll(); } } }, 2000, TimeUnit.MILLISECONDS); final RequestCallBack requestCallBack = this.connection.getRequestCallBack(requestCommand.getOpaque()); Assert.assertNotNull(requestCallBack); synchronized (this.connection) { while (!invoked.get()) { this.connection.wait(); } } Assert.assertTrue(invoked.get()); } private class InnerSetResultRunner implements Runnable { final NotifyDummyRequestCommand request; final NotifyDummyAckCommand response; public InnerSetResultRunner(final NotifyDummyRequestCommand requestCommand, final NotifyDummyAckCommand response) { super(); this.request = requestCommand; this.response = response; } public void run() { try { while (DefaultConnectionUnitTest.this.connection.getRequestCallBack(this.request.getOpaque()) == null) { Thread.sleep(100); } final RequestCallBack requestCallBack = DefaultConnectionUnitTest.this.connection.getRequestCallBack(this.request.getOpaque()); requestCallBack.onResponse("test", this.response, DefaultConnectionUnitTest.this.connection); } catch (final InterruptedException e) { throw new RuntimeException(e); } } } @Test public void testInvoke() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("hello"); final NotifyDummyAckCommand response = new NotifyDummyAckCommand(requestCommand, "hello"); new Thread(new InnerSetResultRunner(requestCommand, response)).start(); final ResponseCommand responseCommand = this.connection.invoke(requestCommand); Assert.assertSame(response, responseCommand); } @Test public void testAddRemoveInvalidRequstCallback() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("test"); RequestCallBack requestCallBack = new SingleRequestCallBack(requestCommand.getRequestHeader(), 2000); this.connection.addRequestCallBack(requestCommand.getOpaque(), requestCallBack); try { this.connection.addRequestCallBack(requestCommand.getOpaque(), requestCallBack); } catch (final NotifyRemotingException e) { Assert.assertEquals("�벻Ҫ�ظ�����ͬһ�����ͬһ������", e.getMessage()); } Assert.assertSame(requestCallBack, this.connection.getRequestCallBack(requestCommand.getOpaque())); Assert.assertSame(requestCallBack, this.connection.removeRequestCallBack(requestCommand.getOpaque())); Assert.assertNull(this.connection.getRequestCallBack(requestCommand.getOpaque())); requestCallBack = new SingleRequestCallBack(requestCommand.getRequestHeader(), 2000); this.connection.addRequestCallBack(requestCommand.getOpaque(), requestCallBack); Assert.assertSame(requestCallBack, this.connection.getRequestCallBack(requestCommand.getOpaque())); Thread.sleep(3000); this.connection.removeAllInvalidRequestCallBack(); Assert.assertNull(this.connection.getRequestCallBack(requestCommand.getOpaque())); } @Test public void testInvokeTimeout() throws Exception { final NotifyDummyRequestCommand requestCommand = new NotifyDummyRequestCommand("hello"); try { this.connection.invoke(requestCommand); Assert.fail(); } catch (final java.util.concurrent.TimeoutException e) { Assert.assertEquals("Operation timeout", e.getMessage()); } } }