mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:39:29 +00:00
Polishing contribution
Closes gh-36650
This commit is contained in:
+24
-31
@@ -19,6 +19,7 @@ package org.springframework.web.reactive.socket.adapter;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
@@ -45,51 +46,45 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link JettyWebSocketSession}.
|
* Tests for {@link JettyWebSocketSession}.
|
||||||
*
|
|
||||||
* @author Max Guiking
|
* @author Max Guiking
|
||||||
*/
|
*/
|
||||||
class JettyWebSocketSessionTests {
|
class JettyWebSocketSessionTests {
|
||||||
|
|
||||||
private final DefaultDataBufferFactory bufferFactory = DefaultDataBufferFactory.sharedInstance;
|
private final Session nativeSession = mock(Session.class);
|
||||||
|
|
||||||
private final Session jettySession = mock(Session.class);
|
private final JettyWebSocketSession webSocketSession = new JettyWebSocketSession(
|
||||||
|
this.nativeSession, new HandshakeInfo(URI.create("ws://example.org"),
|
||||||
private final JettyWebSocketSession session = new JettyWebSocketSession(this.jettySession,
|
new HttpHeaders(), Mono.empty(), null), DefaultDataBufferFactory.sharedInstance);
|
||||||
new HandshakeInfo(URI.create("ws://example.org"), new HttpHeaders(), Mono.empty(), null),
|
|
||||||
this.bufferFactory);
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sendBinaryMessageWithSingleFragmentMarksFragmentAsLast() {
|
void sendBinaryMessageWithSingleBuffer() {
|
||||||
succeedOnSendPartialBinary();
|
succeedOnSendPartialBinary();
|
||||||
|
|
||||||
DataBuffer payload = this.bufferFactory.wrap("hello".getBytes(StandardCharsets.UTF_8));
|
DataBuffer payload = DefaultDataBufferFactory.sharedInstance.wrap("hello".getBytes(StandardCharsets.UTF_8));
|
||||||
WebSocketMessage message = new WebSocketMessage(WebSocketMessage.Type.BINARY, payload);
|
WebSocketMessage message = new WebSocketMessage(WebSocketMessage.Type.BINARY, payload);
|
||||||
|
|
||||||
this.session.sendMessage(message).block();
|
this.webSocketSession.sendMessage(message).block();
|
||||||
|
|
||||||
ArgumentCaptor<Boolean> lastCaptor = ArgumentCaptor.forClass(Boolean.class);
|
ArgumentCaptor<Boolean> last = ArgumentCaptor.forClass(Boolean.class);
|
||||||
verify(this.jettySession).sendPartialBinary(any(ByteBuffer.class), lastCaptor.capture(), any(Callback.class));
|
verify(this.nativeSession).sendPartialBinary(any(ByteBuffer.class), last.capture(), any(Callback.class));
|
||||||
assertThat(lastCaptor.getValue()).as("FIN bit must be set for the final (and only) fragment").isTrue();
|
assertThat(last.getValue()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sendBinaryMessageWithMultipleFragmentsMarksOnlyFinalFragmentAsLast() {
|
void sendBinaryMessageWithMultipleBuffers() {
|
||||||
succeedOnSendPartialBinary();
|
succeedOnSendPartialBinary();
|
||||||
|
|
||||||
List<ByteBuffer> fragments = List.of(
|
WebSocketMessage message = new WebSocketMessage(WebSocketMessage.Type.BINARY, new MultiBufferDataBuffer(
|
||||||
ByteBuffer.wrap("one".getBytes(StandardCharsets.UTF_8)),
|
ByteBuffer.wrap("one".getBytes(StandardCharsets.UTF_8)),
|
||||||
ByteBuffer.wrap("two".getBytes(StandardCharsets.UTF_8)),
|
ByteBuffer.wrap("two".getBytes(StandardCharsets.UTF_8)),
|
||||||
ByteBuffer.wrap("three".getBytes(StandardCharsets.UTF_8)));
|
ByteBuffer.wrap("three".getBytes(StandardCharsets.UTF_8))));
|
||||||
WebSocketMessage message = new WebSocketMessage(WebSocketMessage.Type.BINARY,
|
|
||||||
new MultiBufferDataBuffer(this.bufferFactory, fragments));
|
|
||||||
|
|
||||||
this.session.sendMessage(message).block();
|
this.webSocketSession.sendMessage(message).block();
|
||||||
|
|
||||||
ArgumentCaptor<Boolean> lastCaptor = ArgumentCaptor.forClass(Boolean.class);
|
ArgumentCaptor<Boolean> last = ArgumentCaptor.forClass(Boolean.class);
|
||||||
verify(this.jettySession, times(fragments.size()))
|
verify(this.nativeSession, times(3)).sendPartialBinary(any(ByteBuffer.class), last.capture(), any(Callback.class));
|
||||||
.sendPartialBinary(any(ByteBuffer.class), lastCaptor.capture(), any(Callback.class));
|
assertThat(last.getAllValues()).containsExactly(false, false, true);
|
||||||
assertThat(lastCaptor.getAllValues()).containsExactly(false, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void succeedOnSendPartialBinary() {
|
private void succeedOnSendPartialBinary() {
|
||||||
@@ -97,22 +92,20 @@ class JettyWebSocketSessionTests {
|
|||||||
Callback callback = invocation.getArgument(2);
|
Callback callback = invocation.getArgument(2);
|
||||||
callback.succeed();
|
callback.succeed();
|
||||||
return null;
|
return null;
|
||||||
}).when(this.jettySession).sendPartialBinary(any(ByteBuffer.class), anyBoolean(), any(Callback.class));
|
}).when(this.nativeSession).sendPartialBinary(any(ByteBuffer.class), anyBoolean(), any(Callback.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal {@link DataBuffer} whose {@link #readableByteBuffers()} yields a
|
* Minimal DataBuffer that returns a given list of buffers from {@link #readableByteBuffers()}.
|
||||||
* caller-supplied list of buffers, exercising the multi-fragment branch of
|
|
||||||
* {@link JettyWebSocketSession#sendMessage(WebSocketMessage)}.
|
|
||||||
*/
|
*/
|
||||||
private static final class MultiBufferDataBuffer extends DataBufferWrapper {
|
private static final class MultiBufferDataBuffer extends DataBufferWrapper {
|
||||||
|
|
||||||
private final List<ByteBuffer> buffers;
|
private final List<ByteBuffer> buffers;
|
||||||
|
|
||||||
MultiBufferDataBuffer(DefaultDataBufferFactory factory, List<ByteBuffer> buffers) {
|
MultiBufferDataBuffer(ByteBuffer... buffers) {
|
||||||
super(factory.allocateBuffer(0));
|
super(DefaultDataBufferFactory.sharedInstance.allocateBuffer(0));
|
||||||
this.buffers = buffers;
|
this.buffers = Arrays.asList(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,7 +116,7 @@ class JettyWebSocketSessionTests {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return this.index < MultiBufferDataBuffer.this.buffers.size();
|
return (this.index < MultiBufferDataBuffer.this.buffers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user