summaryrefslogtreecommitdiffstats
path: root/tests/src/tests
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-03-29 13:38:24 -0700
committerJeff Sharkey <jsharkey@android.com>2012-03-29 15:10:31 -0700
commitae6856b0fca5215f45619dd031a7e7beae7bd8cc (patch)
treef54a7fcfc663db7a22e57f3f81d77f1c98f70fa9 /tests/src/tests
parentdb4c69fbb558efe193ec81d593fc3868268ba2cf (diff)
downloadandroid_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.tar.gz
android_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.tar.bz2
android_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.zip
Migrate to shared MockWebServer.
Bug: 4726601 Change-Id: Ibe537bd5c2a092dbf974360cd454751881f7f4ea
Diffstat (limited to 'tests/src/tests')
-rw-r--r--tests/src/tests/http/MockResponse.java147
-rw-r--r--tests/src/tests/http/MockWebServer.java356
-rw-r--r--tests/src/tests/http/RecordedRequest.java93
3 files changed, 0 insertions, 596 deletions
diff --git a/tests/src/tests/http/MockResponse.java b/tests/src/tests/http/MockResponse.java
deleted file mode 100644
index aec5490c..00000000
--- a/tests/src/tests/http/MockResponse.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2010 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 tests.http;
-
-import static tests.http.MockWebServer.ASCII;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A scripted response to be replayed by the mock web server.
- */
-public class MockResponse {
- private static final byte[] EMPTY_BODY = new byte[0];
-
- private String status = "HTTP/1.1 200 OK";
- private Map<String, String> headers = new HashMap<String, String>();
- private byte[] body = EMPTY_BODY;
- private boolean closeConnectionAfter = false;
- private int numPackets = 0;
-
- public MockResponse() {
- addHeader("Content-Length", 0);
- }
-
- /**
- * Returns the HTTP response line, such as "HTTP/1.1 200 OK".
- */
- public String getStatus() {
- return status;
- }
-
- public MockResponse setResponseCode(int code) {
- this.status = "HTTP/1.1 " + code + " OK";
- return this;
- }
-
- /**
- * Returns the HTTP headers, such as "Content-Length: 0".
- */
- public List<String> getHeaders() {
- List<String> headerStrings = new ArrayList<String>();
- for (String header : headers.keySet()) {
- headerStrings.add(header + ": " + headers.get(header));
- }
- return headerStrings;
- }
-
- public MockResponse addHeader(String header, String value) {
- headers.put(header.toLowerCase(), value);
- return this;
- }
-
- public MockResponse addHeader(String header, long value) {
- return addHeader(header, Long.toString(value));
- }
-
- public MockResponse removeHeader(String header) {
- headers.remove(header.toLowerCase());
- return this;
- }
-
- /**
- * Returns an input stream containing the raw HTTP payload.
- */
- public byte[] getBody() {
- return body;
- }
-
- public MockResponse setBody(byte[] body) {
- addHeader("Content-Length", body.length);
- this.body = body;
- return this;
- }
-
- public MockResponse setBody(String body) {
- try {
- return setBody(body.getBytes(ASCII));
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- }
-
- public MockResponse setChunkedBody(byte[] body, int maxChunkSize) throws IOException {
- addHeader("Transfer-encoding", "chunked");
-
- ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
- int pos = 0;
- while (pos < body.length) {
- int chunkSize = Math.min(body.length - pos, maxChunkSize);
- bytesOut.write(Integer.toHexString(chunkSize).getBytes(ASCII));
- bytesOut.write("\r\n".getBytes(ASCII));
- bytesOut.write(body, pos, chunkSize);
- bytesOut.write("\r\n".getBytes(ASCII));
- pos += chunkSize;
- }
- bytesOut.write("0\r\n".getBytes(ASCII));
- this.body = bytesOut.toByteArray();
- return this;
- }
-
- public MockResponse setChunkedBody(String body, int maxChunkSize) throws IOException {
- return setChunkedBody(body.getBytes(ASCII), maxChunkSize);
- }
-
- @Override public String toString() {
- return status;
- }
-
- public boolean shouldCloseConnectionAfter() {
- return closeConnectionAfter;
- }
-
- public MockResponse setCloseConnectionAfter(boolean closeConnectionAfter) {
- this.closeConnectionAfter = closeConnectionAfter;
- return this;
- }
-
- public int getNumPackets() {
- return numPackets;
- }
-
- public MockResponse setNumPackets(int numPackets) {
- this.numPackets = numPackets;
- return this;
- }
-
-}
diff --git a/tests/src/tests/http/MockWebServer.java b/tests/src/tests/http/MockWebServer.java
deleted file mode 100644
index 6096783d..00000000
--- a/tests/src/tests/http/MockWebServer.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2010 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 tests.http;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A scriptable web server. Callers supply canned responses and the server
- * replays them upon request in sequence.
- *
- * TODO: merge with the version from libcore/support/src/tests/java once it's in.
- */
-public final class MockWebServer {
- static final String ASCII = "US-ASCII";
-
- private final BlockingQueue<RecordedRequest> requestQueue
- = new LinkedBlockingQueue<RecordedRequest>();
- private final BlockingQueue<MockResponse> responseQueue
- = new LinkedBlockingQueue<MockResponse>();
- private int bodyLimit = Integer.MAX_VALUE;
- private final ExecutorService executor = Executors.newCachedThreadPool();
- // keep Futures around so we can rethrow any exceptions thrown by Callables
- private final Queue<Future<?>> futures = new LinkedList<Future<?>>();
-
- private int port = -1;
- private ServerSocket serverSocket;
-
- public int getPort() {
- if (port == -1) {
- throw new IllegalStateException("Cannot retrieve port before calling play()");
- }
- return port;
- }
-
- /**
- * Returns a URL for connecting to this server.
- *
- * @param path the request path, such as "/".
- */
- public URL getUrl(String path) throws MalformedURLException {
- return new URL("http://localhost:" + getPort() + path);
- }
-
- /**
- * Sets the number of bytes of the POST body to keep in memory to the given
- * limit.
- */
- public void setBodyLimit(int maxBodyLength) {
- this.bodyLimit = maxBodyLength;
- }
-
- public void enqueue(MockResponse response) {
- responseQueue.add(response);
- }
-
- /**
- * Awaits the next HTTP request, removes it, and returns it. Callers should
- * use this to verify the request sent was as intended.
- */
- public RecordedRequest takeRequest() throws InterruptedException {
- return requestQueue.take();
- }
-
- public RecordedRequest takeRequestWithTimeout(long timeoutMillis) throws InterruptedException {
- return requestQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
- }
-
- public List<RecordedRequest> drainRequests() {
- List<RecordedRequest> requests = new ArrayList<RecordedRequest>();
- requestQueue.drainTo(requests);
- return requests;
- }
-
- /**
- * Starts the server, serves all enqueued requests, and shuts the server
- * down.
- */
- public void play() throws IOException {
- serverSocket = new ServerSocket(0);
- serverSocket.setReuseAddress(true);
- port = serverSocket.getLocalPort();
- submitCallable(new Callable<Void>() {
- public Void call() throws Exception {
- int count = 0;
- while (true) {
- if (count > 0 && responseQueue.isEmpty()) {
- serverSocket.close();
- executor.shutdown();
- return null;
- }
-
- serveConnection(serverSocket.accept());
- count++;
- }
- }
- });
- }
-
- /**
- * shutdown the webserver
- */
- public void shutdown() throws IOException {
- responseQueue.clear();
- serverSocket.close();
- executor.shutdown();
- }
-
- private void serveConnection(final Socket s) {
- submitCallable(new Callable<Void>() {
- public Void call() throws Exception {
- InputStream in = new BufferedInputStream(s.getInputStream());
- OutputStream out = new BufferedOutputStream(s.getOutputStream());
-
- int sequenceNumber = 0;
- while (true) {
- RecordedRequest request = readRequest(in, sequenceNumber);
- if (request == null) {
- if (sequenceNumber == 0) {
- throw new IllegalStateException("Connection without any request!");
- } else {
- break;
- }
- }
- requestQueue.add(request);
- MockResponse response = sendResponse(out, request);
- if (response.shouldCloseConnectionAfter()) {
- break;
- }
- sequenceNumber++;
- }
-
- in.close();
- out.close();
- return null;
- }
- });
- }
-
- private void submitCallable(Callable<?> callable) {
- Future<?> future = executor.submit(callable);
- futures.add(future);
- }
-
- /**
- * Check for and raise any exceptions that have been thrown by child threads. Will not block on
- * children still running.
- * @throws ExecutionException for the first child thread that threw an exception
- */
- public void checkForExceptions() throws ExecutionException, InterruptedException {
- final int originalSize = futures.size();
- for (int i = 0; i < originalSize; i++) {
- Future<?> future = futures.remove();
- try {
- future.get(0, TimeUnit.SECONDS);
- } catch (TimeoutException e) {
- futures.add(future); // still running
- }
- }
- }
-
- /**
- * @param sequenceNumber the index of this request on this connection.
- */
- private RecordedRequest readRequest(InputStream in, int sequenceNumber) throws IOException {
- String request = readAsciiUntilCrlf(in);
- if (request.equals("")) {
- return null; // end of data; no more requests
- }
-
- List<String> headers = new ArrayList<String>();
- int contentLength = -1;
- boolean chunked = false;
- String header;
- while (!(header = readAsciiUntilCrlf(in)).equals("")) {
- headers.add(header);
- String lowercaseHeader = header.toLowerCase();
- if (contentLength == -1 && lowercaseHeader.startsWith("content-length:")) {
- contentLength = Integer.parseInt(header.substring(15).trim());
- }
- if (lowercaseHeader.startsWith("transfer-encoding:") &&
- lowercaseHeader.substring(18).trim().equals("chunked")) {
- chunked = true;
- }
- }
-
- boolean hasBody = false;
- TruncatingOutputStream requestBody = new TruncatingOutputStream();
- List<Integer> chunkSizes = new ArrayList<Integer>();
- if (contentLength != -1) {
- hasBody = true;
- transfer(contentLength, in, requestBody);
- } else if (chunked) {
- hasBody = true;
- while (true) {
- int chunkSize = Integer.parseInt(readAsciiUntilCrlf(in).trim(), 16);
- if (chunkSize == 0) {
- readEmptyLine(in);
- break;
- }
- chunkSizes.add(chunkSize);
- transfer(chunkSize, in, requestBody);
- readEmptyLine(in);
- }
- }
-
- if (request.startsWith("GET ")) {
- if (hasBody) {
- throw new IllegalArgumentException("GET requests should not have a body!");
- }
- } else if (request.startsWith("POST ")) {
- if (!hasBody) {
- throw new IllegalArgumentException("POST requests must have a body!");
- }
- } else {
- throw new UnsupportedOperationException("Unexpected method: " + request);
- }
- return new RecordedRequest(request, headers, chunkSizes,
- requestBody.numBytesReceived, requestBody.toByteArray(), sequenceNumber);
- }
-
- /**
- * Returns a response to satisfy {@code request}.
- */
- private MockResponse sendResponse(OutputStream out, RecordedRequest request)
- throws InterruptedException, IOException {
- if (responseQueue.isEmpty()) {
- throw new IllegalStateException("Unexpected request: " + request);
- }
- MockResponse response = responseQueue.take();
- writeResponse(out, response, false);
- if (response.getNumPackets() > 0) {
- // there are continuing packets to send as part of this response.
- for (int i = 0; i < response.getNumPackets(); i++) {
- writeResponse(out, response, true);
- // delay sending next continuing response just a little bit
- Thread.sleep(100);
- }
- }
- return response;
- }
-
- private void writeResponse(OutputStream out, MockResponse response,
- boolean continuingPacket) throws IOException {
- if (continuingPacket) {
- // this is a continuing response - just send the body - no headers, status
- out.write(response.getBody());
- out.flush();
- return;
- }
- out.write((response.getStatus() + "\r\n").getBytes(ASCII));
- for (String header : response.getHeaders()) {
- out.write((header + "\r\n").getBytes(ASCII));
- }
- out.write(("\r\n").getBytes(ASCII));
- out.write(response.getBody());
- out.flush();
- }
-
- /**
- * Transfer bytes from {@code in} to {@code out} until either {@code length}
- * bytes have been transferred or {@code in} is exhausted.
- */
- private void transfer(int length, InputStream in, OutputStream out) throws IOException {
- byte[] buffer = new byte[1024];
- while (length > 0) {
- int count = in.read(buffer, 0, Math.min(buffer.length, length));
- if (count == -1) {
- return;
- }
- out.write(buffer, 0, count);
- length -= count;
- }
- }
-
- /**
- * Returns the text from {@code in} until the next "\r\n", or null if
- * {@code in} is exhausted.
- */
- private String readAsciiUntilCrlf(InputStream in) throws IOException {
- StringBuilder builder = new StringBuilder();
- while (true) {
- int c = in.read();
- if (c == '\n' && builder.length() > 0 && builder.charAt(builder.length() - 1) == '\r') {
- builder.deleteCharAt(builder.length() - 1);
- return builder.toString();
- } else if (c == -1) {
- return builder.toString();
- } else {
- builder.append((char) c);
- }
- }
- }
-
- private void readEmptyLine(InputStream in) throws IOException {
- String line = readAsciiUntilCrlf(in);
- if (!line.equals("")) {
- throw new IllegalStateException("Expected empty but was: " + line);
- }
- }
-
- /**
- * An output stream that drops data after bodyLimit bytes.
- */
- private class TruncatingOutputStream extends ByteArrayOutputStream {
- private int numBytesReceived = 0;
- @Override public void write(byte[] buffer, int offset, int len) {
- numBytesReceived += len;
- super.write(buffer, offset, Math.min(len, bodyLimit - count));
- }
- @Override public void write(int oneByte) {
- numBytesReceived++;
- if (count < bodyLimit) {
- super.write(oneByte);
- }
- }
- }
-}
diff --git a/tests/src/tests/http/RecordedRequest.java b/tests/src/tests/http/RecordedRequest.java
deleted file mode 100644
index 6b67af20..00000000
--- a/tests/src/tests/http/RecordedRequest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 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 tests.http;
-
-import java.util.List;
-
-/**
- * An HTTP request that came into the mock web server.
- */
-public final class RecordedRequest {
- private final String requestLine;
- private final List<String> headers;
- private final List<Integer> chunkSizes;
- private final int bodySize;
- private final byte[] body;
- private final int sequenceNumber;
-
- RecordedRequest(String requestLine, List<String> headers, List<Integer> chunkSizes,
- int bodySize, byte[] body, int sequenceNumber) {
- this.requestLine = requestLine;
- this.headers = headers;
- this.chunkSizes = chunkSizes;
- this.bodySize = bodySize;
- this.body = body;
- this.sequenceNumber = sequenceNumber;
- }
-
- public String getRequestLine() {
- return requestLine;
- }
-
- public List<String> getHeaders() {
- return headers;
- }
-
- /**
- * Returns the sizes of the chunks of this request's body, or an empty list
- * if the request's body was empty or unchunked.
- */
- public List<Integer> getChunkSizes() {
- return chunkSizes;
- }
-
- /**
- * Returns the total size of the body of this POST request (before
- * truncation).
- */
- public int getBodySize() {
- return bodySize;
- }
-
- /**
- * Returns the body of this POST request. This may be truncated.
- */
- public byte[] getBody() {
- return body;
- }
-
- /**
- * Returns the index of this request on its HTTP connection. Since a single
- * HTTP connection may serve multiple requests, each request is assigned its
- * own sequence number.
- */
- public int getSequenceNumber() {
- return sequenceNumber;
- }
-
- @Override public String toString() {
- return requestLine;
- }
-
- public String getMethod() {
- return getRequestLine().split(" ")[0];
- }
-
- public String getPath() {
- return getRequestLine().split(" ")[1];
- }
-}