1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.testing.classic;
29
30 import static org.hamcrest.MatcherAssert.assertThat;
31
32 import java.io.IOException;
33 import java.util.concurrent.CountDownLatch;
34 import java.util.concurrent.ExecutorService;
35 import java.util.concurrent.Executors;
36 import java.util.concurrent.TimeUnit;
37 import java.util.concurrent.atomic.AtomicLong;
38 import java.util.concurrent.atomic.AtomicReference;
39
40 import org.apache.hc.core5.http.ClassicHttpRequest;
41 import org.apache.hc.core5.http.ClassicHttpResponse;
42 import org.apache.hc.core5.http.ContentType;
43 import org.apache.hc.core5.http.HttpHost;
44 import org.apache.hc.core5.http.HttpStatus;
45 import org.apache.hc.core5.http.Method;
46 import org.apache.hc.core5.http.URIScheme;
47 import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
48 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
49 import org.apache.hc.core5.http.io.entity.EntityUtils;
50 import org.apache.hc.core5.http.io.entity.StringEntity;
51 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
52 import org.apache.hc.core5.http.protocol.HttpCoreContext;
53 import org.apache.hc.core5.util.Timeout;
54 import org.hamcrest.CoreMatchers;
55 import org.junit.jupiter.api.Assertions;
56 import org.junit.jupiter.api.Test;
57
58 public abstract class ClassicHttpCoreTransportTest {
59
60 private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
61
62 private final URIScheme scheme;
63
64 public ClassicHttpCoreTransportTest(final URIScheme scheme) {
65 this.scheme = scheme;
66 }
67
68 abstract HttpServer serverStart() throws IOException;
69
70 abstract HttpRequester clientStart() throws IOException;
71
72 @Test
73 public void testSequentialRequests() throws Exception {
74 final HttpServer server = serverStart();
75 final HttpRequester requester = clientStart();
76
77 final HttpHost target = new HttpHost(scheme.id, "localhost", server.getLocalPort());
78 final HttpCoreContext context = HttpCoreContext.create();
79 final ClassicHttpRequest request1 = new BasicClassicHttpRequest(Method.POST, "/stuff");
80 request1.setEntity(new StringEntity("some stuff", ContentType.TEXT_PLAIN));
81 try (final ClassicHttpResponse response1 = requester.execute(target, request1, TIMEOUT, context)) {
82 assertThat(response1.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
83 final String body1 = EntityUtils.toString(response1.getEntity());
84 assertThat(body1, CoreMatchers.equalTo("some stuff"));
85 }
86 final ClassicHttpRequest request2 = new BasicClassicHttpRequest(Method.POST, "/other-stuff");
87 request2.setEntity(new StringEntity("some other stuff", ContentType.TEXT_PLAIN));
88 try (final ClassicHttpResponse response2 = requester.execute(target, request2, TIMEOUT, context)) {
89 assertThat(response2.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
90 final String body2 = EntityUtils.toString(response2.getEntity());
91 assertThat(body2, CoreMatchers.equalTo("some other stuff"));
92 }
93 final ClassicHttpRequest request3 = new BasicClassicHttpRequest(Method.POST, "/more-stuff");
94 request3.setEntity(new StringEntity("some more stuff", ContentType.TEXT_PLAIN));
95 try (final ClassicHttpResponse response3 = requester.execute(target, request3, TIMEOUT, context)) {
96 assertThat(response3.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
97 final String body3 = EntityUtils.toString(response3.getEntity());
98 assertThat(body3, CoreMatchers.equalTo("some more stuff"));
99 }
100 }
101
102 @Test
103 public void testSequentialRequestsNonPersistentConnection() throws Exception {
104 final HttpServer server = serverStart();
105 final HttpRequester requester = clientStart();
106
107 final HttpHost target = new HttpHost(scheme.id, "localhost", server.getLocalPort());
108 final HttpCoreContext context = HttpCoreContext.create();
109 final ClassicHttpRequest request1 = new BasicClassicHttpRequest(Method.POST, "/no-keep-alive/stuff");
110 request1.setEntity(new StringEntity("some stuff", ContentType.TEXT_PLAIN));
111 try (final ClassicHttpResponse response1 = requester.execute(target, request1, TIMEOUT, context)) {
112 assertThat(response1.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
113 final String body1 = EntityUtils.toString(response1.getEntity());
114 assertThat(body1, CoreMatchers.equalTo("some stuff"));
115 }
116 final ClassicHttpRequest request2 = new BasicClassicHttpRequest(Method.POST, "/no-keep-alive/other-stuff");
117 request2.setEntity(new StringEntity("some other stuff", ContentType.TEXT_PLAIN));
118 try (final ClassicHttpResponse response2 = requester.execute(target, request2, TIMEOUT, context)) {
119 assertThat(response2.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
120 final String body2 = EntityUtils.toString(response2.getEntity());
121 assertThat(body2, CoreMatchers.equalTo("some other stuff"));
122 }
123 final ClassicHttpRequest request3 = new BasicClassicHttpRequest(Method.POST, "/no-keep-alive/more-stuff");
124 request3.setEntity(new StringEntity("some more stuff", ContentType.TEXT_PLAIN));
125 try (final ClassicHttpResponse response3 = requester.execute(target, request3, TIMEOUT, context)) {
126 assertThat(response3.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
127 final String body3 = EntityUtils.toString(response3.getEntity());
128 assertThat(body3, CoreMatchers.equalTo("some more stuff"));
129 }
130 }
131
132 @Test
133 public void testMultiThreadedRequests() throws Exception {
134 final HttpServer server = serverStart();
135 final HttpRequester requester = clientStart();
136
137 final int c = 10;
138 final CountDownLatch latch = new CountDownLatch(c);
139 final AtomicLong n = new AtomicLong(c + 100);
140 final AtomicReference<AssertionError> exRef = new AtomicReference<>();
141 final ExecutorService executorService = Executors.newFixedThreadPool(c);
142 try {
143 final HttpHost target = new HttpHost(scheme.id, "localhost", server.getLocalPort());
144 for (int i = 0; i < c; i++) {
145 executorService.execute(() -> {
146 try {
147 while (n.decrementAndGet() > 0) {
148 try {
149 final HttpCoreContext context = HttpCoreContext.create();
150 final ClassicHttpRequest request1 = new BasicClassicHttpRequest(Method.POST, "/stuff");
151 request1.setEntity(new StringEntity("some stuff", ContentType.TEXT_PLAIN));
152 requester.execute(target, request1, TIMEOUT, context, response -> {
153 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
154 Assertions.assertEquals("some stuff", EntityUtils.toString(response.getEntity()));
155 return null;
156 });
157 } catch (final Exception ex) {
158 Assertions.fail(ex);
159 }
160 }
161 } catch (final AssertionError ex) {
162 exRef.compareAndSet(null, ex);
163 } finally {
164 latch.countDown();
165 }
166 });
167 }
168 Assertions.assertTrue(latch.await(5, TimeUnit.MINUTES));
169 } finally {
170 executorService.shutdownNow();
171 }
172
173 final AssertionError assertionError = exRef.get();
174 if (assertionError != null) {
175 throw assertionError;
176 }
177 }
178
179 }