/* * Copyright 2014 NAVER Corp. * * 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.navercorp.pinpoint.rpc.server; import com.navercorp.pinpoint.rpc.PinpointSocket; import com.navercorp.pinpoint.rpc.TestAwaitTaskUtils; import com.navercorp.pinpoint.rpc.TestAwaitUtils; import com.navercorp.pinpoint.rpc.client.PinpointClient; import com.navercorp.pinpoint.rpc.client.PinpointClientFactory; import com.navercorp.pinpoint.rpc.common.SocketStateCode; import com.navercorp.pinpoint.rpc.control.ProtocolException; import com.navercorp.pinpoint.rpc.packet.ControlHandshakePacket; import com.navercorp.pinpoint.rpc.util.ControlMessageEncodingUtils; import com.navercorp.pinpoint.rpc.util.PinpointRPCTestUtils; import org.jboss.netty.buffer.ChannelBuffer; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.util.SocketUtils; import java.io.IOException; import java.net.Socket; import java.util.List; import java.util.Map; /** * @author Taejin Koo */ public class PinpointServerStateTest { private static int bindPort; private final TestAwaitUtils awaitUtils = new TestAwaitUtils(100, 1000); @BeforeClass public static void setUp() throws IOException { bindPort = SocketUtils.findAvailableTcpPort(); } @Test public void closeByPeerTest() throws InterruptedException { PinpointServerAcceptor serverAcceptor = null; PinpointClient client = null; PinpointClientFactory clientFactory = null; try { serverAcceptor = PinpointRPCTestUtils.createPinpointServerFactory(bindPort, PinpointRPCTestUtils.createEchoServerListener()); clientFactory = PinpointRPCTestUtils.createClientFactory(PinpointRPCTestUtils.getParams(), PinpointRPCTestUtils.createEchoClientListener()); client = clientFactory.connect("127.0.0.1", bindPort); assertAvaiableWritableSocket(serverAcceptor); List<PinpointSocket> pinpointServerList = serverAcceptor.getWritableSocketList(); PinpointSocket pinpointServer = pinpointServerList.get(0); if (pinpointServer instanceof PinpointServer) { Assert.assertEquals(SocketStateCode.RUN_DUPLEX, ((PinpointServer) pinpointServer).getCurrentStateCode()); client.close(); assertPinpointServerState(SocketStateCode.CLOSED_BY_CLIENT, (PinpointServer)pinpointServer); } else { Assert.fail(); } } finally { PinpointRPCTestUtils.close(client); if (clientFactory != null) { clientFactory.release(); } PinpointRPCTestUtils.close(serverAcceptor); } } @Test public void closeTest() throws InterruptedException { PinpointServerAcceptor serverAcceptor = null; PinpointClient client = null; PinpointClientFactory clientFactory = null; try { serverAcceptor = PinpointRPCTestUtils.createPinpointServerFactory(bindPort, PinpointRPCTestUtils.createEchoServerListener()); clientFactory = PinpointRPCTestUtils.createClientFactory(PinpointRPCTestUtils.getParams(), PinpointRPCTestUtils.createEchoClientListener()); client = clientFactory.connect("127.0.0.1", bindPort); assertAvaiableWritableSocket(serverAcceptor); List<PinpointSocket> pinpointServerList = serverAcceptor.getWritableSocketList(); PinpointSocket pinpointServer = pinpointServerList.get(0); Assert.assertEquals(SocketStateCode.RUN_DUPLEX, ((PinpointServer) pinpointServer).getCurrentStateCode()); serverAcceptor.close(); assertPinpointServerState(SocketStateCode.CLOSED_BY_SERVER, (PinpointServer)pinpointServer); } finally { PinpointRPCTestUtils.close(client); if (clientFactory != null) { clientFactory.release(); } PinpointRPCTestUtils.close(serverAcceptor); } } @Test public void unexpectedCloseByPeerTest() throws InterruptedException, IOException, ProtocolException { PinpointServerAcceptor serverAcceptor = null; try { serverAcceptor = PinpointRPCTestUtils.createPinpointServerFactory(bindPort, PinpointRPCTestUtils.createEchoServerListener()); Socket socket = new Socket("127.0.0.1", bindPort); socket.getOutputStream().write(createHandshakePayload(PinpointRPCTestUtils.getParams())); socket.getOutputStream().flush(); final PinpointServerAcceptor ImmutableServerAcceptor = serverAcceptor; awaitUtils.await(new TestAwaitTaskUtils() { @Override public boolean checkCompleted() { return ImmutableServerAcceptor.getWritableSocketList().size() == 1; } }); List<PinpointSocket> pinpointServerList = serverAcceptor.getWritableSocketList(); PinpointSocket pinpointServer = pinpointServerList.get(0); if (!(pinpointServer instanceof PinpointServer)) { socket.close(); Assert.fail(); } Assert.assertEquals(SocketStateCode.RUN_DUPLEX, ((PinpointServer)pinpointServer).getCurrentStateCode()); socket.close(); assertPinpointServerState(SocketStateCode.UNEXPECTED_CLOSE_BY_CLIENT, (PinpointServer)pinpointServer); } finally { PinpointRPCTestUtils.close(serverAcceptor); } } @Test public void unexpectedCloseTest() throws InterruptedException, IOException, ProtocolException { PinpointServerAcceptor serverAcceptor = null; PinpointClient client = null; PinpointClientFactory clientFactory = null; try { serverAcceptor = PinpointRPCTestUtils.createPinpointServerFactory(bindPort, PinpointRPCTestUtils.createEchoServerListener()); clientFactory = PinpointRPCTestUtils.createClientFactory(PinpointRPCTestUtils.getParams(), PinpointRPCTestUtils.createEchoClientListener()); client = clientFactory.connect("127.0.0.1", bindPort); assertAvaiableWritableSocket(serverAcceptor); List<PinpointSocket> pinpointServerList = serverAcceptor.getWritableSocketList(); PinpointSocket pinpointServer = pinpointServerList.get(0); Assert.assertEquals(SocketStateCode.RUN_DUPLEX, ((PinpointServer) pinpointServer).getCurrentStateCode()); ((DefaultPinpointServer)pinpointServer).stop(true); assertPinpointServerState(SocketStateCode.UNEXPECTED_CLOSE_BY_SERVER, (PinpointServer)pinpointServer); } finally { PinpointRPCTestUtils.close(client); if (clientFactory != null) { clientFactory.release(); } PinpointRPCTestUtils.close(serverAcceptor); } } private byte[] createHandshakePayload(Map<String, Object> data) throws ProtocolException { byte[] payload = ControlMessageEncodingUtils.encode(data); ControlHandshakePacket handshakePacket = new ControlHandshakePacket(payload); ChannelBuffer channelBuffer = handshakePacket.toBuffer(); return channelBuffer.toByteBuffer().array(); } private void assertAvaiableWritableSocket(final PinpointServerAcceptor serverAcceptor) { boolean pass = awaitUtils.await(new TestAwaitTaskUtils() { @Override public boolean checkCompleted() { return !serverAcceptor.getWritableSocketList().isEmpty(); } }); Assert.assertTrue(pass); } private void assertPinpointServerState(final SocketStateCode stateCode, final PinpointServer pinpointServer) { boolean passed = awaitUtils.await(new TestAwaitTaskUtils() { @Override public boolean checkCompleted() { return pinpointServer.getCurrentStateCode() == stateCode; } }); Assert.assertTrue(passed); } }