1 /* 2 * Copyright (C) 2011 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.mockwebserver; 18 19 import java.io.BufferedReader; 20 import java.io.ByteArrayInputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.InputStreamReader; 24 import java.net.HttpURLConnection; 25 import java.net.SocketTimeoutException; 26 import java.net.URL; 27 import java.net.URLConnection; 28 import java.util.Arrays; 29 import java.util.Collections; 30 import java.util.List; 31 import junit.framework.TestCase; 32 33 public final class MockWebServerTest extends TestCase { 34 35 private MockWebServer server = new MockWebServer(); 36 tearDown()37 @Override protected void tearDown() throws Exception { 38 server.shutdown(); 39 super.tearDown(); 40 } 41 testRecordedRequestAccessors()42 public void testRecordedRequestAccessors() { 43 List<String> headers = Arrays.asList( 44 "User-Agent: okhttp", 45 "Cookie: s=square", 46 "Cookie: a=android", 47 "X-Whitespace: left", 48 "X-Whitespace:right ", 49 "X-Whitespace: both " 50 ); 51 List<Integer> chunkSizes = Collections.emptyList(); 52 byte[] body = {'A', 'B', 'C'}; 53 String requestLine = "GET / HTTP/1.1"; 54 RecordedRequest request = new RecordedRequest( 55 requestLine, headers, chunkSizes, body.length, body, 0, null); 56 assertEquals("s=square", request.getHeader("cookie")); 57 assertEquals(Arrays.asList("s=square", "a=android"), request.getHeaders("cookie")); 58 assertEquals("left", request.getHeader("x-whitespace")); 59 assertEquals(Arrays.asList("left", "right", "both"), request.getHeaders("x-whitespace")); 60 assertEquals("ABC", request.getUtf8Body()); 61 } 62 testDefaultMockResponse()63 public void testDefaultMockResponse() { 64 MockResponse response = new MockResponse(); 65 assertEquals(Arrays.asList("Content-Length: 0"), response.getHeaders()); 66 assertEquals("HTTP/1.1 200 OK", response.getStatus()); 67 } 68 testSetBodyAdjustsHeaders()69 public void testSetBodyAdjustsHeaders() throws IOException { 70 MockResponse response = new MockResponse().setBody("ABC"); 71 assertEquals(Arrays.asList("Content-Length: 3"), response.getHeaders()); 72 InputStream in = response.getBodyStream(); 73 assertEquals('A', in.read()); 74 assertEquals('B', in.read()); 75 assertEquals('C', in.read()); 76 assertEquals(-1, in.read()); 77 assertEquals("HTTP/1.1 200 OK", response.getStatus()); 78 } 79 testMockResponseAddHeader()80 public void testMockResponseAddHeader() { 81 MockResponse response = new MockResponse() 82 .clearHeaders() 83 .addHeader("Cookie: s=square") 84 .addHeader("Cookie", "a=android"); 85 assertEquals(Arrays.asList("Cookie: s=square", "Cookie: a=android"), 86 response.getHeaders()); 87 } 88 testMockResponseSetHeader()89 public void testMockResponseSetHeader() { 90 MockResponse response = new MockResponse() 91 .clearHeaders() 92 .addHeader("Cookie: s=square") 93 .addHeader("Cookie: a=android") 94 .addHeader("Cookies: delicious"); 95 response.setHeader("cookie", "r=robot"); 96 assertEquals(Arrays.asList("Cookies: delicious", "cookie: r=robot"), 97 response.getHeaders()); 98 } 99 testRegularResponse()100 public void testRegularResponse() throws Exception { 101 server.enqueue(new MockResponse().setBody("hello world")); 102 server.play(); 103 104 URL url = server.getUrl("/"); 105 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 106 connection.setRequestProperty("Accept-Language", "en-US"); 107 InputStream in = connection.getInputStream(); 108 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 109 assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); 110 assertEquals("hello world", reader.readLine()); 111 112 RecordedRequest request = server.takeRequest(); 113 assertEquals("GET / HTTP/1.1", request.getRequestLine()); 114 assertTrue(request.getHeaders().contains("Accept-Language: en-US")); 115 } 116 testRedirect()117 public void testRedirect() throws Exception { 118 server.play(); 119 server.enqueue(new MockResponse() 120 .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) 121 .addHeader("Location: " + server.getUrl("/new-path")) 122 .setBody("This page has moved!")); 123 server.enqueue(new MockResponse().setBody("This is the new location!")); 124 125 URLConnection connection = server.getUrl("/").openConnection(); 126 InputStream in = connection.getInputStream(); 127 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 128 assertEquals("This is the new location!", reader.readLine()); 129 130 RecordedRequest first = server.takeRequest(); 131 assertEquals("GET / HTTP/1.1", first.getRequestLine()); 132 RecordedRequest redirect = server.takeRequest(); 133 assertEquals("GET /new-path HTTP/1.1", redirect.getRequestLine()); 134 } 135 136 /** 137 * Test that MockWebServer blocks for a call to enqueue() if a request 138 * is made before a mock response is ready. 139 */ testDispatchBlocksWaitingForEnqueue()140 public void testDispatchBlocksWaitingForEnqueue() throws Exception { 141 server.play(); 142 143 new Thread() { 144 @Override public void run() { 145 try { 146 Thread.sleep(1000); 147 } catch (InterruptedException ignored) { 148 } 149 server.enqueue(new MockResponse().setBody("enqueued in the background")); 150 } 151 }.start(); 152 153 URLConnection connection = server.getUrl("/").openConnection(); 154 InputStream in = connection.getInputStream(); 155 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 156 assertEquals("enqueued in the background", reader.readLine()); 157 } 158 testNonHexadecimalChunkSize()159 public void testNonHexadecimalChunkSize() throws Exception { 160 server.enqueue(new MockResponse() 161 .setBody("G\r\nxxxxxxxxxxxxxxxx\r\n0\r\n\r\n") 162 .clearHeaders() 163 .addHeader("Transfer-encoding: chunked")); 164 server.play(); 165 166 URLConnection connection = server.getUrl("/").openConnection(); 167 InputStream in = connection.getInputStream(); 168 try { 169 in.read(); 170 fail(); 171 } catch (IOException expected) { 172 } 173 } 174 testResponseTimeout()175 public void testResponseTimeout() throws Exception { 176 server.enqueue(new MockResponse() 177 .setBody("ABC") 178 .clearHeaders() 179 .addHeader("Content-Length: 4")); 180 server.enqueue(new MockResponse() 181 .setBody("DEF")); 182 server.play(); 183 184 URLConnection urlConnection = server.getUrl("/").openConnection(); 185 urlConnection.setReadTimeout(1000); 186 InputStream in = urlConnection.getInputStream(); 187 assertEquals('A', in.read()); 188 assertEquals('B', in.read()); 189 assertEquals('C', in.read()); 190 try { 191 in.read(); // if Content-Length was accurate, this would return -1 immediately 192 fail(); 193 } catch (SocketTimeoutException expected) { 194 } 195 196 URLConnection urlConnection2 = server.getUrl("/").openConnection(); 197 InputStream in2 = urlConnection2.getInputStream(); 198 assertEquals('D', in2.read()); 199 assertEquals('E', in2.read()); 200 assertEquals('F', in2.read()); 201 assertEquals(-1, in2.read()); 202 203 assertEquals(0, server.takeRequest().getSequenceNumber()); 204 assertEquals(0, server.takeRequest().getSequenceNumber()); 205 } 206 testDisconnectAtStart()207 public void testDisconnectAtStart() throws Exception { 208 server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START)); 209 server.enqueue(new MockResponse()); // The jdk's HttpUrlConnection is a bastard. 210 server.enqueue(new MockResponse()); 211 server.play(); 212 try { 213 server.getUrl("/a").openConnection().getInputStream(); 214 } catch (IOException e) { 215 // Expected. 216 } 217 server.getUrl("/b").openConnection().getInputStream(); // Should succeed. 218 } 219 testStreamingResponseBody()220 public void testStreamingResponseBody() throws Exception { 221 InputStream responseBody = new ByteArrayInputStream("ABC".getBytes("UTF-8")); 222 server.enqueue(new MockResponse().setBody(responseBody, 3)); 223 server.play(); 224 225 InputStream in = server.getUrl("/").openConnection().getInputStream(); 226 assertEquals('A', in.read()); 227 assertEquals('B', in.read()); 228 assertEquals('C', in.read()); 229 230 assertEquals(-1, responseBody.read()); // The body is exhausted. 231 } 232 } 233