View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.impl.cache;
28  
29  import java.io.IOException;
30  import java.util.HashMap;
31  
32  import org.apache.hc.client5.http.HttpRoute;
33  import org.apache.hc.client5.http.classic.ExecChain;
34  import org.apache.hc.client5.http.classic.ExecChainHandler;
35  import org.apache.hc.client5.http.classic.ExecRuntime;
36  import org.apache.hc.client5.http.protocol.HttpClientContext;
37  import org.apache.hc.core5.http.ClassicHttpRequest;
38  import org.apache.hc.core5.http.ClassicHttpResponse;
39  import org.apache.hc.core5.http.HttpEntity;
40  import org.apache.hc.core5.http.HttpException;
41  import org.apache.hc.core5.http.HttpHost;
42  import org.apache.hc.core5.http.HttpRequest;
43  import org.apache.hc.core5.http.HttpResponse;
44  import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
45  import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
46  import org.easymock.EasyMock;
47  import org.easymock.IExpectationSetters;
48  import org.junit.Before;
49  
50  public abstract class AbstractProtocolTest {
51  
52      protected static final int MAX_BYTES = 1024;
53      protected static final int MAX_ENTRIES = 100;
54      protected final int entityLength = 128;
55      protected HttpHost host;
56      protected HttpRoute route;
57      protected HttpEntity body;
58      protected HttpClientContext context;
59      protected ExecChain mockExecChain;
60      protected ExecRuntime mockExecRuntime;
61      protected HttpCache mockCache;
62      protected ClassicHttpRequest request;
63      protected ClassicHttpResponse originResponse;
64      protected CacheConfig config;
65      protected ExecChainHandler impl;
66      protected HttpCache cache;
67  
68      public static ClassicHttpRequest eqRequest(final ClassicHttpRequest in) {
69          EasyMock.reportMatcher(new RequestEquivalent(in));
70          return null;
71      }
72  
73      public static HttpResponse eqResponse(final HttpResponse in) {
74          EasyMock.reportMatcher(new ResponseEquivalent(in));
75          return null;
76      }
77  
78      public static ClassicHttpResponse eqCloseableResponse(final ClassicHttpResponse in) {
79          EasyMock.reportMatcher(new ResponseEquivalent(in));
80          return null;
81      }
82  
83      @Before
84      public void setUp() {
85          host = new HttpHost("foo.example.com", 80);
86  
87          route = new HttpRoute(host);
88  
89          body = HttpTestUtils.makeBody(entityLength);
90  
91          request = new BasicClassicHttpRequest("GET", "/foo");
92  
93          context = HttpClientContext.create();
94  
95          originResponse = HttpTestUtils.make200Response();
96  
97          config = CacheConfig.custom()
98              .setMaxCacheEntries(MAX_ENTRIES)
99              .setMaxObjectSize(MAX_BYTES)
100             .build();
101 
102         cache = new BasicHttpCache(config);
103         mockExecChain = EasyMock.createNiceMock(ExecChain.class);
104         mockExecRuntime = EasyMock.createNiceMock(ExecRuntime.class);
105         mockCache = EasyMock.createNiceMock(HttpCache.class);
106         impl = createCachingExecChain(cache, config);
107     }
108 
109     public ClassicHttpResponse execute(final ClassicHttpRequest request) throws IOException, HttpException {
110         return impl.execute(
111                 ClassicRequestBuilder.copy(request).build(),
112                 new ExecChain.Scope("test", route, request, mockExecRuntime, context),
113                 mockExecChain);
114     }
115 
116     protected ExecChainHandler createCachingExecChain(final HttpCache cache, final CacheConfig config) {
117         return new CachingExec(cache, null, config);
118     }
119 
120     protected boolean supportsRangeAndContentRangeHeaders(final ExecChainHandler impl) {
121         return impl instanceof CachingExec && ((CachingExec) impl).supportsRangeAndContentRangeHeaders();
122     }
123 
124     protected void replayMocks() {
125         EasyMock.replay(mockExecChain);
126         EasyMock.replay(mockCache);
127     }
128 
129     protected void verifyMocks() {
130         EasyMock.verify(mockExecChain);
131         EasyMock.verify(mockCache);
132     }
133 
134     protected IExpectationSetters<ClassicHttpResponse> backendExpectsAnyRequest() throws Exception {
135         final ClassicHttpResponse resp = mockExecChain.proceed(
136                 EasyMock.isA(ClassicHttpRequest.class),
137                 EasyMock.isA(ExecChain.Scope.class));
138         return EasyMock.expect(resp);
139     }
140 
141     protected IExpectationSetters<ClassicHttpResponse> backendExpectsAnyRequestAndReturn(
142             final ClassicHttpResponse response) throws Exception {
143         final ClassicHttpResponse resp = mockExecChain.proceed(
144                 EasyMock.isA(ClassicHttpRequest.class),
145                 EasyMock.isA(ExecChain.Scope.class));
146         return EasyMock.expect(resp).andReturn(response);
147     }
148 
149     protected void emptyMockCacheExpectsNoPuts() throws Exception {
150         mockExecChain = EasyMock.createNiceMock(ExecChain.class);
151         mockCache = EasyMock.createNiceMock(HttpCache.class);
152 
153         impl = new CachingExec(mockCache, null, config);
154 
155         EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
156             .andReturn(null).anyTimes();
157         EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
158             .andReturn(new HashMap<String,Variant>()).anyTimes();
159 
160         mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
161         EasyMock.expectLastCall().anyTimes();
162 
163         mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
164         EasyMock.expectLastCall().anyTimes();
165 
166         mockCache.flushCacheEntriesInvalidatedByRequest(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
167         EasyMock.expectLastCall().anyTimes();
168 
169         mockCache.flushCacheEntriesInvalidatedByExchange(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class), EasyMock.isA(HttpResponse.class));
170         EasyMock.expectLastCall().anyTimes();
171     }
172 
173     protected void behaveAsNonSharedCache() {
174         config = CacheConfig.custom()
175                 .setMaxCacheEntries(MAX_ENTRIES)
176                 .setMaxObjectSize(MAX_BYTES)
177                 .setSharedCache(false)
178                 .build();
179         impl = new CachingExec(cache, null, config);
180     }
181 
182     public AbstractProtocolTest() {
183         super();
184     }
185 
186 }