package org.webpieces.httpfrontend2.api.http2; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.Assert; import org.junit.Test; import org.webpieces.httpfrontend2.api.mock2.MockHttp2RequestListener.PassedIn; import com.webpieces.hpack.api.dto.Http2Headers; import com.webpieces.hpack.api.dto.Http2Push; import com.webpieces.http2engine.api.StreamWriter; import com.webpieces.http2engine.impl.shared.HeaderSettings; import com.webpieces.http2parser.api.dto.DataFrame; import com.webpieces.http2parser.api.dto.SettingsFrame; import com.webpieces.http2parser.api.dto.lib.Http2Msg; public class TestSMaxConcurrentSetting extends AbstractHttp2Test { @Test public void testSend2ndPushHeadersOnlyOnCompletionOfFirst() throws InterruptedException, ExecutionException, TimeoutException { WriterHolder sent = sendTwoRequests(); DataFrame data1 = Http2Requests.createData1(sent.getResp1().getStreamId(), true); //ending this promise stream starts the next sent.getWriter1().send(data1); List<Http2Msg> frames = mockChannel.getFramesAndClear(); Assert.assertEquals(2, frames.size()); DataFrame dataRecv1 = (DataFrame) frames.get(0); Assert.assertEquals(sent.getResp1().getStreamId(), dataRecv1.getStreamId()); Assert.assertEquals(sent.getResp2(), frames.get(1)); StreamWriter writer2 = sent.getFuture2().get(2, TimeUnit.SECONDS); DataFrame data2 = Http2Requests.createData1(sent.getResp2().getStreamId(), true); writer2.send(data2); DataFrame dataRecv2 = (DataFrame) mockChannel.getFrameAndClear(); Assert.assertEquals(sent.getResp2().getStreamId(), dataRecv2.getStreamId()); } @Test public void testSend2ndPushHeadersOnlyOnAfterSettingsFrameMaxConcurrentBigger() throws InterruptedException, ExecutionException, TimeoutException { WriterHolder sent = sendTwoRequests(); //client increases max concurrent HeaderSettings settings = new HeaderSettings(); settings.setMaxConcurrentStreams(2L); mockChannel.write(HeaderSettings.createSettingsFrame(settings)); List<Http2Msg> frames = mockChannel.getFramesAndClear(); Assert.assertEquals(2, frames.size()); Assert.assertEquals(sent.getResp2(), frames.get(0)); SettingsFrame dataRecv1 = (SettingsFrame) frames.get(1); Assert.assertTrue(dataRecv1.isAck()); StreamWriter writer2 = sent.getFuture2().get(2, TimeUnit.SECONDS); DataFrame data2 = Http2Requests.createData1(sent.getResp2().getStreamId(), true); writer2.send(data2); DataFrame dataRecv2 = (DataFrame) mockChannel.getFrameAndClear(); Assert.assertEquals(sent.getResp2().getStreamId(), dataRecv2.getStreamId()); } private WriterHolder sendTwoRequests() throws InterruptedException, ExecutionException, TimeoutException { PassedIn in1 = sendRequestToServer(1, true); PassedIn in2 = sendRequestToServer(3, true); Assert.assertTrue(in1.stream != in2.stream); Http2Push push1 = Http2Requests.createPush(in1.request.getStreamId()); CompletableFuture<StreamWriter> future1 = in1.stream.sendPush(push1); Http2Msg push1Recv = mockChannel.getFrameAndClear(); Assert.assertEquals(push1, push1Recv); StreamWriter writer1 = future1.get(2, TimeUnit.SECONDS); Http2Push push2 = Http2Requests.createPush(in2.request.getStreamId()); CompletableFuture<StreamWriter> future2 = in2.stream.sendPush(push2); Http2Msg push2Recv = mockChannel.getFrameAndClear(); Assert.assertEquals(push2, push2Recv); Assert.assertEquals(push1, push1Recv); StreamWriter writer2 = future2.get(2, TimeUnit.SECONDS); //send the two responses following the pushes Http2Headers resp1 = Http2Requests.createResponse(push1.getPromisedStreamId(), false); CompletableFuture<StreamWriter> fut1 = writer1.send(resp1); writer1 = fut1.get(2, TimeUnit.SECONDS); Http2Headers resp2 = Http2Requests.createResponse(push2.getPromisedStreamId(), false); CompletableFuture<StreamWriter> fut2 = writer2.send(resp2); Assert.assertTrue(!fut2.isDone()); Http2Headers clientRecvResp = (Http2Headers) mockChannel.getFrameAndClear(); Assert.assertEquals(resp1, clientRecvResp); return new WriterHolder(writer1, fut2, resp1, resp2); } }