|
80 | 80 |
|
81 | 81 | import static org.junit.jupiter.api.Assertions.assertEquals; |
82 | 82 | import static org.junit.jupiter.api.Assertions.assertFalse; |
| 83 | +import static org.junit.jupiter.api.Assertions.assertNotEquals; |
83 | 84 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
84 | 85 | import static org.junit.jupiter.api.Assertions.assertNull; |
85 | 86 | import static org.junit.jupiter.api.Assertions.assertTrue; |
86 | 87 |
|
87 | 88 | import org.junit.jupiter.api.Assertions; |
| 89 | +import org.junit.jupiter.api.Test; |
88 | 90 | import org.junit.jupiter.params.ParameterizedTest; |
89 | 91 | import org.junit.jupiter.params.provider.MethodSource; |
90 | 92 |
|
91 | 93 | /* |
92 | 94 | * @test |
| 95 | + * @bug 8349910 8386985 |
93 | 96 | * @summary tests the logic to build an AckFrame |
94 | 97 | * @library /test/lib |
95 | 98 | * @library ../debug |
|
102 | 105 | * @run junit/othervm -Dseed=-4159871071396382784 ${test.main.class} |
103 | 106 | * @run junit/othervm -Dseed=2252276218459363615 ${test.main.class} |
104 | 107 | * @run junit/othervm -Dseed=-5130588140709404919 ${test.main.class} |
| 108 | + * @run junit/othervm -Dseed=4257295716830862528 ${test.main.class} |
105 | 109 | */ |
106 | 110 | // -Djdk.internal.httpclient.debug=true |
107 | 111 | public class PacketSpaceManagerTest { |
@@ -766,6 +770,22 @@ boolean isDue(Deadline now) { |
766 | 770 | } |
767 | 771 | } |
768 | 772 |
|
| 773 | + public List<QuicFrame> sendPacket(long offset, AckFrame ackFrameToSend, Packet packet, long largestReceivedAckedPN) { |
| 774 | + // add a crypto frame and build the packet |
| 775 | + CryptoFrame crypto = new CryptoFrame(offset, 1, |
| 776 | + ByteBuffer.wrap(new byte[] {nextByte(offset)})); |
| 777 | + List<QuicFrame> frames = ackFrameToSend == null ? |
| 778 | + List.of(crypto) : List.of(crypto, ackFrameToSend); |
| 779 | + QuicPacket newPacket = codingContext.encoder |
| 780 | + .newInitialPacket(localId, peerId, |
| 781 | + null, |
| 782 | + packet.packetNumber, |
| 783 | + largestReceivedAckedPN, |
| 784 | + frames, codingContext); |
| 785 | + // pretend that we sent a packet |
| 786 | + manager.packetSent(newPacket, -1, packet.packetNumber); |
| 787 | + return frames; |
| 788 | + } |
769 | 789 | /** |
770 | 790 | * Drives the test by pretending to emit each packet in order, |
771 | 791 | * then pretending to receive ack frames (as soon as possible |
@@ -830,19 +850,8 @@ public void run() throws Exception { |
830 | 850 | debug.log("largestAckSent is: " + largestAckAcked); |
831 | 851 | } |
832 | 852 |
|
833 | | - // add a crypto frame and build the packet |
834 | | - CryptoFrame crypto = new CryptoFrame(offset, 1, |
835 | | - ByteBuffer.wrap(new byte[] {nextByte(offset)})); |
836 | | - List<QuicFrame> frames = ackFrameToSend == null ? |
837 | | - List.of(crypto) : List.of(crypto, ackFrameToSend); |
838 | | - QuicPacket newPacket = codingContext.encoder |
839 | | - .newInitialPacket(localId, peerId, |
840 | | - null, |
841 | | - packet.packetNumber, |
842 | | - largestReceivedAckedPN, |
843 | | - frames, codingContext); |
844 | | - // pretend that we sent a packet |
845 | | - manager.packetSent(newPacket, -1, packet.packetNumber); |
| 853 | + // send a packet |
| 854 | + List<QuicFrame> frames = sendPacket(offset, ackFrameToSend, packet, largestReceivedAckedPN); |
846 | 855 |
|
847 | 856 | // compute next deadline |
848 | 857 | var nextDeadline = timerQueue.nextDeadline(); |
@@ -1125,4 +1134,52 @@ public void testPacketSpaceManager(TestCase testCase) throws Exception { |
1125 | 1134 | driver.check(); |
1126 | 1135 | } |
1127 | 1136 |
|
| 1137 | + @Test |
| 1138 | + public void testPacketSent() throws Exception { |
| 1139 | + // this test case is specifically for JDK-8386985 |
| 1140 | + System.out.printf("%n ------- testPacketSent ------- %n"); |
| 1141 | + |
| 1142 | + // create a minimal SynchronousTestDriver |
| 1143 | + TestCase testCase = new TestCase(List.of(new Acknowledged(1, 3), new Acknowledged(4,4)), |
| 1144 | + List.of(new Packet(3, 0), new Packet(4, 0))); |
| 1145 | + SynchronousTestDriver driver = new SynchronousTestDriver(testCase); |
| 1146 | + |
| 1147 | + // send a first ack-eliciting packet, and move the timeline past PTO |
| 1148 | + driver.sendPacket(0, null, new Packet(1, 0), -1); |
| 1149 | + Deadline pto = driver.manager.nextScheduledDeadline(); // should be PTO |
| 1150 | + driver.timeSource.advance(driver.timeSource.instant().until(pto, ChronoUnit.MILLIS) + 250, ChronoUnit.MILLIS); |
| 1151 | + |
| 1152 | + // start processing events, but delay the task that will run the transmitter |
| 1153 | + ArrayList<Runnable> tasks = new ArrayList<>(); |
| 1154 | + Executor executor = new Executor() { |
| 1155 | + @Override |
| 1156 | + public void execute(Runnable command) { |
| 1157 | + tasks.add(command); |
| 1158 | + } |
| 1159 | + }; |
| 1160 | + driver.timerQueue.processEventsAndReturnNextDeadline(driver.timeSource.instant(), executor); |
| 1161 | + |
| 1162 | + // acknowledge the first packet so that it's no longer pending retransmission |
| 1163 | + driver.manager.processAckFrame(new AckFrameBuilder().addAck(1).build()); |
| 1164 | + |
| 1165 | + // send a second packet, and examine the timerQueue next deadline |
| 1166 | + // if sending the second packet didn't cause the task to be rescheduled, we |
| 1167 | + // will observe Deadline.MAX, or a deadline before now: that's the bug. |
| 1168 | + driver.sendPacket(1, null, new Packet(2, 0), -1); |
| 1169 | + |
| 1170 | + Deadline next = driver.timerQueue.nextDeadline(); |
| 1171 | + assertNotEquals(next, Deadline.MAX); |
| 1172 | + assertTrue(next.isAfter(driver.timeSource.instant())); |
| 1173 | + |
| 1174 | + // now finish running the task and ack the second packet, |
| 1175 | + // so that we leave the packet space manager in a clean state |
| 1176 | + // for running the driver with the next two packets. |
| 1177 | + for (Runnable task : tasks) { |
| 1178 | + task.run(); |
| 1179 | + } |
| 1180 | + driver.manager.processAckFrame(new AckFrameBuilder().addAck(1).addAck(2).build()); |
| 1181 | + driver.run(); |
| 1182 | + driver.check(); |
| 1183 | + } |
| 1184 | + |
1128 | 1185 | } |
0 commit comments