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.impl.classic.ClassicRequestCopier;
37  import org.apache.hc.client5.http.protocol.HttpClientContext;
38  import org.apache.hc.core5.http.ClassicHttpRequest;
39  import org.apache.hc.core5.http.ClassicHttpResponse;
40  import org.apache.hc.core5.http.HttpEntity;
41  import org.apache.hc.core5.http.HttpException;
42  import org.apache.hc.core5.http.HttpHost;
43  import org.apache.hc.core5.http.HttpRequest;
44  import org.apache.hc.core5.http.HttpResponse;
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 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(ClassicRequestCopier.INSTANCE.copy(request), new ExecChain.Scope(
111                 "test", route, request, mockExecRuntime, context), mockExecChain);
112     }
113 
114     protected ExecChainHandler createCachingExecChain(final HttpCache cache, final CacheConfig config) {
115         return new CachingExec(cache, null, config);
116     }
117 
118     protected boolean supportsRangeAndContentRangeHeaders(final ExecChainHandler impl) {
119         return impl instanceof CachingExec && ((CachingExec) impl).supportsRangeAndContentRangeHeaders();
120     }
121 
122     protected void replayMocks() {
123         EasyMock.replay(mockExecChain);
124         EasyMock.replay(mockCache);
125     }
126 
127     protected void verifyMocks() {
128         EasyMock.verify(mockExecChain);
129         EasyMock.verify(mockCache);
130     }
131 
132     protected IExpectationSetters<ClassicHttpResponse> backendExpectsAnyRequest() throws Exception {
133         final ClassicHttpResponse resp = mockExecChain.proceed(
134                 EasyMock.isA(ClassicHttpRequest.class),
135                 EasyMock.isA(ExecChain.Scope.class));
136         return EasyMock.expect(resp);
137     }
138 
139     protected IExpectationSetters<ClassicHttpResponse> backendExpectsAnyRequestAndReturn(
140             final ClassicHttpResponse response) throws Exception {
141         final ClassicHttpResponse resp = mockExecChain.proceed(
142                 EasyMock.isA(ClassicHttpRequest.class),
143                 EasyMock.isA(ExecChain.Scope.class));
144         return EasyMock.expect(resp).andReturn(response);
145     }
146 
147     protected void emptyMockCacheExpectsNoPuts() throws Exception {
148         mockExecChain = EasyMock.createNiceMock(ExecChain.class);
149         mockCache = EasyMock.createNiceMock(HttpCache.class);
150 
151         impl = new CachingExec(mockCache, null, config);
152 
153         EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
154             .andReturn(null).anyTimes();
155         EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
156             .andReturn(new HashMap<String,Variant>()).anyTimes();
157 
158         mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
159         EasyMock.expectLastCall().anyTimes();
160 
161         mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
162         EasyMock.expectLastCall().anyTimes();
163 
164         mockCache.flushCacheEntriesInvalidatedByRequest(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
165         EasyMock.expectLastCall().anyTimes();
166 
167         mockCache.flushCacheEntriesInvalidatedByExchange(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class), EasyMock.isA(HttpResponse.class));
168         EasyMock.expectLastCall().anyTimes();
169     }
170 
171     protected void behaveAsNonSharedCache() {
172         config = CacheConfig.custom()
173                 .setMaxCacheEntries(MAX_ENTRIES)
174                 .setMaxObjectSize(MAX_BYTES)
175                 .setSharedCache(false)
176                 .build();
177         impl = new CachingExec(cache, null, config);
178     }
179 
180     public AbstractProtocolTest() {
181         super();
182     }
183 
184 }