Skip to content

Commit ea0611d

Browse files
committed
add test
1 parent a8bfba5 commit ea0611d

File tree

5 files changed

+126
-27
lines changed

5 files changed

+126
-27
lines changed

buildSrc/src/main/groovy/configure-java.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ javadoc {
3535
test {
3636
useJUnitPlatform()
3737
failOnNoDiscoveredTests = false
38+
jvmArgs("-XX:+EnableDynamicAgentLoading")
3839
}
3940

4041
tasks.register("loadTest", Test) {
@@ -52,6 +53,8 @@ dependencies {
5253
compileOnly libs.lombok
5354
annotationProcessor libs.lombok
5455

56+
testImplementation libs.mockito.core
57+
testImplementation libs.mockito.junit.jupiter
5558
testImplementation libs.junit.api
5659
testImplementation libs.junit.jupiter.params
5760

gradle/libs.versions.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ lombok = "1.18.38"
1717
jspecify = "1.0.0"
1818
# https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher
1919
junit-platform-launcher = "1.13.4"
20+
# https://mvnrepository.com/artifact/org.mockito/mockito-core
21+
mockito = "5.20.0"
2022

2123
[libraries]
2224
project-reactor-core = { module = "io.projectreactor:reactor-core", version.ref = "project-reactor" }
@@ -32,6 +34,8 @@ slf4j-ext = { module = "org.slf4j:slf4j-ext", version.ref = "slf4j" }
3234
jakarta-mail-api = { module = "jakarta.mail:jakarta.mail-api", version.ref = "jakarta-mail" }
3335
angus-mail = { module = "org.eclipse.angus:angus-mail", version.ref = "angus-mail" }
3436
testcontainers = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" }
37+
mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" }
38+
mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" }
3539

3640
[bundles]
3741
mail = ["jakarta-mail-api", "angus-mail"]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package javasabr.rlib.network.exception;
2+
3+
public class MalformedProtocolException extends RuntimeException {
4+
public MalformedProtocolException(String message) {
5+
super(message);
6+
}
7+
}

rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractNetworkPacketReader.java

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import javasabr.rlib.network.Network;
1818
import javasabr.rlib.network.NetworkConfig;
1919
import javasabr.rlib.network.UnsafeConnection;
20+
import javasabr.rlib.network.exception.MalformedProtocolException;
2021
import javasabr.rlib.network.packet.NetworkPacketReader;
2122
import javasabr.rlib.network.packet.ReadableNetworkPacket;
2223
import lombok.AccessLevel;
@@ -121,8 +122,6 @@ protected void startReadImpl() {
121122
if (reading.compareAndSet(true, false)) {
122123
retryReadLater();
123124
}
124-
} catch (Error error) {
125-
throw error;
126125
}
127126
}
128127

@@ -219,7 +218,7 @@ else if (waitedBytes > 0) {
219218
int positionBeforeRead = endPosition;
220219
int packetFullLength = readFullPacketLength(bufferToRead);
221220
if (packetFullLength > networkConfig.maxPacketSize()) {
222-
throw new IllegalStateException(
221+
throw new MalformedProtocolException(
223222
"Received to big packet:[" + packetFullLength + ">" + networkConfig.maxPacketSize() + "]");
224223
}
225224

@@ -412,8 +411,9 @@ protected void handleReceivedData(int receivedBytes, ByteBuffer readingBuffer) {
412411
emptyReadsCounter.set(0);
413412
try {
414413
readPackets(readingBuffer);
415-
} catch (Exception e) {
416-
log.error(e);
414+
} catch (MalformedProtocolException e) {
415+
handleFailedReceiving(e, readingBuffer);
416+
return;
417417
}
418418
startReadImpl();
419419
}
@@ -451,19 +451,20 @@ protected void handleEmptyReadFromChannel() {
451451
* @param readingBuffer the currently reading buffer.
452452
*/
453453
protected void handleFailedReceiving(Throwable exception, ByteBuffer readingBuffer) {
454-
if (exception instanceof InterruptedByTimeoutException) {
455-
if (reading.compareAndSet(true, false)) {
456-
retryReadLater();
454+
switch (exception) {
455+
case InterruptedByTimeoutException ex -> {
456+
if (reading.compareAndSet(true, false)) {
457+
retryReadLater();
458+
}
459+
}
460+
case AsynchronousCloseException ex ->
461+
log.info(remoteAddress(), "[%s] Connection was closed"::formatted);
462+
case ClosedChannelException ex ->
463+
log.info(remoteAddress(), "[%s] Connection was closed"::formatted);
464+
default -> {
465+
log.error(exception);
466+
connection.close();
457467
}
458-
return;
459-
}
460-
if (exception instanceof AsynchronousCloseException) {
461-
log.info(remoteAddress(), "[%s] Connection was closed"::formatted);
462-
} else if (exception instanceof ClosedChannelException) {
463-
log.info(remoteAddress(), "[%s] Connection was closed"::formatted);
464-
} else {
465-
log.error(exception);
466-
connection.close();
467468
}
468469
}
469470

@@ -475,16 +476,12 @@ protected int maxPacketsByRead() {
475476
}
476477

477478
protected int readHeader(ByteBuffer buffer, int headerSize) {
478-
switch (headerSize) {
479-
case 1:
480-
return buffer.get() & 0xFF;
481-
case 2:
482-
return buffer.getShort() & 0xFFFF;
483-
case 4:
484-
return buffer.getInt();
485-
default:
486-
throw new IllegalStateException("Wrong packet's header size: " + headerSize);
487-
}
479+
return switch (headerSize) {
480+
case 1 -> buffer.get() & 0xFF;
481+
case 2 -> buffer.getShort() & 0xFFFF;
482+
case 4 -> buffer.getInt();
483+
default -> throw new MalformedProtocolException("Wrong packet's header size:" + headerSize);
484+
};
488485
}
489486

490487
/**
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package javasabr.rlib.network.impl;
2+
3+
import java.nio.ByteBuffer;
4+
import java.nio.channels.AsynchronousSocketChannel;
5+
import java.nio.channels.CompletionHandler;
6+
import java.nio.charset.StandardCharsets;
7+
import javasabr.rlib.network.BufferAllocator;
8+
import javasabr.rlib.network.Network;
9+
import javasabr.rlib.network.NetworkConfig;
10+
import javasabr.rlib.network.ServerNetworkConfig.SimpleServerNetworkConfig;
11+
import javasabr.rlib.network.packet.ReadableNetworkPacket;
12+
import javasabr.rlib.network.packet.impl.DefaultNetworkPacketReader;
13+
import org.jspecify.annotations.NonNull;
14+
import org.junit.jupiter.api.Assertions;
15+
import org.junit.jupiter.api.DisplayName;
16+
import org.junit.jupiter.api.Test;
17+
import org.junit.jupiter.api.extension.ExtendWith;
18+
import org.mockito.Mock;
19+
import org.mockito.Mockito;
20+
import org.mockito.junit.jupiter.MockitoExtension;
21+
22+
@ExtendWith(MockitoExtension.class)
23+
class DefaultDataConnectionTest {
24+
25+
private static class TestDataConnection extends DefaultDataConnection<TestDataConnection> {
26+
27+
public TestDataConnection(
28+
Network<TestDataConnection> network,
29+
AsynchronousSocketChannel channel,
30+
BufferAllocator bufferAllocator,
31+
int maxPacketsByRead,
32+
int packetLengthHeaderSize) {
33+
super(network, channel, bufferAllocator, maxPacketsByRead, packetLengthHeaderSize);
34+
}
35+
36+
@Override
37+
protected ReadableNetworkPacket<TestDataConnection> createReadablePacket() {
38+
throw new UnsupportedOperationException();
39+
}
40+
}
41+
42+
@Mock
43+
Network<@NonNull TestDataConnection> network;
44+
45+
@Mock
46+
AsynchronousSocketChannel channel;
47+
48+
@Test
49+
@DisplayName("should not allow to read too big packet")
50+
void shouldNotAllowToReadTooBigPacket() {
51+
// given:
52+
NetworkConfig networkConfig = SimpleServerNetworkConfig
53+
.builder()
54+
.build();
55+
56+
var bufferAllocator = new DefaultBufferAllocator(networkConfig);
57+
var connection = new TestDataConnection(network, channel, bufferAllocator, 100, 4);
58+
var packetReader = (DefaultNetworkPacketReader<?, ?>) connection.packetReader;
59+
60+
int nextPacketSize = 250_000_000;
61+
62+
var incomingBuffer = ByteBuffer.allocate(100);
63+
incomingBuffer.putInt(nextPacketSize);
64+
incomingBuffer.put("Test data".getBytes(StandardCharsets.UTF_8));
65+
66+
Mockito
67+
.when(network.config())
68+
.thenReturn(networkConfig);
69+
70+
Mockito
71+
.doAnswer(invocationOnMock -> {
72+
CompletionHandler<Integer, ByteBuffer> readChannelHandler = invocationOnMock.getArgument(2);
73+
readChannelHandler.completed(incomingBuffer.remaining(), incomingBuffer);
74+
return null;
75+
})
76+
.when(channel)
77+
.read(Mockito.any(), Mockito.any(), Mockito.any());
78+
79+
// then:
80+
Assertions.assertFalse(connection.closed());
81+
82+
// when:
83+
packetReader.startRead();
84+
85+
// then:
86+
Assertions.assertTrue(connection.closed());
87+
}
88+
}

0 commit comments

Comments
 (0)