mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-27 13:52:27 +00:00
8378276: Refactor test/jdk/java/net/httpclient/quic/ TestNG tests to JUnit
Reviewed-by: vyazici
This commit is contained in:
parent
feecb042fe
commit
2ebd612634
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -71,8 +71,6 @@ import jdk.internal.net.quic.QuicTLSEngine;
|
||||
import jdk.internal.net.quic.QuicTransportException;
|
||||
import jdk.internal.net.quic.QuicTransportParametersConsumer;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
@ -80,16 +78,19 @@ import javax.net.ssl.SSLSession;
|
||||
|
||||
import static jdk.internal.net.http.quic.frames.QuicFrame.*;
|
||||
import static jdk.internal.net.http.quic.frames.ConnectionCloseFrame.CONNECTION_CLOSE_VARIANT;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
/**
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary tests the logic to decide whether a packet or
|
||||
* a frame is ACK-eliciting.
|
||||
* @library /test/lib
|
||||
* @run testng AckElicitingTest
|
||||
* @run testng/othervm -Dseed=-7997973196290088038 AckElicitingTest
|
||||
* @run junit AckElicitingTest
|
||||
* @run junit/othervm -Dseed=-7997973196290088038 AckElicitingTest
|
||||
*/
|
||||
public class AckElicitingTest {
|
||||
|
||||
@ -307,7 +308,7 @@ public class AckElicitingTest {
|
||||
* {@code obj.ackEliciting()}
|
||||
* @param <T> A concrete subclass of {@link QuicFrame} or {@link QuicPacket}
|
||||
*/
|
||||
static record TestCase<T>(Class<? extends T> type,
|
||||
record TestCase<T>(Class<? extends T> type,
|
||||
Function<T, String> describer,
|
||||
Predicate<? super T> ackEliciting,
|
||||
T obj,
|
||||
@ -336,7 +337,7 @@ public class AckElicitingTest {
|
||||
*/
|
||||
public static <T extends QuicFrame> TestCase<T>
|
||||
of(Class<? extends T> type, T frame, boolean expected) {
|
||||
return new TestCase<T>(type, TestCase::describeFrame,
|
||||
return new TestCase<>(type, TestCase::describeFrame,
|
||||
QuicFrame::isAckEliciting, frame, expected);
|
||||
}
|
||||
|
||||
@ -349,7 +350,7 @@ public class AckElicitingTest {
|
||||
* @return a new instance of {@code TestCase}
|
||||
*/
|
||||
public static <T extends QuicFrame> TestCase<T> of(T frame, boolean expected) {
|
||||
return new TestCase<T>((Class<T>)frame.getClass(),
|
||||
return new TestCase<>((Class<T>)frame.getClass(),
|
||||
TestCase::describeFrame,
|
||||
QuicFrame::isAckEliciting,
|
||||
frame, expected);
|
||||
@ -391,7 +392,7 @@ public class AckElicitingTest {
|
||||
* @param <T> a concrete subclass of {@code QuicFrame}
|
||||
* @return a new instance of the given concrete class.
|
||||
*/
|
||||
<T extends QuicFrame> T newFrame(Class<T> frameClass) {
|
||||
static <T extends QuicFrame> T newFrame(Class<T> frameClass) {
|
||||
var frameType = QuicFrame.frameTypeOf(frameClass);
|
||||
if (frameType == CONNECTION_CLOSE) {
|
||||
if (RANDOM.nextBoolean()) {
|
||||
@ -454,7 +455,7 @@ public class AckElicitingTest {
|
||||
* @return a list of {@code TestCase} to test all possible concrete
|
||||
* subclasses of {@code QuicFrame}
|
||||
*/
|
||||
public List<TestCase<? extends QuicFrame>> createFramesTests() {
|
||||
static List<TestCase<? extends QuicFrame>> createFramesTests() {
|
||||
List<TestCase<? extends QuicFrame>> frames = new ArrayList<>();
|
||||
frames.add(of(newFrame(AckFrame.class), false));
|
||||
frames.add(of(newFrame(ConnectionCloseFrame.class), false));
|
||||
@ -476,7 +477,7 @@ public class AckElicitingTest {
|
||||
* @param frames a list of frames
|
||||
* @return a new instance of {@code QuicPacket}
|
||||
*/
|
||||
QuicPacket createPacket(List<QuicFrame> frames) {
|
||||
static QuicPacket createPacket(List<QuicFrame> frames) {
|
||||
PacketType[] values = PacketType.values();
|
||||
int index = PacketType.NONE.ordinal();
|
||||
while (index == PacketType.NONE.ordinal()) {
|
||||
@ -506,9 +507,9 @@ public class AckElicitingTest {
|
||||
* pseudo random list of concrete {@link QuicFrame} instances.
|
||||
* @param ackEliciting whether the returned packet should be
|
||||
* ack eliciting.
|
||||
* @return
|
||||
* @return a new QuicPacket
|
||||
*/
|
||||
QuicPacket createPacket(boolean ackEliciting) {
|
||||
static QuicPacket createPacket(boolean ackEliciting) {
|
||||
List<QuicFrame> frames = new ArrayList<>();
|
||||
int mincount = ackEliciting ? 1 : 0;
|
||||
int ackCount = RANDOM.nextInt(mincount, 5);
|
||||
@ -542,7 +543,7 @@ public class AckElicitingTest {
|
||||
return createPacket(mergeConsecutivePaddingFrames(frames));
|
||||
}
|
||||
|
||||
private List<QuicFrame> mergeConsecutivePaddingFrames(List<QuicFrame> frames) {
|
||||
private static List<QuicFrame> mergeConsecutivePaddingFrames(List<QuicFrame> frames) {
|
||||
var iterator = frames.listIterator();
|
||||
QuicFrame previous = null;
|
||||
|
||||
@ -567,7 +568,7 @@ public class AckElicitingTest {
|
||||
* @return a list of {@code TestCase} to test random instances of
|
||||
* {@code QuicPacket} containing random instances of {@link QuicFrame}
|
||||
*/
|
||||
public List<TestCase<? extends QuicPacket>> createPacketsTests() {
|
||||
static List<TestCase<? extends QuicPacket>> createPacketsTests() {
|
||||
List<TestCase<? extends QuicPacket>> packets = new ArrayList<>();
|
||||
packets.add(of(createPacket(List.of(newFrame(AckFrame.class))), false));
|
||||
packets.add(of(createPacket(List.of(newFrame(ConnectionCloseFrame.class))), false));
|
||||
@ -593,8 +594,7 @@ public class AckElicitingTest {
|
||||
* @return test case to test
|
||||
* {@link QuicFrame#isAckEliciting()}
|
||||
*/
|
||||
@DataProvider(name = "frames")
|
||||
public Object[][] framesDataProvider() {
|
||||
public static Object[][] framesDataProvider() {
|
||||
return createFramesTests().stream()
|
||||
.map(List::of)
|
||||
.map(List::toArray)
|
||||
@ -607,8 +607,7 @@ public class AckElicitingTest {
|
||||
* @return test case to test
|
||||
* {@link QuicPacket#isAckEliciting()}
|
||||
*/
|
||||
@DataProvider(name = "packets")
|
||||
public Object[][] packetsDataProvider() {
|
||||
public static Object[][] packetsDataProvider() {
|
||||
return createPacketsTests().stream()
|
||||
.map(List::of)
|
||||
.map(List::toArray)
|
||||
@ -621,8 +620,9 @@ public class AckElicitingTest {
|
||||
* @param test the test inputs
|
||||
* @param <T> a concrete subclass of QuicFrame
|
||||
*/
|
||||
@Test(dataProvider = "frames")
|
||||
public <T extends QuicFrame> void testFrames(TestCase<T> test) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("framesDataProvider")
|
||||
<T extends QuicFrame> void testFrames(TestCase<T> test) {
|
||||
testAckEliciting(test.type(),
|
||||
test.describer(),
|
||||
test.ackEliciting(),
|
||||
@ -636,8 +636,9 @@ public class AckElicitingTest {
|
||||
* @param test the test inputs
|
||||
* @param <T> a concrete subclass of QuickPacket
|
||||
*/
|
||||
@Test(dataProvider = "packets")
|
||||
public <T extends QuicPacket> void testPackets(TestCase<T> test) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("packetsDataProvider")
|
||||
<T extends QuicPacket> void testPackets(TestCase<T> test) {
|
||||
testAckEliciting(test.type(),
|
||||
test.describer(),
|
||||
test.ackEliciting(),
|
||||
@ -664,7 +665,7 @@ public class AckElicitingTest {
|
||||
type.getSimpleName(),
|
||||
describer.apply(obj),
|
||||
expected);
|
||||
assertEquals(ackEliciting.test(obj), expected, describer.apply(obj));
|
||||
assertEquals(expected, ackEliciting.test(obj), describer.apply(obj));
|
||||
if (obj instanceof QuicFrame frame) {
|
||||
checkFrame(frame);
|
||||
} else if (obj instanceof QuicPacket packet) {
|
||||
@ -695,10 +696,10 @@ public class AckElicitingTest {
|
||||
System.out.printf("Comparing frames: %s with %s%n",
|
||||
decoded.getClass().getSimpleName(),
|
||||
expected.getClass().getSimpleName());
|
||||
assertEquals(decoded.getClass(), expected.getClass());
|
||||
assertEquals(decoded.size(), expected.size());
|
||||
assertEquals(decoded.getTypeField(), expected.getTypeField());
|
||||
assertEquals(decoded.isAckEliciting(), expected.isAckEliciting());
|
||||
assertEquals(expected.getClass(), decoded.getClass());
|
||||
assertEquals(expected.size(), decoded.size());
|
||||
assertEquals(expected.getTypeField(), decoded.getTypeField());
|
||||
assertEquals(expected.isAckEliciting(), decoded.isAckEliciting());
|
||||
}
|
||||
|
||||
// This is not a full-fledged test for packet encoding/decoding.
|
||||
@ -714,13 +715,13 @@ public class AckElicitingTest {
|
||||
encoder.encode(packet, buffer, CONTEXT);
|
||||
buffer.flip();
|
||||
var decoded = decoder.decode(buffer, CONTEXT);
|
||||
assertEquals(decoded.size(), packet.size());
|
||||
assertEquals(decoded.packetType(), packet.packetType());
|
||||
assertEquals(decoded.payloadSize(), packet.payloadSize());
|
||||
assertEquals(decoded.isAckEliciting(), packet.isAckEliciting());
|
||||
assertEquals(packet.size(), decoded.size());
|
||||
assertEquals(packet.packetType(), decoded.packetType());
|
||||
assertEquals(packet.payloadSize(), decoded.payloadSize());
|
||||
assertEquals(packet.isAckEliciting(), decoded.isAckEliciting());
|
||||
var frames = packet.frames();
|
||||
var decodedFrames = decoded.frames();
|
||||
assertEquals(decodedFrames.size(), frames.size());
|
||||
assertEquals(frames.size(), decodedFrames.size());
|
||||
} catch (Exception x) {
|
||||
throw new AssertionError(packet.getClass().getName(), x);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,20 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.net.http.quic.CodingContext;
|
||||
import jdk.internal.net.http.quic.frames.AckFrame;
|
||||
import jdk.internal.net.http.quic.frames.AckFrame.AckFrameBuilder;
|
||||
import jdk.internal.net.http.quic.frames.AckFrame.AckRange;
|
||||
import jdk.internal.net.http.quic.frames.QuicFrame;
|
||||
import jdk.internal.net.http.quic.packets.QuicPacket;
|
||||
import jdk.internal.net.http.quic.packets.QuicPacket.PacketNumberSpace;
|
||||
import jdk.internal.net.http.quic.QuicConnectionId;
|
||||
import jdk.internal.net.quic.QuicTLSEngine;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -43,66 +35,24 @@ import java.util.Random;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @summary tests the logic to build an AckFrame
|
||||
* @library /test/lib
|
||||
* @run testng AckFrameTest
|
||||
* @run junit AckFrameTest
|
||||
*/
|
||||
public class AckFrameTest {
|
||||
|
||||
static final Random RANDOM = RandomFactory.getRandom();
|
||||
|
||||
private static abstract class TestCodingContext implements CodingContext {
|
||||
TestCodingContext() { }
|
||||
@Override
|
||||
public int writePacket(QuicPacket packet, ByteBuffer buffer) {
|
||||
throw new AssertionError("should not come here!");
|
||||
}
|
||||
@Override
|
||||
public QuicPacket parsePacket(ByteBuffer src) throws IOException {
|
||||
throw new AssertionError("should not come here!");
|
||||
}
|
||||
@Override
|
||||
public boolean verifyToken(QuicConnectionId destinationID, byte[] token) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public QuicTLSEngine getTLSEngine() {
|
||||
throw new AssertionError("should not come here!");
|
||||
}
|
||||
}
|
||||
|
||||
static final int CIDLEN = RANDOM.nextInt(5, QuicConnectionId.MAX_CONNECTION_ID_LENGTH + 1);
|
||||
|
||||
private static final TestCodingContext CONTEXT = new TestCodingContext() {
|
||||
|
||||
@Override
|
||||
public long largestProcessedPN(PacketNumberSpace packetSpace) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long largestAckedPN(PacketNumberSpace packetSpace) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int connectionIdLength() {
|
||||
return CIDLEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuicConnectionId originalServerConnId() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public static record Acknowledged(long first, long last) {
|
||||
public record Acknowledged(long first, long last) {
|
||||
public boolean contains(long packet) {
|
||||
return first <= packet && last >= packet;
|
||||
}
|
||||
@ -116,7 +66,7 @@ public class AckFrameTest {
|
||||
return List.copyOf(res);
|
||||
}
|
||||
}
|
||||
public static record Packet(long packetNumber) {
|
||||
public record Packet(long packetNumber) {
|
||||
static List<Packet> ofAcks(List<Acknowledged> acks) {
|
||||
return packets(acks);
|
||||
}
|
||||
@ -125,7 +75,7 @@ public class AckFrameTest {
|
||||
}
|
||||
}
|
||||
|
||||
public static record TestCase(List<Acknowledged> acks, List<Packet> packets, boolean shuffled) {
|
||||
public record TestCase(List<Acknowledged> acks, List<Packet> packets, boolean shuffled) {
|
||||
public TestCase(List<Acknowledged> acks) {
|
||||
this(acks, Packet.ofAcks(acks), false);
|
||||
}
|
||||
@ -137,7 +87,7 @@ public class AckFrameTest {
|
||||
}
|
||||
}
|
||||
|
||||
List<TestCase> generateTests() {
|
||||
static List<TestCase> generateTests() {
|
||||
List<TestCase> tests = new ArrayList<>();
|
||||
List<TestCase> simples = List.of(
|
||||
new TestCase(List.of(new Acknowledged(5,5))),
|
||||
@ -177,7 +127,7 @@ public class AckFrameTest {
|
||||
return tests;
|
||||
}
|
||||
|
||||
List<Acknowledged> generateAcks() {
|
||||
static List<Acknowledged> generateAcks() {
|
||||
int count = RANDOM.nextInt(3, 10);
|
||||
List<Acknowledged> acks = new ArrayList<>(count);
|
||||
long prev = -1;
|
||||
@ -202,22 +152,19 @@ public class AckFrameTest {
|
||||
return res;
|
||||
}
|
||||
|
||||
@DataProvider(name = "tests")
|
||||
public Object[][] tests() {
|
||||
public static Object[][] tests() {
|
||||
return generateTests().stream()
|
||||
.map(List::of)
|
||||
.map(List::toArray)
|
||||
.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "tests")
|
||||
@ParameterizedTest
|
||||
@MethodSource("tests")
|
||||
public void testAckFrames(TestCase testCase) {
|
||||
AckFrameBuilder builder = new AckFrameBuilder();
|
||||
List<Acknowledged> acks = testCase.acks;
|
||||
List<Packet> packets = testCase.packets;
|
||||
long largest = packets.stream()
|
||||
.mapToLong(Packet::packetNumber)
|
||||
.max().getAsLong();
|
||||
System.out.printf("%ntestAckFrames(%s, %s)%n", acks, testCase.shuffled);
|
||||
builder.ackDelay(250);
|
||||
packets.stream().mapToLong(Packet::packetNumber).forEach(builder::addAck);
|
||||
@ -227,8 +174,8 @@ public class AckFrameTest {
|
||||
checkAcknowledging(builder::isAcknowledging, testCase, packets);
|
||||
|
||||
AckFrameBuilder dup = new AckFrameBuilder(frame);
|
||||
assertEquals(frame, dup.build());
|
||||
assertEquals(frame, builder.build());
|
||||
assertEquals(dup.build(), frame);
|
||||
assertEquals(builder.build(), frame);
|
||||
checkAcknowledging(dup::isAcknowledging, testCase, packets);
|
||||
|
||||
packets.stream().mapToLong(Packet::packetNumber).forEach(builder::addAck);
|
||||
@ -255,25 +202,25 @@ public class AckFrameTest {
|
||||
long largest = testCase.packets.stream()
|
||||
.mapToLong(Packet::packetNumber)
|
||||
.max().getAsLong();
|
||||
assertEquals(frame.largestAcknowledged(), largest);
|
||||
assertEquals(largest, frame.largestAcknowledged());
|
||||
checkAcknowledging(frame::isAcknowledging, testCase, packets);
|
||||
for (var ack : testCase.acks) {
|
||||
checkRangeAcknowledged(frame, ack.first, ack.last);
|
||||
}
|
||||
assertEquals(frame, reference);
|
||||
assertEquals(reference, frame);
|
||||
int size = frame.size();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(size + 10);
|
||||
buffer.position(5);
|
||||
buffer.limit(size + 5);
|
||||
try {
|
||||
frame.encode(buffer);
|
||||
assertEquals(buffer.position(), buffer.limit());
|
||||
assertEquals(buffer.limit(), buffer.position());
|
||||
buffer.position(5);
|
||||
buffer.limit(buffer.capacity());
|
||||
var decoded = QuicFrame.decode(buffer);
|
||||
assertEquals(buffer.position(), size + 5);
|
||||
assertEquals(decoded, frame);
|
||||
assertEquals(decoded, reference);
|
||||
assertEquals(size + 5, buffer.position());
|
||||
assertEquals(frame, decoded);
|
||||
assertEquals(reference, decoded);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Can't encode or decode frame: " + frame, e);
|
||||
}
|
||||
@ -327,14 +274,14 @@ public class AckFrameTest {
|
||||
if (isAcknowledging != expected && testCase.shuffled) {
|
||||
System.out.printf(" -> %s%n", packets);
|
||||
}
|
||||
assertEquals(isAcknowledging, expected, String.valueOf(pn));
|
||||
assertEquals(expected, isAcknowledging, String.valueOf(pn));
|
||||
}
|
||||
for (var p : testCase.packets) {
|
||||
boolean isAcknowledging = isAckPredicate.test(p.packetNumber);
|
||||
if (!isAcknowledging && testCase.shuffled) {
|
||||
System.out.printf(" -> %s%n", packets);
|
||||
}
|
||||
assertEquals(isAcknowledging, true, p.toString());
|
||||
assertEquals(true, isAcknowledging, p.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,9 +292,9 @@ public class AckFrameTest {
|
||||
assertTrue(frame.isAcknowledging(1), "1 should be acked");
|
||||
assertFalse(frame.isAcknowledging(0), "0 should not be acked");
|
||||
assertFalse(frame.isAcknowledging(2), "2 should not be acked");
|
||||
assertEquals(frame.smallestAcknowledged(), 1);
|
||||
assertEquals(frame.largestAcknowledged(), 1);
|
||||
assertEquals(frame.acknowledged().toArray(), new long[] {1L});
|
||||
assertEquals(1, frame.smallestAcknowledged());
|
||||
assertEquals(1, frame.largestAcknowledged());
|
||||
assertEquals(List.of(1L), frame.acknowledged().boxed().toList());
|
||||
assertTrue(frame.isRangeAcknowledged(1,1), "[1,1] should be acked");
|
||||
assertFalse(frame.isRangeAcknowledged(0, 1), "[0,1] should not be acked");
|
||||
assertFalse(frame.isRangeAcknowledged(1, 2), "[1,2] should not be acked");
|
||||
@ -358,9 +305,9 @@ public class AckFrameTest {
|
||||
assertTrue(frame.isAcknowledging(1), "1 should be acked");
|
||||
assertTrue(frame.isAcknowledging(0), "0 should be acked");
|
||||
assertFalse(frame.isAcknowledging(2), "2 should not be acked");
|
||||
assertEquals(frame.smallestAcknowledged(), 0);
|
||||
assertEquals(frame.largestAcknowledged(), 1);
|
||||
assertEquals(frame.acknowledged().toArray(), new long[] {1L, 0L});
|
||||
assertEquals(0, frame.smallestAcknowledged());
|
||||
assertEquals(1, frame.largestAcknowledged());
|
||||
assertEquals(List.of(1L, 0L), frame.acknowledged().boxed().toList());
|
||||
assertTrue(frame.isRangeAcknowledged(0,0), "[0,0] should be acked");
|
||||
assertTrue(frame.isRangeAcknowledged(1,1), "[1,1] should be acked");
|
||||
assertTrue(frame.isRangeAcknowledged(0, 1), "[0,1] should be acked");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,29 +27,26 @@ import java.util.List;
|
||||
import jdk.internal.net.http.quic.BuffersReader;
|
||||
import jdk.internal.net.http.quic.BuffersReader.ListBuffersReader;
|
||||
import jdk.internal.net.http.quic.VariableLengthEncoder;
|
||||
import jtreg.SkippedException;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertThrows;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.expectThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @modules java.net.http/jdk.internal.net.http.quic
|
||||
* @run testng/othervm BuffersReaderVLTest
|
||||
* @run junit/othervm BuffersReaderVLTest
|
||||
* @summary Tests to check quic/util methods encode/decodeVariableLength methods
|
||||
* work as expected.
|
||||
*/
|
||||
public class BuffersReaderVLTest {
|
||||
static final Class<? extends Throwable> IAE = IllegalArgumentException.class;
|
||||
|
||||
@DataProvider(name = "decode invariants")
|
||||
public Object[][] decodeInvariants() {
|
||||
public static Object[][] decodeInvariants() {
|
||||
return new Object[][]
|
||||
{
|
||||
{ new byte[]{7}, 7, 1 }, // 00
|
||||
@ -61,8 +58,7 @@ public class BuffersReaderVLTest {
|
||||
{ new byte[]{-65}, -1, 0 },
|
||||
};
|
||||
}
|
||||
@DataProvider(name = "prefix invariants")
|
||||
public Object[][] prefixInvariants() {
|
||||
public static Object[][] prefixInvariants() {
|
||||
return new Object[][]
|
||||
{
|
||||
{ Long.MAX_VALUE, 0, IAE },
|
||||
@ -101,44 +97,47 @@ public class BuffersReaderVLTest {
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "decode invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("decodeInvariants")
|
||||
public void testDecode(byte[] values, long expectedLength, int expectedPosition) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(values);
|
||||
BuffersReader br = BuffersReader.list(bb);
|
||||
var actualLength = VariableLengthEncoder.decode(br);
|
||||
assertEquals(actualLength, expectedLength);
|
||||
assertEquals(expectedLength, actualLength);
|
||||
|
||||
var actualPosition = bb.position();
|
||||
assertEquals(actualPosition, expectedPosition);
|
||||
assertEquals(br.position(), expectedPosition);
|
||||
assertEquals(expectedPosition, actualPosition);
|
||||
assertEquals(expectedPosition, br.position());
|
||||
br.release();
|
||||
assertEquals(br.read(), expectedPosition);
|
||||
assertEquals(expectedPosition, br.read());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "decode invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("decodeInvariants")
|
||||
public void testPeek(byte[] values, long expectedLength, int expectedPosition) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(values);
|
||||
BuffersReader br = BuffersReader.list(bb);
|
||||
var actualLength = VariableLengthEncoder.peekEncodedValue(br, 0);
|
||||
assertEquals(actualLength, expectedLength);
|
||||
assertEquals(expectedLength, actualLength);
|
||||
|
||||
var actualPosition = bb.position();
|
||||
assertEquals(actualPosition, 0);
|
||||
assertEquals(br.position(), 0);
|
||||
assertEquals(0, actualPosition);
|
||||
assertEquals(0, br.position());
|
||||
br.release();
|
||||
assertEquals(br.read(), 0);
|
||||
assertEquals(0, br.read());
|
||||
}
|
||||
|
||||
// Encode the given length and then decodes it and compares
|
||||
// the results, asserting various invariants along the way.
|
||||
@Test(dataProvider = "prefix invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("prefixInvariants")
|
||||
public void testEncodeDecode(long length, int expectedPrefix, Class<? extends Exception> exception) {
|
||||
if (exception != null) {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.getEncodedSize(length));
|
||||
assertThrows(exception, () -> VariableLengthEncoder.encode(ByteBuffer.allocate(16), length));
|
||||
} else {
|
||||
var actualSize = VariableLengthEncoder.getEncodedSize(length);
|
||||
assertEquals(actualSize, 1 << expectedPrefix);
|
||||
assertEquals(1 << expectedPrefix, actualSize);
|
||||
assertTrue(actualSize > 0, "length is negative or zero: " + actualSize);
|
||||
assertTrue(actualSize < 9, "length is too big: " + actualSize);
|
||||
|
||||
@ -158,33 +157,33 @@ public class BuffersReaderVLTest {
|
||||
longer.position(offset);
|
||||
|
||||
// attempt to encode with a buffer too short
|
||||
expectThrows(IAE, () -> VariableLengthEncoder.encode(shorter, length));
|
||||
assertEquals(shorter.position(), offset);
|
||||
assertEquals(shorter.limit(), shorter.capacity());
|
||||
assertThrows(IAE, () -> VariableLengthEncoder.encode(shorter, length));
|
||||
assertEquals(offset, shorter.position());
|
||||
assertEquals(shorter.capacity(), shorter.limit());
|
||||
|
||||
assertEquals(shorter.mismatch(shorterref), -1);
|
||||
assertEquals(shorterref.mismatch(shorter), -1);
|
||||
assertEquals(-1, shorter.mismatch(shorterref));
|
||||
assertEquals(-1, shorterref.mismatch(shorter));
|
||||
|
||||
// attempt to encode with a buffer that has the exact size
|
||||
var exactres = VariableLengthEncoder.encode(exact, length);
|
||||
assertEquals(exactres, actualSize);
|
||||
assertEquals(exact.position(), actualSize + offset);
|
||||
assertEquals(actualSize, exactres);
|
||||
assertEquals(actualSize + offset, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
|
||||
// attempt to encode with a buffer that has more bytes
|
||||
var longres = VariableLengthEncoder.encode(longer, length);
|
||||
assertEquals(longres, actualSize);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(actualSize, longres);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
assertEquals(10, longer.remaining());
|
||||
|
||||
// compare encodings
|
||||
|
||||
// first reset buffer positions for reading.
|
||||
exact.position(offset);
|
||||
longer.position(offset);
|
||||
assertEquals(longer.mismatch(exact), actualSize);
|
||||
assertEquals(exact.mismatch(longer), actualSize);
|
||||
assertEquals(actualSize, longer.mismatch(exact));
|
||||
assertEquals(actualSize, exact.mismatch(longer));
|
||||
|
||||
// decode with a buffer that is missing the last
|
||||
// byte...
|
||||
@ -193,23 +192,23 @@ public class BuffersReaderVLTest {
|
||||
shortSlice.limit(offset + actualSize -1);
|
||||
ListBuffersReader br = BuffersReader.list(shortSlice);
|
||||
var actualLength = VariableLengthEncoder.decode(br);
|
||||
assertEquals(actualLength, -1L);
|
||||
assertEquals(shortSlice.position(), offset);
|
||||
assertEquals(shortSlice.limit(), offset + actualSize - 1);
|
||||
assertEquals(br.position(), offset);
|
||||
assertEquals(br.limit(), offset + actualSize - 1);
|
||||
assertEquals(-1L, actualLength);
|
||||
assertEquals(offset, shortSlice.position());
|
||||
assertEquals(offset + actualSize - 1, shortSlice.limit());
|
||||
assertEquals(offset, br.position());
|
||||
assertEquals(offset + actualSize - 1, br.limit());
|
||||
br.release();
|
||||
|
||||
// decode with the exact buffer
|
||||
br = BuffersReader.list(exact);
|
||||
actualLength = VariableLengthEncoder.decode(br);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(exact.position(), offset + actualSize);
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(offset + actualSize, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
assertEquals(br.position(), offset + actualSize);
|
||||
assertEquals(offset + actualSize, br.position());
|
||||
assertFalse(br.hasRemaining());
|
||||
br.release();
|
||||
assertEquals(br.read(), actualSize);
|
||||
assertEquals(actualSize, br.read());
|
||||
assertFalse(br.hasRemaining());
|
||||
|
||||
|
||||
@ -217,14 +216,14 @@ public class BuffersReaderVLTest {
|
||||
long read = br.read();
|
||||
br.add(longer);
|
||||
actualLength = VariableLengthEncoder.decode(br);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(br.position(), offset + actualSize);
|
||||
assertEquals(br.remaining(), 10);
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(10, longer.remaining());
|
||||
assertEquals(offset + actualSize, br.position());
|
||||
assertEquals(10, br.remaining());
|
||||
br.release();
|
||||
assertEquals(br.read() - read, actualSize);
|
||||
assertEquals(br.remaining(), 10);
|
||||
assertEquals(actualSize, br.read() - read);
|
||||
assertEquals(10, br.remaining());
|
||||
}
|
||||
|
||||
}
|
||||
@ -232,7 +231,8 @@ public class BuffersReaderVLTest {
|
||||
|
||||
// Encode the given length and then peeks it and compares
|
||||
// the results, asserting various invariants along the way.
|
||||
@Test(dataProvider = "prefix invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("prefixInvariants")
|
||||
public void testEncodePeek(long length, int expectedPrefix, Class<? extends Exception> exception) {
|
||||
if (exception != null) {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.getEncodedSize(length));
|
||||
@ -241,7 +241,7 @@ public class BuffersReaderVLTest {
|
||||
}
|
||||
|
||||
var actualSize = VariableLengthEncoder.getEncodedSize(length);
|
||||
assertEquals(actualSize, 1 << expectedPrefix);
|
||||
assertEquals(1 << expectedPrefix, actualSize);
|
||||
assertTrue(actualSize > 0, "length is negative or zero: " + actualSize);
|
||||
assertTrue(actualSize < 9, "length is too big: " + actualSize);
|
||||
|
||||
@ -258,24 +258,24 @@ public class BuffersReaderVLTest {
|
||||
|
||||
// attempt to encode with a buffer that has the exact size
|
||||
var exactres = VariableLengthEncoder.encode(exact, length);
|
||||
assertEquals(exactres, actualSize);
|
||||
assertEquals(exact.position(), actualSize + offset);
|
||||
assertEquals(actualSize, exactres);
|
||||
assertEquals(actualSize + offset, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
|
||||
// attempt to encode with a buffer that has more bytes
|
||||
var longres = VariableLengthEncoder.encode(longer, length);
|
||||
assertEquals(longres, actualSize);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(actualSize, longres);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
assertEquals(10, longer.remaining());
|
||||
|
||||
// compare encodings
|
||||
|
||||
// first reset buffer positions for reading.
|
||||
exact.position(offset);
|
||||
longer.position(offset);
|
||||
assertEquals(longer.mismatch(exact), actualSize);
|
||||
assertEquals(exact.mismatch(longer), actualSize);
|
||||
assertEquals(actualSize, longer.mismatch(exact));
|
||||
assertEquals(actualSize, exact.mismatch(longer));
|
||||
exact.position(0);
|
||||
longer.position(0);
|
||||
exact.limit(exact.capacity());
|
||||
@ -288,38 +288,26 @@ public class BuffersReaderVLTest {
|
||||
shortSlice.limit(offset + actualSize - 1);
|
||||
// need at least one byte to decode the size len...
|
||||
var expectedSize = shortSlice.limit() <= offset ? -1 : actualSize;
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(shortSlice, offset), expectedSize);
|
||||
assertEquals(expectedSize, VariableLengthEncoder.peekEncodedValueSize(shortSlice, offset));
|
||||
var actualLength = VariableLengthEncoder.peekEncodedValue(shortSlice, offset);
|
||||
assertEquals(actualLength, -1L);
|
||||
assertEquals(shortSlice.position(), 0);
|
||||
assertEquals(shortSlice.limit(), offset + actualSize - 1);
|
||||
assertEquals(-1L, actualLength);
|
||||
assertEquals(0, shortSlice.position());
|
||||
assertEquals(offset + actualSize - 1, shortSlice.limit());
|
||||
|
||||
// decode with the exact buffer
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(exact, offset), actualSize);
|
||||
assertEquals(actualSize, VariableLengthEncoder.peekEncodedValueSize(exact, offset));
|
||||
actualLength = VariableLengthEncoder.peekEncodedValue(exact, offset);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(exact.position(), 0);
|
||||
assertEquals(exact.limit(), exact.capacity());
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(0, exact.position());
|
||||
assertEquals(exact.capacity(), exact.limit());
|
||||
|
||||
// decode with the longer buffer
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(longer, offset), actualSize);
|
||||
assertEquals(actualSize, VariableLengthEncoder.peekEncodedValueSize(longer, offset));
|
||||
actualLength = VariableLengthEncoder.peekEncodedValue(longer, offset);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(longer.position(), 0);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(0, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private ByteBuffer getTestBuffer(long length, int capacity) {
|
||||
return switch (capacity) {
|
||||
case 0 -> ByteBuffer.allocate(1).put((byte) length);
|
||||
case 1 -> ByteBuffer.allocate(capacity).put((byte) length);
|
||||
case 2 -> ByteBuffer.allocate(capacity).putShort((short) length);
|
||||
case 4 -> ByteBuffer.allocate(capacity).putInt((int) length);
|
||||
case 8 -> ByteBuffer.allocate(capacity).putLong(length);
|
||||
default -> throw new SkippedException("bad value used for capacity");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,12 +29,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.internal.net.http.quic.QuicConnectionIdFactory;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run testng/othervm ConnectionIDSTest
|
||||
* @run junit/othervm ConnectionIDSTest
|
||||
*/
|
||||
public class ConnectionIDSTest {
|
||||
|
||||
@ -76,14 +77,14 @@ public class ConnectionIDSTest {
|
||||
int expectedLength = Math.min(length, 20);
|
||||
expectedLength = Math.max(9, expectedLength);
|
||||
long token = idFactory.newToken();
|
||||
assertEquals(token, previous +1);
|
||||
assertEquals(previous +1, token);
|
||||
previous = token;
|
||||
var id = idFactory.newConnectionId(length, token);
|
||||
var cid = new ConnID(token, id);
|
||||
System.out.printf("%s: %s/%s%n", length, token, cid);
|
||||
assertEquals(id.length, expectedLength);
|
||||
assertEquals(idFactory.getConnectionIdLength(id), expectedLength);
|
||||
assertEquals(idFactory.getConnectionIdToken(id), token);
|
||||
assertEquals(expectedLength, id.length);
|
||||
assertEquals(expectedLength, idFactory.getConnectionIdLength(id));
|
||||
assertEquals(token, idFactory.getConnectionIdToken(id));
|
||||
ids.add(cid);
|
||||
}
|
||||
|
||||
@ -101,9 +102,9 @@ public class ConnectionIDSTest {
|
||||
var id = idFactory.newConnectionId(length, token);
|
||||
var cid = new ConnID(expectedToken, id);
|
||||
System.out.printf("%s: %s/%s%n", length, token, cid);
|
||||
assertEquals(id.length, length);
|
||||
assertEquals(idFactory.getConnectionIdLength(id), length);
|
||||
assertEquals(idFactory.getConnectionIdToken(id), expectedToken);
|
||||
assertEquals(length, id.length);
|
||||
assertEquals(length, idFactory.getConnectionIdLength(id));
|
||||
assertEquals(expectedToken, idFactory.getConnectionIdToken(id));
|
||||
ids.add(cid);
|
||||
}
|
||||
}
|
||||
@ -119,15 +120,15 @@ public class ConnectionIDSTest {
|
||||
var id = idFactory.newConnectionId(length, token);
|
||||
var cid = new ConnID(expectedToken, id);
|
||||
System.out.printf("%s: %s/%s%n", length, token, cid);
|
||||
assertEquals(id.length, length);
|
||||
assertEquals(idFactory.getConnectionIdLength(id), length);
|
||||
assertEquals(idFactory.getConnectionIdToken(id), expectedToken);
|
||||
assertEquals(length, id.length);
|
||||
assertEquals(length, idFactory.getConnectionIdLength(id));
|
||||
assertEquals(expectedToken, idFactory.getConnectionIdToken(id));
|
||||
ids.add(cid);
|
||||
}
|
||||
}
|
||||
|
||||
// now verify uniqueness
|
||||
Map<ConnID, ConnID> tested = new HashMap();
|
||||
Map<ConnID, ConnID> tested = new HashMap<>();
|
||||
record duplicates(ConnID first, ConnID second) {}
|
||||
List<duplicates> duplicates = new ArrayList<>();
|
||||
for (var cid : ids) {
|
||||
@ -144,9 +145,9 @@ public class ConnectionIDSTest {
|
||||
// and the token value is too big; check and remove them
|
||||
for (var iter = duplicates.iterator(); iter.hasNext(); ) {
|
||||
var dup = iter.next();
|
||||
assertEquals(dup.first.token(), dup.second.token());
|
||||
assertEquals(dup.first.bytes().length, dup.second.bytes().length);
|
||||
assertEquals(dup.first.bytes(), dup.second.bytes());
|
||||
assertEquals(dup.second.token(), dup.first.token());
|
||||
assertEquals(dup.second.bytes().length, dup.first.bytes().length);
|
||||
assertArrayEquals(dup.second.bytes(), dup.first.bytes());
|
||||
long mask = 0x00FFFFFF00000000L;
|
||||
for (int i=0; i<3; i++) {
|
||||
mask = mask << 8;
|
||||
@ -165,6 +166,6 @@ public class ConnectionIDSTest {
|
||||
for (var dup : duplicates) {
|
||||
System.out.println("unexpected duplicate: " + dup);
|
||||
}
|
||||
assertEquals(duplicates.size(), 0);
|
||||
assertEquals(0, duplicates.size());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,18 +23,18 @@
|
||||
|
||||
import jdk.internal.net.http.quic.frames.CryptoFrame;
|
||||
import jdk.internal.net.http.quic.streams.CryptoWriterQueue;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @summary Tests jdk.internal.net.http.quic.streams,CryptoWriterQueue
|
||||
* @modules java.net.http/jdk.internal.net.http.quic.streams
|
||||
* java.net.http/jdk.internal.net.http.quic.frames
|
||||
* @run testng CryptoWriterQueueTest
|
||||
* @run junit CryptoWriterQueueTest
|
||||
*/
|
||||
public class CryptoWriterQueueTest {
|
||||
|
||||
@ -54,7 +54,7 @@ public class CryptoWriterQueueTest {
|
||||
writerQueue.enqueue(buff2);
|
||||
writerQueue.enqueue(buff3);
|
||||
final int expectedRemaining = buff1.remaining() + buff2.remaining() + buff3.remaining();
|
||||
assertEquals(writerQueue.remaining(), expectedRemaining,
|
||||
assertEquals(expectedRemaining, writerQueue.remaining(),
|
||||
"Unexpected remaining bytes in CryptoWriterQueue");
|
||||
// create frame(s) from the enqueued buffers
|
||||
final int maxPayloadSize = 1134;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -48,12 +48,14 @@ import jdk.internal.net.quic.QuicKeyUnavailableException;
|
||||
import jdk.internal.net.quic.QuicTLSContext;
|
||||
import jdk.internal.net.quic.QuicVersion;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import sun.security.ssl.QuicTLSEngineImpl;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -78,22 +80,22 @@ import static org.testng.Assert.assertTrue;
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @comment the test is run with -Djava.security.properties=<URL> to augment
|
||||
* the master java.security file
|
||||
* @run testng/othervm -Djava.security.properties=${test.src}/quic-tls-keylimits-java.security
|
||||
* @run junit/othervm -Djava.security.properties=${test.src}/quic-tls-keylimits-java.security
|
||||
* -Djdk.internal.httpclient.debug=true
|
||||
* -Djavax.net.debug=all
|
||||
* KeyUpdateTest
|
||||
*/
|
||||
public class KeyUpdateTest {
|
||||
|
||||
private QuicStandaloneServer server;
|
||||
private static QuicStandaloneServer server;
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
private ExecutorService executor;
|
||||
private static ExecutorService executor;
|
||||
|
||||
private static final byte[] HELLO_MSG = "Hello Quic".getBytes(StandardCharsets.UTF_8);
|
||||
private static final EchoHandler handler = new EchoHandler(HELLO_MSG.length);
|
||||
|
||||
@BeforeClass
|
||||
public void beforeClass() throws Exception {
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
executor = Executors.newCachedThreadPool();
|
||||
server = QuicStandaloneServer.newBuilder()
|
||||
.availableVersions(new QuicVersion[]{QuicVersion.QUIC_V1})
|
||||
@ -105,8 +107,8 @@ public class KeyUpdateTest {
|
||||
System.out.println("Server started at " + server.getAddress());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void afterClass() throws Exception {
|
||||
@AfterAll
|
||||
public static void afterClass() throws Exception {
|
||||
if (server != null) {
|
||||
System.out.println("Stopping server " + server.getAddress());
|
||||
server.close();
|
||||
@ -163,7 +165,7 @@ public class KeyUpdateTest {
|
||||
// keep track of the 1-RTT key phase that was used by the client connection
|
||||
final int invocation = i;
|
||||
getKeyPhase(conn.underlyingQuicConnection()).ifPresent((keyPhase) -> {
|
||||
if (clientConnKeyPhases.empty() || clientConnKeyPhases.peek() != keyPhase) {
|
||||
if (clientConnKeyPhases.empty() || !keyPhase.equals(clientConnKeyPhases.peek())) {
|
||||
// new key phase detected, add it
|
||||
clientConnKeyPhases.push(keyPhase);
|
||||
System.out.println("Detected client 1-RTT key phase " + keyPhase
|
||||
@ -223,7 +225,7 @@ public class KeyUpdateTest {
|
||||
// keep track of the 1-RTT key phase that was used by the server connection
|
||||
getKeyPhase(conn).ifPresent((keyPhase) -> {
|
||||
if (this.serverConnKeyPhases.empty()
|
||||
|| this.serverConnKeyPhases.peek() != keyPhase) {
|
||||
|| !keyPhase.equals(this.serverConnKeyPhases.peek())) {
|
||||
// new key phase detected, add it
|
||||
this.serverConnKeyPhases.push(keyPhase);
|
||||
System.out.println("Detected server 1-RTT key phase " + keyPhase
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,24 +37,24 @@ import jdk.internal.net.http.quic.OrderedFlow;
|
||||
import jdk.internal.net.http.quic.frames.CryptoFrame;
|
||||
import jdk.internal.net.http.quic.frames.QuicFrame;
|
||||
import jdk.internal.net.http.quic.frames.StreamFrame;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @summary tests the reordering logic implemented by OrderedFlow
|
||||
* and its two concrete subclasses
|
||||
* @library /test/lib
|
||||
* @run testng OrderedFlowTest
|
||||
* @run testng/othervm -Dseed=-2680947227866359853 OrderedFlowTest
|
||||
* @run testng/othervm -Dseed=-273117134353023275 OrderedFlowTest
|
||||
* @run testng/othervm -Dseed=3649132517916066643 OrderedFlowTest
|
||||
* @run testng/othervm -Dseed=4568737726943220431 OrderedFlowTest
|
||||
* @run junit OrderedFlowTest
|
||||
* @run junit/othervm -Dseed=-2680947227866359853 OrderedFlowTest
|
||||
* @run junit/othervm -Dseed=-273117134353023275 OrderedFlowTest
|
||||
* @run junit/othervm -Dseed=3649132517916066643 OrderedFlowTest
|
||||
* @run junit/othervm -Dseed=4568737726943220431 OrderedFlowTest
|
||||
*/
|
||||
public class OrderedFlowTest {
|
||||
|
||||
@ -135,13 +135,13 @@ public class OrderedFlowTest {
|
||||
""";
|
||||
|
||||
interface FramesFactory<T extends QuicFrame> {
|
||||
public T create(int offset, String payload, boolean fin);
|
||||
public int length(T frame);
|
||||
public long offset(T frame);
|
||||
public String getPayload(T frame);
|
||||
public OrderedFlow<T> flow();
|
||||
public Class<T> frameType();
|
||||
public Comparator<T> comparator();
|
||||
T create(int offset, String payload, boolean fin);
|
||||
int length(T frame);
|
||||
long offset(T frame);
|
||||
String getPayload(T frame);
|
||||
OrderedFlow<T> flow();
|
||||
Class<T> frameType();
|
||||
Comparator<T> comparator();
|
||||
}
|
||||
|
||||
static class StreamFrameFactory implements FramesFactory<StreamFrame> {
|
||||
@ -307,7 +307,7 @@ public class OrderedFlowTest {
|
||||
// not be buffered.
|
||||
static <T extends QuicFrame> TestData<T> reversed(TestData<T> data) {
|
||||
List<T> sorted = new ArrayList<>(data.frames());
|
||||
Collections.sort(sorted, data.framesComparator().reversed());
|
||||
sorted.sort(data.framesComparator().reversed());
|
||||
return new TestData<>(data.frameType(),data.flowSupplier(), data.payloadAccessor(),
|
||||
data.framesComparator(), List.copyOf(sorted), data.expectedResult(),
|
||||
data.duplicates(), true);
|
||||
@ -336,8 +336,7 @@ public class OrderedFlowTest {
|
||||
return List.copyOf(result);
|
||||
}
|
||||
|
||||
@DataProvider(name="CryptoFrame")
|
||||
Object[][] generateCryptoFrames() {
|
||||
static Object[][] generateCryptoFrames() {
|
||||
return generateData(new CryptoFrameFactory())
|
||||
.stream()
|
||||
.map(List::of)
|
||||
@ -345,8 +344,7 @@ public class OrderedFlowTest {
|
||||
.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider(name="StreamFrame")
|
||||
Object[][] generateStreanFrames() {
|
||||
static Object[][] generateStreanFrames() {
|
||||
return generateData(new StreamFrameFactory())
|
||||
.stream()
|
||||
.map(List::of)
|
||||
@ -380,21 +378,23 @@ public class OrderedFlowTest {
|
||||
"buffered data %s exceeds or equals payload size %s".formatted(buffered, size));
|
||||
while (received != null) {
|
||||
var payload = testData.payloadAccessor.apply(received);
|
||||
assertNotEquals(payload, "", "empty frames not expected: " + received);
|
||||
assertNotEquals("", payload, "empty frames not expected: " + received);
|
||||
result.append(payload);
|
||||
received = flow.poll();
|
||||
}
|
||||
}
|
||||
assertEquals(result.toString(), testData.expectedResult);
|
||||
assertEquals(testData.expectedResult, result.toString());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "CryptoFrame")
|
||||
public void testCryptoFlow(TestData<CryptoFrame> testData) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("generateCryptoFrames")
|
||||
void testCryptoFlow(TestData<CryptoFrame> testData) {
|
||||
testOrderedFlow(testData, CryptoFrame::offset);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "StreamFrame")
|
||||
public void testStreamFlow(TestData<StreamFrame> testData) {
|
||||
@ParameterizedTest
|
||||
@MethodSource("generateStreanFrames")
|
||||
void testStreamFlow(TestData<StreamFrame> testData) {
|
||||
testOrderedFlow(testData, StreamFrame::offset);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,20 +26,21 @@ import jdk.internal.net.http.quic.QuicCongestionController;
|
||||
import jdk.internal.net.http.quic.QuicPacer;
|
||||
import jdk.internal.net.http.quic.QuicRttEstimator;
|
||||
import jdk.internal.net.http.quic.packets.QuicPacket;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run testng/othervm -Djdk.httpclient.quic.timerFrequency=1000 PacerTest
|
||||
* @run junit/othervm -Djdk.httpclient.quic.timerFrequency=1000 PacerTest
|
||||
*/
|
||||
public class PacerTest {
|
||||
|
||||
@ -136,8 +137,7 @@ public class PacerTest {
|
||||
int initialPermit, int periodicPermit, boolean slowStart) {
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] pacerFirstFlight() {
|
||||
public static Object[][] pacerFirstFlight() {
|
||||
return List.of(
|
||||
// Should permit initial window before blocking
|
||||
new TestCase(1200, 10, 32, 16, 10, 4, true),
|
||||
@ -150,7 +150,8 @@ public class PacerTest {
|
||||
.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "pacerFirstFlight")
|
||||
@ParameterizedTest
|
||||
@MethodSource("pacerFirstFlight")
|
||||
public void testBasicPacing(TestCase test) {
|
||||
int maxDatagramSize = test.maxDatagramSize;
|
||||
int packetsInIW = test.packetsInIW;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,8 +52,6 @@ import jdk.internal.net.http.quic.QuicConnectionId;
|
||||
import jdk.internal.net.quic.QuicTLSEngine;
|
||||
import jdk.internal.net.quic.QuicTransportParametersConsumer;
|
||||
import jdk.internal.net.http.quic.VariableLengthEncoder;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
@ -71,29 +69,32 @@ import java.util.function.IntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static jdk.internal.net.http.quic.packets.QuicPacketNumbers.computePacketNumberLength;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @summary test packet encoding and decoding in unencrypted form and without
|
||||
* any network involvement.
|
||||
* @run testng/othervm -Dseed=2646683818688275736 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=-3723256402256409075 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=-3689060484817342283 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=2425718686525936108 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=-2996954753243104355 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=8750823652999067800 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=2906555779406889127 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=902801756808168822 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=5643545543196691308 PacketEncodingTest
|
||||
* @run testng/othervm -Dseed=2646683818688275736 PacketEncodingTest
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=2646683818688275736 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=-3723256402256409075 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=-3689060484817342283 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=2425718686525936108 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=-2996954753243104355 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=8750823652999067800 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=2906555779406889127 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=902801756808168822 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=5643545543196691308 PacketEncodingTest
|
||||
* @run junit/othervm -Dseed=2646683818688275736 PacketEncodingTest
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true PacketEncodingTest
|
||||
*/
|
||||
public class PacketEncodingTest {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longHeaderPacketProvider() {
|
||||
public static Object[][] longHeaderPacketProvider() {
|
||||
final QuicVersion[] quicVersions = QuicVersion.values();
|
||||
final List<Object[]> params = new ArrayList<>();
|
||||
for (final QuicVersion version : quicVersions) {
|
||||
@ -117,8 +118,7 @@ public class PacketEncodingTest {
|
||||
return params.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortHeaderPacketProvider() {
|
||||
public static Object[][] shortHeaderPacketProvider() {
|
||||
final QuicVersion[] quicVersions = QuicVersion.values();
|
||||
final List<Object[]> params = new ArrayList<>();
|
||||
for (final QuicVersion version : quicVersions) {
|
||||
@ -141,8 +141,7 @@ public class PacketEncodingTest {
|
||||
return params.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] versionAndRetryProvider() {
|
||||
public static Object[][] versionAndRetryProvider() {
|
||||
final QuicVersion[] quicVersions = QuicVersion.values();
|
||||
final List<Object[]> params = new ArrayList<>();
|
||||
for (final QuicVersion version : quicVersions) {
|
||||
@ -393,23 +392,23 @@ public class PacketEncodingTest {
|
||||
QuicConnectionId destConnectionId,
|
||||
List<QuicFrame> payload) {
|
||||
// Check created packet
|
||||
assertEquals(packet.headersType(), HeadersType.LONG);
|
||||
assertEquals(packet.packetType(), packetType);
|
||||
assertEquals(HeadersType.LONG, packet.headersType());
|
||||
assertEquals(packetType, packet.packetType());
|
||||
boolean hasLength = switch (packetType) {
|
||||
case VERSIONS, RETRY -> false;
|
||||
default -> true;
|
||||
};
|
||||
assertEquals(packet.hasLength(), hasLength);
|
||||
assertEquals(packet.numberSpace(), packetNumberSpace);
|
||||
assertEquals(hasLength, packet.hasLength());
|
||||
assertEquals(packetNumberSpace, packet.numberSpace());
|
||||
if (payload == null) {
|
||||
assertTrue(packet.frames().isEmpty());
|
||||
} else {
|
||||
assertEquals(getBuffers(packet.frames()), getBuffers(payload));
|
||||
assertEquals(getBuffers(payload), getBuffers(packet.frames()));
|
||||
}
|
||||
assertEquals(packet.version(), versionNumber);
|
||||
assertEquals(packet.packetNumber(), packetNumber);
|
||||
assertEquals(packet.sourceId(), srcConnectionId);
|
||||
assertEquals(packet.destinationId(), destConnectionId);
|
||||
assertEquals(versionNumber, packet.version());
|
||||
assertEquals(packetNumber, packet.packetNumber());
|
||||
assertEquals(srcConnectionId, packet.sourceId());
|
||||
assertEquals(destConnectionId, packet.destinationId());
|
||||
|
||||
}
|
||||
|
||||
@ -446,11 +445,11 @@ public class PacketEncodingTest {
|
||||
PacketType packetType, int versionNumber,
|
||||
QuicConnectionId srcConnectionId,
|
||||
QuicConnectionId destConnectionId) {
|
||||
assertEquals(QuicPacketDecoder.peekHeaderType(datagram, offset), HeadersType.LONG);
|
||||
assertEquals(QuicPacketDecoder.of(datagram, offset).peekPacketType(datagram, offset), packetType);
|
||||
assertEquals(HeadersType.LONG, QuicPacketDecoder.peekHeaderType(datagram, offset));
|
||||
assertEquals(packetType, QuicPacketDecoder.of(datagram, offset).peekPacketType(datagram, offset));
|
||||
LongHeader header = QuicPacketDecoder.peekLongHeader(datagram, offset);
|
||||
assertNotNull(header, "Could not parse packet header");
|
||||
assertEquals(header.version(), versionNumber);
|
||||
assertEquals(versionNumber, header.version());
|
||||
assertTrue(header.destinationId()
|
||||
.matches(destConnectionId.asReadOnlyBuffer()), "Destination ID doesn't match");
|
||||
assertTrue(header.sourceId()
|
||||
@ -494,10 +493,10 @@ public class PacketEncodingTest {
|
||||
padding.encode(buf);
|
||||
}
|
||||
if (insert) {
|
||||
assertEquals(buf.position(), remaining);
|
||||
assertEquals(buf.remaining(), payloadSize - remaining);
|
||||
assertEquals(remaining, buf.position());
|
||||
assertEquals(payloadSize - remaining, buf.remaining());
|
||||
} else {
|
||||
assertEquals(buf.remaining(), 0);
|
||||
assertEquals(0, buf.remaining());
|
||||
}
|
||||
return List.copyOf(frames);
|
||||
}
|
||||
@ -507,7 +506,7 @@ public class PacketEncodingTest {
|
||||
int size = outgoingQuicPacket.size();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(size);
|
||||
encoder.encode(outgoingQuicPacket, buffer, context);
|
||||
assertEquals(buffer.position(), size, " for " + outgoingQuicPacket);
|
||||
assertEquals(size, buffer.position(), " for " + outgoingQuicPacket);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
@ -520,33 +519,34 @@ public class PacketEncodingTest {
|
||||
List<QuicFrame> payload,
|
||||
int minSize) {
|
||||
// Check created packet
|
||||
assertEquals(packet.headersType(), HeadersType.SHORT);
|
||||
assertEquals(packet.packetType(), packetType);
|
||||
assertEquals(packet.hasLength(), false);
|
||||
assertEquals(packet.numberSpace(), packetNumberSpace);
|
||||
assertEquals(getBuffers(packet.frames()), getBuffers(payload, minSize));
|
||||
assertEquals(packet.packetNumber(), packetNumber);
|
||||
assertEquals(packet.destinationId(), destConnectionId);
|
||||
assertEquals(HeadersType.SHORT, packet.headersType());
|
||||
assertEquals(packetType, packet.packetType());
|
||||
assertEquals(false, packet.hasLength());
|
||||
assertEquals(packetNumberSpace, packet.numberSpace());
|
||||
assertEquals(getBuffers(payload, minSize), getBuffers(packet.frames()));
|
||||
assertEquals(packetNumber, packet.packetNumber());
|
||||
assertEquals(destConnectionId, packet.destinationId());
|
||||
}
|
||||
|
||||
private void checkShortHeaderPacketAt(ByteBuffer datagram, int offset,
|
||||
PacketType packetType,
|
||||
QuicConnectionId destConnectionId,
|
||||
CodingContext context) {
|
||||
assertEquals(QuicPacketDecoder.peekHeaderType(datagram, offset), HeadersType.SHORT);
|
||||
assertEquals(QuicPacketDecoder.of(QuicVersion.QUIC_V1).peekPacketType(datagram, offset), packetType);
|
||||
assertEquals(QuicPacketDecoder.peekVersion(datagram, offset), 0);
|
||||
assertEquals(HeadersType.SHORT, QuicPacketDecoder.peekHeaderType(datagram, offset));
|
||||
assertEquals(packetType, QuicPacketDecoder.of(QuicVersion.QUIC_V1).peekPacketType(datagram, offset));
|
||||
assertEquals(0, QuicPacketDecoder.peekVersion(datagram, offset));
|
||||
int pos = datagram.position();
|
||||
if (pos != offset) datagram.position(offset);
|
||||
try {
|
||||
assertEquals(QuicPacketDecoder.peekShortConnectionId(datagram, destConnectionId.length())
|
||||
.mismatch(destConnectionId.asReadOnlyBuffer()), -1);
|
||||
assertEquals(-1, QuicPacketDecoder.peekShortConnectionId(datagram, destConnectionId.length())
|
||||
.mismatch(destConnectionId.asReadOnlyBuffer()));
|
||||
} finally {
|
||||
if (pos != offset) datagram.position(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longHeaderPacketProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("longHeaderPacketProvider")
|
||||
public void testInitialPacket(QuicVersion quicVersion, int srcIdLength, int destIdLength,
|
||||
long packetNumber, long largestAcked) throws Exception {
|
||||
System.out.printf("%ntestInitialPacket(qv:%s, scid:%d, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -557,12 +557,12 @@ public class PacketEncodingTest {
|
||||
.newConnectionId(destIdLength, IDS.incrementAndGet());
|
||||
assert destid.length <= 20;
|
||||
final QuicConnectionId destConnectionId = new PeerConnectionId(destid);
|
||||
assertEquals(destid.length, destConnectionId.length(), "dcid length");
|
||||
assertEquals(destConnectionId.length(), destid.length, "dcid length");
|
||||
destIdLength = destid.length;
|
||||
|
||||
byte[] srcid = randomIdBytes(srcIdLength);
|
||||
final QuicConnectionId srcConnectionId = new PeerConnectionId(srcid);
|
||||
assertEquals(srcid.length, srcConnectionId.length(), "scid length");
|
||||
assertEquals(srcConnectionId.length(), srcid.length, "scid length");
|
||||
|
||||
int bound = MAX_DATAGRAM_IPV6 - srcIdLength - destid.length - 7
|
||||
- QuicPacketNumbers.computePacketNumberLength(packetNumber, largestAcked)
|
||||
@ -603,8 +603,8 @@ public class PacketEncodingTest {
|
||||
|
||||
byte[] payload = new byte[payloadSize];
|
||||
List<QuicFrame> frames = frames(payload, padding != 0);
|
||||
assertEquals(frames.stream().mapToInt(QuicFrame::size)
|
||||
.reduce(0, Math::addExact), payloadSize);
|
||||
assertEquals(payloadSize, frames.stream().mapToInt(QuicFrame::size)
|
||||
.reduce(0, Math::addExact));
|
||||
|
||||
|
||||
// Create an initial packet
|
||||
@ -626,7 +626,7 @@ public class PacketEncodingTest {
|
||||
largestAcked,
|
||||
frames2,
|
||||
context);
|
||||
assertEquals(padding, padding + (1200 - packet2.size()));
|
||||
assertEquals(padding + (1200 - packet2.size()), padding);
|
||||
}
|
||||
|
||||
// Check created packet
|
||||
@ -640,10 +640,10 @@ public class PacketEncodingTest {
|
||||
checkLongHeaderPacket(initialPacket, PacketType.INITIAL, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.INITIAL, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames, padding);
|
||||
assertEquals(initialPacket.tokenLength(), tokenLength);
|
||||
assertEquals(initialPacket.token(), token);
|
||||
assertEquals(initialPacket.hasLength(), true);
|
||||
assertEquals(initialPacket.length(), packetNumberLength + payloadSize + padding);
|
||||
assertEquals(tokenLength, initialPacket.tokenLength());
|
||||
assertEquals(token, initialPacket.token());
|
||||
assertEquals(true, initialPacket.hasLength());
|
||||
assertEquals(packetNumberLength + payloadSize + padding, initialPacket.length());
|
||||
|
||||
// Check that peeking at the encoded packet returns correct information
|
||||
|
||||
@ -682,9 +682,9 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(datagram.capacity());
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), second);
|
||||
assertEquals(second, datagram.position());
|
||||
decoder.skipPacket(datagram, second);
|
||||
assertEquals(datagram.remaining(), offset);
|
||||
assertEquals(offset, datagram.remaining());
|
||||
|
||||
datagram.position(offset);
|
||||
int size = second - offset;
|
||||
@ -692,23 +692,24 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof InitialPacket, "decoded: " + decodedPacket);
|
||||
InitialPacket initialDecoded = InitialPacket.class.cast(decodedPacket);
|
||||
checkLongHeaderPacket(initialDecoded, PacketType.INITIAL, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.INITIAL, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames, padding);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(initialDecoded.tokenLength(), tokenLength);
|
||||
assertEquals(initialDecoded.token(), token);
|
||||
assertEquals(initialDecoded.length(), initialPacket.length());
|
||||
assertEquals(initialDecoded.length(), packetNumberLength + payloadSize + padding);
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
assertEquals(tokenLength, initialDecoded.tokenLength());
|
||||
assertArrayEquals(token, initialDecoded.token());
|
||||
assertEquals(initialPacket.length(), initialDecoded.length());
|
||||
assertEquals(packetNumberLength + payloadSize + padding, initialDecoded.length());
|
||||
}
|
||||
assertEquals(datagram.position(), second + second - offset);
|
||||
assertEquals(second + second - offset, datagram.position());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longHeaderPacketProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("longHeaderPacketProvider")
|
||||
public void testHandshakePacket(QuicVersion quicVersion, int srcIdLength, int destIdLength,
|
||||
long packetNumber, long largestAcked) throws Exception {
|
||||
System.out.printf("%ntestHandshakePacket(qv:%s, scid:%d, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -757,8 +758,8 @@ public class PacketEncodingTest {
|
||||
checkLongHeaderPacket(handshakePacket, PacketType.HANDSHAKE, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.HANDSHAKE, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames);
|
||||
assertEquals(handshakePacket.hasLength(), true);
|
||||
assertEquals(handshakePacket.length(), packetNumberLength + payloadSize);
|
||||
assertEquals(true, handshakePacket.hasLength());
|
||||
assertEquals(packetNumberLength + payloadSize, handshakePacket.length());
|
||||
|
||||
// Decode the two packets in the datagram
|
||||
// Check that peeking at the encoded packet returns correct information
|
||||
@ -797,9 +798,9 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(datagram.capacity());
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), second);
|
||||
assertEquals(second, datagram.position());
|
||||
decoder.skipPacket(datagram, second);
|
||||
assertEquals(datagram.remaining(), offset);
|
||||
assertEquals(offset, datagram.remaining());
|
||||
|
||||
datagram.position(offset);
|
||||
int size = second - offset;
|
||||
@ -807,21 +808,22 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof HandshakePacket, "decoded: " + decodedPacket);
|
||||
HandshakePacket handshakeDecoded = HandshakePacket.class.cast(decodedPacket);
|
||||
checkLongHeaderPacket(handshakeDecoded, PacketType.HANDSHAKE, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.HANDSHAKE, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(handshakeDecoded.length(), handshakePacket.length());
|
||||
assertEquals(handshakeDecoded.length(), packetNumberLength + payloadSize);
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
assertEquals(handshakePacket.length(), handshakeDecoded.length());
|
||||
assertEquals(packetNumberLength + payloadSize, handshakeDecoded.length());
|
||||
}
|
||||
assertEquals(datagram.position(), second + second - offset);
|
||||
assertEquals(second + second - offset, datagram.position());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longHeaderPacketProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("longHeaderPacketProvider")
|
||||
public void testZeroRTTPacket(QuicVersion quicVersion, int srcIdLength, int destIdLength,
|
||||
long packetNumber, long largestAcked) throws Exception {
|
||||
System.out.printf("%ntestZeroRTTPacket(qv:%s, scid:%d, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -870,8 +872,8 @@ public class PacketEncodingTest {
|
||||
checkLongHeaderPacket(zeroRttPacket, PacketType.ZERORTT, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.APPLICATION, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames);
|
||||
assertEquals(zeroRttPacket.hasLength(), true);
|
||||
assertEquals(zeroRttPacket.length(), packetNumberLength + payloadSize);
|
||||
assertEquals(true, zeroRttPacket.hasLength());
|
||||
assertEquals(packetNumberLength + payloadSize, zeroRttPacket.length());
|
||||
|
||||
// Check that peeking at the encoded packet returns correct information
|
||||
ByteBuffer encoded = toByteBuffer(encoder, packet, context);
|
||||
@ -909,9 +911,9 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(datagram.capacity());
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), second);
|
||||
assertEquals(second, datagram.position());
|
||||
decoder.skipPacket(datagram, second);
|
||||
assertEquals(datagram.remaining(), offset);
|
||||
assertEquals(offset, datagram.remaining());
|
||||
|
||||
// Decode the two packets in the datagram
|
||||
datagram.position(offset);
|
||||
@ -920,21 +922,22 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof ZeroRttPacket, "decoded: " + decodedPacket);
|
||||
ZeroRttPacket zeroRttDecoded = ZeroRttPacket.class.cast(decodedPacket);
|
||||
checkLongHeaderPacket(zeroRttDecoded, PacketType.ZERORTT, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.APPLICATION, packetNumber,
|
||||
srcConnectionId, destConnectionId, frames);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(zeroRttDecoded.length(), zeroRttPacket.length());
|
||||
assertEquals(zeroRttDecoded.length(), packetNumberLength + payloadSize);
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
assertEquals(zeroRttPacket.length(), zeroRttDecoded.length());
|
||||
assertEquals(packetNumberLength + payloadSize, zeroRttDecoded.length());
|
||||
}
|
||||
assertEquals(datagram.position(), second + second - offset);
|
||||
assertEquals(second + second - offset, datagram.position());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "versionAndRetryProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("versionAndRetryProvider")
|
||||
public void testVersionNegotiationPacket(QuicVersion quicVersion, int srcIdLength, int destIdLength)
|
||||
throws Exception {
|
||||
System.out.printf("%ntestVersionNegotiationPacket(qv:%s, scid:%d, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -965,9 +968,9 @@ public class PacketEncodingTest {
|
||||
checkLongHeaderPacket(versionPacket, PacketType.VERSIONS, 0,
|
||||
PacketNumberSpace.NONE, -1,
|
||||
srcConnectionId, destConnectionId, null);
|
||||
assertEquals(versionPacket.hasLength(), false);
|
||||
assertEquals(versionPacket.supportedVersions(),
|
||||
versionList.stream().mapToInt(Integer::intValue).toArray());
|
||||
assertEquals(false, versionPacket.hasLength());
|
||||
assertArrayEquals(versionList.stream().mapToInt(Integer::intValue).toArray(),
|
||||
versionPacket.supportedVersions());
|
||||
|
||||
CodingContext context = new TestCodingContext() {
|
||||
@Override public long largestProcessedPN(PacketNumberSpace packetSpace) {
|
||||
@ -1009,8 +1012,8 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(datagram.capacity());
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), end);
|
||||
assertEquals(datagram.remaining(), 0);
|
||||
assertEquals(end, datagram.position());
|
||||
assertEquals(0, datagram.remaining());
|
||||
|
||||
// Decode the two packets in the datagram
|
||||
datagram.position(offset);
|
||||
@ -1019,21 +1022,22 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof VersionNegotiationPacket, "decoded: " + decodedPacket);
|
||||
VersionNegotiationPacket decodedVersion = VersionNegotiationPacket.class.cast(decodedPacket);
|
||||
checkLongHeaderPacket(decodedVersion, PacketType.VERSIONS, 0,
|
||||
PacketNumberSpace.NONE, -1,
|
||||
srcConnectionId, destConnectionId, null);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(decodedVersion.supportedVersions(),
|
||||
versionList.stream().mapToInt(Integer::intValue).toArray());
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
assertArrayEquals(versionList.stream().mapToInt(Integer::intValue).toArray(),
|
||||
decodedVersion.supportedVersions());
|
||||
}
|
||||
assertEquals(datagram.position(), end);
|
||||
assertEquals(end, datagram.position());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "versionAndRetryProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("versionAndRetryProvider")
|
||||
public void testRetryPacket(QuicVersion quicVersion, int srcIdLength, int destIdLength)
|
||||
throws Exception {
|
||||
System.out.printf("%ntestRetryPacket(qv:%s, scid:%d, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -1067,9 +1071,9 @@ public class PacketEncodingTest {
|
||||
checkLongHeaderPacket(retryPacket, PacketType.RETRY, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.NONE, -1,
|
||||
srcConnectionId, destConnectionId, null);
|
||||
assertEquals(retryPacket.hasLength(), false);
|
||||
assertEquals(retryPacket.retryToken(), retryToken);
|
||||
assertEquals(retryPacket.size(), expectedSize);
|
||||
assertEquals(false, retryPacket.hasLength());
|
||||
assertArrayEquals(retryToken, retryPacket.retryToken());
|
||||
assertEquals(expectedSize, retryPacket.size());
|
||||
|
||||
CodingContext context = new TestCodingContext() {
|
||||
@Override public long largestProcessedPN(PacketNumberSpace packetSpace) {
|
||||
@ -1112,8 +1116,8 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(datagram.capacity());
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), end);
|
||||
assertEquals(datagram.remaining(), 0);
|
||||
assertEquals(end, datagram.position());
|
||||
assertEquals(0, datagram.remaining());
|
||||
|
||||
// Decode the two packets in the datagram
|
||||
datagram.position(offset);
|
||||
@ -1122,21 +1126,22 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof RetryPacket, "decoded: " + decodedPacket);
|
||||
RetryPacket decodedRetry = RetryPacket.class.cast(decodedPacket);
|
||||
checkLongHeaderPacket(decodedRetry, PacketType.RETRY, quicVersion.versionNumber(),
|
||||
PacketNumberSpace.NONE, -1,
|
||||
srcConnectionId, destConnectionId, null);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(decodedPacket.size(), expectedSize);
|
||||
assertEquals(decodedRetry.retryToken(), retryToken);
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
assertEquals(expectedSize, decodedPacket.size());
|
||||
assertArrayEquals(retryToken, decodedRetry.retryToken());
|
||||
}
|
||||
assertEquals(datagram.position(), end);
|
||||
assertEquals(end, datagram.position());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortHeaderPacketProvider")
|
||||
@ParameterizedTest
|
||||
@MethodSource("shortHeaderPacketProvider")
|
||||
public void testOneRTTPacket(QuicVersion quicVersion, int destIdLength,
|
||||
long packetNumber, long largestAcked) throws Exception {
|
||||
System.out.printf("%ntestOneRTTPacket(qv:%s, dcid:%d, pn:%d, ack:%d)%n",
|
||||
@ -1186,8 +1191,8 @@ public class PacketEncodingTest {
|
||||
checkShortHeaderPacket(packet, PacketType.ONERTT,
|
||||
PacketNumberSpace.APPLICATION, packetNumber,
|
||||
destConnectionId, frames, minPayloadSize);
|
||||
assertEquals(packet.hasLength(), false);
|
||||
assertEquals(packet.size(), expectedSize);
|
||||
assertEquals(false, packet.hasLength());
|
||||
assertEquals(expectedSize, packet.size());
|
||||
|
||||
// Check that peeking at the encoded packet returns correct information
|
||||
ByteBuffer encoded = toByteBuffer(encoder, packet, context);
|
||||
@ -1218,9 +1223,9 @@ public class PacketEncodingTest {
|
||||
datagram.position(0);
|
||||
datagram.limit(end);
|
||||
decoder.skipPacket(datagram, offset);
|
||||
assertEquals(datagram.position(), offset + expectedSize);
|
||||
assertEquals(datagram.position(), datagram.limit());
|
||||
assertEquals(datagram.position(), datagram.capacity() - offset);
|
||||
assertEquals(offset + expectedSize, datagram.position());
|
||||
assertEquals(datagram.limit(), datagram.position());
|
||||
assertEquals(datagram.capacity() - offset, datagram.position());
|
||||
|
||||
|
||||
// Decode the packet in the datagram
|
||||
@ -1230,7 +1235,7 @@ public class PacketEncodingTest {
|
||||
int pos = datagram.position();
|
||||
System.out.printf("Decoding packet: %d at %d%n", (i+1), pos);
|
||||
var decodedPacket = decoder.decode(datagram, context);
|
||||
assertEquals(datagram.position(), pos + size);
|
||||
assertEquals(pos + size, datagram.position());
|
||||
assertTrue(decodedPacket instanceof OneRttPacket, "decoded: " + decodedPacket);
|
||||
OneRttPacket oneRttDecoded = OneRttPacket.class.cast(decodedPacket);
|
||||
List<QuicFrame> expectedFrames = frames;
|
||||
@ -1258,12 +1263,12 @@ public class PacketEncodingTest {
|
||||
checkShortHeaderPacket(oneRttDecoded, PacketType.ONERTT,
|
||||
PacketNumberSpace.APPLICATION, packetNumber,
|
||||
destConnectionId, expectedFrames, minPayloadSize);
|
||||
assertEquals(decodedPacket.size(), packet.size());
|
||||
assertEquals(decodedPacket.size(), size);
|
||||
assertEquals(packet.size(), decodedPacket.size());
|
||||
assertEquals(size, decodedPacket.size());
|
||||
}
|
||||
assertEquals(datagram.position(), offset + size);
|
||||
assertEquals(datagram.remaining(), 0);
|
||||
assertEquals(datagram.limit(), end);
|
||||
assertEquals(offset + size, datagram.position());
|
||||
assertEquals(0, datagram.remaining());
|
||||
assertEquals(end, datagram.limit());
|
||||
|
||||
}
|
||||
|
||||
@ -1299,15 +1304,15 @@ public class PacketEncodingTest {
|
||||
ByteBuffer.wrap(new byte[] {16, 17}),
|
||||
ByteBuffer.wrap(new byte[] {18, 19, 20})
|
||||
);
|
||||
assertEquals(Utils.mismatch(match1, match1), -1);
|
||||
assertEquals(Utils.mismatch(match2, match2), -1);
|
||||
assertEquals(Utils.mismatch(match3, match3), -1);
|
||||
assertEquals(Utils.mismatch(match1, match2), -1);
|
||||
assertEquals(Utils.mismatch(match2, match1), -1);
|
||||
assertEquals(Utils.mismatch(match1, match3), -1);
|
||||
assertEquals(Utils.mismatch(match3, match1), -1);
|
||||
assertEquals(Utils.mismatch(match2, match3), -1);
|
||||
assertEquals(Utils.mismatch(match3, match2), -1);
|
||||
assertEquals(-1, Utils.mismatch(match1, match1));
|
||||
assertEquals(-1, Utils.mismatch(match2, match2));
|
||||
assertEquals(-1, Utils.mismatch(match3, match3));
|
||||
assertEquals(-1, Utils.mismatch(match1, match2));
|
||||
assertEquals(-1, Utils.mismatch(match2, match1));
|
||||
assertEquals(-1, Utils.mismatch(match1, match3));
|
||||
assertEquals(-1, Utils.mismatch(match3, match1));
|
||||
assertEquals(-1, Utils.mismatch(match2, match3));
|
||||
assertEquals(-1, Utils.mismatch(match3, match2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1413,25 +1418,25 @@ public class PacketEncodingTest {
|
||||
ByteBuffer.wrap(new byte[] {18, 19, 20, 41, 42, 43})
|
||||
);
|
||||
|
||||
assertEquals(Utils.mismatch(nomatch0, nomatch0), -1L);
|
||||
assertEquals(Utils.mismatch(nomatch10, nomatch10), -1L);
|
||||
assertEquals(Utils.mismatch(nomatch19, nomatch19), -1L);
|
||||
assertEquals(Utils.mismatch(morematch1, morematch1), -1L);
|
||||
assertEquals(Utils.mismatch(morematch2, morematch2), -1L);
|
||||
assertEquals(Utils.mismatch(morematch3, morematch3), -1L);
|
||||
assertEquals(Utils.mismatch(morematch2, morematch3), -1L);
|
||||
assertEquals(Utils.mismatch(morematch3, morematch2), -1L);
|
||||
assertEquals(-1L, Utils.mismatch(nomatch0, nomatch0));
|
||||
assertEquals(-1L, Utils.mismatch(nomatch10, nomatch10));
|
||||
assertEquals(-1L, Utils.mismatch(nomatch19, nomatch19));
|
||||
assertEquals(-1L, Utils.mismatch(morematch1, morematch1));
|
||||
assertEquals(-1L, Utils.mismatch(morematch2, morematch2));
|
||||
assertEquals(-1L, Utils.mismatch(morematch3, morematch3));
|
||||
assertEquals(-1L, Utils.mismatch(morematch2, morematch3));
|
||||
assertEquals(-1L, Utils.mismatch(morematch3, morematch2));
|
||||
|
||||
for (var match : List.of(match1, match2, match3)) {
|
||||
assertEquals(Utils.mismatch(match, nomatch0), 0L);
|
||||
assertEquals(Utils.mismatch(match, nomatch10), 10L);
|
||||
assertEquals(Utils.mismatch(match, nomatch19), 19L);
|
||||
assertEquals(Utils.mismatch(nomatch0, match), 0L);
|
||||
assertEquals(Utils.mismatch(nomatch10, match), 10L);
|
||||
assertEquals(Utils.mismatch(nomatch19, match), 19L);
|
||||
assertEquals(0L, Utils.mismatch(match, nomatch0));
|
||||
assertEquals(10L, Utils.mismatch(match, nomatch10));
|
||||
assertEquals(19L, Utils.mismatch(match, nomatch19));
|
||||
assertEquals(0L, Utils.mismatch(nomatch0, match));
|
||||
assertEquals(10L, Utils.mismatch(nomatch10, match));
|
||||
assertEquals(19L, Utils.mismatch(nomatch19, match));
|
||||
for (var morematch : List.of(morematch1, morematch2, morematch3)) {
|
||||
assertEquals(Utils.mismatch(match, morematch), 20L);
|
||||
assertEquals(Utils.mismatch(morematch, match), 20L);
|
||||
assertEquals(20L, Utils.mismatch(match, morematch));
|
||||
assertEquals(20L, Utils.mismatch(morematch, match));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,16 +27,17 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.net.http.quic.packets.QuicPacketNumbers;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.expectThrows;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @run testng PacketNumbersTest
|
||||
* @run junit PacketNumbersTest
|
||||
*/
|
||||
public class PacketNumbersTest {
|
||||
|
||||
@ -85,8 +86,7 @@ public class PacketNumbersTest {
|
||||
}
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] encode() {
|
||||
public static Object[][] encode() {
|
||||
return List.of(
|
||||
// these first three test cases are extracted from RFC 9000, appendix A.2 and A.3
|
||||
new TestCase("success", 0xa82f9b32L, 0xa82f30eaL, EncodeResult.success(0x9b32)),
|
||||
@ -127,19 +127,18 @@ public class PacketNumbersTest {
|
||||
.toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "encode")
|
||||
@ParameterizedTest
|
||||
@MethodSource("encode")
|
||||
public void testEncodePacketNumber(TestCase test) {
|
||||
System.out.println(test);
|
||||
if (test.result().assertion()) {
|
||||
if (!QuicPacketNumbers.class.desiredAssertionStatus()) {
|
||||
throw new SkipException("needs assertion enabled (-esa)");
|
||||
}
|
||||
Throwable t = expectThrows(test.result().failure(), test::encode);
|
||||
Assumptions.assumeFalse(!QuicPacketNumbers.class.desiredAssertionStatus(), "needs assertion enabled (-esa)");
|
||||
Throwable t = Assertions.assertThrows(test.result().failure(), test::encode);
|
||||
System.out.println("Got expected assertion: " + t);
|
||||
return;
|
||||
}
|
||||
if (test.result().fail()) {
|
||||
Throwable t = expectThrows(test.result().failure(), test::encode);
|
||||
Throwable t = Assertions.assertThrows(test.result().failure(), test::encode);
|
||||
System.out.println("Got expected exception: " + t);
|
||||
return;
|
||||
|
||||
@ -152,8 +151,8 @@ public class PacketNumbersTest {
|
||||
}
|
||||
|
||||
// encode the full PN - check that the truncated PN == expected
|
||||
assertEquals(truncated, test.result().expected());
|
||||
assertEquals(test.result().expected(), truncated);
|
||||
// check that decode(encoded) == fullPN
|
||||
assertEquals(test.decode(), test.fullPN());
|
||||
assertEquals(test.fullPN(), test.decode());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -73,34 +73,35 @@ import jdk.internal.net.quic.QuicVersion;
|
||||
import jdk.internal.net.quic.QuicTransportException;
|
||||
import jdk.internal.net.quic.QuicTransportParametersConsumer;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary tests the logic to build an AckFrame
|
||||
* @library /test/lib
|
||||
* @library ../debug
|
||||
* @build java.net.http/jdk.internal.net.http.common.TestLoggerUtil
|
||||
* @run testng/othervm PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=-7947549564260911920 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=-5413111674202728207 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=-176652423987357212 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=6550551791799910315 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=-4159871071396382784 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=2252276218459363615 PacketSpaceManagerTest
|
||||
* @run testng/othervm -Dseed=-5130588140709404919 PacketSpaceManagerTest
|
||||
* @run junit/othervm PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=-7947549564260911920 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=-5413111674202728207 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=-176652423987357212 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=6550551791799910315 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=-4159871071396382784 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=2252276218459363615 PacketSpaceManagerTest
|
||||
* @run junit/othervm -Dseed=-5130588140709404919 PacketSpaceManagerTest
|
||||
*/
|
||||
// -Djdk.internal.httpclient.debug=true
|
||||
public class PacketSpaceManagerTest {
|
||||
@ -337,7 +338,7 @@ public class PacketSpaceManagerTest {
|
||||
* @param first the first packet acknowledged, inclusive
|
||||
* @param last the last packet acknowledged, inclusive
|
||||
*/
|
||||
public static record Acknowledged(long first, long last) {
|
||||
public record Acknowledged(long first, long last) {
|
||||
public Acknowledged {
|
||||
assert first >= 0 && first <= last;
|
||||
}
|
||||
@ -360,7 +361,7 @@ public class PacketSpaceManagerTest {
|
||||
* @param packetNumber the packet number of the packet to send
|
||||
* @param delay a delay before the next packet should be emitted
|
||||
*/
|
||||
public static record Packet(long packetNumber, long delay) {
|
||||
public record Packet(long packetNumber, long delay) {
|
||||
Packet(long packetNumber) {
|
||||
this(packetNumber, RANDOM.nextLong(1, 255));
|
||||
}
|
||||
@ -391,7 +392,7 @@ public class PacketSpaceManagerTest {
|
||||
* before it's been emitted).
|
||||
* @param shuffled whether the list of packets is shuffled.
|
||||
*/
|
||||
public static record TestCase(List<Acknowledged> acks,
|
||||
public record TestCase(List<Acknowledged> acks,
|
||||
List<Packet> packets,
|
||||
List<AckFrame> ackframes,
|
||||
boolean shuffled) {
|
||||
@ -440,7 +441,7 @@ public class PacketSpaceManagerTest {
|
||||
* a list of special testcases, and a list of random testcases.
|
||||
* @return A list of TestCases to test.
|
||||
*/
|
||||
List<TestCase> generateTests() {
|
||||
static List<TestCase> generateTests() {
|
||||
List<TestCase> tests = new ArrayList<>();
|
||||
List<TestCase> simples = List.of(
|
||||
new TestCase(List.of(new Acknowledged(5,5))),
|
||||
@ -485,7 +486,7 @@ public class PacketSpaceManagerTest {
|
||||
* A packet should only be present once.
|
||||
* @return a random list of increasing acknowledgement ranges.
|
||||
*/
|
||||
List<Acknowledged> generateAcks() {
|
||||
static List<Acknowledged> generateAcks() {
|
||||
int count = RANDOM.nextInt(3, 10);
|
||||
List<Acknowledged> acks = new ArrayList<>(count);
|
||||
long prev = -1;
|
||||
@ -516,8 +517,7 @@ public class PacketSpaceManagerTest {
|
||||
return res;
|
||||
}
|
||||
|
||||
@DataProvider(name = "tests")
|
||||
public Object[][] tests() {
|
||||
public static Object[][] tests() {
|
||||
return generateTests().stream()
|
||||
.map(List::of)
|
||||
.map(List::toArray)
|
||||
@ -757,7 +757,7 @@ public class PacketSpaceManagerTest {
|
||||
final CopyOnWriteArrayList<Retransmission> retransmissions = new CopyOnWriteArrayList<>();
|
||||
final CopyOnWriteArrayList<Retransmission> successfulExpectations = new CopyOnWriteArrayList<>();
|
||||
|
||||
static record Retransmission(long packetNumber, Deadline atOrAfter, long largestAckSent) {
|
||||
record Retransmission(long packetNumber, Deadline atOrAfter, long largestAckSent) {
|
||||
boolean isFor(long number) {
|
||||
return number == packetNumber;
|
||||
}
|
||||
@ -774,7 +774,7 @@ public class PacketSpaceManagerTest {
|
||||
* the test.
|
||||
* This method checks that the retransmission logic works as
|
||||
* expected.
|
||||
* @throws Exception
|
||||
* @throws Exception if the call fails
|
||||
*/
|
||||
// TODO: in the end we need to check that everything that was
|
||||
// expected to happen happened. What is missing is to
|
||||
@ -890,7 +890,7 @@ public class PacketSpaceManagerTest {
|
||||
.stream().filter(AckFrame.class::isInstance)
|
||||
.map(AckFrame.class::cast)
|
||||
.toList();
|
||||
assertEquals(frames.size(), 1,
|
||||
assertEquals(1, frames.size(),
|
||||
"unexpected ack frames: " + frames);
|
||||
AckFrame ackFrame = ackFrames.get(0);
|
||||
LongStream.range(firstAckPaket, lastAckPacket + 1)
|
||||
@ -1029,10 +1029,11 @@ public class PacketSpaceManagerTest {
|
||||
void check() {
|
||||
assertFalse(now().isBefore(timeSource.first.plusMillis(timeline)));
|
||||
assertTrue(expectedRetransmissions.isEmpty());
|
||||
assertEquals(retransmissions.stream()
|
||||
assertEquals(successfulExpectations.stream()
|
||||
.map(Retransmission::packetNumber)
|
||||
.filter(pn -> pn <= maxPacketNumber).toList(),
|
||||
successfulExpectations.stream().map(Retransmission::packetNumber)
|
||||
retransmissions.stream()
|
||||
.map(Retransmission::packetNumber)
|
||||
.filter(pn -> pn <= maxPacketNumber).toList());
|
||||
for (Retransmission r : retransmissions) {
|
||||
if (r.packetNumber > maxPacketNumber ||
|
||||
@ -1040,14 +1041,14 @@ public class PacketSpaceManagerTest {
|
||||
List<Retransmission> succesful = successfulExpectations.stream()
|
||||
.filter(s -> s.isFor(r.packetNumber))
|
||||
.toList();
|
||||
assertEquals(succesful.size(), 1);
|
||||
assertEquals(1, succesful.size());
|
||||
succesful.forEach(s -> assertFalse(s.atOrAfter.isAfter(r.atOrAfter)));
|
||||
}
|
||||
|
||||
List<Long> acknowledged = new ArrayList<>(acknowledgePackets(allAcks.build()));
|
||||
Collections.sort(acknowledged);
|
||||
assertEquals(acknowledged, test.packets.stream()
|
||||
.map(Packet::packetNumber).sorted().toList());
|
||||
assertEquals(test.packets.stream()
|
||||
.map(Packet::packetNumber).sorted().toList(), acknowledged);
|
||||
}
|
||||
|
||||
// TODO: add a LongStream acknowledged() to AckFrame - write a spliterator
|
||||
@ -1073,8 +1074,8 @@ public class PacketSpaceManagerTest {
|
||||
default String negation() {
|
||||
return (this == FALSE) ? "doesn't " : "";
|
||||
}
|
||||
Assertion TRUE = Assert::assertTrue;
|
||||
Assertion FALSE = Assert::assertFalse;
|
||||
Assertion TRUE = Assertions::assertTrue;
|
||||
Assertion FALSE = Assertions::assertFalse;
|
||||
}
|
||||
static void assertContains(Assertion assertion, List<Long> list, long number, String desc) {
|
||||
assertion.check(list.contains(number),
|
||||
@ -1115,7 +1116,8 @@ public class PacketSpaceManagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "tests")
|
||||
@ParameterizedTest
|
||||
@MethodSource("tests")
|
||||
public void testPacketSpaceManager(TestCase testCase) throws Exception {
|
||||
System.out.printf("%n ------- testPacketSpaceManager ------- %n");
|
||||
SynchronousTestDriver driver = new SynchronousTestDriver(testCase);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,20 +24,20 @@
|
||||
import jdk.internal.net.http.quic.frames.QuicFrame;
|
||||
import jdk.internal.net.quic.QuicTransportErrors;
|
||||
import jdk.internal.net.quic.QuicTransportException;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HexFormat;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @summary Tests to check QUIC frame decoding errors are handled correctly
|
||||
* @run testng/othervm QuicFramesDecoderTest
|
||||
* @run junit/othervm QuicFramesDecoderTest
|
||||
*/
|
||||
public class QuicFramesDecoderTest {
|
||||
|
||||
@ -181,7 +181,6 @@ public class QuicFramesDecoderTest {
|
||||
private static final byte[] NEW_CONNECTION_ID_ZERO = HexFormat.of().parseHex("181716"+
|
||||
"00"+"0f0e0d0c0b0a09080706050403020100");
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] goodFrames() {
|
||||
return new Object[][]{
|
||||
new Object[]{"ack without ecn", ACK_BASE, false},
|
||||
@ -226,7 +225,6 @@ public class QuicFramesDecoderTest {
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] badFrames() {
|
||||
return new Object[][]{
|
||||
new Object[]{"ack without ecn, negative pn", ACK_NEG_BASE},
|
||||
@ -242,7 +240,8 @@ public class QuicFramesDecoderTest {
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "goodFrames")
|
||||
@ParameterizedTest
|
||||
@MethodSource("goodFrames")
|
||||
public void testReencode(String desc, byte[] frame, boolean bloated) throws Exception {
|
||||
// check if the goodFrames provider indeed contains good frames
|
||||
ByteBuffer buf = ByteBuffer.wrap(frame);
|
||||
@ -250,16 +249,17 @@ public class QuicFramesDecoderTest {
|
||||
assertFalse(buf.hasRemaining(), buf.remaining() + " bytes left in buffer after parsing");
|
||||
// some frames deliberately use suboptimal encoding, skip them
|
||||
if (bloated) return;
|
||||
assertEquals(qf.size(), frame.length, "Frame size mismatch");
|
||||
assertEquals(frame.length, qf.size(), "Frame size mismatch");
|
||||
buf.clear();
|
||||
ByteBuffer encoded = ByteBuffer.allocate(frame.length);
|
||||
qf.encode(encoded);
|
||||
assertFalse(encoded.hasRemaining(), "Actual frame length mismatch");
|
||||
encoded.flip();
|
||||
assertEquals(buf, encoded, "Encoded buffer is different from the original one");
|
||||
assertEquals(encoded, buf, "Encoded buffer is different from the original one");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "goodFrames")
|
||||
@ParameterizedTest
|
||||
@MethodSource("goodFrames")
|
||||
public void testToString(String desc, byte[] frame, boolean bloated) throws Exception {
|
||||
// check if the goodFrames provider indeed contains good frames
|
||||
ByteBuffer buf = ByteBuffer.wrap(frame);
|
||||
@ -268,7 +268,8 @@ public class QuicFramesDecoderTest {
|
||||
System.out.println(qf); // should not throw
|
||||
}
|
||||
|
||||
@Test(dataProvider = "goodFrames")
|
||||
@ParameterizedTest
|
||||
@MethodSource("goodFrames")
|
||||
public void testTruncatedFrame(String desc, byte[] frame, boolean bloated) throws Exception {
|
||||
// check if parsing a truncated frame throws the right error
|
||||
ByteBuffer buf = ByteBuffer.wrap(frame);
|
||||
@ -279,12 +280,13 @@ public class QuicFramesDecoderTest {
|
||||
var qf = QuicFrame.decode(buf);
|
||||
fail("Expected the decoder to throw on length " + i + ", got: " + qf);
|
||||
} catch (QuicTransportException e) {
|
||||
assertEquals(e.getErrorCode(), QuicTransportErrors.FRAME_ENCODING_ERROR.code());
|
||||
assertEquals(QuicTransportErrors.FRAME_ENCODING_ERROR.code(), e.getErrorCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "badFrames")
|
||||
@ParameterizedTest
|
||||
@MethodSource("badFrames")
|
||||
public void testBadFrame(String desc, byte[] frame) throws Exception {
|
||||
// check if parsing a bad frame throws the right error
|
||||
ByteBuffer buf = ByteBuffer.wrap(frame);
|
||||
@ -292,7 +294,7 @@ public class QuicFramesDecoderTest {
|
||||
var qf = QuicFrame.decode(buf);
|
||||
fail("Expected the decoder to throw, got: "+qf);
|
||||
} catch (QuicTransportException e) {
|
||||
assertEquals(e.getErrorCode(), QuicTransportErrors.FRAME_ENCODING_ERROR.code());
|
||||
assertEquals(QuicTransportErrors.FRAME_ENCODING_ERROR.code(), e.getErrorCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,9 +43,10 @@ import jdk.internal.net.http.quic.QuicClient;
|
||||
import jdk.internal.net.quic.QuicTLSContext;
|
||||
import jdk.internal.net.quic.QuicVersion;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -54,18 +55,18 @@ import org.testng.annotations.Test;
|
||||
* jdk.httpclient.test.lib.quic.ClientConnection
|
||||
* jdk.httpclient.test.lib.common.TestUtil
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true QuicRequestResponseTest
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true QuicRequestResponseTest
|
||||
*/
|
||||
public class QuicRequestResponseTest {
|
||||
|
||||
private QuicStandaloneServer server;
|
||||
private static QuicStandaloneServer server;
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
private ExecutorService executor;
|
||||
private static ExecutorService executor;
|
||||
|
||||
private static final byte[] HELLO_MSG = "Hello Quic".getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
@BeforeClass
|
||||
public void beforeClass() throws Exception {
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
executor = Executors.newCachedThreadPool();
|
||||
server = QuicStandaloneServer.newBuilder()
|
||||
.availableVersions(new QuicVersion[]{QuicVersion.QUIC_V1})
|
||||
@ -77,8 +78,8 @@ public class QuicRequestResponseTest {
|
||||
System.out.println("Server started at " + server.getAddress());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void afterClass() throws Exception {
|
||||
@AfterAll
|
||||
public static void afterClass() throws Exception {
|
||||
if (server != null) {
|
||||
System.out.println("Stopping server " + server.getAddress());
|
||||
server.close();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,32 +22,31 @@
|
||||
*/
|
||||
import jdk.internal.net.http.quic.VariableLengthEncoder;
|
||||
import jtreg.SkippedException;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertThrows;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.expectThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @modules java.net.http/jdk.internal.net.http.quic
|
||||
* @run testng/othervm VariableLengthTest
|
||||
* @run junit/othervm VariableLengthTest
|
||||
* @summary Tests to check quic/util methods encode/decodeVariableLength methods
|
||||
* work as expected.
|
||||
*/
|
||||
public class VariableLengthTest {
|
||||
static final Class<? extends Throwable> IAE = IllegalArgumentException.class;
|
||||
|
||||
@DataProvider(name = "decode invariants")
|
||||
public Object[][] decodeInvariants() {
|
||||
public static Object[][] decodeInvariants() {
|
||||
return new Object[][]
|
||||
{
|
||||
{ new byte[]{7}, 7, 1 }, // 00
|
||||
@ -59,8 +58,7 @@ public class VariableLengthTest {
|
||||
{ new byte[]{-65}, -1, 0 },
|
||||
};
|
||||
}
|
||||
@DataProvider(name = "encode invariants")
|
||||
public Object[][] encodeInvariants() {
|
||||
public static Object[][] encodeInvariants() {
|
||||
return new Object[][]
|
||||
{
|
||||
{ 7, 1, null }, // 00
|
||||
@ -71,8 +69,7 @@ public class VariableLengthTest {
|
||||
{ -1, 0, IAE },
|
||||
};
|
||||
}
|
||||
@DataProvider(name = "prefix invariants")
|
||||
public Object[][] prefixInvariants() {
|
||||
public static Object[][] prefixInvariants() {
|
||||
return new Object[][]
|
||||
{
|
||||
{ Long.MAX_VALUE, 0, IAE },
|
||||
@ -111,27 +108,30 @@ public class VariableLengthTest {
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "decode invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("decodeInvariants")
|
||||
public void testDecode(byte[] values, long expectedLength, int expectedPosition) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(values);
|
||||
var actualLength = VariableLengthEncoder.decode(bb);
|
||||
assertEquals(actualLength, expectedLength);
|
||||
assertEquals(expectedLength, actualLength);
|
||||
|
||||
var actualPosition = bb.position();
|
||||
assertEquals(actualPosition, expectedPosition);
|
||||
assertEquals(expectedPosition, actualPosition);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "decode invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("decodeInvariants")
|
||||
public void testPeek(byte[] values, long expectedLength, int expectedPosition) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(values);
|
||||
var actualLength = VariableLengthEncoder.peekEncodedValue(bb, 0);
|
||||
assertEquals(actualLength, expectedLength);
|
||||
assertEquals(expectedLength, actualLength);
|
||||
|
||||
var actualPosition = bb.position();
|
||||
assertEquals(actualPosition, 0);
|
||||
assertEquals(0, actualPosition);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "encode invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("encodeInvariants")
|
||||
public void testEncode(long length, int capacity, Class<? extends Exception> exception) throws IOException {
|
||||
var actualBuffer = ByteBuffer.allocate(capacity);
|
||||
var expectedBuffer = getTestBuffer(length, capacity);
|
||||
@ -140,46 +140,48 @@ public class VariableLengthTest {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.encode(actualBuffer, length));
|
||||
// if method fails ensure that position hasn't changed
|
||||
var actualPosition = actualBuffer.position();
|
||||
assertEquals(actualPosition, capacity);
|
||||
assertEquals(capacity, actualPosition);
|
||||
} else {
|
||||
VariableLengthEncoder.encode(actualBuffer, length);
|
||||
var actualPosition = actualBuffer.position();
|
||||
assertEquals(actualPosition, capacity);
|
||||
assertEquals(capacity, actualPosition);
|
||||
|
||||
// check length prefix
|
||||
int firstByte = actualBuffer.get(0) & 0xFF;
|
||||
int lengthPrefix = firstByte & 0xC0;
|
||||
lengthPrefix >>= 6;
|
||||
int expectedValue = (int)(Math.log(capacity) / Math.log(2));
|
||||
assertEquals(lengthPrefix, expectedValue);
|
||||
assertEquals(expectedValue, lengthPrefix);
|
||||
|
||||
// check length encoded in buffer correctly
|
||||
int b = firstByte & 0x3F;
|
||||
actualBuffer.put(0, (byte) b);
|
||||
assertEquals(actualBuffer.compareTo(expectedBuffer), 0);
|
||||
assertEquals(0, actualBuffer.compareTo(expectedBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "prefix invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("prefixInvariants")
|
||||
public void testLengthPrefix(long length, int expectedPrefix, Class<? extends Exception> exception) {
|
||||
if (exception != null) {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.getVariableLengthPrefix(length));
|
||||
} else {
|
||||
var actualValue = VariableLengthEncoder.getVariableLengthPrefix(length);
|
||||
assertEquals(actualValue, expectedPrefix);
|
||||
assertEquals(expectedPrefix, actualValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the given length and then decodes it and compares
|
||||
// the results, asserting various invariants along the way.
|
||||
@Test(dataProvider = "prefix invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("prefixInvariants")
|
||||
public void testEncodeDecode(long length, int expectedPrefix, Class<? extends Exception> exception) {
|
||||
if (exception != null) {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.getEncodedSize(length));
|
||||
assertThrows(exception, () -> VariableLengthEncoder.encode(ByteBuffer.allocate(16), length));
|
||||
} else {
|
||||
var actualSize = VariableLengthEncoder.getEncodedSize(length);
|
||||
assertEquals(actualSize, 1 << expectedPrefix);
|
||||
assertEquals(1 << expectedPrefix, actualSize);
|
||||
assertTrue(actualSize > 0, "length is negative or zero: " + actualSize);
|
||||
assertTrue(actualSize < 9, "length is too big: " + actualSize);
|
||||
|
||||
@ -199,33 +201,33 @@ public class VariableLengthTest {
|
||||
longer.position(offset);
|
||||
|
||||
// attempt to encode with a buffer too short
|
||||
expectThrows(IAE, () -> VariableLengthEncoder.encode(shorter, length));
|
||||
assertEquals(shorter.position(), offset);
|
||||
assertEquals(shorter.limit(), shorter.capacity());
|
||||
assertThrows(IAE, () -> VariableLengthEncoder.encode(shorter, length));
|
||||
assertEquals(offset, shorter.position());
|
||||
assertEquals(shorter.capacity(), shorter.limit());
|
||||
|
||||
assertEquals(shorter.mismatch(shorterref), -1);
|
||||
assertEquals(shorterref.mismatch(shorter), -1);
|
||||
assertEquals(-1, shorter.mismatch(shorterref));
|
||||
assertEquals(-1, shorterref.mismatch(shorter));
|
||||
|
||||
// attempt to encode with a buffer that has the exact size
|
||||
var exactres = VariableLengthEncoder.encode(exact, length);
|
||||
assertEquals(exactres, actualSize);
|
||||
assertEquals(exact.position(), actualSize + offset);
|
||||
assertEquals(actualSize, exactres);
|
||||
assertEquals(actualSize + offset, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
|
||||
// attempt to encode with a buffer that has more bytes
|
||||
var longres = VariableLengthEncoder.encode(longer, length);
|
||||
assertEquals(longres, actualSize);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(actualSize, longres);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
assertEquals(10, longer.remaining());
|
||||
|
||||
// compare encodings
|
||||
|
||||
// first reset buffer positions for reading.
|
||||
exact.position(offset);
|
||||
longer.position(offset);
|
||||
assertEquals(longer.mismatch(exact), actualSize);
|
||||
assertEquals(exact.mismatch(longer), actualSize);
|
||||
assertEquals(actualSize, longer.mismatch(exact));
|
||||
assertEquals(actualSize, exact.mismatch(longer));
|
||||
|
||||
// decode with a buffer that is missing the last
|
||||
// byte...
|
||||
@ -233,21 +235,21 @@ public class VariableLengthTest {
|
||||
shortSlice.position(offset);
|
||||
shortSlice.limit(offset + actualSize -1);
|
||||
var actualLength = VariableLengthEncoder.decode(shortSlice);
|
||||
assertEquals(actualLength, -1L);
|
||||
assertEquals(shortSlice.position(), offset);
|
||||
assertEquals(shortSlice.limit(), offset + actualSize - 1);
|
||||
assertEquals(-1L, actualLength);
|
||||
assertEquals(offset, shortSlice.position());
|
||||
assertEquals(offset + actualSize - 1, shortSlice.limit());
|
||||
|
||||
// decode with the exact buffer
|
||||
actualLength = VariableLengthEncoder.decode(exact);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(exact.position(), offset + actualSize);
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(offset + actualSize, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
|
||||
// decode with the longer buffer
|
||||
actualLength = VariableLengthEncoder.decode(longer);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(10, longer.remaining());
|
||||
}
|
||||
|
||||
}
|
||||
@ -255,7 +257,8 @@ public class VariableLengthTest {
|
||||
|
||||
// Encode the given length and then peeks it and compares
|
||||
// the results, asserting various invariants along the way.
|
||||
@Test(dataProvider = "prefix invariants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("prefixInvariants")
|
||||
public void testEncodePeek(long length, int expectedPrefix, Class<? extends Exception> exception) {
|
||||
if (exception != null) {
|
||||
assertThrows(exception, () -> VariableLengthEncoder.getEncodedSize(length));
|
||||
@ -264,7 +267,7 @@ public class VariableLengthTest {
|
||||
}
|
||||
|
||||
var actualSize = VariableLengthEncoder.getEncodedSize(length);
|
||||
assertEquals(actualSize, 1 << expectedPrefix);
|
||||
assertEquals(1 << expectedPrefix, actualSize);
|
||||
assertTrue(actualSize > 0, "length is negative or zero: " + actualSize);
|
||||
assertTrue(actualSize < 9, "length is too big: " + actualSize);
|
||||
|
||||
@ -281,24 +284,24 @@ public class VariableLengthTest {
|
||||
|
||||
// attempt to encode with a buffer that has the exact size
|
||||
var exactres = VariableLengthEncoder.encode(exact, length);
|
||||
assertEquals(exactres, actualSize);
|
||||
assertEquals(exact.position(), actualSize + offset);
|
||||
assertEquals(actualSize, exactres);
|
||||
assertEquals(actualSize + offset, exact.position());
|
||||
assertFalse(exact.hasRemaining());
|
||||
|
||||
// attempt to encode with a buffer that has more bytes
|
||||
var longres = VariableLengthEncoder.encode(longer, length);
|
||||
assertEquals(longres, actualSize);
|
||||
assertEquals(longer.position(), offset + actualSize);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(longer.remaining(), 10);
|
||||
assertEquals(actualSize, longres);
|
||||
assertEquals(offset + actualSize, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
assertEquals(10, longer.remaining());
|
||||
|
||||
// compare encodings
|
||||
|
||||
// first reset buffer positions for reading.
|
||||
exact.position(offset);
|
||||
longer.position(offset);
|
||||
assertEquals(longer.mismatch(exact), actualSize);
|
||||
assertEquals(exact.mismatch(longer), actualSize);
|
||||
assertEquals(actualSize, longer.mismatch(exact));
|
||||
assertEquals(actualSize, exact.mismatch(longer));
|
||||
exact.position(0);
|
||||
longer.position(0);
|
||||
exact.limit(exact.capacity());
|
||||
@ -311,25 +314,25 @@ public class VariableLengthTest {
|
||||
shortSlice.limit(offset + actualSize - 1);
|
||||
// need at least one byte to decode the size len...
|
||||
var expectedSize = shortSlice.limit() <= offset ? -1 : actualSize;
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(shortSlice, offset), expectedSize);
|
||||
assertEquals(expectedSize, VariableLengthEncoder.peekEncodedValueSize(shortSlice, offset));
|
||||
var actualLength = VariableLengthEncoder.peekEncodedValue(shortSlice, offset);
|
||||
assertEquals(actualLength, -1L);
|
||||
assertEquals(shortSlice.position(), 0);
|
||||
assertEquals(shortSlice.limit(), offset + actualSize - 1);
|
||||
assertEquals(-1L, actualLength);
|
||||
assertEquals(0, shortSlice.position());
|
||||
assertEquals(offset + actualSize - 1, shortSlice.limit());
|
||||
|
||||
// decode with the exact buffer
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(exact, offset), actualSize);
|
||||
assertEquals(actualSize, VariableLengthEncoder.peekEncodedValueSize(exact, offset));
|
||||
actualLength = VariableLengthEncoder.peekEncodedValue(exact, offset);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(exact.position(), 0);
|
||||
assertEquals(exact.limit(), exact.capacity());
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(0, exact.position());
|
||||
assertEquals(exact.capacity(), exact.limit());
|
||||
|
||||
// decode with the longer buffer
|
||||
assertEquals(VariableLengthEncoder.peekEncodedValueSize(longer, offset), actualSize);
|
||||
assertEquals(actualSize, VariableLengthEncoder.peekEncodedValueSize(longer, offset));
|
||||
actualLength = VariableLengthEncoder.peekEncodedValue(longer, offset);
|
||||
assertEquals(actualLength, length);
|
||||
assertEquals(longer.position(), 0);
|
||||
assertEquals(longer.limit(), longer.capacity());
|
||||
assertEquals(length, actualLength);
|
||||
assertEquals(0, longer.position());
|
||||
assertEquals(longer.capacity(), longer.limit());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,13 +41,15 @@ import jdk.internal.net.http.quic.QuicClient;
|
||||
import jdk.internal.net.quic.QuicTLSContext;
|
||||
import jdk.internal.net.quic.QuicVersion;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.expectThrows;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -57,19 +59,19 @@ import static org.testng.Assert.expectThrows;
|
||||
* jdk.httpclient.test.lib.common.TestUtil
|
||||
* jdk.httpclient.test.lib.quic.ClientConnection
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true VersionNegotiationTest
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true VersionNegotiationTest
|
||||
*/
|
||||
public class VersionNegotiationTest {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
private static ExecutorService executor;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
executor = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@AfterAll
|
||||
public static void afterClass() throws Exception {
|
||||
if (executor != null) executor.shutdown();
|
||||
}
|
||||
@ -96,7 +98,7 @@ public class VersionNegotiationTest {
|
||||
try (final QuicServer server = createAndStartServer(serverVersion)) {
|
||||
System.out.println("Attempting to connect " + client.getAvailableVersions()
|
||||
+ " client to a " + server.getAvailableVersions() + " server");
|
||||
final IOException thrown = expectThrows(IOException.class,
|
||||
final IOException thrown = Assertions.assertThrows(IOException.class,
|
||||
() -> ClientConnection.establishConnection(client, server.getAddress()));
|
||||
// a version negotiation failure (since it happens during a QUIC connection
|
||||
// handshake) gets thrown as a SSLHandshakeException
|
||||
@ -105,7 +107,7 @@ public class VersionNegotiationTest {
|
||||
}
|
||||
System.out.println("Received (potentially expected) exception: " + sslhe);
|
||||
// additional check to make sure it was thrown for the right reason
|
||||
assertEquals(sslhe.getMessage(), "QUIC connection establishment failed");
|
||||
assertEquals("QUIC connection establishment failed", sslhe.getMessage());
|
||||
// underlying cause of SSLHandshakeException should be version negotiation failure
|
||||
final Throwable underlyingCause = sslhe.getCause();
|
||||
assertNotNull(underlyingCause, "missing cause in SSLHandshakeException");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@ import jdk.internal.net.quic.QuicKeyUnavailableException;
|
||||
import jdk.internal.net.quic.QuicTLSContext;
|
||||
import jdk.internal.net.quic.QuicTLSEngine;
|
||||
import jdk.internal.net.quic.QuicTransportException;
|
||||
import org.testng.annotations.Test;
|
||||
import sun.security.ssl.QuicTLSEngineImpl;
|
||||
import sun.security.ssl.QuicTLSEngineImplAccessor;
|
||||
|
||||
@ -40,8 +39,11 @@ import java.util.HexFormat;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import static jdk.internal.net.quic.QuicVersion.QUIC_V1;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -50,7 +52,7 @@ import static org.testng.Assert.fail;
|
||||
* java.base/jdk.internal.net.quic
|
||||
* @build java.base/sun.security.ssl.QuicTLSEngineImplAccessor
|
||||
* @summary known-answer test for packet encryption and decryption
|
||||
* @run testng/othervm PacketEncryptionTest
|
||||
* @run junit/othervm PacketEncryptionTest
|
||||
*/
|
||||
public class PacketEncryptionTest {
|
||||
|
||||
@ -183,7 +185,7 @@ public class PacketEncryptionTest {
|
||||
clientEngine.encryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, clientEngine, 0x0f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_C_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_C_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -202,26 +204,25 @@ public class PacketEncryptionTest {
|
||||
|
||||
String expectedContents = INITIAL_C_HEADER + INITIAL_C_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
public void testDecryptClientInitialPacketBadTag() throws Exception {
|
||||
QuicTLSEngine serverEngine = getQuicV1Engine(SSLContext.getDefault(), false);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
serverEngine.deriveInitialKeys(QUIC_V1, dcid);
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_C_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, serverEngine, 0x0f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(INITIAL_C_PAYLOAD_OFFSET);
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, -1,
|
||||
src, INITIAL_C_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
@Test
|
||||
public void testDecryptClientInitialPacketBadTag() {
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngine serverEngine = getQuicV1Engine(SSLContext.getDefault(), false);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
serverEngine.deriveInitialKeys(QUIC_V1, dcid);
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_C_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, serverEngine, 0x0f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(INITIAL_C_PAYLOAD_OFFSET);
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, -1,
|
||||
src, INITIAL_C_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -242,7 +243,7 @@ public class PacketEncryptionTest {
|
||||
serverEngine.encryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_S_PN, new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_S_PN_OFFSET, INITIAL_S_PAYLOAD_OFFSET - INITIAL_S_PN_OFFSET, serverEngine, 0x0f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_S_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_S_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -261,7 +262,7 @@ public class PacketEncryptionTest {
|
||||
|
||||
String expectedContents = INITIAL_S_HEADER + INITIAL_S_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -302,7 +303,7 @@ public class PacketEncryptionTest {
|
||||
|
||||
clientEngine.signRetryPacket(QUIC_V1, dcid, src, packet);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), SIGNED_RETRY);
|
||||
assertEquals(SIGNED_RETRY, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -315,17 +316,17 @@ public class PacketEncryptionTest {
|
||||
clientEngine.verifyRetryPacket(QUIC_V1, dcid, packet);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
public void testVerifyBadRetry() throws NoSuchAlgorithmException, AEADBadTagException, QuicTransportException {
|
||||
QuicTLSEngine clientEngine = getQuicV1Engine(SSLContext.getDefault(), true);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(SIGNED_RETRY));
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
clientEngine.verifyRetryPacket(QUIC_V1, dcid, packet);
|
||||
fail("Verification should have failed");
|
||||
@Test
|
||||
public void testVerifyBadRetry() {
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngine clientEngine = getQuicV1Engine(SSLContext.getDefault(), true);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(SIGNED_RETRY));
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
clientEngine.verifyRetryPacket(QUIC_V1, dcid, packet);
|
||||
fail("Verification should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -346,7 +347,7 @@ public class PacketEncryptionTest {
|
||||
clientEngine.encryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN , new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, clientEngine, 0x1f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_ONERTT_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_ONERTT_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -367,7 +368,7 @@ public class PacketEncryptionTest {
|
||||
|
||||
String expectedContents = ONERTT_HEADER + ONERTT_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -397,25 +398,24 @@ public class PacketEncryptionTest {
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, keyPhase, src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
public void testDecryptChaChaBadTag() throws Exception {
|
||||
QuicTLSEngineImpl serverEngine = (QuicTLSEngineImpl) getQuicV1Engine(SSLContext.getDefault(), false);
|
||||
// mark the TLS handshake as FINISHED
|
||||
QuicTLSEngineImplAccessor.completeHandshake(serverEngine);
|
||||
SecretKey key = new SecretKeySpec(HexFormat.of().parseHex(ONERTT_SECRET), 0, 32, "ChaCha20-Poly1305");
|
||||
QuicTLSEngineImplAccessor.testDeriveOneRTTKeys(QUIC_V1, serverEngine, key, key, "TLS_CHACHA20_POLY1305_SHA256", false);
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_ONERTT_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, serverEngine, 0x1f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(ONERTT_PAYLOAD_OFFSET);
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, (byte) 0,
|
||||
src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
@Test
|
||||
public void testDecryptChaChaBadTag() {
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngineImpl serverEngine = (QuicTLSEngineImpl) getQuicV1Engine(SSLContext.getDefault(), false);
|
||||
// mark the TLS handshake as FINISHED
|
||||
QuicTLSEngineImplAccessor.completeHandshake(serverEngine);
|
||||
SecretKey key = new SecretKeySpec(HexFormat.of().parseHex(ONERTT_SECRET), 0, 32, "ChaCha20-Poly1305");
|
||||
QuicTLSEngineImplAccessor.testDeriveOneRTTKeys(QUIC_V1, serverEngine, key, key, "TLS_CHACHA20_POLY1305_SHA256", false);
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_ONERTT_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, serverEngine, 0x1f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(ONERTT_PAYLOAD_OFFSET);
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, (byte) 0,
|
||||
src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@ import jdk.internal.net.quic.QuicKeyUnavailableException;
|
||||
import jdk.internal.net.quic.QuicTLSContext;
|
||||
import jdk.internal.net.quic.QuicTLSEngine;
|
||||
import jdk.internal.net.quic.QuicTransportException;
|
||||
import org.testng.annotations.Test;
|
||||
import sun.security.ssl.QuicTLSEngineImpl;
|
||||
import sun.security.ssl.QuicTLSEngineImplAccessor;
|
||||
|
||||
@ -40,8 +39,11 @@ import java.util.HexFormat;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import static jdk.internal.net.quic.QuicVersion.QUIC_V2;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -50,7 +52,7 @@ import static org.testng.Assert.fail;
|
||||
* java.base/jdk.internal.net.quic
|
||||
* @build java.base/sun.security.ssl.QuicTLSEngineImplAccessor
|
||||
* @summary known-answer test for packet encryption and decryption with Quic v2
|
||||
* @run testng/othervm Quicv2PacketEncryptionTest
|
||||
* @run junit/othervm Quicv2PacketEncryptionTest
|
||||
*/
|
||||
public class Quicv2PacketEncryptionTest {
|
||||
|
||||
@ -182,7 +184,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
clientEngine.encryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, clientEngine, 0x0f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_C_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_C_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -200,25 +202,24 @@ public class Quicv2PacketEncryptionTest {
|
||||
|
||||
String expectedContents = INITIAL_C_HEADER + INITIAL_C_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
@Test
|
||||
public void testDecryptClientInitialPacketBadTag() throws Exception {
|
||||
QuicTLSEngine serverEngine = getQuicV2Engine(SSLContext.getDefault(), false);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
serverEngine.deriveInitialKeys(QUIC_V2, dcid);
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_C_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, serverEngine, 0x0f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(INITIAL_C_PAYLOAD_OFFSET);
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, -1, src, INITIAL_C_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngine serverEngine = getQuicV2Engine(SSLContext.getDefault(), false);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
serverEngine.deriveInitialKeys(QUIC_V2, dcid);
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_C_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_C_PN_OFFSET, INITIAL_C_PAYLOAD_OFFSET - INITIAL_C_PN_OFFSET, serverEngine, 0x0f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(INITIAL_C_PAYLOAD_OFFSET);
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_C_PN, -1, src, INITIAL_C_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -239,7 +240,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
serverEngine.encryptPacket(QuicTLSEngine.KeySpace.INITIAL, INITIAL_S_PN, new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.INITIAL, packet, INITIAL_S_PN_OFFSET, INITIAL_S_PAYLOAD_OFFSET - INITIAL_S_PN_OFFSET, serverEngine, 0x0f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_S_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_S_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -257,7 +258,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
|
||||
String expectedContents = INITIAL_S_HEADER + INITIAL_S_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -298,7 +299,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
|
||||
clientEngine.signRetryPacket(QUIC_V2, dcid, src, packet);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), SIGNED_RETRY);
|
||||
assertEquals(SIGNED_RETRY, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -311,17 +312,17 @@ public class Quicv2PacketEncryptionTest {
|
||||
clientEngine.verifyRetryPacket(QUIC_V2, dcid, packet);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
@Test
|
||||
public void testVerifyBadRetry() throws NoSuchAlgorithmException, AEADBadTagException, QuicTransportException {
|
||||
QuicTLSEngine clientEngine = getQuicV2Engine(SSLContext.getDefault(), true);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(SIGNED_RETRY));
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
clientEngine.verifyRetryPacket(QUIC_V2, dcid, packet);
|
||||
fail("Verification should have failed");
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngine clientEngine = getQuicV2Engine(SSLContext.getDefault(), true);
|
||||
ByteBuffer dcid = ByteBuffer.wrap(HexFormat.of().parseHex(INITIAL_DCID));
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(SIGNED_RETRY));
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
clientEngine.verifyRetryPacket(QUIC_V2, dcid, packet);
|
||||
fail("Verification should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -342,7 +343,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
clientEngine.encryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN , new FixedHeaderContent(header), payload, packet);
|
||||
protect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, clientEngine, 0x1f);
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()), ENCRYPTED_ONERTT_PAYLOAD);
|
||||
assertEquals(ENCRYPTED_ONERTT_PAYLOAD, HexFormat.of().formatHex(packet.array()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -362,7 +363,7 @@ public class Quicv2PacketEncryptionTest {
|
||||
|
||||
String expectedContents = ONERTT_HEADER + ONERTT_PAYLOAD;
|
||||
|
||||
assertEquals(HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()), expectedContents);
|
||||
assertEquals(expectedContents, HexFormat.of().formatHex(packet.array()).substring(0, expectedContents.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -392,24 +393,23 @@ public class Quicv2PacketEncryptionTest {
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, keyphase, src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AEADBadTagException.class)
|
||||
@Test
|
||||
public void testDecryptChaChaBadTag() throws Exception {
|
||||
QuicTLSEngineImpl serverEngine = (QuicTLSEngineImpl) getQuicV2Engine(SSLContext.getDefault(), false);
|
||||
// mark the TLS handshake as FINISHED
|
||||
QuicTLSEngineImplAccessor.completeHandshake(serverEngine);
|
||||
SecretKey key = new SecretKeySpec(HexFormat.of().parseHex(ONERTT_SECRET), 0, 32, "ChaCha20-Poly1305");
|
||||
QuicTLSEngineImplAccessor.testDeriveOneRTTKeys(QUIC_V2, serverEngine, key, key, "TLS_CHACHA20_POLY1305_SHA256", false);
|
||||
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_ONERTT_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, serverEngine, 0x1f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(ONERTT_PAYLOAD_OFFSET);
|
||||
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, 0, src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
Assertions.assertThrows(AEADBadTagException.class, () -> {
|
||||
QuicTLSEngineImpl serverEngine = (QuicTLSEngineImpl) getQuicV2Engine(SSLContext.getDefault(), false);
|
||||
// mark the TLS handshake as FINISHED
|
||||
QuicTLSEngineImplAccessor.completeHandshake(serverEngine);
|
||||
SecretKey key = new SecretKeySpec(HexFormat.of().parseHex(ONERTT_SECRET), 0, 32, "ChaCha20-Poly1305");
|
||||
QuicTLSEngineImplAccessor.testDeriveOneRTTKeys(QUIC_V2, serverEngine, key, key, "TLS_CHACHA20_POLY1305_SHA256", false);
|
||||
ByteBuffer packet = ByteBuffer.wrap(HexFormat.of().parseHex(ENCRYPTED_ONERTT_PAYLOAD));
|
||||
unprotect(QuicTLSEngine.KeySpace.ONE_RTT, packet, ONERTT_PN_OFFSET, ONERTT_PAYLOAD_OFFSET - ONERTT_PN_OFFSET, serverEngine, 0x1f);
|
||||
ByteBuffer src = packet.asReadOnlyBuffer();
|
||||
packet.position(ONERTT_PAYLOAD_OFFSET);
|
||||
// change one byte of AEAD tag
|
||||
packet.put(packet.limit() - 1, (byte)0);
|
||||
serverEngine.decryptPacket(QuicTLSEngine.KeySpace.ONE_RTT, ONERTT_PN, 0, src, ONERTT_PAYLOAD_OFFSET, packet);
|
||||
fail("Decryption should have failed");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user