Commit adaeb580 authored by Seth Hampson's avatar Seth Hampson Committed by Commit Bot

Adding tests for RTCQuicStream.

Bug: 874296
Change-Id: I33e79a0641e38b420a23d0ff42933cd26bc0b368
Reviewed-on: https://chromium-review.googlesource.com/c/1341153
Commit-Queue: Seth Hampson <shampson@chromium.org>
Reviewed-by: default avatarSteve Anton <steveanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611242}
parent 01168f4a
...@@ -310,6 +310,38 @@ TEST_F(RTCQuicStreamTest, OnRemoteResetSetsWriteBufferedAmountToZero) { ...@@ -310,6 +310,38 @@ TEST_F(RTCQuicStreamTest, OnRemoteResetSetsWriteBufferedAmountToZero) {
RunUntilIdle(); RunUntilIdle();
} }
// Test that writeBufferedAmount is set to 0 if the stream calls finish(),
// followed by receiving a finish from the remote side, and reading it out.
//
// TODO(https://crbug.com/874296): It doesn't really make sense the write buffer
// gets cleared in this case. Consider changing this.
TEST_F(RTCQuicStreamTest,
FinishThenReceiveFinishSetsWriteBufferedAmountToZero) {
V8TestingScope scope;
P2PQuicStream::Delegate* stream_delegate = nullptr;
auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);
Persistent<RTCQuicStream> stream =
CreateQuicStream(scope, p2p_quic_stream.get());
stream->write(CreateUint8ArrayOfLength(4), ASSERT_NO_EXCEPTION);
stream->finish();
RunUntilIdle();
ASSERT_TRUE(stream_delegate);
stream_delegate->OnDataReceived({}, /*fin=*/true);
RunUntilIdle();
EXPECT_EQ(4u, stream->writeBufferedAmount());
NotShared<DOMUint8Array> read_buffer(DOMUint8Array::Create(10));
EXPECT_TRUE(stream->readInto(read_buffer, ASSERT_NO_EXCEPTION)->finished());
EXPECT_EQ(0u, stream->writeBufferedAmount());
RunUntilIdle();
}
// Test that write throws an InvalidStateError if the stream was reset by the // Test that write throws an InvalidStateError if the stream was reset by the
// remote peer. // remote peer.
TEST_F(RTCQuicStreamTest, WriteThrowsIfRemoteReset) { TEST_F(RTCQuicStreamTest, WriteThrowsIfRemoteReset) {
...@@ -488,6 +520,34 @@ TEST_F(RTCQuicStreamTest, ...@@ -488,6 +520,34 @@ TEST_F(RTCQuicStreamTest,
promise_90.V8Value().As<v8::Promise>()->State()); promise_90.V8Value().As<v8::Promise>()->State());
} }
// Test that when receiving OnRemoteReset() the waitForWriteBufferedAmountBelow
// Promise will be rejected.
TEST_F(RTCQuicStreamTest,
WaitForWriteBufferedAmountBelowPromisesRejectedOnRemoteReset) {
V8TestingScope scope;
P2PQuicStream::Delegate* stream_delegate = nullptr;
auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);
Persistent<RTCQuicStream> stream =
CreateQuicStream(scope, p2p_quic_stream.get());
stream->write(CreateUint8ArrayOfLength(stream->maxWriteBufferedAmount()),
ASSERT_NO_EXCEPTION);
ScriptPromise promise = stream->waitForWriteBufferedAmountBelow(
scope.GetScriptState(), 0, ASSERT_NO_EXCEPTION);
RunUntilIdle();
ASSERT_TRUE(stream_delegate);
stream_delegate->OnRemoteReset();
RunUntilIdle();
EXPECT_EQ(v8::Promise::kRejected,
promise.V8Value().As<v8::Promise>()->State());
}
// Test that there is no crash when the ExecutionContext is being destroyed and // Test that there is no crash when the ExecutionContext is being destroyed and
// there are pending waitForWriteBufferedAmountBelow() promises. If the // there are pending waitForWriteBufferedAmountBelow() promises. If the
// RTCQuicStream attempts to resolve the promise in ContextDestroyed, it will // RTCQuicStream attempts to resolve the promise in ContextDestroyed, it will
...@@ -845,6 +905,32 @@ TEST_F(RTCQuicStreamTest, WaitForReadableResolveImmediately) { ...@@ -845,6 +905,32 @@ TEST_F(RTCQuicStreamTest, WaitForReadableResolveImmediately) {
RunUntilIdle(); RunUntilIdle();
} }
// Test that a waitForReadable() promise resolves immediately if finish has
// been received, but not yet read out.
TEST_F(RTCQuicStreamTest,
WaitForReadableResolveImmediatelyAfterFinishReceived) {
V8TestingScope scope;
P2PQuicStream::Delegate* stream_delegate = nullptr;
auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);
Persistent<RTCQuicStream> stream =
CreateQuicStream(scope, p2p_quic_stream.get());
RunUntilIdle();
ASSERT_TRUE(stream_delegate);
stream_delegate->OnDataReceived({}, /*fin=*/true);
RunUntilIdle();
ScriptPromise promise =
stream->waitForReadable(scope.GetScriptState(), 10, ASSERT_NO_EXCEPTION);
EXPECT_EQ(v8::Promise::kFulfilled,
promise.V8Value().As<v8::Promise>()->State());
RunUntilIdle();
}
// Test that a waitForReadable() promise does not resolve until OnDataReceived() // Test that a waitForReadable() promise does not resolve until OnDataReceived()
// delivers at least the readable amount. // delivers at least the readable amount.
TEST_F(RTCQuicStreamTest, WaitForReadableDoesNotResolveUntilExceedsThreshold) { TEST_F(RTCQuicStreamTest, WaitForReadableDoesNotResolveUntilExceedsThreshold) {
...@@ -1001,9 +1087,8 @@ TEST_F(RTCQuicStreamTest, WaitForReadableResolvesImmediatelyIfRemoteFinished) { ...@@ -1001,9 +1087,8 @@ TEST_F(RTCQuicStreamTest, WaitForReadableResolvesImmediatelyIfRemoteFinished) {
// The following group tests state transitions with reset(), finish(), remote // The following group tests state transitions with reset(), finish(), remote
// reset() and remote finish() // reset() and remote finish()
// Test that a OnRemoteReset() immediately transitions the state to 'closed' // Test that a OnRemoteReset() immediately transitions the state to 'closed'.
// and clears any buffered data. TEST_F(RTCQuicStreamTest, OnRemoteResetTransitionsToClosed) {
TEST_F(RTCQuicStreamTest, OnRemoteResetTransitionsToClosedAndClearsBuffers) {
V8TestingScope scope; V8TestingScope scope;
P2PQuicStream::Delegate* stream_delegate = nullptr; P2PQuicStream::Delegate* stream_delegate = nullptr;
...@@ -1011,26 +1096,15 @@ TEST_F(RTCQuicStreamTest, OnRemoteResetTransitionsToClosedAndClearsBuffers) { ...@@ -1011,26 +1096,15 @@ TEST_F(RTCQuicStreamTest, OnRemoteResetTransitionsToClosedAndClearsBuffers) {
Persistent<RTCQuicStream> stream = Persistent<RTCQuicStream> stream =
CreateQuicStream(scope, p2p_quic_stream.get()); CreateQuicStream(scope, p2p_quic_stream.get());
stream->write(CreateUint8Array({1, 2}), ASSERT_NO_EXCEPTION);
RunUntilIdle(); RunUntilIdle();
ASSERT_TRUE(stream_delegate); ASSERT_TRUE(stream_delegate);
stream_delegate->OnDataReceived({5, 6, 7, 8}, /*fin=*/false);
RunUntilIdle();
EXPECT_EQ("open", stream->state()); EXPECT_EQ("open", stream->state());
EXPECT_EQ(2u, stream->writeBufferedAmount());
EXPECT_EQ(4u, stream->readBufferedAmount());
stream_delegate->OnRemoteReset(); stream_delegate->OnRemoteReset();
RunUntilIdle(); RunUntilIdle();
EXPECT_EQ("closed", stream->state()); EXPECT_EQ("closed", stream->state());
EXPECT_EQ(0u, stream->writeBufferedAmount());
EXPECT_EQ(0u, stream->readBufferedAmount());
RunUntilIdle(); RunUntilIdle();
} }
......
...@@ -35,6 +35,43 @@ function closed_stream_test(test_func, description) { ...@@ -35,6 +35,43 @@ function closed_stream_test(test_func, description) {
return test_func(t, remoteStream); return test_func(t, remoteStream);
}, 'Stream closed by remote reset(): ' + description); }, 'Stream closed by remote reset(): ' + description);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
const remoteWatcher =
new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
remoteStream.finish();
await localStream.waitForReadable(localStream.maxReadBufferedAmount);
assert_object_equals(
localStream.readInto(new Uint8Array(10)),
{ amount: 0, finished: true });
assert_equals(localStream.state, 'closed');
return test_func(t, localStream);
}, 'Stream closed by finish(), followed by reading remote finish: ' +
description);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.write(new Uint8Array(1));
const remoteWatcher =
new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
remoteStream.finish();
await localStream.waitForReadable(localStream.maxReadBufferedAmount);
assert_object_equals(
localStream.readInto(new Uint8Array(10)),
{ amount: 0, finished: true });
localStream.finish();
assert_equals(localStream.state, 'closed');
return test_func(t, localStream);
}, 'Stream closed by by reading remote finish, followed by finish(): ' +
description);
promise_test(async t => { promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] = const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t); await makeTwoConnectedQuicTransports(t);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment