Skip to content

Commit dbe6198

Browse files
Expand coverage across reactor, protocol, HTTP/2, and testing framework. (#615)
1 parent 5c5c1fb commit dbe6198

58 files changed

Lines changed: 5534 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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.core5.http2.impl.nio;
28+
29+
import java.nio.ByteBuffer;
30+
31+
import org.apache.hc.core5.http.ProtocolException;
32+
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
33+
import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
34+
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
35+
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
36+
import org.apache.hc.core5.http.nio.HandlerFactory;
37+
import org.apache.hc.core5.http.protocol.HttpCoreContext;
38+
import org.apache.hc.core5.http.protocol.HttpProcessor;
39+
import org.junit.jupiter.api.Assertions;
40+
import org.junit.jupiter.api.Test;
41+
import org.mockito.Mockito;
42+
43+
class TestClientH2StreamHandler {
44+
45+
private ClientH2StreamHandler newHandler() {
46+
final H2StreamChannel channel = Mockito.mock(H2StreamChannel.class);
47+
final HttpProcessor httpProcessor = Mockito.mock(HttpProcessor.class);
48+
final BasicHttpConnectionMetrics metrics = new BasicHttpConnectionMetrics(
49+
new BasicHttpTransportMetrics(), new BasicHttpTransportMetrics());
50+
final AsyncClientExchangeHandler exchangeHandler = Mockito.mock(AsyncClientExchangeHandler.class);
51+
@SuppressWarnings("unchecked")
52+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
53+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
54+
return new ClientH2StreamHandler(channel, httpProcessor, metrics, exchangeHandler, pushHandlerFactory,
55+
HttpCoreContext.create());
56+
}
57+
58+
@Test
59+
void defaults() {
60+
final ClientH2StreamHandler handler = newHandler();
61+
Assertions.assertNotNull(handler.getPushHandlerFactory());
62+
Assertions.assertTrue(handler.isOutputReady());
63+
}
64+
65+
@Test
66+
void consumePromiseRejected() {
67+
final ClientH2StreamHandler handler = newHandler();
68+
Assertions.assertThrows(ProtocolException.class, () -> handler.consumePromise(null));
69+
}
70+
71+
@Test
72+
void consumeDataRejectedBeforeHeaders() {
73+
final ClientH2StreamHandler handler = newHandler();
74+
Assertions.assertThrows(ProtocolException.class, () ->
75+
handler.consumeData(ByteBuffer.allocate(0), true));
76+
}
77+
78+
@Test
79+
void updateCapacityDelegates() throws Exception {
80+
final H2StreamChannel channel = Mockito.mock(H2StreamChannel.class);
81+
final HttpProcessor httpProcessor = Mockito.mock(HttpProcessor.class);
82+
final BasicHttpConnectionMetrics metrics = new BasicHttpConnectionMetrics(
83+
new BasicHttpTransportMetrics(), new BasicHttpTransportMetrics());
84+
final AsyncClientExchangeHandler exchangeHandler = Mockito.mock(AsyncClientExchangeHandler.class);
85+
@SuppressWarnings("unchecked")
86+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
87+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
88+
final ClientH2StreamHandler handler = new ClientH2StreamHandler(
89+
channel, httpProcessor, metrics, exchangeHandler, pushHandlerFactory, HttpCoreContext.create());
90+
91+
handler.updateInputCapacity();
92+
93+
Mockito.verify(exchangeHandler).updateCapacity(channel);
94+
}
95+
96+
@Test
97+
void toStringIncludesStates() {
98+
final ClientH2StreamHandler handler = newHandler();
99+
final String text = handler.toString();
100+
Assertions.assertTrue(text.contains("requestState"));
101+
Assertions.assertTrue(text.contains("responseState"));
102+
}
103+
104+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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.core5.http2.impl.nio;
28+
29+
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
30+
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
31+
import org.apache.hc.core5.http.nio.AsyncPushProducer;
32+
import org.apache.hc.core5.http.nio.HandlerFactory;
33+
import org.apache.hc.core5.http.protocol.HttpProcessor;
34+
import org.apache.hc.core5.http2.H2ConnectionException;
35+
import org.apache.hc.core5.http2.H2Error;
36+
import org.apache.hc.core5.http2.config.H2Config;
37+
import org.apache.hc.core5.http2.config.H2Param;
38+
import org.apache.hc.core5.http2.frame.DefaultFrameFactory;
39+
import org.apache.hc.core5.reactor.ProtocolIOSession;
40+
import org.junit.jupiter.api.Assertions;
41+
import org.junit.jupiter.api.Test;
42+
import org.mockito.Mockito;
43+
44+
class TestClientH2StreamMultiplexer {
45+
46+
private ClientH2StreamMultiplexer newMultiplexer() {
47+
final ProtocolIOSession ioSession = Mockito.mock(ProtocolIOSession.class);
48+
final HttpProcessor httpProcessor = Mockito.mock(HttpProcessor.class);
49+
@SuppressWarnings("unchecked")
50+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
51+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
52+
return new ClientH2StreamMultiplexer(
53+
ioSession,
54+
DefaultFrameFactory.INSTANCE,
55+
httpProcessor,
56+
pushHandlerFactory,
57+
H2Config.DEFAULT,
58+
null,
59+
null);
60+
}
61+
62+
@Test
63+
void validateSettingRejectsEnablePush() {
64+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
65+
final H2ConnectionException ex = Assertions.assertThrows(H2ConnectionException.class, () ->
66+
multiplexer.validateSetting(H2Param.ENABLE_PUSH, 1));
67+
Assertions.assertEquals(H2Error.PROTOCOL_ERROR.getCode(), ex.getCode());
68+
}
69+
70+
@Test
71+
void acceptHeaderFrameRejected() {
72+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
73+
Assertions.assertThrows(H2ConnectionException.class, multiplexer::acceptHeaderFrame);
74+
}
75+
76+
@Test
77+
void outgoingRequestCreatesHandler() {
78+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
79+
final H2StreamHandler handler = multiplexer.outgoingRequest(
80+
Mockito.mock(H2StreamChannel.class),
81+
Mockito.mock(AsyncClientExchangeHandler.class),
82+
null,
83+
null);
84+
Assertions.assertNotNull(handler);
85+
}
86+
87+
@Test
88+
void incomingRequestRejected() {
89+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
90+
Assertions.assertThrows(H2ConnectionException.class, () ->
91+
multiplexer.incomingRequest(Mockito.mock(H2StreamChannel.class)));
92+
}
93+
94+
@Test
95+
void outgoingPushPromiseRejected() {
96+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
97+
Assertions.assertThrows(H2ConnectionException.class, () ->
98+
multiplexer.outgoingPushPromise(Mockito.mock(H2StreamChannel.class), Mockito.mock(AsyncPushProducer.class)));
99+
}
100+
101+
@Test
102+
void incomingPushPromiseCreatesHandler() {
103+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
104+
@SuppressWarnings("unchecked")
105+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
106+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
107+
final H2StreamHandler handler = multiplexer.incomingPushPromise(
108+
Mockito.mock(H2StreamChannel.class),
109+
pushHandlerFactory);
110+
Assertions.assertNotNull(handler);
111+
}
112+
113+
@Test
114+
void allowGracefulAbortUsesRemoteClosed() {
115+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
116+
final H2Stream stream = Mockito.mock(H2Stream.class);
117+
Mockito.when(stream.isRemoteClosed()).thenReturn(true);
118+
Mockito.when(stream.isLocalClosed()).thenReturn(false);
119+
Assertions.assertTrue(multiplexer.allowGracefulAbort(stream));
120+
}
121+
122+
@Test
123+
void toStringContainsState() {
124+
final ClientH2StreamMultiplexer multiplexer = newMultiplexer();
125+
final String text = multiplexer.toString();
126+
Assertions.assertTrue(text.startsWith("["));
127+
Assertions.assertTrue(text.endsWith("]"));
128+
}
129+
130+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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.core5.http2.impl.nio;
28+
29+
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
30+
import org.apache.hc.core5.http.nio.HandlerFactory;
31+
import org.apache.hc.core5.http.protocol.HttpProcessor;
32+
import org.apache.hc.core5.reactor.ProtocolIOSession;
33+
import org.junit.jupiter.api.Assertions;
34+
import org.junit.jupiter.api.Test;
35+
import org.mockito.Mockito;
36+
37+
class TestClientH2StreamMultiplexerFactory {
38+
39+
@Test
40+
void createUsesDefaults() {
41+
final HttpProcessor httpProcessor = Mockito.mock(HttpProcessor.class);
42+
@SuppressWarnings("unchecked")
43+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
44+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
45+
final ClientH2StreamMultiplexerFactory factory = new ClientH2StreamMultiplexerFactory(
46+
httpProcessor, pushHandlerFactory, null, null, null);
47+
48+
final ProtocolIOSession ioSession = Mockito.mock(ProtocolIOSession.class);
49+
final ClientH2StreamMultiplexer multiplexer = factory.create(ioSession);
50+
51+
Assertions.assertNotNull(multiplexer);
52+
}
53+
54+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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.core5.http2.impl.nio;
28+
29+
import java.util.concurrent.locks.ReentrantLock;
30+
31+
import org.apache.hc.core5.function.Callback;
32+
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
33+
import org.apache.hc.core5.http.nio.HandlerFactory;
34+
import org.apache.hc.core5.http.protocol.HttpProcessor;
35+
import org.apache.hc.core5.reactor.ProtocolIOSession;
36+
import org.junit.jupiter.api.Test;
37+
import org.mockito.Mockito;
38+
39+
class TestClientH2UpgradeHandler {
40+
41+
@Test
42+
void upgradeRegistersPrefaceHandler() throws Exception {
43+
final HttpProcessor httpProcessor = Mockito.mock(HttpProcessor.class);
44+
@SuppressWarnings("unchecked")
45+
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory =
46+
(HandlerFactory<AsyncPushConsumer>) Mockito.mock(HandlerFactory.class);
47+
final ClientH2StreamMultiplexerFactory factory = new ClientH2StreamMultiplexerFactory(
48+
httpProcessor, pushHandlerFactory, null, null, null);
49+
50+
final ProtocolIOSession ioSession = Mockito.mock(ProtocolIOSession.class);
51+
Mockito.when(ioSession.getLock()).thenReturn(new ReentrantLock());
52+
53+
final ClientH2UpgradeHandler handler = new ClientH2UpgradeHandler(factory, (Callback<Exception>) ex -> {
54+
});
55+
handler.upgrade(ioSession, null);
56+
57+
Mockito.verify(ioSession).upgrade(Mockito.any());
58+
}
59+
60+
}

0 commit comments

Comments
 (0)