blob: 77996dd30260906dd301c0babdfa88120063c1ac [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 libcore.javax.net;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ServerSocketFactory;
import junit.framework.TestCase;
public class ServerSocketFactoryTest extends TestCase {
public void testCreateServerSocket() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket();
serverSocket.bind(new InetSocketAddress(0));
testSocket(serverSocket, 50);
}
public void testCreateServerSocketWithPort() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0);
testSocket(serverSocket, 50);
}
public void testCreateServerSocketWithPortNoBacklog() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 1);
testSocket(serverSocket, 1);
}
public void testCreateServerSocketWithPortZeroBacklog() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 0);
testSocket(serverSocket, 50);
}
public void testCreateServerSocketWithPortAndBacklog() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 50);
testSocket(serverSocket, 50);
}
private void testSocket(final ServerSocket serverSocket, int specifiedBacklog)
throws IOException {
final byte[] data = "abc".getBytes();
new Thread(new Runnable() {
public void run() {
try {
Socket s = serverSocket.accept();
s.getOutputStream().write(data);
s.close();
} catch (IOException e) {
}
}
}).start();
Socket socket = new Socket(InetAddress.getLocalHost(), serverSocket.getLocalPort());
assertBacklog(specifiedBacklog, new InetSocketAddress(
InetAddress.getLocalHost(), serverSocket.getLocalPort()));
InputStream in = socket.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
transfer(in, out);
assertEquals(Arrays.toString(data), Arrays.toString(out.toByteArray()));
socket.close();
serverSocket.close();
}
/**
* Validates that the backlog of the listening address is as specified.
*/
private void assertBacklog(int specifiedBacklog, InetSocketAddress serverAddress)
throws IOException {
List<Socket> backlog = new ArrayList<Socket>();
int peak = 0;
try {
int max = 100;
for (int i = 0; i < max; i++) {
Socket socket = new Socket();
backlog.add(socket);
socket.connect(serverAddress, 500);
peak++;
}
fail("Failed to exhaust backlog after " + max + " connections!");
} catch (IOException expected) {
}
System.out.println("backlog peaked at " + peak);
for (Socket socket : backlog) {
socket.close();
}
/*
* In 4.5 of UNIX Network Programming, Stevens says:
* "Berkeley-derived implementations add a fudge factor to the
* backlog: it is multiplied by 1.5."
*
* We've observed that Linux always adds 3 to the user-specified
* backlog.
*/
assertTrue(peak >= specifiedBacklog && peak <= (specifiedBacklog + 3) * 1.5);
}
private void transfer(InputStream in, ByteArrayOutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int count;
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
}
}