197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes/* 297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Copyright (C) 2010 The Android Open Source Project 397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * you may not use this file except in compliance with the License. 697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * You may obtain a copy of the License at 797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 1097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Unless required by applicable law or agreed to in writing, software 1197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * See the License for the specific language governing permissions and 1497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * limitations under the License. 1597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes */ 1697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 1797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughespackage benchmarks.regression; 1897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 1997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.Param; 2050b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstromimport com.google.mockwebserver.Dispatcher; 215a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuangimport com.google.mockwebserver.MockResponse; 225a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuangimport com.google.mockwebserver.MockWebServer; 2350b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstromimport com.google.mockwebserver.RecordedRequest; 2497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.IOException; 2597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.InputStream; 265a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuangimport java.net.HttpURLConnection; 2797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.net.URL; 2897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 29ea13f8291a92b6f47f50011da1d5e8c107984bc3Paul Duffinpublic final class URLConnectionBenchmark { 3097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 3197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param({"0", "1024", "1048576"}) private int bodySize; 3297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param({"2048"}) private int chunkSize; 3397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param({"1024"}) private int readBufferSize; 3497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param private ResponseHeaders responseHeaders; 3597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param private TransferEncoding transferEncoding; 3697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private byte[] readBuffer; 3797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 3897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private MockWebServer server; 3997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private URL url; 4097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 4150b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom private static class SingleResponseDispatcher extends Dispatcher { 4250b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom private MockResponse response; 4350b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom SingleResponseDispatcher(MockResponse response) { 4450b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom this.response = response; 4550b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom } 4650b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom @Override public MockResponse dispatch(RecordedRequest request) { 4750b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom return response; 4850b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom } 4950b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom }; 5050b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom 5197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes protected void setUp() throws Exception { 5297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes readBuffer = new byte[readBufferSize]; 5397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes server = new MockWebServer(); 5497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 5597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes MockResponse response = new MockResponse(); 5697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes responseHeaders.apply(response); 5797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes transferEncoding.setBody(response, bodySize, chunkSize); 5897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 595a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuang // keep serving the same response for all iterations 6050b871d4eb3b42a8209bb4a6d54cb649f56e873fBrian Carlstrom server.setDispatcher(new SingleResponseDispatcher(response)); 6197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes server.play(); 6297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 6397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes url = server.getUrl("/"); 6497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes get(); // ensure the server has started its threads, etc. 6597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 6697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 6797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes protected void tearDown() throws Exception { 6897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes server.shutdown(); 6997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 7097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 7197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public int timeGet(int reps) throws IOException { 7297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int totalBytesRead = 0; 7397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes for (int i = 0; i < reps; i++) { 7497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes totalBytesRead += get(); 7597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 7697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return totalBytesRead; 7797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 7897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 7997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private int get() throws IOException { 8097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int totalBytesRead = 0; 815a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuang HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 825a7833b406bb2716b057d3ed923f22f1f86b2a20Tsu Chiang Chuang // URLConnection connection = url.openConnection(); 8397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes InputStream in = connection.getInputStream(); 8497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int count; 8597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes while ((count = in.read(readBuffer)) != -1) { 8697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes totalBytesRead += count; 8797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 8897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return totalBytesRead; 8997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 9097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 9197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes enum TransferEncoding { 9297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes FIXED_LENGTH, 9397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes CHUNKED; 9497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 9597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes void setBody(MockResponse response, int bodySize, int chunkSize) throws IOException { 9697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes if (this == TransferEncoding.FIXED_LENGTH) { 9797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.setBody(new byte[bodySize]); 9897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } else if (this == TransferEncoding.CHUNKED) { 9997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.setChunkedBody(new byte[bodySize], chunkSize); 10097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 10197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 10297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 10397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 10497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes enum ResponseHeaders { 10597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes MINIMAL, 10697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes TYPICAL; 10797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 10897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes void apply(MockResponse response) { 10997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes if (this == TYPICAL) { 11097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes /* from http://api.twitter.com/1/statuses/public_timeline.json */ 11197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Date: Wed, 30 Jun 2010 17:57:39 GMT"); 11297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Server: hi"); 11397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("X-RateLimit-Remaining: 0"); 11497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("X-Runtime: 0.01637"); 11597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Content-Type: application/json; charset=utf-8"); 11697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("X-RateLimit-Class: api_whitelisted"); 11797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Cache-Control: no-cache, max-age=300"); 11897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("X-RateLimit-Reset: 1277920980"); 11997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Set-Cookie: _twitter_sess=BAh7EDoOcmV0dXJuX3RvIjZodHRwOi8vZGV2L" 12097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "nR3aXR0ZXIuY29tL3BhZ2Vz%250AL3NpZ25faW5fd2l0aF90d2l0dGVyOgxjc3JmX2lkIiUw" 12197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "ODFhNGY2NTM5NjRm%250ANjY1N2M2NzcwNWI0MDlmZGZjZjoVaW5fbmV3X3VzZXJfZmxvdzA" 12297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "6EXRyYW5z%250AX3Byb21wdDAiKXNob3dfZGlzY292ZXJhYmlsaXR5X2Zvcl9qZXNzZXdpbH" 12397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "Nv%250AbjA6E3Nob3dfaGVscF9saW5rMDoTcGFzc3dvcmRfdG9rZW4iLWUyYjlhNmM3%250A" 12497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "MWJiNzI3NWNlZDI1NDY3MGMzZWNmMTE0MjI4N2EyNGE6D2NyZWF0ZWRfYXRs%250AKwhiM%2" 12597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "52F6JKQE6CXVzZXJpA8tE3iIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxl%250Acjo6Rmxhc2" 12697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "g6OkZsYXNoSGFzaHsABjoKQHVzZWR7ADoHaWQiJWZmMTNhM2Qx%250AZTU1YTkzMmYyMWM0M" 12797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "GNhZjU4NDVjMTQz--11250628c85830219438eb7eba96a541a9af4098; domain=.twitt" 12897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes + "er.com; path=/"); 12997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Expires: Wed, 30 Jun 2010 18:02:39 GMT"); 13097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes response.addHeader("Vary: Accept-Encoding"); 13197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 13297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 13397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 13497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes} 135