| /* |
| * 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 benchmarks.regression; |
| |
| import com.google.caliper.Param; |
| import com.google.caliper.SimpleBenchmark; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import tests.http.MockResponse; |
| import tests.http.MockWebServer; |
| |
| public final class URLConnectionBenchmark extends SimpleBenchmark { |
| |
| @Param({"0", "1024", "1048576"}) private int bodySize; |
| @Param({"2048"}) private int chunkSize; |
| @Param({"1024"}) private int readBufferSize; |
| @Param private ResponseHeaders responseHeaders; |
| @Param private TransferEncoding transferEncoding; |
| private byte[] readBuffer; |
| |
| private MockWebServer server; |
| private URL url; |
| |
| protected void setUp() throws Exception { |
| readBuffer = new byte[readBufferSize]; |
| server = new MockWebServer(); |
| |
| MockResponse response = new MockResponse(); |
| responseHeaders.apply(response); |
| transferEncoding.setBody(response, bodySize, chunkSize); |
| server.enqueue(response); |
| |
| server.setContinuousServing(true); |
| server.play(); |
| |
| url = server.getUrl("/"); |
| get(); // ensure the server has started its threads, etc. |
| } |
| |
| protected void tearDown() throws Exception { |
| /* |
| * Entice the server to shut itself down gracefully. The shutdown method |
| * doesn't work on Dalvik because socket.close() doesn't release blocked |
| * threads. Instead, read the last continuously-served request, and then |
| * cause the server to close the otherwise-reusable HTTP connection. |
| */ |
| server.setContinuousServing(false); |
| server.enqueue(new MockResponse().setDisconnectAtEnd(true)); |
| get(); |
| get(); |
| server.shutdown(); |
| } |
| |
| public int timeGet(int reps) throws IOException { |
| int totalBytesRead = 0; |
| for (int i = 0; i < reps; i++) { |
| totalBytesRead += get(); |
| } |
| return totalBytesRead; |
| } |
| |
| private int get() throws IOException { |
| int totalBytesRead = 0; |
| URLConnection connection = url.openConnection(); |
| InputStream in = connection.getInputStream(); |
| int count; |
| while ((count = in.read(readBuffer)) != -1) { |
| totalBytesRead += count; |
| } |
| return totalBytesRead; |
| } |
| |
| enum TransferEncoding { |
| FIXED_LENGTH, |
| CHUNKED; |
| |
| void setBody(MockResponse response, int bodySize, int chunkSize) throws IOException { |
| if (this == TransferEncoding.FIXED_LENGTH) { |
| response.setBody(new byte[bodySize]); |
| } else if (this == TransferEncoding.CHUNKED) { |
| response.setChunkedBody(new byte[bodySize], chunkSize); |
| } |
| } |
| } |
| |
| enum ResponseHeaders { |
| MINIMAL, |
| TYPICAL; |
| |
| void apply(MockResponse response) { |
| if (this == TYPICAL) { |
| /* from http://api.twitter.com/1/statuses/public_timeline.json */ |
| response.addHeader("Date: Wed, 30 Jun 2010 17:57:39 GMT"); |
| response.addHeader("Server: hi"); |
| response.addHeader("X-RateLimit-Remaining: 0"); |
| response.addHeader("X-Runtime: 0.01637"); |
| response.addHeader("Content-Type: application/json; charset=utf-8"); |
| response.addHeader("X-RateLimit-Class: api_whitelisted"); |
| response.addHeader("Cache-Control: no-cache, max-age=300"); |
| response.addHeader("X-RateLimit-Reset: 1277920980"); |
| response.addHeader("Set-Cookie: _twitter_sess=BAh7EDoOcmV0dXJuX3RvIjZodHRwOi8vZGV2L" |
| + "nR3aXR0ZXIuY29tL3BhZ2Vz%250AL3NpZ25faW5fd2l0aF90d2l0dGVyOgxjc3JmX2lkIiUw" |
| + "ODFhNGY2NTM5NjRm%250ANjY1N2M2NzcwNWI0MDlmZGZjZjoVaW5fbmV3X3VzZXJfZmxvdzA" |
| + "6EXRyYW5z%250AX3Byb21wdDAiKXNob3dfZGlzY292ZXJhYmlsaXR5X2Zvcl9qZXNzZXdpbH" |
| + "Nv%250AbjA6E3Nob3dfaGVscF9saW5rMDoTcGFzc3dvcmRfdG9rZW4iLWUyYjlhNmM3%250A" |
| + "MWJiNzI3NWNlZDI1NDY3MGMzZWNmMTE0MjI4N2EyNGE6D2NyZWF0ZWRfYXRs%250AKwhiM%2" |
| + "52F6JKQE6CXVzZXJpA8tE3iIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxl%250Acjo6Rmxhc2" |
| + "g6OkZsYXNoSGFzaHsABjoKQHVzZWR7ADoHaWQiJWZmMTNhM2Qx%250AZTU1YTkzMmYyMWM0M" |
| + "GNhZjU4NDVjMTQz--11250628c85830219438eb7eba96a541a9af4098; domain=.twitt" |
| + "er.com; path=/"); |
| response.addHeader("Expires: Wed, 30 Jun 2010 18:02:39 GMT"); |
| response.addHeader("Vary: Accept-Encoding"); |
| } |
| } |
| } |
| } |