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; 36 37 @Override setUp()38 public void setUp() throws Exception { 39 super.setUp(); 40 server = new MockWebServer(); 41 } 42 tearDown()43 @Override protected void tearDown() throws Exception { 44 server.shutdown(); 45 super.tearDown(); 46 } 47 testRecordedRequestAccessors()48 public void testRecordedRequestAccessors() { 49 List<String> headers = Arrays.asList( 50 "User-Agent: okhttp", 51 "Cookie: s=square", 52 "Cookie: a=android", 53 "X-Whitespace: left", 54 "X-Whitespace:right ", 55 "X-Whitespace: both " 56 ); 57 List<Integer> chunkSizes = Collections.emptyList(); 58 byte[] body = {'A', 'B', 'C'}; 59 String requestLine = "GET / HTTP/1.1"; 60 RecordedRequest request = new RecordedRequest( 61 requestLine, headers, chunkSizes, body.length, body, 0, null); 62 assertEquals("s=square", request.getHeader("cookie")); 63 assertEquals(Arrays.asList("s=square", "a=android"), request.getHeaders("cookie")); 64 assertEquals("left", request.getHeader("x-whitespace")); 65 assertEquals(Arrays.asList("left", "right", "both"), request.getHeaders("x-whitespace")); 66 assertEquals("ABC", request.getUtf8Body()); 67 } 68 testDefaultMockResponse()69 public void testDefaultMockResponse() { 70 MockResponse response = new MockResponse(); 71 assertEquals(Arrays.asList("Content-Length: 0"), response.getHeaders()); 72 assertEquals("HTTP/1.1 200 OK", response.getStatus()); 73 } 74 testSetBodyAdjustsHeaders()75 public void testSetBodyAdjustsHeaders() throws IOException { 76 MockResponse response = new MockResponse().setBody("ABC"); 77 assertEquals(Arrays.asList("Content-Length: 3"), response.getHeaders()); 78 InputStream in = response.getBodyStream(); 79 assertEquals('A', in.read()); 80 assertEquals('B', in.read()); 81 assertEquals('C', in.read()); 82 assertEquals(-1, in.read()); 83 assertEquals("HTTP/1.1 200 OK", response.getStatus()); 84 } 85 testMockResponseAddHeader()86 public void testMockResponseAddHeader() { 87 MockResponse response = new MockResponse() 88 .clearHeaders() 89 .addHeader("Cookie: s=square") 90 .addHeader("Cookie", "a=android"); 91 assertEquals(Arrays.asList("Cookie: s=square", "Cookie: a=android"), 92 response.getHeaders()); 93 } 94 testMockResponseSetHeader()95 public void testMockResponseSetHeader() { 96 MockResponse response = new MockResponse() 97 .clearHeaders() 98 .addHeader("Cookie: s=square") 99 .addHeader("Cookie: a=android") 100 .addHeader("Cookies: delicious"); 101 response.setHeader("cookie", "r=robot"); 102 assertEquals(Arrays.asList("Cookies: delicious", "cookie: r=robot"), 103 response.getHeaders()); 104 } 105 testRegularResponse()106 public void testRegularResponse() throws Exception { 107 server.enqueue(new MockResponse().setBody("hello world")); 108 server.play(); 109 110 URL url = server.getUrl("/"); 111 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 112 connection.setRequestProperty("Accept-Language", "en-US"); 113 InputStream in = connection.getInputStream(); 114 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 115 assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); 116 assertEquals("hello world", reader.readLine()); 117 118 RecordedRequest request = server.takeRequest(); 119 assertEquals("GET / HTTP/1.1", request.getRequestLine()); 120 assertTrue(request.getHeaders().contains("Accept-Language: en-US")); 121 } 122 testRedirect()123 public void testRedirect() throws Exception { 124 server.play(); 125 server.enqueue(new MockResponse() 126 .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) 127 .addHeader("Location: " + server.getUrl("/new-path")) 128 .setBody("This page has moved!")); 129 server.enqueue(new MockResponse().setBody("This is the new location!")); 130 131 URLConnection connection = server.getUrl("/").openConnection(); 132 InputStream in = connection.getInputStream(); 133 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 134 assertEquals("This is the new location!", reader.readLine()); 135 136 RecordedRequest first = server.takeRequest(); 137 assertEquals("GET / HTTP/1.1", first.getRequestLine()); 138 RecordedRequest redirect = server.takeRequest(); 139 assertEquals("GET /new-path HTTP/1.1", redirect.getRequestLine()); 140 } 141 142 /** 143 * Test that MockWebServer blocks for a call to enqueue() if a request 144 * is made before a mock response is ready. 145 */ testDispatchBlocksWaitingForEnqueue()146 public void testDispatchBlocksWaitingForEnqueue() throws Exception { 147 server.play(); 148 149 new Thread() { 150 @Override public void run() { 151 try { 152 Thread.sleep(1000); 153 } catch (InterruptedException ignored) { 154 } 155 server.enqueue(new MockResponse().setBody("enqueued in the background")); 156 } 157 }.start(); 158 159 URLConnection connection = server.getUrl("/").openConnection(); 160 InputStream in = connection.getInputStream(); 161 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 162 assertEquals("enqueued in the background", reader.readLine()); 163 } 164 testNonHexadecimalChunkSize()165 public void testNonHexadecimalChunkSize() throws Exception { 166 server.enqueue(new MockResponse() 167 .setBody("G\r\nxxxxxxxxxxxxxxxx\r\n0\r\n\r\n") 168 .clearHeaders() 169 .addHeader("Transfer-encoding: chunked")); 170 server.play(); 171 172 URLConnection connection = server.getUrl("/").openConnection(); 173 InputStream in = connection.getInputStream(); 174 try { 175 in.read(); 176 fail(); 177 } catch (IOException expected) { 178 } 179 } 180 testResponseTimeout()181 public void testResponseTimeout() throws Exception { 182 server.enqueue(new MockResponse() 183 .setBody("ABC") 184 .clearHeaders() 185 .addHeader("Content-Length: 4")); 186 server.enqueue(new MockResponse() 187 .setBody("DEF")); 188 server.play(); 189 190 URLConnection urlConnection = server.getUrl("/").openConnection(); 191 urlConnection.setReadTimeout(1000); 192 InputStream in = urlConnection.getInputStream(); 193 assertEquals('A', in.read()); 194 assertEquals('B', in.read()); 195 assertEquals('C', in.read()); 196 try { 197 in.read(); // if Content-Length was accurate, this would return -1 immediately 198 fail(); 199 } catch (SocketTimeoutException expected) { 200 } 201 202 URLConnection urlConnection2 = server.getUrl("/").openConnection(); 203 InputStream in2 = urlConnection2.getInputStream(); 204 assertEquals('D', in2.read()); 205 assertEquals('E', in2.read()); 206 assertEquals('F', in2.read()); 207 assertEquals(-1, in2.read()); 208 209 assertEquals(0, server.takeRequest().getSequenceNumber()); 210 assertEquals(0, server.takeRequest().getSequenceNumber()); 211 } 212 testDisconnectAtStart()213 public void testDisconnectAtStart() throws Exception { 214 server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START)); 215 server.enqueue(new MockResponse()); // The jdk's HttpUrlConnection is a bastard. 216 server.enqueue(new MockResponse()); 217 server.play(); 218 try { 219 server.getUrl("/a").openConnection().getInputStream(); 220 } catch (IOException e) { 221 // Expected. 222 } 223 server.getUrl("/b").openConnection().getInputStream(); // Should succeed. 224 } 225 testStreamingResponseBody()226 public void testStreamingResponseBody() throws Exception { 227 InputStream responseBody = new ByteArrayInputStream("ABC".getBytes("UTF-8")); 228 server.enqueue(new MockResponse().setBody(responseBody, 3)); 229 server.play(); 230 231 InputStream in = server.getUrl("/").openConnection().getInputStream(); 232 assertEquals('A', in.read()); 233 assertEquals('B', in.read()); 234 assertEquals('C', in.read()); 235 236 assertEquals(-1, responseBody.read()); // The body is exhausted. 237 } 238 } 239