Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java

Issue 517233002: DevTools socket tunnel. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@glue
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java
diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a250009a885ce14223690b9f5faf2cb368ea0907
--- /dev/null
+++ b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java
@@ -0,0 +1,305 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.devtools_bridge;
+
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Tests for {@link SocketTunnelServer}
+ */
+public class SocketTunnelServerTest extends InstrumentationTestCase {
+ private static final int CONNECTION_ID = 30;
+ private static final String SOCKET_NAME = "ksdjhflksjhdflk";
+
+ private DataChannelMock mDataChannelMock;
+ private SocketTunnelServer mServer;
+ private LocalServerSocket mSocket;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mSocket = new LocalServerSocket(SOCKET_NAME);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mSocket.close();
+ if (mServer != null) destroyServer();
+ super.tearDown();
+ }
+
+ private void createServer() {
+ createServer(new DataChannelMock());
+ }
+
+ private void createServer(DataChannelMock dataChannel) {
+ mDataChannelMock = dataChannel;
+ mServer = new SocketTunnelServer(SOCKET_NAME);
+ mServer.bind(mDataChannelMock);
+ }
+
+ private void destroyServer() {
+ mServer.unbind().dispose();
+ mServer = null;
+ }
+
+ @SmallTest
+ public void testOpenDataChannel() {
+ createServer();
+ mDataChannelMock.open();
+ }
+
+ @SmallTest
+ public void testDecodeControlPacket() {
+ createServer();
+ ByteBuffer packet = buildControlPacket(CONNECTION_ID, SocketTunnelBase.SERVER_OPEN_ACK);
+
+ PacketDecoder decoder = PacketDecoder.decode(packet);
+ Assert.assertTrue(decoder.isControlPacket());
+ Assert.assertEquals(CONNECTION_ID, decoder.connectionId());
+ Assert.assertEquals(SocketTunnelBase.SERVER_OPEN_ACK, decoder.opCode());
+ }
+
+ @SmallTest
+ public void testConnectToSocket() throws IOException {
+ createServer();
+ LocalSocket socket = connectToSocket(1);
+ Assert.assertTrue(mServer.hasConnections());
+ socket.close();
+ }
+
+ private LocalSocket connectToSocket(int connectionId) throws IOException {
+ mDataChannelMock.notifyMessage(
+ buildControlPacket(connectionId, SocketTunnelBase.CLIENT_OPEN));
+ return mSocket.accept();
+ }
+
+ private void sendClose(int connectionId) {
+ mDataChannelMock.notifyMessage(
+ buildControlPacket(connectionId, SocketTunnelBase.CLIENT_CLOSE));
+ }
+
+ private ByteBuffer buildControlPacket(int connectionId, byte opCode) {
+ ByteBuffer packet = SocketTunnelBase.buildControlPacket(connectionId, opCode);
+ packet.limit(packet.position());
+ packet.position(0);
+ Assert.assertTrue(packet.remaining() > 0);
+ return packet;
+ }
+
+ private ByteBuffer buildDataPacket(int connectionId, byte[] data) {
+ ByteBuffer packet = SocketTunnelBase.buildDataPacket(connectionId, data, data.length);
+ packet.limit(packet.position());
+ packet.position(0);
+ Assert.assertTrue(packet.remaining() > 0);
+ return packet;
+ }
+
+ @SmallTest
+ public void testReceiveOpenAcknowledgement() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+
+ receiveOpenAck(CONNECTION_ID);
+
+ socket.close();
+ }
+
+ private PacketDecoder receiveControlPacket(int connectionId) throws InterruptedException {
+ PacketDecoder decoder = PacketDecoder.decode(mDataChannelMock.receive());
+ Assert.assertTrue(decoder.isControlPacket());
+ Assert.assertEquals(connectionId, decoder.connectionId());
+ return decoder;
+ }
+
+ private void receiveOpenAck(int connectionId) throws InterruptedException {
+ PacketDecoder decoder = receiveControlPacket(connectionId);
+ Assert.assertEquals(SocketTunnelBase.SERVER_OPEN_ACK, decoder.opCode());
+ }
+
+ private void receiveClose(int connectionId) throws InterruptedException {
+ PacketDecoder decoder = receiveControlPacket(connectionId);
+ Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode());
+ }
+
+ @SmallTest
+ public void testClosingSocket() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+
+ socket.shutdownOutput();
+
+ PacketDecoder decoder = PacketDecoder.decode(mDataChannelMock.receive());
+
+ Assert.assertTrue(decoder.isControlPacket());
+ Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode());
+ Assert.assertEquals(CONNECTION_ID, decoder.connectionId());
+
+ socket.close();
+ }
+
+ @SmallTest
+ public void testReadData() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+
+ byte[] sample = "Sample".getBytes();
+
+ socket.getOutputStream().write(sample);
+ socket.getOutputStream().flush();
+ socket.shutdownOutput();
+
+ ByteBuffer result = receiveData(CONNECTION_ID, sample.length);
+ Assert.assertEquals(ByteBuffer.wrap(sample), result);
+ }
+
+ private ByteBuffer receiveData(int connectionId, int length) throws InterruptedException {
+ ByteBuffer result = ByteBuffer.allocate(length);
+
+ while (true) {
+ PacketDecoder decoder = PacketDecoder.decode(mDataChannelMock.receive());
+ if (decoder.isDataPacket()) {
+ Assert.assertEquals(connectionId, decoder.connectionId());
+ result.put(decoder.data());
+ } else if (decoder.isControlPacket()) {
+ Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode());
+ Assert.assertEquals(connectionId, decoder.connectionId());
+ break;
+ }
+ }
+ result.limit(result.position());
+ result.position(0);
+ return result;
+ }
+
+ private int sum(int[] values) {
+ int result = 0;
+ for (int v : values)
+ result += v;
+ return result;
+ }
+
+ private static final int[] CHUNK_SIZES =
+ new int[] { 0, 1, 5, 100, 1000, SocketTunnelBase.READING_BUFFER_SIZE * 2 };
+
+ @SmallTest
+ public void testReadLongDataChunk() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+
+ byte[] buffer = new byte[CHUNK_SIZES[CHUNK_SIZES.length - 1]];
+ ByteBuffer sentData = ByteBuffer.allocate(sum(CHUNK_SIZES));
+ OutputStream stream = socket.getOutputStream();
+ byte next = 0;
+ int prevSize = 0;
+ for (int size : CHUNK_SIZES) {
+ while (prevSize < size)
+ buffer[prevSize++] = next++;
+
+ stream.write(buffer, 0, size);
+ sentData.put(buffer, 0, size);
+ }
+
+ socket.shutdownOutput();
+
+ sentData.limit(sentData.position());
+ sentData.position(0);
+ ByteBuffer readData = receiveData(CONNECTION_ID, sentData.limit());
+
+ Assert.assertEquals(sentData, readData);
+ }
+
+ @SmallTest
+ public void testReuseConnectionId() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+
+ socket.shutdownOutput();
+ socket.close();
+ receiveClose(CONNECTION_ID);
+ sendClose(CONNECTION_ID);
+
+ // Open connection with the same ID
+ socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+ }
+
+ private static final byte[] SAMPLE = "Sample".getBytes();
+
+ @SmallTest
+ public void testWriteData() throws IOException, InterruptedException {
+ createServer();
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ receiveOpenAck(CONNECTION_ID);
+
+ mDataChannelMock.notifyMessage(buildDataPacket(CONNECTION_ID, SAMPLE));
+
+ byte[] result = new byte[SAMPLE.length];
+ int read = 0;
+ while (read < SAMPLE.length) {
+ int count = socket.getInputStream().read(result, 0, SAMPLE.length - read);
+ Assert.assertTrue(count > 0);
+ read += count;
+ }
+
+ Assert.assertEquals(ByteBuffer.wrap(SAMPLE), ByteBuffer.wrap(result));
+
+ socket.close();
+ }
+
+ private enum TestStates {
+ INITIAL, SENDING, CLOSING, MAY_FINISH_SENDING, SENT, DONE
+ }
+
+ @MediumTest
+ public void testStopWhileSendingData() throws IOException {
+
+ final TestUtils.StateBarrier<TestStates> barrier =
+ new TestUtils.StateBarrier<TestStates>(TestStates.INITIAL);
+
+ createServer(new DataChannelMock() {
+ @Override
+ public void send(ByteBuffer message, AbstractDataChannel.MessageType type) {
+ barrier.advance(TestStates.INITIAL, TestStates.SENDING);
+ barrier.advance(TestStates.MAY_FINISH_SENDING, TestStates.SENT);
+ }
+ });
+
+ LocalSocket socket = connectToSocket(CONNECTION_ID);
+ barrier.advance(TestStates.SENDING, TestStates.CLOSING);
+ socket.close();
+
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ barrier.advance(TestStates.CLOSING, TestStates.MAY_FINISH_SENDING);
+ }
+ }.start();
+
+ destroyServer();
+
+ barrier.advance(TestStates.SENT, TestStates.DONE);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698