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