diff options
Diffstat (limited to 'container-search/src/test/java/com/yahoo/fs4/mplex/BackendTestCase.java')
-rw-r--r-- | container-search/src/test/java/com/yahoo/fs4/mplex/BackendTestCase.java | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/container-search/src/test/java/com/yahoo/fs4/mplex/BackendTestCase.java b/container-search/src/test/java/com/yahoo/fs4/mplex/BackendTestCase.java new file mode 100644 index 00000000000..8696ca08d2b --- /dev/null +++ b/container-search/src/test/java/com/yahoo/fs4/mplex/BackendTestCase.java @@ -0,0 +1,208 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.fs4.mplex; + +import com.yahoo.container.QrConfig; +import com.yahoo.container.search.Fs4Config; +import com.yahoo.fs4.BasicPacket; +import com.yahoo.fs4.ChannelTimeoutException; +import com.yahoo.fs4.PingPacket; +import com.yahoo.fs4.QueryPacket; +import com.yahoo.fs4.mplex.Backend.BackendStatistics; +import com.yahoo.prelude.fastsearch.FS4ResourcePool; +import com.yahoo.search.Query; +import org.junit.Test; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.logging.Logger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Test networking code for talking to dispatch. + * + * @author Steinar Knutsen + */ +public class BackendTestCase { + private static final long TIMEOUT = 30000; + + public static class MockDispatch implements Runnable { + + public final ServerSocket socket; + public volatile Socket connection; + volatile int channelId; + + public byte[] packetData = new byte[] {0,0,0,104, + 0,0,0,217-256, + 0,0,0,1, + 0,0,0,0, + 0,0,0,2, + 0,0,0,0,0,0,0,5, + 0x40,0x39,0,0,0,0,0,0, + 0,0,0,111, + 0,0,0,97, + 0,0,0,3, 1,1,1,1,1,1,1,1,1,1,1,1, 0x40,0x37,0,0,0,0,0,23, 0,0,0,7, 0,0,0,36, + 0,0,0,4, 2,2,2,2,2,2,2,2,2,2,2,2, 0x40,0x35,0,0,0,0,0,21, 0,0,0,8, 0,0,0,37}; + + MockDispatch(ServerSocket socket) { + this.socket = socket; + } + + @Override + public void run() { + try { + connection = socket.accept(); + } catch (IOException e) { + e.printStackTrace(); + return; + } + requestRespond(); + } + + void requestRespond() { + byte[] length = new byte[4]; + try { + connection.getInputStream().read(length); + } catch (IOException e) { + e.printStackTrace(); + return; + } + int actual = ByteBuffer.wrap(length).getInt(); + + int read = 0; + int i = 0; + while (read != -1 && i < actual) { + try { + read = connection.getInputStream().read(); + ++i; + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + ByteBuffer reply = ByteBuffer.wrap(packetData); + if (channelId != -1) { + reply.putInt(8, channelId); + } + try { + connection.getOutputStream().write(packetData); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void setNoChannel() { + channelId = -1; + } + + } + + public static class MockServer { + public InetSocketAddress host; + public Thread worker; + public MockDispatch dispatch; + + public MockServer() throws IOException { + ServerSocket socket = new ServerSocket(0, 50, InetAddress.getLoopbackAddress()); + host = (InetSocketAddress) socket.getLocalSocketAddress(); + dispatch = new MockDispatch(socket); + worker = new Thread(dispatch); + worker.start(); + } + + } + + private Backend backend; + private MockServer server; + private Logger logger; + private boolean initUseParent; + private FS4ResourcePool listeners; + + public static final byte[] PONG = new byte[] { 0, 0, 0, 32, 0, 0, 0, 221 - 256, + 0,0,0,1, 0, 0, 0, 42, 0, 0, 0, 127, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, + 0, 0, 1 }; + + public void setUp() throws Exception { + logger = Logger.getLogger(Backend.class.getName()); + initUseParent = logger.getUseParentHandlers(); + logger.setUseParentHandlers(false); + listeners = new FS4ResourcePool(new Fs4Config(new Fs4Config.Builder()), new QrConfig(new QrConfig.Builder())); + + server = new MockServer(); + backend = listeners.getBackend(server.host.getHostString(), server.host.getPort()); + } + + public void tearDown() throws Exception { + listeners.deconstruct(); + server.dispatch.socket.close(); + if (server.dispatch.connection !=null) server.dispatch.connection.close(); + if (server.worker!=null) server.worker.join(); + if (logger !=null) logger.setUseParentHandlers(initUseParent); + } + + private BasicPacket [] read(FS4Channel channel) throws InvalidChannelException { + try { + return channel.receivePackets(TIMEOUT, 1); + } catch (ChannelTimeoutException e) { + fail("Could not get packets from simulated backend."); + } + return new BasicPacket[1]; + } + + @Test + public void testAll() throws Exception { + setUp(); + doTestBackend(); + tearDown(); + + setUp(); + doTestPinging(); + tearDown(); + + setUp(); + doRequireStatistics(); + tearDown(); + } + + private void doTestBackend() throws IOException, InvalidChannelException { + FS4Channel channel = backend.openChannel(); + Query q = new Query("/?query=a"); + int channelId = channel.getChannelId(); + server.dispatch.channelId = channelId; + + assertTrue(backend.sendPacket(QueryPacket.create("container.0", q), channelId)); + BasicPacket[] b = read(channel); + assertEquals(1, b.length); + assertEquals(217, b[0].getCode()); + channel.close(); + } + + private void doTestPinging() throws IOException, InvalidChannelException { + FS4Channel channel = backend.openPingChannel(); + server.dispatch.setNoChannel(); + server.dispatch.packetData = PONG; + + assertTrue(channel.sendPacket(new PingPacket())); + BasicPacket[] b = read(channel); + assertEquals(1, b.length); + assertEquals(221, b[0].getCode()); + channel.close(); + } + + private void doRequireStatistics() throws IOException, InvalidChannelException { + FS4Channel channel = backend.openPingChannel(); + server.dispatch.channelId = -1; + server.dispatch.packetData = PONG; + + assertTrue(channel.sendPacket(new PingPacket())); + read(channel); + BackendStatistics stats = backend.getStatistics(); + assertEquals(1, stats.totalConnections()); + } + +} |