1 /* 2 * Copyright (C) 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.caliper.runner; 16 17 import static org.junit.Assert.assertEquals; 18 import static org.junit.Assert.assertFalse; 19 import static org.junit.Assert.assertTrue; 20 import static org.junit.Assert.fail; 21 22 import com.google.caliper.bridge.OpenedSocket; 23 import com.google.caliper.bridge.StartupAnnounceMessage; 24 import com.google.common.util.concurrent.ListenableFuture; 25 26 import org.junit.After; 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.JUnit4; 31 32 import java.io.IOException; 33 import java.net.InetAddress; 34 import java.net.Socket; 35 import java.util.UUID; 36 import java.util.concurrent.ExecutionException; 37 38 /** 39 * Tests for {@link ServerSocketService}. 40 */ 41 @RunWith(JUnit4.class) 42 43 public class ServerSocketServiceTest { 44 45 private final ServerSocketService service = new ServerSocketService(); 46 private int port; 47 startService()48 @Before public void startService() { 49 service.startAsync().awaitRunning(); 50 port = service.getPort(); 51 } 52 stopService()53 @After public void stopService() { 54 service.stopAsync().awaitTerminated(); 55 } 56 getConnectionId_requestComesInFirst()57 @Test public void getConnectionId_requestComesInFirst() throws Exception { 58 UUID id = UUID.randomUUID(); 59 ListenableFuture<OpenedSocket> pendingServerConnection = service.getConnection(id); 60 assertFalse(pendingServerConnection.isDone()); 61 OpenedSocket clientSocket = openConnectionAndIdentify(id); 62 // Assert that the ends are hooked up to each other 63 assertEndsConnected(clientSocket, pendingServerConnection.get()); 64 } 65 getConnectionIdTwice_acceptComesFirst()66 @Test public void getConnectionIdTwice_acceptComesFirst() throws Exception { 67 UUID id = UUID.randomUUID(); 68 OpenedSocket clientSocket = openConnectionAndIdentify(id); 69 70 ListenableFuture<OpenedSocket> pendingServerConnection = service.getConnection(id); 71 // wait for the service to fully initialize the connection 72 OpenedSocket serverSocket = pendingServerConnection.get(); 73 assertEndsConnected(clientSocket, serverSocket); 74 try { 75 // the second request is an error 76 service.getConnection(id).get(); 77 fail(); 78 } catch (IllegalStateException expected) {} 79 } 80 getConnectionStoppedService()81 @Test public void getConnectionStoppedService() throws Exception { 82 UUID id = UUID.randomUUID(); 83 ListenableFuture<OpenedSocket> pendingServerConnection = service.getConnection(id); 84 assertFalse(pendingServerConnection.isDone()); 85 service.stopAsync().awaitTerminated(); 86 assertTrue(pendingServerConnection.isDone()); 87 88 try { 89 pendingServerConnection.get(); 90 fail(); 91 } catch (ExecutionException e) { 92 assertEquals("The socket has been closed", e.getCause().getMessage()); 93 } 94 95 try { 96 service.getConnection(UUID.randomUUID()); 97 fail(); 98 } catch (IllegalStateException expected) {} 99 } 100 openClientConnection()101 private OpenedSocket openClientConnection() throws IOException { 102 return OpenedSocket.fromSocket(new Socket(InetAddress.getLoopbackAddress(), port)); 103 } 104 105 /** 106 * Opens a connection to the service and identifies itself using the id. 107 */ openConnectionAndIdentify(UUID id)108 private OpenedSocket openConnectionAndIdentify(UUID id) throws IOException { 109 OpenedSocket clientSocket = openClientConnection(); 110 OpenedSocket.Writer writer = clientSocket.writer(); 111 writer.write(new StartupAnnounceMessage(id)); 112 writer.flush(); 113 return clientSocket; 114 } 115 assertEndsConnected(OpenedSocket clientSocket, OpenedSocket serverSocket)116 private void assertEndsConnected(OpenedSocket clientSocket, OpenedSocket serverSocket) 117 throws IOException { 118 serverSocket.writer().write("hello client!"); 119 serverSocket.writer().flush(); // necessary to prevent deadlock 120 assertEquals("hello client!", clientSocket.reader().read()); 121 122 clientSocket.writer().write("hello server!"); 123 clientSocket.writer().flush(); // ditto 124 assertEquals("hello server!", serverSocket.reader().read()); 125 } 126 } 127