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;
23a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
24a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/**
25a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Records received HTTP responses so they can be later retrieved by tests.
26a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */
27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic class RecordingCallback implements Callback {
28a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath  public static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10);
29a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private final List<RecordedResponse> responses = new ArrayList<>();
31a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
32e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Override public synchronized void onFailure(Request request, IOException e) {
33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    responses.add(new RecordedResponse(request, null, null, null, e));
34a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath    notifyAll();
35a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath  }
36a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
37e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Override public synchronized void onResponse(Response response) throws IOException {
386c251e20f00c7574b217bd4351ac81666f574380Tobias Thierer    String body = response.body().string();
396c251e20f00c7574b217bd4351ac81666f574380Tobias Thierer    responses.add(new RecordedResponse(response.request(), response, null, body, null));
40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    notifyAll();
41a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath  }
42a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
43a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath  /**
44a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath   * Returns the recorded response triggered by {@code request}. Throws if the
45a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath   * response isn't enqueued before the timeout.
46a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath   */
4771b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller  public synchronized RecordedResponse await(HttpUrl url) throws Exception {
48a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath    long timeoutMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) + TIMEOUT_MILLIS;
49a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath    while (true) {
50c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller      for (Iterator<RecordedResponse> i = responses.iterator(); i.hasNext(); ) {
51c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller        RecordedResponse recordedResponse = i.next();
5271b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller        if (recordedResponse.request.httpUrl().equals(url)) {
53c6bd683320121544811f481709b3fdbcbe9b3866Neil Fuller          i.remove();
54a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath          return recordedResponse;
55a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath        }
56a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath      }
57a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
58a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath      long nowMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
59a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath      if (nowMillis >= timeoutMillis) break;
60a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath      wait(timeoutMillis - nowMillis);
61a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath    }
62a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath
633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller    throw new AssertionError("Timed out waiting for response to " + url);
643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller  }
653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller
6671b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller  public synchronized void assertNoResponse(HttpUrl url) throws Exception {
673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller    for (RecordedResponse recordedResponse : responses) {
6871b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller      if (recordedResponse.request.httpUrl().equals(url)) {
693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller        throw new AssertionError("Expected no response for " + url);
703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller      }
713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller    }
72a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath  }
73a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath}
74