1a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/* 2a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Copyright (C) 2013 Square, Inc. 3a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 4a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * you may not use this file except in compliance with the License. 6a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * You may obtain a copy of the License at 7a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 8a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 10a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Unless required by applicable law or agreed to in writing, software 11a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * See the License for the specific language governing permissions and 14a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * limitations under the License. 15a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 16166772be0e5cfdaea1a64b9f63e4c8dbfe48cba3Narayan Kamathpackage com.squareup.okhttp; 17a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 18a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.io.IOException; 19a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.ArrayList; 20c6bd683320121544811f481709b3fdbcbe9b3866Neil Fullerimport java.util.Iterator; 21a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.List; 22a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.concurrent.TimeUnit; 23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport okio.Buffer; 24a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 25a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/** 26a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Records received HTTP responses so they can be later retrieved by tests. 27a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic class RecordingCallback implements Callback { 29a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10); 30a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 31e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final List<RecordedResponse> responses = new ArrayList<>(); 32a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public synchronized void onFailure(Request request, IOException e) { 34e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller responses.add(new RecordedResponse(request, null, null, null, e)); 35a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath notifyAll(); 36a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 37a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 38e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public synchronized void onResponse(Response response) throws IOException { 39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Buffer buffer = new Buffer(); 40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller ResponseBody body = response.body(); 41e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller body.source().readAll(buffer); 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller responses.add(new RecordedResponse(response.request(), response, null, buffer.readUtf8(), null)); 44e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller notifyAll(); 45a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 46a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 47a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** 48a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Returns the recorded response triggered by {@code request}. Throws if the 49a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * response isn't enqueued before the timeout. 50a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 5171b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller public synchronized RecordedResponse await(HttpUrl url) throws Exception { 52a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath long timeoutMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) + TIMEOUT_MILLIS; 53a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath while (true) { 54c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller for (Iterator<RecordedResponse> i = responses.iterator(); i.hasNext(); ) { 55c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller RecordedResponse recordedResponse = i.next(); 5671b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller if (recordedResponse.request.httpUrl().equals(url)) { 57c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller i.remove(); 58a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return recordedResponse; 59a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 60a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 61a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 62a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath long nowMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); 63a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath if (nowMillis >= timeoutMillis) break; 64a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath wait(timeoutMillis - nowMillis); 65a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 66a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller throw new AssertionError("Timed out waiting for response to " + url); 683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 7071b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller public synchronized void assertNoResponse(HttpUrl url) throws Exception { 713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (RecordedResponse recordedResponse : responses) { 7271b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller if (recordedResponse.request.httpUrl().equals(url)) { 733c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller throw new AssertionError("Expected no response for " + url); 743c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 753c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 76a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 77a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath} 78